Commit 6fcb3c21 authored by Dave Partyka's avatar Dave Partyka

ENH: adding new set of classes that place labels in a scene using a priority...

ENH: adding new set of classes that place labels in a scene using a priority stored in a tree based on the spatial subdivision the bounds of the lables in the scene.
parent 6071b701
......@@ -80,6 +80,11 @@ SET( Kit_SRCS
vtkInteractorStyleUser.cxx
vtkIVExporter.cxx
vtkLabeledDataMapper.cxx
vtkLabelHierarchy.cxx
vtkLabelHierarchyAlgorithm.cxx
vtkLabelHierarchyIterator.cxx
vtkLabelPlacer.cxx
vtkLabelSizeCalculator.cxx
vtkLeaderActor2D.cxx
vtkLightCollection.cxx
vtkLight.cxx
......@@ -100,6 +105,7 @@ SET( Kit_SRCS
vtkPicker.cxx
vtkPixelBufferObject.cxx
vtkPointPicker.cxx
vtkPointSetToLabelHierarchy.cxx
vtkPointsPainter.cxx
vtkPOVExporter.cxx
vtkPolyDataMapper2D.cxx
......@@ -272,6 +278,7 @@ SET_SOURCE_FILES_PROPERTIES(
# OK, so it's not abstract, but this stops the instantiator
# from trying to call vtkRenderingInstantiatorvtkglNew():
${VTK_BINARY_DIR}/Rendering/vtkgl.cxx
vtkLabelHierarchyIterator.cxx
ABSTRACT
)
......
This diff is collapsed.
/*=========================================================================
Program: Visualization Toolkit
Module: vtkLabelHierarchy.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*-------------------------------------------------------------------------
Copyright 2008 Sandia Corporation.
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
// .NAME vtkLabelHierarchy - contains an octree of labels
//
// .SECTION Description
// This class represents labels in a hierarchy used to denote rendering priority.
// A binary tree of labels is maintained that subdivides the bounds of the
// of the label anchors spatially. Which level of the tree a label occupies
// determines its priority; those at higher levels of the tree will be
// more likely to render than those at lower levels of the tree.
//
// Pass vtkLabelHierarchy objects to a vtkLabelPlacer filter for dynamic,
// non-overlapping, per-frame placement of labels.
//
// Note that if we have a d-dimensional binary tree and we want a fixed
// number \f$n\f$ of labels in each node (all nodes, not just leaves),
// we can compute the depth of tree required assuming a uniform distribution
// of points. Given a total of \f$N\f$ points we know that
// \f$\frac{N}{|T|} = n\f$, where \f$|T|\f$ is the cardinality of the tree (i.e.,
// the number of nodes it contains).
// Because we have a uniform distribution, the tree will be uniformly subdivided
// and thus \f$|T| = 1 + 2^d + \left(2^d\right)^2 + \cdots + \left(2^d\right)^k\f$,
// where \f$d\f$ is the dimensionality of the input points (fixed at 3 for now).
// As \f$k\f$ becomes large, \f$|T|\approx 2 \left(2^d\right)^k\f$.
// Using this approximation, we can solve for \f$k\f$:
// \f[ k = \frac{\log{\frac{N}{2n}}}{\log{2^d}} \f]
// Given a set of \f$N\f$ input label anchors, we'll compute \f$k\f$ and then
// bin the anchors into tree nodes at level \f$k\f$ of the tree. After this,
// all the nodes will be in the leaves of the tree and those leaves will be at
// the \f$k\f$-th level; no anchors will be in levels \f$1, 2, \ldots, k-1\f$.
// To fix that, we'll choose to move some anchors upwards.
// The exact number to move upwards depends on \a TargetLabelCount. We'll
// move as many up as required to have \a TargetLabelCount at each node.
//
// You should avoid situations where \a MaximumDepth does not allow for
// \a TargetLabelCount or fewer entries at each node. The \a MaximumDepth
// is a hard limit while \a TargetLabelCount is a suggested optimum. You will
// end up with many more than \a TargetLabelCount entries per node and things
// will be sloooow.
#ifndef __vtkLabelHierarchy_h
#define __vtkLabelHierarchy_h
#include "vtkPointSet.h"
class vtkCamera;
class vtkLabelHierarchyIterator;
class vtkPoints;
class vtkPolyData;
class vtkDataArray;
class VTK_RENDERING_EXPORT vtkLabelHierarchy : public vtkPointSet
{
public:
static vtkLabelHierarchy* New();
vtkTypeRevisionMacro(vtkLabelHierarchy,vtkPointSet);
virtual void PrintSelf( ostream& os, vtkIndent indent );
// Description:
// Override SetPoints so we can reset the hierarchy when the points change.
virtual void SetPoints( vtkPoints* );
// Description:
// Fill the hierarchy with the input labels.
virtual void ComputeHierarchy();
// Description:
// The number of labels that is ideally present at any octree node.
// It is best if this is a multiple of \f$2^d\f$.
vtkSetMacro(TargetLabelCount,int);
vtkGetMacro(TargetLabelCount,int);
// Description:
// The maximum depth of the octree.
vtkSetMacro(MaximumDepth,int);
vtkGetMacro(MaximumDepth,int);
//BTX
// Description:
// Enumeration of iterator types.
enum IteratorType {
FULL_SORT,
FRUSTUM
};
//ETX
// Description:
// Set/get the array specifying the importance (priority) of each label.
virtual void SetPriorities(vtkDataArray* arr);
vtkGetObjectMacro(Priorities,vtkDataArray);
//BTX
// Description:
// Returns an iterator for this data object.
// positionsAsNormals should only be true when labels are on a sphere centered at the origin
// (3D world).
// @param type - the type should be one of FULL_SORT, FRUSTUM.
// @param camera - the current camera.
// @param frustumPlanes - should be the output of the camera's frustum planes.
// @param positionsAsNormals - throws out octree nodes on the opposite side of the origin.
vtkLabelHierarchyIterator* NewIterator(
int type, vtkCamera* cam, double frustumPlanes[24], bool positionsAsNormals );
//ETX
// Description:
// Given a depth in the hierarchy (\a level) and a point \a pt in world space, compute \a ijk.
// This is used to find other octree nodes at the same \a level that are within the search radius
// for candidate labels to be placed. It is called with \a pt set to the camera eye point and
// pythagorean quadruples increasingly distant from the origin are added to \a ijk to identify
// octree nodes whose labels should be placed.
// @param[out] ijk - discrete coordinates of the octree node at \a level containing \a pt.
// @param[in] pt - input world point coordinates
// @param[in] level - input octree level to be considered
void GetDiscreteNodeCoordinatesFromWorldPoint( int ijk[3], double pt[3], int level );
// Description:
// Given a \a level of the tree and \a ijk coordinates in a lattice,
// compute a \a path down the tree to reach the corresponding lattice node.
// If the lattice coordinates are outside the tree, this returns
// false. Otherwise it returns true. This does <b>not</b> guarantee that
// the path exists in the hierarchy.
// @param[out] path - a vector of \a level integers specifying which child to descend at each level to reach \a ijk
// @param[in] ijk - discrete coordinates of the octree node at \a level
// @param[in] level - input octree level to be considered
static bool GetPathForNodalCoordinates( int* path, int ijk[3], int level );
// Description:
// Inherited members (from vtkDataSet)
virtual vtkIdType GetNumberOfCells();
virtual vtkCell* GetCell(vtkIdType);
virtual void GetCell(vtkIdType, vtkGenericCell*);
virtual int GetCellType(vtkIdType);
virtual void GetCellPoints(vtkIdType, vtkIdList*);
virtual void GetPointCells(vtkIdType, vtkIdList*);
virtual vtkIdType FindCell(double*, vtkCell*, vtkIdType, double, int&, double*, double*);
virtual vtkIdType FindCell(double*, vtkCell*, vtkGenericCell*, vtkIdType, double, int&, double*, double*);
virtual int GetMaxCellSize();
protected:
vtkLabelHierarchy();
virtual ~vtkLabelHierarchy();
private:
vtkLabelHierarchy( const vtkLabelHierarchy& ); // Not implemented.
void operator = ( const vtkLabelHierarchy& ); // Not implemented.
int TargetLabelCount;
int MaximumDepth;
vtkDataArray* Priorities;
//BTX
class implementation;
implementation* Implementation;
friend class vtkLabelHierarchyFrustumIterator;
friend class vtkLabelHierarchyFullSortIterator;
//ETX
};
#endif // __vtkLabelHierarchy_h
/*=========================================================================
Program: Visualization Toolkit
Module: vtkLabelHierarchyAlgorithm.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkLabelHierarchyAlgorithm.h"
#include "vtkCommand.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkLabelHierarchy.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTrivialProducer.h"
vtkCxxRevisionMacro(vtkLabelHierarchyAlgorithm, "1.1");
vtkStandardNewMacro(vtkLabelHierarchyAlgorithm);
//----------------------------------------------------------------------------
vtkLabelHierarchyAlgorithm::vtkLabelHierarchyAlgorithm()
{
// by default assume filters have one input and one output
// subclasses that deviate should modify this setting
this->SetNumberOfInputPorts( 1 );
this->SetNumberOfOutputPorts( 1 );
}
//----------------------------------------------------------------------------
vtkLabelHierarchyAlgorithm::~vtkLabelHierarchyAlgorithm()
{
}
//----------------------------------------------------------------------------
void vtkLabelHierarchyAlgorithm::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
//----------------------------------------------------------------------------
vtkLabelHierarchy* vtkLabelHierarchyAlgorithm::GetOutput()
{
return this->GetOutput(0);
}
//----------------------------------------------------------------------------
vtkLabelHierarchy* vtkLabelHierarchyAlgorithm::GetOutput(int port)
{
return vtkLabelHierarchy::SafeDownCast(this->GetOutputDataObject(port));
}
//----------------------------------------------------------------------------
void vtkLabelHierarchyAlgorithm::SetOutput(vtkDataObject* d)
{
this->GetExecutive()->SetOutputData(0, d);
}
//----------------------------------------------------------------------------
vtkDataObject* vtkLabelHierarchyAlgorithm::GetInput()
{
return this->GetInput(0);
}
//----------------------------------------------------------------------------
vtkDataObject* vtkLabelHierarchyAlgorithm::GetInput(int port)
{
return this->GetExecutive()->GetInputData(port, 0);
}
//----------------------------------------------------------------------------
vtkLabelHierarchy* vtkLabelHierarchyAlgorithm::GetLabelHierarchyInput(int port)
{
return vtkLabelHierarchy::SafeDownCast(this->GetInput(port));
}
//----------------------------------------------------------------------------
int vtkLabelHierarchyAlgorithm::ProcessRequest(vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector)
{
// Create an output object of the correct type.
if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA_OBJECT()))
{
return this->RequestDataObject(request, inputVector, outputVector);
}
// generate the data
if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
{
return this->RequestData(request, inputVector, outputVector);
}
if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
{
return this->RequestUpdateExtent(request, inputVector, outputVector);
}
// execute information
if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
{
return this->RequestInformation(request, inputVector, outputVector);
}
return this->Superclass::ProcessRequest(request, inputVector, outputVector);
}
//----------------------------------------------------------------------------
int vtkLabelHierarchyAlgorithm::FillOutputPortInformation(
int vtkNotUsed(port), vtkInformation* info)
{
// now add our info
info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkLabelHierarchy");
return 1;
}
//----------------------------------------------------------------------------
int vtkLabelHierarchyAlgorithm::FillInputPortInformation(
int vtkNotUsed(port), vtkInformation* info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkLabelHierarchy");
return 1;
}
//----------------------------------------------------------------------------
int vtkLabelHierarchyAlgorithm::RequestDataObject(
vtkInformation* vtkNotUsed(request),
vtkInformationVector** vtkNotUsed(inputVector),
vtkInformationVector* outputVector )
{
for ( int i = 0; i < this->GetNumberOfOutputPorts(); ++i )
{
vtkInformation* outInfo = outputVector->GetInformationObject( i );
vtkLabelHierarchy* output = vtkLabelHierarchy::SafeDownCast(
outInfo->Get( vtkDataObject::DATA_OBJECT() ) );
if ( ! output )
{
output = vtkLabelHierarchy::New();
outInfo->Set( vtkDataObject::DATA_OBJECT(), output );
output->FastDelete();
output->SetPipelineInformation( outInfo );
this->GetOutputPortInformation( i )->Set(
vtkDataObject::DATA_EXTENT_TYPE(), output->GetExtentType() );
}
}
return 1;
}
//----------------------------------------------------------------------------
int vtkLabelHierarchyAlgorithm::RequestInformation(
vtkInformation* vtkNotUsed(request),
vtkInformationVector** vtkNotUsed(inputVector),
vtkInformationVector* vtkNotUsed(outputVector))
{
// do nothing let subclasses handle it
return 1;
}
//----------------------------------------------------------------------------
int vtkLabelHierarchyAlgorithm::RequestUpdateExtent(
vtkInformation* vtkNotUsed(request),
vtkInformationVector** inputVector,
vtkInformationVector* vtkNotUsed(outputVector))
{
int numInputPorts = this->GetNumberOfInputPorts();
for (int i=0; i<numInputPorts; i++)
{
int numInputConnections = this->GetNumberOfInputConnections(i);
for (int j=0; j<numInputConnections; j++)
{
vtkInformation* inputInfo = inputVector[i]->GetInformationObject(j);
inputInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
}
}
return 1;
}
//----------------------------------------------------------------------------
// This is the superclasses style of Execute method. Convert it into
// an imaging style Execute method.
int vtkLabelHierarchyAlgorithm::RequestData(
vtkInformation* vtkNotUsed(request),
vtkInformationVector** vtkNotUsed( inputVector ),
vtkInformationVector* vtkNotUsed(outputVector) )
{
// do nothing let subclasses handle it
return 1;
}
//----------------------------------------------------------------------------
void vtkLabelHierarchyAlgorithm::SetInput(vtkDataObject* input)
{
this->SetInput(0, input);
}
//----------------------------------------------------------------------------
void vtkLabelHierarchyAlgorithm::SetInput(int index, vtkDataObject* input)
{
if(input)
{
this->SetInputConnection(index, input->GetProducerPort());
}
else
{
// Setting a NULL input removes the connection.
this->SetInputConnection(index, 0);
}
}
//----------------------------------------------------------------------------
void vtkLabelHierarchyAlgorithm::AddInput(vtkDataObject* input)
{
this->AddInput(0, input);
}
//----------------------------------------------------------------------------
void vtkLabelHierarchyAlgorithm::AddInput(int index, vtkDataObject* input)
{
if(input)
{
this->AddInputConnection(index, input->GetProducerPort());
}
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkLabelHierarchyAlgorithm.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkLabelHierarchyAlgorithm - Superclass for algorithms that produce only label hierarchies as output
// .SECTION Description
//
// vtkLabelHierarchyAlgorithm is a convenience class to make writing algorithms
// easier. It is also designed to help transition old algorithms to the new
// pipeline architecture. There are some assumptions and defaults made by this
// class you should be aware of. This class defaults such that your filter
// will have one input port and one output port. If that is not the case
// simply change it with SetNumberOfInputPorts etc. See this class
// constructor for the default. This class also provides a FillInputPortInfo
// method that by default says that all inputs will be DataObjects. If that
// isn't the case then please override this method in your subclass. This
// class breaks out the downstream requests into separate functions such as
// RequestData and RequestInformation. You should
// implement RequestData( request, inputVec, outputVec) in subclasses.
#ifndef __vtkLabelHierarchyAlgorithm_h
#define __vtkLabelHierarchyAlgorithm_h
#include "vtkAlgorithm.h"
class vtkDataSet;
class vtkLabelHierarchy;
class VTK_RENDERING_EXPORT vtkLabelHierarchyAlgorithm : public vtkAlgorithm
{
public:
static vtkLabelHierarchyAlgorithm *New();
vtkTypeRevisionMacro(vtkLabelHierarchyAlgorithm,vtkAlgorithm);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Get the output data object for a port on this algorithm.
vtkLabelHierarchy* GetOutput();
vtkLabelHierarchy* GetOutput(int);
virtual void SetOutput(vtkDataObject* d);
// Description:
// see vtkAlgorithm for details
virtual int ProcessRequest(vtkInformation*,
vtkInformationVector**,
vtkInformationVector*);
// this method is not recommended for use, but lots of old style filters use it
vtkDataObject* GetInput();
vtkDataObject* GetInput(int port);
vtkLabelHierarchy* GetLabelHierarchyInput(int port);
// Description:
// Set an input of this algorithm. You should not override these
// methods because they are not the only way to connect a pipeline.
// Note that these methods support old-style pipeline connections.
// When writing new code you should use the more general
// vtkAlgorithm::SetInputConnection(). These methods transform the
// input index to the input port index, not an index of a connection
// within a single port.
void SetInput( vtkDataObject* );
void SetInput( int, vtkDataObject* );
// Description:
// Add an input of this algorithm. Note that these methods support
// old-style pipeline connections. When writing new code you should
// use the more general vtkAlgorithm::AddInputConnection(). See
// SetInput() for details.
void AddInput( vtkDataObject* );
void AddInput( int, vtkDataObject* );
protected:
vtkLabelHierarchyAlgorithm();
~vtkLabelHierarchyAlgorithm();
// Description:
// This is called by the superclass.
// This is the method you should override.
virtual int RequestDataObject(
vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector );
// convenience method
virtual int RequestInformation(
vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector );
// Description:
// This is called by the superclass.
// This is the method you should override.
virtual int RequestData(
vtkInformation* request,
vtkInformationVector** inputVector,
vtkInformationVector* outputVector );
// Description:
// This is called by the superclass.
// This is the method you should override.
virtual int RequestUpdateExtent(
vtkInformation*,
vtkInformationVector**,
vtkInformationVector* );
// see algorithm for more info
virtual int FillOutputPortInformation( int port, vtkInformation* info );
virtual int FillInputPortInformation( int port, vtkInformation* info );
private:
vtkLabelHierarchyAlgorithm( const vtkLabelHierarchyAlgorithm& ); // Not implemented.
void operator = ( const vtkLabelHierarchyAlgorithm& ); // Not implemented.
};
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkLabelHierarchyIterator.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*-------------------------------------------------------------------------
Copyright 2008 Sandia Corporation.
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#include "vtkLabelHierarchyIterator.h"
#include "vtkCamera.h"
#include "vtkCellType.h"
#include "vtkCoordinate.h"
#include "vtkDataArray.h"
#include "vtkExtractSelectedFrustum.h"
#include "vtkIntArray.h"
#include "vtkLabelHierarchy.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPlanes.h"
#include "vtkPoints.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
vtkCxxRevisionMacro( vtkLabelHierarchyIterator, "1.1" );
vtkCxxSetObjectMacro( vtkLabelHierarchyIterator, Hierarchy, vtkLabelHierarchy );
vtkLabelHierarchyIterator::vtkLabelHierarchyIterator()
{
this->Hierarchy = 0;
}
vtkLabelHierarchyIterator::~vtkLabelHierarchyIterator()
{
if (this->Hierarchy)
{
this->Hierarchy->Delete();
}
}
void vtkLabelHierarchyIterator::GetPoint( double x[3] )
{
this->Hierarchy->GetPoints()->GetPoint( this->GetLabelId(), x );
}
void vtkLabelHierarchyIterator::GetSize( double sz[2] )
{
vtkDataArray* labelSizeArr = this->Hierarchy->GetPointData()->GetArray( "LabelSize" );
if ( ! labelSizeArr )
{
sz[0] = sz[1] = 0.;
return;
}
vtkIdType lid = this->GetLabelId();
double* ls = labelSizeArr->GetTuple( lid );
sz[0] = ls[0];
sz[1] = ls[1];
}
int vtkLabelHierarchyIterator::GetType()
{
vtkDataArray* labelTypeArr = this->Hierarchy->GetPointData()->GetArray( "Type" );
if ( ! labelTypeArr )
{
return -1;
}
vtkIntArray* labelTypeIArr = vtkIntArray::SafeDownCast( labelTypeArr );
if ( ! labelTypeIArr )
{
return -1;
}
vtkIdType lid = this->GetLabelId();
return labelTypeIArr->GetValue( lid );
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkLabelHierarchyIterator.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*-------------------------------------------------------------------------
Copyright 2008 Sandia Corporation.
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
// .NAME vtkLabelHierarchyIterator - iterator over vtkLabelHierarchy
//
// .SECTION Description
// Abstract superclass for iterators over vtkLabelHierarchy.
#ifndef __vtkLabelHierarchyIterator_h
#define __vtkLabelHierarchyIterator_h
#include "vtkObject.h"
class vtkIdTypeArray;
class vtkLabelHierarchy;
class vtkPolyData;