diff --git a/Changes.md b/Changes.md index 5f4bc82b395..f5534e132c1 100644 --- a/Changes.md +++ b/Changes.md @@ -1,7 +1,13 @@ 1.5.x.x (relative to 1.5.2.0) ======= +Improvements +------------ +- VisualiserTool : Added `mode` plug. There are three current modes : + - Auto : Currently the same as `Color (Type Range)`. + - Color (Type Range) : Float, integer, V2f and color data is displayed without modification. Vector data is remapped from `[-1, 1]` to `[0, 1]`. + - Color (Manual Range) : Values are remapped from the range `[valueMin, valueMax]` to `[0, 1]`. 1.5.2.0 (relative to 1.5.1.0) ======= diff --git a/include/GafferSceneUI/Private/VisualiserTool.h b/include/GafferSceneUI/Private/VisualiserTool.h index 05091411474..2eebed72c35 100644 --- a/include/GafferSceneUI/Private/VisualiserTool.h +++ b/include/GafferSceneUI/Private/VisualiserTool.h @@ -68,12 +68,25 @@ class GAFFERSCENEUI_API VisualiserTool : public SelectionTool GAFFER_NODE_DECLARE_TYPE( GafferSceneUI::VisualiserTool, VisualiserToolTypeId, SelectionTool ); + enum class Mode + { + Auto, + ColorTypeRange, + ColorManualRange, + + First = Auto, + Last = ColorManualRange + }; + Gaffer::StringPlug *dataNamePlug(); const Gaffer::StringPlug *dataNamePlug() const; Gaffer::FloatPlug *opacityPlug(); const Gaffer::FloatPlug *opacityPlug() const; + Gaffer::IntPlug *modePlug(); + const Gaffer::IntPlug *modePlug() const; + Gaffer::V3fPlug *valueMinPlug(); const Gaffer::V3fPlug *valueMinPlug() const; diff --git a/python/GafferSceneUI/VisualiserToolUI.py b/python/GafferSceneUI/VisualiserToolUI.py index 072c7455173..4e75a1ad4ca 100644 --- a/python/GafferSceneUI/VisualiserToolUI.py +++ b/python/GafferSceneUI/VisualiserToolUI.py @@ -57,6 +57,8 @@ "order", 8, "tool:exclusive", False, + "toolbarLayout:activator:modeIsColorManualRange", lambda node : node["mode"].getValue() == GafferSceneUI.VisualiserTool.Mode.ColorManualRange, + plugs = { "dataName" : [ @@ -83,6 +85,34 @@ "toolbarLayout:section", "Bottom", "toolbarLayout:width", 100, + ], + "mode" : [ + + "description", + """ + The method for displaying the data. + + Float and integer data are displayed as grayscale. V2f data is displayed with + the `x` value for red, `y` value for green and `0` for blue. Vector data is + displayed with the `x` value for red, `y` value for green and `z` value for blue. + Color data is displayed directly. + + - Auto : Same as `Color (Type Range)`. + - Color (Type Range) : Float, integer, V2f and color data is displayed without + modification. Vector data is remapped from `[-1, 1]` to `[0, 1]`. + - Color (Manual Range) : Values are remapped from the range `[valueMin, valueMax]` to + `[0, 1]`. + """, + + "preset:Auto", GafferSceneUI.VisualiserTool.Mode.Auto, + "preset:Color (Type Range)", GafferSceneUI.VisualiserTool.Mode.ColorTypeRange, + "preset:Color (Manual Range)", GafferSceneUI.VisualiserTool.Mode.ColorManualRange, + + "plugValueWidget:type", "GafferUI.PresetsPlugValueWidget", + + "toolbarLayout:section", "Bottom", + "toolbarLayout:width", 150, + ], "valueMin" : [ @@ -97,6 +127,8 @@ "toolbarLayout:section", "Bottom", "toolbarLayout:width", 175, + "toolbarLayout:visibilityActivator", "modeIsColorManualRange", + ], "valueMax" : [ @@ -111,6 +143,8 @@ "toolbarLayout:section", "Bottom", "toolbarLayout:width", 175, + "toolbarLayout:visibilityActivator", "modeIsColorManualRange", + ], "size": [ diff --git a/src/GafferSceneUI/VisualiserTool.cpp b/src/GafferSceneUI/VisualiserTool.cpp index 70a5551eacf..1bb40e035e6 100644 --- a/src/GafferSceneUI/VisualiserTool.cpp +++ b/src/GafferSceneUI/VisualiserTool.cpp @@ -258,6 +258,7 @@ class VisualiserGadget : public Gadget // Get min/max values and colors and opacity UniformBlock uniforms; + const VisualiserTool::Mode mode = (VisualiserTool::Mode)m_tool->modePlug()->getValue(); const V3f valueMin = m_tool->valueMinPlug()->getValue(); const V3f valueMax = m_tool->valueMaxPlug()->getValue(); uniforms.opacity = m_tool->opacityPlug()->getValue(); @@ -265,10 +266,14 @@ class VisualiserGadget : public Gadget // Compute value range reciprocal // // NOTE : when range is <= 0 set the reciprocal to 0 so that value becomes 0 (minimum) - V3f valueRange = ( valueMax - valueMin ); - for( int i = 0; i < 3; ++i ) + std::optional valueRange; + if( mode == VisualiserTool::Mode::ColorManualRange ) { - valueRange[i] = ( valueRange[i] > 0.f ) ? ( 1.f / valueRange[i] ) : 0.f; + valueRange = ( valueMax - valueMin ); + for( int i = 0; i < 3; ++i ) + { + valueRange.value()[i] = ( valueRange.value()[i] > 0.f ) ? ( 1.f / valueRange.value()[i] ) : 0.f; + } } // Get the world to clip space matrix @@ -431,22 +436,29 @@ class VisualiserGadget : public Gadget [[fallthrough]]; case FloatVectorDataTypeId: enableVSZ = true; - uniforms.valueMin = V3f( valueMin.x ); - uniforms.valueRange = V3f( valueRange.x ); + uniforms.valueMin = valueRange ? V3f( valueMin.x ) : V3f( 0.f ); + uniforms.valueRange = valueRange ? V3f( valueRange.value().x ) : V3f( 1.f ); break; case V2fVectorDataTypeId: stride = 2; offset = true; - uniforms.valueMin = V3f( valueMin.x, valueMin.y, 0.f ); - uniforms.valueRange = V3f( valueRange.x, valueRange.y, 0.f ); + uniforms.valueMin = valueRange ? V3f( valueMin.x, valueMin.y, 0.f ) : V3f( 0.f ); + uniforms.valueRange = valueRange ? V3f( valueRange.value().x, valueRange.value().y, 0.f ) : V3f( 1.f, 1.f, 0.f ); break; case Color3fVectorDataTypeId: + stride = 3; + offset = true; + enableVSZ = true; + uniforms.valueMin = valueRange ? valueMin : V3f( 0.f ); + uniforms.valueRange = valueRange ? valueRange.value() : V3f( 1.f ); + break; case V3fVectorDataTypeId: stride = 3; offset = true; enableVSZ = true; - uniforms.valueMin = valueMin; - uniforms.valueRange = valueRange; + uniforms.valueMin = valueRange ? valueMin : V3f( -1.f ); + // Use 0.5 instead of 2.0 to account for reciprocal in `valueRange` above + uniforms.valueRange = valueRange ? valueRange.value() : V3f( 0.5f ); break; default: continue; @@ -702,6 +714,7 @@ VisualiserTool::VisualiserTool( SceneView *view, const std::string &name ) : Sel addChild( new StringPlug( "dataName", Plug::In, "uv" ) ); addChild( new FloatPlug( "opacity", Plug::In, g_opacityDefault, g_opacityMin, g_opacityMax ) ); + addChild( new IntPlug( "mode", Plug::In, (int)Mode::Auto, (int)Mode::First, (int)Mode::Last ) ); addChild( new V3fPlug( "valueMin", Plug::In, g_valueMinDefault ) ); addChild( new V3fPlug( "valueMax", Plug::In, g_valueMaxDefault ) ); addChild( new FloatPlug( "size", Plug::In, g_textSizeDefault, g_textSizeMin ) ); @@ -790,44 +803,54 @@ const FloatPlug *VisualiserTool::opacityPlug() const return getChild( g_firstPlugIndex + 1 ); } +IntPlug *VisualiserTool::modePlug() +{ + return getChild( g_firstPlugIndex + 2 ); +} + +const IntPlug *VisualiserTool::modePlug() const +{ + return getChild( g_firstPlugIndex + 2 ); +} + V3fPlug *VisualiserTool::valueMinPlug() { - return getChild( g_firstPlugIndex + 2 ); + return getChild( g_firstPlugIndex + 3 ); } const V3fPlug *VisualiserTool::valueMinPlug() const { - return getChild( g_firstPlugIndex + 2 ); + return getChild( g_firstPlugIndex + 3 ); } V3fPlug *VisualiserTool::valueMaxPlug() { - return getChild( g_firstPlugIndex + 3 ); + return getChild( g_firstPlugIndex + 4 ); } const V3fPlug *VisualiserTool::valueMaxPlug() const { - return getChild( g_firstPlugIndex + 3 ); + return getChild( g_firstPlugIndex + 4 ); } FloatPlug *VisualiserTool::sizePlug() { - return getChild( g_firstPlugIndex + 4 ); + return getChild( g_firstPlugIndex + 5 ); } const FloatPlug *VisualiserTool::sizePlug() const { - return getChild( g_firstPlugIndex + 4 ); + return getChild( g_firstPlugIndex + 5 ); } ScenePlug *VisualiserTool::internalScenePlug() { - return getChild( g_firstPlugIndex + 5 ); + return getChild( g_firstPlugIndex + 6 ); } const ScenePlug *VisualiserTool::internalScenePlug() const { - return getChild( g_firstPlugIndex + 5 ); + return getChild( g_firstPlugIndex + 6 ); } const std::vector &VisualiserTool::selection() const @@ -1036,7 +1059,8 @@ void VisualiserTool::plugDirtied( const Plug *plug ) plug == opacityPlug() || plug == valueMinPlug() || plug == valueMaxPlug() || - plug == sizePlug() + plug == sizePlug() || + plug == modePlug() ) { m_gadgetDirty = true; diff --git a/src/GafferSceneUIModule/ToolBinding.cpp b/src/GafferSceneUIModule/ToolBinding.cpp index f2290ea724b..2fffc1c6edd 100644 --- a/src/GafferSceneUIModule/ToolBinding.cpp +++ b/src/GafferSceneUIModule/ToolBinding.cpp @@ -317,8 +317,16 @@ void GafferSceneUIModule::bindTools() ; } - GafferBindings::NodeClass( nullptr, no_init ) - .def( init() ) - ; + { + scope s = GafferBindings::NodeClass( nullptr, no_init ) + .def( init() ) + ; + + enum_( "Mode" ) + .value( "Auto", VisualiserTool::Mode::Auto ) + .value( "ColorTypeRange", VisualiserTool::Mode::ColorTypeRange ) + .value( "ColorManualRange", VisualiserTool::Mode::ColorManualRange ) + ; + } }