Commit 52fd8ad8 authored by Kyle Lutz's avatar Kyle Lutz Committed by Utkarsh Ayachit

Refactoring code to set color/opacity/visibility for blocks.

This commit refactors some of the code added in recent weeks to add ability for
users to set display paramaters for blocks within a composite dataset. This
commit additionally adds support for changing block opacity.

Blocks colors/opacities can also be overridden when using scalar coloring.
The only issue is when depth-peeling gets used. In that case, point-data coloring
with texture (i.e. using interpolate scalars before mapping) results in color
bleeds. We need to dig into the depth peeling code to address that issue.

Change-Id: I2c86912b45bc0516dc4dc726df9448e0569c8312
parent cdde4af4
......@@ -47,6 +47,11 @@ bool vtkCompositeDataDisplayAttributes::GetBlockVisibility(unsigned int flat_ind
}
}
bool vtkCompositeDataDisplayAttributes::HasBlockVisibilities() const
{
return !this->BlockVisibilities.empty();
}
bool vtkCompositeDataDisplayAttributes::HasBlockVisibility(unsigned int flat_index) const
{
return this->BlockVisibilities.count(flat_index) == size_t(1);
......@@ -91,6 +96,11 @@ vtkColor3d vtkCompositeDataDisplayAttributes::GetBlockColor(
return vtkColor3d();
}
bool vtkCompositeDataDisplayAttributes::HasBlockColors() const
{
return !this->BlockColors.empty();
}
bool vtkCompositeDataDisplayAttributes::HasBlockColor(
unsigned int flat_index) const
{
......@@ -112,3 +122,40 @@ void vtkCompositeDataDisplayAttributes::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
void vtkCompositeDataDisplayAttributes::SetBlockOpacity(unsigned int flat_index, double opacity)
{
this->BlockOpacities[flat_index] = opacity;
}
double vtkCompositeDataDisplayAttributes::GetBlockOpacity(unsigned int flat_index) const
{
std::map<unsigned int, double>::const_iterator iter = this->BlockOpacities.find(flat_index);
if(iter != this->BlockOpacities.end())
{
return iter->second;
}
return 0;
}
bool vtkCompositeDataDisplayAttributes::HasBlockOpacities() const
{
return !this->BlockOpacities.empty();
}
bool vtkCompositeDataDisplayAttributes::HasBlockOpacity(unsigned int flat_index) const
{
return this->BlockOpacities.find(flat_index) != this->BlockOpacities.end();
}
void vtkCompositeDataDisplayAttributes::RemoveBlockOpacity(unsigned int flat_index)
{
this->BlockOpacities.erase(flat_index);
}
void vtkCompositeDataDisplayAttributes::RemoveBlockOpacities()
{
this->BlockOpacities.clear();
}
......@@ -34,6 +34,10 @@ public:
vtkTypeMacro(vtkCompositeDataDisplayAttributes, vtkObject)
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Returns true if any block has any block visibility is set.
bool HasBlockVisibilities() const;
// Description:
// Set/get the visibility for the block with \p flat_index.
void SetBlockVisibility(unsigned int flat_index, bool visible);
......@@ -59,6 +63,10 @@ public:
void GetBlockColor(unsigned int flat_index, double color[3]) const;
vtkColor3d GetBlockColor(unsigned int flat_index) const;
// Description:
// Returns true if any block has any block color is set.
bool HasBlockColors() const;
// Description:
// Returns true if the block with the given \p flat_index has a color.
bool HasBlockColor(unsigned int flat_index) const;
......@@ -71,6 +79,27 @@ public:
// Removes all block colors.
void RemoveBlockColors();
// Description:
// Set/get the opacity for the block with flat_index.
void SetBlockOpacity(unsigned int flat_index, double opacity);
double GetBlockOpacity(unsigned int flat_index) const;
// Description:
// Returns true if any block has an opacity set.
bool HasBlockOpacities() const;
// Description:
// Returns true if the block with flat_index has an opacity set.
bool HasBlockOpacity(unsigned int flat_index) const;
// Description:
// Removes the set opacity for the block with flat_index.
void RemoveBlockOpacity(unsigned int flat_index);
// Description:
// Removes all block opacities.
void RemoveBlockOpacities();
protected:
vtkCompositeDataDisplayAttributes();
~vtkCompositeDataDisplayAttributes();
......@@ -82,6 +111,7 @@ private:
private:
std::map<unsigned int, bool> BlockVisibilities;
std::map<unsigned int, vtkColor3d> BlockColors;
std::map<unsigned int, double> BlockOpacities;
};
#endif // __vtkCompositeDataDisplayAttributes_h
......@@ -14,30 +14,40 @@
=========================================================================*/
#include "vtkCompositePainter.h"
#include "vtkColor.h"
#include "vtkCompositeDataDisplayAttributes.h"
#include "vtkCompositeDataIterator.h"
#include "vtkCompositeDataSet.h"
#include "vtkGarbageCollector.h"
#include "vtkHardwareSelector.h"
#include "vtkObjectFactory.h"
#include "vtkRenderer.h"
#include "vtkPolyData.h"
#include "vtkInformation.h"
#include "vtkInformationObjectBaseKey.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkMultiPieceDataSet.h"
#include "vtkCompositeDataDisplayAttributes.h"
#include "vtkRenderWindow.h"
#include "vtkColor.h"
#include "vtkObjectFactory.h"
#include "vtkPolyData.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include <assert.h>
vtkStandardNewMacro(vtkCompositePainter);
// Return NULL if no override is supplied.
vtkAbstractObjectFactoryNewMacro(vtkCompositePainter)
vtkInformationKeyMacro(vtkCompositePainter, DISPLAY_ATTRIBUTES, ObjectBase);
vtkCxxSetObjectMacro(vtkCompositePainter, CompositeDataDisplayAttributes, vtkCompositeDataDisplayAttributes);
//----------------------------------------------------------------------------
vtkCompositePainter::vtkCompositePainter()
{
this->OutputData = 0;
this->CompositeDataDisplayAttributes = 0;
}
//----------------------------------------------------------------------------
vtkCompositePainter::~vtkCompositePainter()
{
this->SetCompositeDataDisplayAttributes(0);
}
//----------------------------------------------------------------------------
......@@ -62,20 +72,39 @@ void vtkCompositePainter::RenderInternal(vtkRenderer* renderer,
vtkHardwareSelector* selector = renderer->GetSelector();
if(this->CompositeDataDisplayAttributes)
if (this->CompositeDataDisplayAttributes &&
(this->CompositeDataDisplayAttributes->HasBlockOpacities() ||
this->CompositeDataDisplayAttributes->HasBlockVisibilities() ||
this->CompositeDataDisplayAttributes->HasBlockColors()))
{
vtkProperty* prop = actor->GetProperty();
RenderBlockState state;
// Push base-values on the state stack.
state.Visibility.push(true);
state.Opacity.push(prop->GetOpacity());
state.AmbientColor.push(vtkColor3d(prop->GetAmbientColor()));
state.DiffuseColor.push(vtkColor3d(prop->GetDiffuseColor()));
state.SpecularColor.push(vtkColor3d(prop->GetSpecularColor()));
// OpenGL currently knows how to render *this* state.
state.RenderedOpacity = state.Opacity.top();
state.RenderedAmbientColor = state.AmbientColor.top();
state.RenderedDiffuseColor = state.DiffuseColor.top();
state.RenderedSpecularColor = state.SpecularColor.top();
// render using the composite data attributes
unsigned int flat_index = 0;
bool visible = true;
vtkColor3d color(0.5, 0.5, 0.5);
this->RenderBlock(renderer,
actor,
typeflags,
forceCompileOnly,
input,
flat_index,
visible,
color);
state);
// restore OpenGL state, if it was changed.
this->UpdateRenderingState(renderer->GetRenderWindow(), actor->GetProperty(), state);
}
else
{
......@@ -117,101 +146,103 @@ void vtkCompositePainter::RenderBlock(vtkRenderer *renderer,
bool forceCompileOnly,
vtkDataObject *dobj,
unsigned int &flat_index,
bool &visible,
vtkColor3d &color)
vtkCompositePainter::RenderBlockState &state)
{
vtkHardwareSelector *selector = renderer->GetSelector();
vtkProperty *property = actor->GetProperty();
assert("Sanity Check" &&
(state.Visibility.size() > 0) &&
(state.Opacity.size() > 0) &&
(state.AmbientColor.size() > 0) &&
(state.DiffuseColor.size() > 0) &&
(state.SpecularColor.size() > 0));
// push display attributes
bool pop_visibility = false;
bool prev_visible = visible;
if(this->CompositeDataDisplayAttributes->HasBlockVisibility(flat_index))
{
visible = this->CompositeDataDisplayAttributes->GetBlockVisibility(flat_index);
pop_visibility = true;
}
vtkHardwareSelector *selector = renderer->GetSelector();
vtkProperty *property = actor->GetProperty();
vtkCompositeDataDisplayAttributes* cda = this->CompositeDataDisplayAttributes;
bool pop_color = false;
vtkColor3d prev_color = color;
if(this->CompositeDataDisplayAttributes->HasBlockColor(flat_index))
{
color = this->CompositeDataDisplayAttributes->GetBlockColor(flat_index);
pop_color = true;
// A block always *has* a visibility state, either explicitly set or
// inherited.
state.Visibility.push(
cda->HasBlockVisibility(flat_index) ?
cda->GetBlockVisibility(flat_index) : state.Visibility.top());
double color4[] = { color[0], color[1], color[2], 1. };
property->RenderMaterial(actor, renderer, color4, color4, color4, 1.);
}
bool overrides_opacity = cda->HasBlockOpacity(flat_index);
if (overrides_opacity)
{
state.Opacity.push(cda->GetBlockOpacity(flat_index));
}
vtkMultiBlockDataSet *mbds = vtkMultiBlockDataSet::SafeDownCast(dobj);
vtkMultiPieceDataSet *mpds = vtkMultiPieceDataSet::SafeDownCast(dobj);
if(mbds || mpds)
{
// move flat_index to first child
flat_index++;
bool overrides_color = cda->HasBlockColor(flat_index);
if (overrides_color)
{
vtkColor3d color = cda->GetBlockColor(flat_index);
state.AmbientColor.push(color);
state.DiffuseColor.push(color);
state.SpecularColor.push(color);
}
unsigned int my_flat_index = flat_index;
// Advance flat-index. After this point, flat_index no longer points to this
// block.
flat_index++;
// recurse down to child blocks
unsigned int childCount =
mbds ? mbds->GetNumberOfBlocks() : mpds->GetNumberOfPieces();
for(unsigned int i = 0; i < childCount; i++)
vtkMultiBlockDataSet *mbds = vtkMultiBlockDataSet::SafeDownCast(dobj);
vtkMultiPieceDataSet *mpds = vtkMultiPieceDataSet::SafeDownCast(dobj);
if (mbds || mpds)
{
unsigned int numChildren = mbds? mbds->GetNumberOfBlocks() :
mpds->GetNumberOfPieces();
for (unsigned int cc=0 ; cc < numChildren; cc++)
{
vtkDataObject* child = mbds ? mbds->GetBlock(cc) : mpds->GetPiece(cc);
if (child == NULL)
{
this->RenderBlock(renderer,
actor,
typeflags,
forceCompileOnly,
mbds ? mbds->GetBlock(i) : mpds->GetPiece(i),
flat_index,
visible,
color);
// speeds things up when dealing with NULL blocks (which is common with
// AMRs).
flat_index++;
continue;
}
this->RenderBlock(renderer, actor, typeflags, forceCompileOnly,
child, flat_index, state);
}
else if(dobj)
}
else if (dobj && state.Visibility.top() == true && state.Opacity.top() > 0.0)
{
// Implies that the block is a non-null leaf node.
// The top of the "stacks" have the state that this block must be rendered
// with.
if (selector)
{
// render leaf-node
if(visible)
{
if(selector)
{
selector->BeginRenderProp();
// If hardware selection is in progress, we need to pass the composite
// index to the selection framework,
selector->RenderCompositeIndex(flat_index);
}
this->DelegatePainter->SetInput(dobj);
this->OutputData = dobj;
this->Superclass::RenderInternal(renderer,
actor,
typeflags,
forceCompileOnly);
this->OutputData = 0;
if(selector)
{
selector->EndRenderProp();
}
}
flat_index++;
selector->BeginRenderProp();
selector->RenderCompositeIndex(my_flat_index);
}
else
{
flat_index++;
// Not selecting, render the colors and stuff correctly for this block.
// For that.
this->UpdateRenderingState(renderer->GetRenderWindow(), property, state);
}
// pop display attributes (if neccessary)
if(pop_visibility)
{
visible = prev_visible;
this->DelegatePainter->SetInput(dobj);
this->OutputData = dobj;
this->Superclass::RenderInternal(renderer, actor, typeflags, forceCompileOnly);
this->OutputData = 0;
if (selector)
{
selector->EndRenderProp();
}
}
if(pop_color)
if (overrides_color)
{
color = prev_color;
double color4[] = { color[0], color[1], color[2], 1. };
property->RenderMaterial(actor, renderer, color4, color4, color4, 1.);
state.AmbientColor.pop();
state.DiffuseColor.pop();
state.SpecularColor.pop();
}
if (overrides_opacity)
{
state.Opacity.pop();
}
state.Visibility.pop();
}
//-----------------------------------------------------------------------------
......@@ -222,9 +253,33 @@ void vtkCompositePainter::ReportReferences(vtkGarbageCollector *collector)
vtkGarbageCollectorReport(collector, this->OutputData, "Output");
}
//----------------------------------------------------------------------------
void vtkCompositePainter::ProcessInformation(vtkInformation* info)
{
this->Superclass::ProcessInformation(info);
if (info->Has(DISPLAY_ATTRIBUTES()))
{
this->SetCompositeDataDisplayAttributes(
vtkCompositeDataDisplayAttributes::SafeDownCast(
info->Get(DISPLAY_ATTRIBUTES())));
}
}
//----------------------------------------------------------------------------
void vtkCompositePainter::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "CompositeDataDisplayAttributes: " ;
if (this->CompositeDataDisplayAttributes)
{
os << endl;
this->CompositeDataDisplayAttributes->PrintSelf(os, indent.GetNextIndent());
}
else
{
os << "(none)" << endl;
}
}
......@@ -24,8 +24,13 @@
#include "vtkRenderingCoreModule.h" // For export macro
#include "vtkPainter.h"
#include "vtkColor.h" // needed for vtkColor3d
#include <stack> // needed for RenderBlockState.
class vtkColor3d;
class vtkCompositeDataDisplayAttributes;
class vtkInformationObjectBaseKey;
class vtkProperty;
class vtkRenderWindow;
class VTKRENDERINGCORE_EXPORT vtkCompositePainter : public vtkPainter
{
......@@ -39,6 +44,18 @@ public:
// simply forwards the input data object as the output.
virtual vtkDataObject* GetOutput();
// Description:
// Key used to pass a vtkCompositeDataDisplayAttributes instance doing the
// painter pipeline.
static vtkInformationObjectBaseKey* DISPLAY_ATTRIBUTES();
// Description:
// Set/get the composite data set display attributes. If set, these attributes
// can be used by the painter to control specific rendering attributes on a
// per-block basis for a multi-block dataset.
void SetCompositeDataDisplayAttributes(vtkCompositeDataDisplayAttributes *attributes);
vtkGetObjectMacro(CompositeDataDisplayAttributes, vtkCompositeDataDisplayAttributes)
//BTX
protected:
vtkCompositePainter();
......@@ -48,6 +65,11 @@ protected:
// Take part in garbage collection.
virtual void ReportReferences(vtkGarbageCollector *collector);
// Description:
// Called before RenderInternal() if the Information has been changed
// since the last time this method was called.
virtual void ProcessInformation(vtkInformation* information);
// Description:
// Performs the actual rendering. Subclasses may override this method.
// default implementation merely call a Render on the DelegatePainter,
......@@ -57,16 +79,36 @@ protected:
virtual void RenderInternal(vtkRenderer* renderer, vtkActor* actor,
unsigned long typeflags, bool forceCompileOnly);
class RenderBlockState
{
public:
std::stack<bool> Visibility;
std::stack<double> Opacity;
std::stack<vtkColor3d> AmbientColor;
std::stack<vtkColor3d> DiffuseColor;
std::stack<vtkColor3d> SpecularColor;
double RenderedOpacity;
vtkColor3d RenderedAmbientColor;
vtkColor3d RenderedDiffuseColor;
vtkColor3d RenderedSpecularColor;
};
void RenderBlock(vtkRenderer *renderer,
vtkActor *actor,
unsigned long typeflags,
bool forceCompileOnly,
vtkDataObject *dobj,
unsigned int &flat_index,
bool &visible,
vtkColor3d &color);
RenderBlockState &state);
// Description:
// Overridden in vtkOpenGLCompositePainter to pass attributes to OpenGL.
virtual void UpdateRenderingState(
vtkRenderWindow*, vtkProperty*, RenderBlockState&) {}
vtkDataObject* OutputData;
vtkCompositeDataDisplayAttributes *CompositeDataDisplayAttributes;
private:
vtkCompositePainter(const vtkCompositePainter&); // Not implemented.
void operator=(const vtkCompositePainter&); // Not implemented.
......
......@@ -137,6 +137,12 @@ bool vtkCompositePolyDataMapper2::GetIsOpaque()
}
}
}
else if(this->CompositeAttributes &&
this->CompositeAttributes->HasBlockOpacities())
{
return false;
}
return this->Superclass::GetIsOpaque();
}
......@@ -221,6 +227,46 @@ void vtkCompositePolyDataMapper2::RemoveBlockColors()
}
}
//----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::SetBlockOpacity(unsigned int index, double opacity)
{
if(this->CompositeAttributes)
{
this->CompositeAttributes->SetBlockOpacity(index, opacity);
this->Modified();
}
}
//----------------------------------------------------------------------------
double vtkCompositePolyDataMapper2::GetBlockOpacity(unsigned int index)
{
if(this->CompositeAttributes)
{
return this->CompositeAttributes->GetBlockOpacity(index);
}
return 1.;
}
//----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::RemoveBlockOpacity(unsigned int index)
{
if(this->CompositeAttributes)
{
this->CompositeAttributes->RemoveBlockOpacity(index);
this->Modified();
}
}
//----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::RemoveBlockOpacities()
{
if(this->CompositeAttributes)
{
this->CompositeAttributes->RemoveBlockOpacities();
this->Modified();
}
}
//----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::SetCompositeDataDisplayAttributes(
vtkCompositeDataDisplayAttributes *attributes)
......@@ -228,25 +274,7 @@ void vtkCompositePolyDataMapper2::SetCompositeDataDisplayAttributes(
if(this->CompositeAttributes != attributes)
{
this->CompositeAttributes = attributes;
// set composite display attributes on the composite painter
vtkDefaultPainter *defaultPainter =
vtkDefaultPainter::SafeDownCast(this->Painter);
if(defaultPainter)
{
vtkCompositePainter *compositePainter =
defaultPainter->GetCompositePainter();
compositePainter->
SetCompositeDataDisplayAttributes(this->CompositeAttributes);
}
// set composite display attributes on the selection painter
if(this->SelectionCompositePainter)
{
this->SelectionCompositePainter->
SetCompositeDataDisplayAttributes(this->CompositeAttributes);
}
this->Modified();
}
}
......@@ -257,6 +285,15 @@ vtkCompositePolyDataMapper2::GetCompositeDataDisplayAttributes()
return this->CompositeAttributes;
}
//----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::UpdatePainterInformation()
{
this->Superclass::UpdatePainterInformation();
this->PainterInformation->Set(