From 9817cb4c44e4f47b777fdd0368c1893e5623f554 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 7 Nov 2017 15:35:43 +0100 Subject: [PATCH] Added highlight configuration in HighlightStageSetup job --- .../ui/overlays/ContextOverlayInterface.cpp | 2 +- .../render-utils/src/HighlightEffect.cpp | 5 +- .../render/src/render/HighlightStage.cpp | 97 +++++++++++++- libraries/render/src/render/HighlightStage.h | 60 ++++++++- .../developer/utilities/render/highlight.qml | 123 ++++++++++++++++-- 5 files changed, 262 insertions(+), 25 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 6a21221a8b..d40c0972e9 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -72,7 +72,7 @@ ContextOverlayInterface::ContextOverlayInterface() { render::Transaction transaction; initializeSelectionToSceneHandler(_selectionToSceneHandlers[0], "contextOverlayHighlightList", transaction); for (auto i = 1; i < MAX_SELECTION_COUNT; i++) { - auto selectionName = QString("contextOverlayHighlightList") + QString::number(i); + auto selectionName = QString("highlightList") + QString::number(i); initializeSelectionToSceneHandler(_selectionToSceneHandlers[i], selectionName, transaction); } const render::ScenePointer& scene = qApp->getMain3DScene(); diff --git a/libraries/render-utils/src/HighlightEffect.cpp b/libraries/render-utils/src/HighlightEffect.cpp index e332be53de..c938567425 100644 --- a/libraries/render-utils/src/HighlightEffect.cpp +++ b/libraries/render-utils/src/HighlightEffect.cpp @@ -434,9 +434,10 @@ void SelectionToHighlight::run(const render::RenderContextPointer& renderContext for (auto i = 0; i < HighlightSharedParameters::MAX_HIGHLIGHT_COUNT; i++) { std::ostringstream stream; - stream << "contextOverlayHighlightList"; if (i > 0) { - stream << i; + stream << "highlightList" << i; + } else { + stream << "contextOverlayHighlightList"; } auto selectionName = stream.str(); auto highlightId = highlightStage->getHighlightIdBySelection(selectionName); diff --git a/libraries/render/src/render/HighlightStage.cpp b/libraries/render/src/render/HighlightStage.cpp index effb7c7e98..6821504649 100644 --- a/libraries/render/src/render/HighlightStage.cpp +++ b/libraries/render/src/render/HighlightStage.cpp @@ -34,13 +34,96 @@ Index HighlightStage::getHighlightIdBySelection(const std::string& selectionName return INVALID_INDEX; } -HighlightStageSetup::HighlightStageSetup() { -} - -void HighlightStageSetup::run(const render::RenderContextPointer& renderContext) { - if (!renderContext->_scene->getStage(HighlightStage::getName())) { - auto stage = std::make_shared(); - renderContext->_scene->resetStage(HighlightStage::getName(), stage); +const HighlightStyle& HighlightStageConfig::getStyle() const { + auto styleIterator = _styles.find(_selectionName); + if (styleIterator != _styles.end()) { + return styleIterator->second; + } else { + auto insertion = _styles.insert(SelectionStyles::value_type{ _selectionName, HighlightStyle{} }); + return insertion.first->second; + } +} + +HighlightStyle& HighlightStageConfig::editStyle() { + auto styleIterator = _styles.find(_selectionName); + if (styleIterator != _styles.end()) { + return styleIterator->second; + } else { + auto insertion = _styles.insert(SelectionStyles::value_type{ _selectionName, HighlightStyle{} }); + return insertion.first->second; + } +} + +void HighlightStageConfig::setSelectionName(const QString& name) { + _selectionName = name.toStdString(); + emit dirty(); +} + +void HighlightStageConfig::setOutlineSmooth(bool isSmooth) { + editStyle().isOutlineSmooth = isSmooth; + emit dirty(); +} + +void HighlightStageConfig::setColorRed(float value) { + editStyle().color.r = value; + emit dirty(); +} + +void HighlightStageConfig::setColorGreen(float value) { + editStyle().color.g = value; + emit dirty(); +} + +void HighlightStageConfig::setColorBlue(float value) { + editStyle().color.b = value; + emit dirty(); +} + +void HighlightStageConfig::setOutlineWidth(float value) { + editStyle().outlineWidth = value; + emit dirty(); +} + +void HighlightStageConfig::setOutlineIntensity(float value) { + editStyle().outlineIntensity = value; + emit dirty(); +} + +void HighlightStageConfig::setUnoccludedFillOpacity(float value) { + editStyle().unoccludedFillOpacity = value; + emit dirty(); +} + +void HighlightStageConfig::setOccludedFillOpacity(float value) { + editStyle().occludedFillOpacity = value; + emit dirty(); +} + +HighlightStageSetup::HighlightStageSetup() { +} + +void HighlightStageSetup::configure(const Config& config) { + // Copy the styles here but update the stage with the new styles in run to be sure everything is + // thread safe... + _styles = config._styles; +} + +void HighlightStageSetup::run(const render::RenderContextPointer& renderContext) { + auto stage = renderContext->_scene->getStage(HighlightStage::getName()); + if (!stage) { + stage = std::make_shared(); + renderContext->_scene->resetStage(HighlightStage::getName(), stage); + } + + if (!_styles.empty()) { + render::Transaction transaction; + for (const auto& selection : _styles) { + auto& selectionName = selection.first; + auto& selectionStyle = selection.second; + transaction.resetSelectionHighlight(selectionName, selectionStyle); + } + renderContext->_scene->enqueueTransaction(transaction); + _styles.clear(); } } diff --git a/libraries/render/src/render/HighlightStage.h b/libraries/render/src/render/HighlightStage.h index a2c123580c..7600f1f724 100644 --- a/libraries/render/src/render/HighlightStage.h +++ b/libraries/render/src/render/HighlightStage.h @@ -63,14 +63,72 @@ namespace render { }; using HighlightStagePointer = std::shared_ptr; + class HighlightStageConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(QString selectionName READ getSelectionName WRITE setSelectionName NOTIFY dirty) + Q_PROPERTY(bool isOutlineSmooth READ isOutlineSmooth WRITE setOutlineSmooth NOTIFY dirty) + Q_PROPERTY(float colorR READ getColorRed WRITE setColorRed NOTIFY dirty) + Q_PROPERTY(float colorG READ getColorGreen WRITE setColorGreen NOTIFY dirty) + Q_PROPERTY(float colorB READ getColorBlue WRITE setColorBlue NOTIFY dirty) + Q_PROPERTY(float outlineWidth READ getOutlineWidth WRITE setOutlineWidth NOTIFY dirty) + Q_PROPERTY(float outlineIntensity READ getOutlineIntensity WRITE setOutlineIntensity NOTIFY dirty) + Q_PROPERTY(float unoccludedFillOpacity READ getUnoccludedFillOpacity WRITE setUnoccludedFillOpacity NOTIFY dirty) + Q_PROPERTY(float occludedFillOpacity READ getOccludedFillOpacity WRITE setOccludedFillOpacity NOTIFY dirty) + + public: + + using SelectionStyles = std::map; + + QString getSelectionName() const { return QString(_selectionName.c_str()); } + void setSelectionName(const QString& name); + + bool isOutlineSmooth() const { return getStyle().isOutlineSmooth; } + void setOutlineSmooth(bool isSmooth); + + float getColorRed() const { return getStyle().color.r; } + void setColorRed(float value); + + float getColorGreen() const { return getStyle().color.g; } + void setColorGreen(float value); + + float getColorBlue() const { return getStyle().color.b; } + void setColorBlue(float value); + + float getOutlineWidth() const { return getStyle().outlineWidth; } + void setOutlineWidth(float value); + + float getOutlineIntensity() const { return getStyle().outlineIntensity; } + void setOutlineIntensity(float value); + + float getUnoccludedFillOpacity() const { return getStyle().unoccludedFillOpacity; } + void setUnoccludedFillOpacity(float value); + + float getOccludedFillOpacity() const { return getStyle().occludedFillOpacity; } + void setOccludedFillOpacity(float value); + + std::string _selectionName{ "contextOverlayHighlightList" }; + mutable SelectionStyles _styles; + + const HighlightStyle& getStyle() const; + HighlightStyle& editStyle(); + + signals: + void dirty(); + }; + class HighlightStageSetup { public: - using JobModel = render::Job::Model; + using Config = HighlightStageConfig; + using JobModel = render::Job::Model; HighlightStageSetup(); + + void configure(const Config& config); void run(const RenderContextPointer& renderContext); protected: + + HighlightStageConfig::SelectionStyles _styles; }; } diff --git a/scripts/developer/utilities/render/highlight.qml b/scripts/developer/utilities/render/highlight.qml index eb2c66b275..6be74fcf40 100644 --- a/scripts/developer/utilities/render/highlight.qml +++ b/scripts/developer/utilities/render/highlight.qml @@ -11,9 +11,10 @@ import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 -import "highlightPage" + import "qrc:///qml/styles-uit" import "qrc:///qml/controls-uit" as HifiControls +import "configSlider" Rectangle { id: root @@ -22,10 +23,13 @@ Rectangle { anchors.margins: hifi.dimensions.contentMargin.x property var debugConfig: Render.getConfig("RenderMainView.HighlightDebug") + property var highlightConfig: Render.getConfig("UpdateScene.HighlightStageSetup") + signal sendToScript(var message); Column { - spacing: 5 + id: col + spacing: 10 anchors.left: parent.left anchors.right: parent.right anchors.margins: hifi.dimensions.contentMargin.x @@ -59,21 +63,112 @@ Rectangle { } } - TabView { - id: tabs - width: 384 - height: 400 + HifiControls.ComboBox { + id: box + width: 350 + z: 999 + editable: true + colorScheme: hifi.colorSchemes.dark + model: [ + "contextOverlayHighlightList", + "highlightList1", + "highlightList2", + "highlightList3", + "highlightList4"] + label: "" - onCurrentIndexChanged: { - sendToScript("highlight "+currentIndex) + Timer { + id: postpone + interval: 100; running: false; repeat: false + onTriggered: { paramWidgetLoader.sourceComponent = paramWidgets } } + onCurrentIndexChanged: { + root.highlightConfig["selectionName"] = model[currentIndex]; + sendToScript("highlight "+currentIndex) + // This is a hack to be sure the widgets below properly reflect the change of category: delete the Component + // by setting the loader source to Null and then recreate it 100ms later + paramWidgetLoader.sourceComponent = undefined; + postpone.interval = 100 + postpone.start() + } + } - Repeater { - model: [ 0, 1, 2, 3 ] - Tab { - title: "Outl."+modelData - HighlightPage { - highlightIndex: modelData + Loader { + id: paramWidgetLoader + sourceComponent: paramWidgets + width: 350 + } + + Component { + id: paramWidgets + + Column { + spacing: 10 + anchors.margins: hifi.dimensions.contentMargin.x + + HifiControls.Label { + text: "Outline" + } + Column { + spacing: 10 + anchors.left: parent.left + anchors.right: parent.right + HifiControls.CheckBox { + text: "Smooth" + checked: root.highlightConfig["isOutlineSmooth"] + onCheckedChanged: { + root.highlightConfig["isOutlineSmooth"] = checked; + } + } + Repeater { + model: ["Width:outlineWidth:5.0:0.0", + "Intensity:outlineIntensity:1.0:0.0" + ] + ConfigSlider { + label: qsTr(modelData.split(":")[0]) + integral: false + config: root.highlightConfig + property: modelData.split(":")[1] + max: modelData.split(":")[2] + min: modelData.split(":")[3] + } + } + } + + Separator {} + HifiControls.Label { + text: "Color" + } + Repeater { + model: ["Red:colorR:1.0:0.0", + "Green:colorG:1.0:0.0", + "Blue:colorB:1.0:0.0" + ] + ConfigSlider { + label: qsTr(modelData.split(":")[0]) + integral: false + config: root.highlightConfig + property: modelData.split(":")[1] + max: modelData.split(":")[2] + min: modelData.split(":")[3] + } + } + + Separator {} + HifiControls.Label { + text: "Fill Opacity" + } + Repeater { + model: ["Unoccluded:unoccludedFillOpacity:1.0:0.0", + "Occluded:occludedFillOpacity:1.0:0.0" + ] + ConfigSlider { + label: qsTr(modelData.split(":")[0]) + integral: false + config: root.highlightConfig + property: modelData.split(":")[1] + max: modelData.split(":")[2] + min: modelData.split(":")[3] } } }