diff options
author | Jack Ha <jackha@gmail.com> | 2018-03-21 18:55:58 +0300 |
---|---|---|
committer | Jack Ha <jackha@gmail.com> | 2018-03-21 18:55:58 +0300 |
commit | d8d226c0d654b3dbfc05e800785a013db8cc1642 (patch) | |
tree | ef02946d9320718f901bed495cb2f339eec1f94e | |
parent | 25bf7a6ababeaee3428924a25bc2f748897db817 (diff) |
CURA-4557 it's now a small button next to the job spec when one of the warping materials is selected
-rw-r--r-- | plugins/ModelChecker/ModelChecker.py | 138 | ||||
-rw-r--r-- | plugins/ModelChecker/ModelChecker.qml | 47 | ||||
-rw-r--r-- | plugins/ModelChecker/__init__.py | 15 | ||||
-rw-r--r-- | plugins/ModelChecker/model_checker.svg | 6 | ||||
-rw-r--r-- | resources/qml/JobSpecs.qml | 37 | ||||
-rw-r--r-- | resources/themes/cura-light/theme.json | 2 |
6 files changed, 189 insertions, 56 deletions
diff --git a/plugins/ModelChecker/ModelChecker.py b/plugins/ModelChecker/ModelChecker.py index afe8a7e47d..285002deda 100644 --- a/plugins/ModelChecker/ModelChecker.py +++ b/plugins/ModelChecker/ModelChecker.py @@ -1,13 +1,16 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from PyQt5.QtCore import QTimer -from cura.Scene.CuraSceneNode import CuraSceneNode +import os + +from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, pyqtProperty from UM.Application import Application -from UM.Tool import Tool +from UM.Extension import Extension +from UM.Logger import Logger from UM.Message import Message from UM.i18n import i18nCatalog +from UM.PluginRegistry import PluginRegistry from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator catalog = i18nCatalog("cura") @@ -17,35 +20,34 @@ SHRINKAGE_THRESHOLD = 0.5 WARNING_SIZE_XY = 150 WARNING_SIZE_Z = 100 +# Use this when actual shrinkage data is not in fdm_materials yet +MATERIALS_LOOKUP = { + "generic_abs": 1, + "generic_pc": 1, + "generic_pp": 1, + "generic_cpe_plus": 1 +} + + +class ModelChecker(QObject, Extension): + + needCheckChanged = pyqtSignal() -class ModelChecker(Tool): def __init__(self): super().__init__() - self._last_known_tool_id = None + self._button_view = None + self._need_checks = False - self._controller.activeToolChanged.connect(self._onActiveToolChanged) + Application.getInstance().initializationFinished.connect(self.bindSignals) - def checkObjects(self, nodes_to_check): - warning_nodes = [] - global_container_stack = Application.getInstance().getGlobalContainerStack() - if global_container_stack is None: - return [] - material_shrinkage = {} - need_check = False + def bindSignals(self): + Application.getInstance().getMachineManager().rootMaterialChanged.connect(self._onChanged) - # Get all shrinkage values of materials used - for extruder_position, extruder in global_container_stack.extruders.items(): - shrinkage = extruder.material.getProperty("material_shrinkage_percentage", "value") - if shrinkage is None: - shrinkage = 0 - if shrinkage > SHRINKAGE_THRESHOLD: - need_check = True - material_shrinkage[extruder_position] = shrinkage + def checkObjectsForShrinkage(self, nodes_to_check): + material_shrinkage = self.getMaterialShrinkage() - # Check if we can bail out fast - if not need_check: - return + warning_nodes = [] # Check node material shrinkage and bounding box size for node in nodes_to_check: @@ -64,7 +66,7 @@ class ModelChecker(Tool): for node in DepthFirstIterator(scene.getRoot()): if node.callDecoration("isSliceable"): nodes_to_check.append(node) - return self.checkObjects(nodes_to_check) + return self.checkObjectsForShrinkage(nodes_to_check) ## Display warning message def showWarningMessage(self, warning_nodes): @@ -82,23 +84,77 @@ class ModelChecker(Tool): def showHappyMessage(self): happy_message = Message(catalog.i18nc( "@info:status", - "The Model Checker did not detect any problems with your model / print setup combination."), + "The Model Checker did not detect any problems with your model / chosen materials combination."), lifetime = 5, title = catalog.i18nc("@info:title", "Model Checker")) happy_message.show() - def _onActiveToolChanged(self): - active_tool = self.getController().getActiveTool() - if active_tool is None: - return - active_tool_id = active_tool.getPluginId() - if active_tool_id != self.getPluginId(): - self._last_known_tool_id = active_tool_id - if active_tool_id == self.getPluginId(): - warning_nodes = self.checkAllSliceableNodes() - if warning_nodes: - self.showWarningMessage(warning_nodes) - else: - self.showHappyMessage() - if self._last_known_tool_id is not None: - self.getController().setActiveTool(self._last_known_tool_id) + ## Creates the view used by show popup. The view is saved because of the fairly aggressive garbage collection. + def _createView(self): + Logger.log("d", "Creating model checker view.") + + # Create the plugin dialog component + path = os.path.join(PluginRegistry.getInstance().getPluginPath("ModelChecker"), "ModelChecker.qml") + self._button_view = Application.getInstance().createQmlComponent(path, {"manager": self}) + + # The qml is only the button + Application.getInstance().addAdditionalComponent("jobSpecsButton", self._button_view) + + Logger.log("d", "Model checker view created.") + + def _onChanged(self, *args): + if self._button_view is None: + self._createView() + old_need_checks = self._need_checks + self._need_checks = self.calculateNeedCheck() + if old_need_checks != self._need_checks: + self.needCheckChanged.emit() + + @pyqtSlot() + def runChecks(self): + warning_nodes = self.checkAllSliceableNodes() + if warning_nodes: + self.showWarningMessage(warning_nodes) + else: + self.showHappyMessage() + + # TODO: use this if branch feature_model_check is merged in fdm_materials to master + # def getMaterialShrinkage(self): + # global_container_stack = Application.getInstance().getGlobalContainerStack() + # if global_container_stack is None: + # return {} + # + # material_shrinkage = {} + # # Get all shrinkage values of materials used + # for extruder_position, extruder in global_container_stack.extruders.items(): + # shrinkage = extruder.material.getProperty("material_shrinkage_percentage", "value") + # if shrinkage is None: + # shrinkage = 0 + # material_shrinkage[extruder_position] = shrinkage + # return material_shrinkage + + def getMaterialShrinkage(self): + global_container_stack = Application.getInstance().getGlobalContainerStack() + if global_container_stack is None: + return {} + + material_shrinkage = {} + # Get all shrinkage values of materials used + for extruder_position, extruder in global_container_stack.extruders.items(): + base_file = extruder.material.getMetaDataEntry("base_file") + shrinkage = MATERIALS_LOOKUP.get(base_file, 0) + material_shrinkage[extruder_position] = shrinkage + return material_shrinkage + + @pyqtProperty(bool, notify = needCheckChanged) + def needCheck(self): + return self._need_checks + + def calculateNeedCheck(self): + need_check = False + + for shrinkage in self.getMaterialShrinkage().values(): + if shrinkage > SHRINKAGE_THRESHOLD: + need_check = True + + return need_check diff --git a/plugins/ModelChecker/ModelChecker.qml b/plugins/ModelChecker/ModelChecker.qml new file mode 100644 index 0000000000..77a483c2c6 --- /dev/null +++ b/plugins/ModelChecker/ModelChecker.qml @@ -0,0 +1,47 @@ +// 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 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"} + + visible: manager.needCheck + tooltip: catalog.i18nc("@info:tooltip", "Check current setup for known problems.") + onClicked: manager.runChecks() + + //anchors.leftMargin: UM.Theme.getSize("default_margin").width + + //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 + + 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: "model_checker.svg" + } + } + } +} diff --git a/plugins/ModelChecker/__init__.py b/plugins/ModelChecker/__init__.py index b2b8587a7a..5f4d443729 100644 --- a/plugins/ModelChecker/__init__.py +++ b/plugins/ModelChecker/__init__.py @@ -1,21 +1,14 @@ -# Copyright (c) 2017 Ultimaker B.V. +# Copyright (c) 2018 Ultimaker B.V. # This example is released under the terms of the AGPLv3 or higher. from . import ModelChecker from UM.i18n import i18nCatalog -i18n_catalog = i18nCatalog("uranium") +i18n_catalog = i18nCatalog("cura") def getMetaData(): - return { - "tool": { - "name": i18n_catalog.i18nc("@label", "Model Checker"), - "description": i18n_catalog.i18nc("@info:tooltip", "Checks models and print configuration for possible printing issues and give suggestions."), - "icon": "model_checker.svg", - "weight": 10 - } - } + return {} def register(app): - return { "tool": ModelChecker.ModelChecker() } + return { "extension": ModelChecker.ModelChecker() } diff --git a/plugins/ModelChecker/model_checker.svg b/plugins/ModelChecker/model_checker.svg index ca5228155a..5b9dd4d197 100644 --- a/plugins/ModelChecker/model_checker.svg +++ b/plugins/ModelChecker/model_checker.svg @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> <svg width="30px" height="30px" viewBox="0 0 30 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title>ModelChecker</title> - <g id="ModelChecker" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> - <polygon id="Rectangle-3" fill="#000000" points="19 11 30 8 30 24 19 27"></polygon> + <g id="ModelChecker" stroke="none" fill="none"> + <polygon fill="#000000" points="19 11 30 8 30 24 19 27"></polygon> <path d="M10,19 C5.581722,19 2,15.418278 2,11 C2,6.581722 5.581722,3 10,3 C14.418278,3 18,6.581722 18,11 C18,15.418278 14.418278,19 10,19 Z M10,17 C13.3137085,17 16,14.3137085 16,11 C16,7.6862915 13.3137085,5 10,5 C6.6862915,5 4,7.6862915 4,11 C4,14.3137085 6.6862915,17 10,17 Z" id="Combined-Shape" fill="#000000"></path> - <polygon id="Polygon" fill="#000000" points="4.2 15 6 16.8 1.8 21 0 19.2"></polygon> + <polygon fill="#000000" points="4.2 15 6 16.8 1.8 21 0 19.2"></polygon> <path d="M18.7333454,8.81666365 C18.2107269,6.71940704 16.9524304,4.91317986 15.248379,3.68790525 L18,3 L30,6 L18.7333454,8.81666365 Z M17,16.6573343 L17,27 L6,24 L6,19.0644804 C7.20495897,19.6632939 8.56315852,20 10,20 C12.8272661,20 15.3500445,18.6963331 17,16.6573343 Z" id="Combined-Shape" fill="#000000"></path> </g> </svg> diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml index 04e8ec397f..5cf6987f75 100644 --- a/resources/qml/JobSpecs.qml +++ b/resources/qml/JobSpecs.qml @@ -124,15 +124,50 @@ Item { } } + Row { + id: additionalComponentsRow + anchors.top: jobNameRow.bottom + anchors.right: parent.right + } + Label { id: boundingSpec anchors.top: jobNameRow.bottom - anchors.right: parent.right + anchors.right: additionalComponentsRow.left + anchors.rightMargin: + { + if (additionalComponentsRow.width > 0) + { + return UM.Theme.getSize("default_margin").width + } + else + { + return 0; + } + } height: UM.Theme.getSize("jobspecs_line").height verticalAlignment: Text.AlignVCenter font: UM.Theme.getFont("small") color: UM.Theme.getColor("text_scene") text: CuraApplication.getSceneBoundingBoxString } + + Component.onCompleted: { + base.addAdditionalComponents("jobSpecsButton") + } + + Connections { + target: CuraApplication + onAdditionalComponentsChanged: base.addAdditionalComponents("jobSpecsButton") + } + + function addAdditionalComponents (areaId) { + if(areaId == "jobSpecsButton") { + for (var component in CuraApplication.additionalComponents["jobSpecsButton"]) { + CuraApplication.additionalComponents["jobSpecsButton"][component].parent = additionalComponentsRow + } + } + } + } diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json index 4f4b2306a8..0fde7f3bc9 100644 --- a/resources/themes/cura-light/theme.json +++ b/resources/themes/cura-light/theme.json @@ -411,6 +411,8 @@ "save_button_save_to_button": [0.3, 2.7], "save_button_specs_icons": [1.4, 1.4], + "job_specs_button": [2.7, 2.7], + "monitor_preheat_temperature_control": [4.5, 2.0], "modal_window_minimum": [60.0, 45], |