Commit 2bc33df6 authored by Jeff Baumes's avatar Jeff Baumes
Browse files

ENH: Adding domains to selections/views.

parent 53adcb3b
......@@ -23,6 +23,7 @@
#include "vtkAbstractArray.h"
#include "vtkDataArray.h"
#include "vtkDataSetAttributes.h"
#include "vtkFieldData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
......@@ -34,7 +35,7 @@
// Standard functions
//
vtkCxxRevisionMacro(vtkTable, "1.11");
vtkCxxRevisionMacro(vtkTable, "1.12");
vtkStandardNewMacro(vtkTable);
//----------------------------------------------------------------------------
......@@ -48,6 +49,10 @@ vtkTable::vtkTable()
this->Information->Set(vtkDataObject::DATA_PIECE_NUMBER(), -1);
this->Information->Set(vtkDataObject::DATA_NUMBER_OF_PIECES(), 1);
this->Information->Set(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS(), 0);
// Use vtkDataSetAttributes instance as the field data.
vtkDataSetAttributes* dsa = vtkDataSetAttributes::New();
this->SetFieldData(dsa);
}
//----------------------------------------------------------------------------
......
......@@ -41,7 +41,7 @@
#include "vtkSmartPointer.h"
#include "vtkVariant.h"
vtkCxxRevisionMacro(vtkQtItemView, "1.4");
vtkCxxRevisionMacro(vtkQtItemView, "1.5");
vtkStandardNewMacro(vtkQtItemView);
......@@ -153,7 +153,8 @@ QItemSelectionModel* vtkQtItemView::GetSelectionModel()
}
//----------------------------------------------------------------------------
void vtkQtItemView::AddInputConnection(vtkAlgorithmOutput* conn)
void vtkQtItemView::AddInputConnection(
vtkAlgorithmOutput* conn, vtkAlgorithmOutput* vtkNotUsed(selectionConn))
{
// Make sure I have a view and a model
if (CheckViewAndModelError()) return;
......@@ -179,7 +180,8 @@ void vtkQtItemView::AddInputConnection(vtkAlgorithmOutput* conn)
}
//----------------------------------------------------------------------------
void vtkQtItemView::RemoveInputConnection(vtkAlgorithmOutput* conn)
void vtkQtItemView::RemoveInputConnection(
vtkAlgorithmOutput* conn, vtkAlgorithmOutput* vtkNotUsed(selectionConn))
{
// Make sure I have a view and a model
if (CheckViewAndModelError()) return;
......
......@@ -87,11 +87,15 @@ protected:
// Description:
// Connects the algorithm output to the internal pipeline.
// This view only supports a single representation.
virtual void AddInputConnection(vtkAlgorithmOutput* conn);
virtual void AddInputConnection(
vtkAlgorithmOutput* conn,
vtkAlgorithmOutput* selectionConn);
// Description:
// Removes the algorithm output from the internal pipeline.
virtual void RemoveInputConnection(vtkAlgorithmOutput* conn);
virtual void RemoveInputConnection(
vtkAlgorithmOutput* conn,
vtkAlgorithmOutput* selectionConn);
// Description:
// Called when the QItemView selection changes.
......
......@@ -31,7 +31,7 @@
#include "vtkTimerLog.h"
#include "vtkView.h"
vtkCxxRevisionMacro(vtkGeoAlignedImageRepresentation, "1.1");
vtkCxxRevisionMacro(vtkGeoAlignedImageRepresentation, "1.2");
vtkStandardNewMacro(vtkGeoAlignedImageRepresentation);
......@@ -41,6 +41,9 @@ vtkGeoAlignedImageRepresentation::vtkGeoAlignedImageRepresentation()
this->Actor = vtkSmartPointer<vtkAssembly>::New();
this->Terrain = 0;
this->Image = 0;
// Turn off selectability.
this->SelectableOff();
}
//-----------------------------------------------------------------------------
......
......@@ -60,7 +60,7 @@
#include "vtkViewTheme.h"
#include "vtkXMLDataSetWriter.h"
vtkCxxRevisionMacro(vtkGeoGraphRepresentation, "1.6");
vtkCxxRevisionMacro(vtkGeoGraphRepresentation, "1.7");
vtkStandardNewMacro(vtkGeoGraphRepresentation);
//----------------------------------------------------------------------------
vtkGeoGraphRepresentation::vtkGeoGraphRepresentation()
......@@ -94,7 +94,7 @@ vtkGeoGraphRepresentation::vtkGeoGraphRepresentation()
this->GraphMapper->SetInputConnection(this->EdgeLayout->GetOutputPort());
this->GraphActor->SetMapper(this->GraphMapper);
this->ExtractSelection->SetInputConnection(0, this->EdgeLayout->GetOutputPort());
this->ExtractSelection->SetInputConnection(1, this->SelectionLink->GetOutputPort());
this->ExtractSelection->SetInputConnection(1, this->GetSelectionConnection());
this->SelectionMapper->SetInputConnection(this->ExtractSelection->GetOutputPort());
this->SelectionActor->SetMapper(this->SelectionMapper);
......@@ -184,13 +184,6 @@ void vtkGeoGraphRepresentation::SetInputConnection(vtkAlgorithmOutput* conn)
this->AssignCoordinates->SetInputConnection(conn);
}
//----------------------------------------------------------------------------
void vtkGeoGraphRepresentation::SetSelectionLink(vtkSelectionLink* link)
{
this->Superclass::SetSelectionLink(link);
this->ExtractSelection->SetInputConnection(1, link->GetOutputPort());
}
//----------------------------------------------------------------------------
void vtkGeoGraphRepresentation::SetVertexLabelArrayName(const char* name)
{
......
......@@ -64,10 +64,6 @@ public:
// Sets the input pipeGraph connection to this representation.
virtual void SetInputConnection(vtkAlgorithmOutput* conn);
// Description:
// Plugs the selection link into the internal pipeGraph.
virtual void SetSelectionLink(vtkSelectionLink* link);
// Description:
// The array to use for vertex labeling. Default is "label".
virtual void SetVertexLabelArrayName(const char* name);
......
......@@ -42,10 +42,11 @@
#include "vtkRenderView.h"
#include "vtkSelection.h"
#include "vtkSelectionLink.h"
#include "vtkSmartPointer.h"
#include "vtkVertexGlyphFilter.h"
#include "vtkXMLDataSetWriter.h"
vtkCxxRevisionMacro(vtkGeoLineRepresentation, "1.1");
vtkCxxRevisionMacro(vtkGeoLineRepresentation, "1.2");
vtkStandardNewMacro(vtkGeoLineRepresentation);
//----------------------------------------------------------------------------
vtkGeoLineRepresentation::vtkGeoLineRepresentation()
......@@ -78,7 +79,7 @@ vtkGeoLineRepresentation::vtkGeoLineRepresentation()
this->VertexGlyphFilter->SetInputConnection(this->GeoSampleArcs->GetOutputPort());
this->VertexMapper->SetInputConnection(this->VertexGlyphFilter->GetOutputPort());
this->VertexActor->SetMapper(this->VertexMapper);
this->ExtractSelection->SetInputConnection(1, this->SelectionLink->GetOutputPort());
this->ExtractSelection->SetInputConnection(1, this->GetSelectionConnection());
this->SelectionGeometryFilter->SetInputConnection(this->ExtractSelection->GetOutputPort());
this->SelectionAssignCoords->SetInputConnection(this->SelectionGeometryFilter->GetOutputPort());
//this->SelectionGeoArcs->SetInputConnection(this->SelectionAssignCoords->GetOutputPort());
......@@ -105,6 +106,10 @@ vtkGeoLineRepresentation::vtkGeoLineRepresentation()
this->SelectionActor->GetProperty()->SetColor(1, 0, 1);
this->SelectionActor->GetProperty()->SetRepresentationToWireframe();
this->SelectionActor->PickableOff();
// This normally represents static lines like political boundaries,
// so turn off selectability by default.
this->SelectableOff();
}
//----------------------------------------------------------------------------
......@@ -136,13 +141,6 @@ void vtkGeoLineRepresentation::SetInputConnection(vtkAlgorithmOutput* conn)
this->ExtractSelection->SetInputConnection(conn);
}
//----------------------------------------------------------------------------
void vtkGeoLineRepresentation::SetSelectionLink(vtkSelectionLink* link)
{
this->Superclass::SetSelectionLink(link);
this->ExtractSelection->SetInputConnection(1, link->GetOutputPort());
}
//----------------------------------------------------------------------------
void vtkGeoLineRepresentation::SetLatitudeArrayName(const char* name)
{
......
......@@ -55,10 +55,6 @@ public:
// Sets the input pipeline connection to this representation.
virtual void SetInputConnection(vtkAlgorithmOutput *conn);
// Description:
// Plugs the selection link into the internal pipeline.
virtual void SetSelectionLink(vtkSelectionLink *link);
// Description:
// The point array holding the latitude.
virtual void SetLatitudeArrayName(const char *name);
......
......@@ -44,6 +44,7 @@
#include "vtkVariantArray.h"
#include <vtkstd/algorithm>
#include <vtkstd/map>
#include <vtkstd/set>
#include <vtkstd/vector>
......@@ -52,7 +53,7 @@
vtkCxxSetObjectMacro(vtkConvertSelection, ArrayNames, vtkStringArray);
vtkCxxRevisionMacro(vtkConvertSelection, "1.16");
vtkCxxRevisionMacro(vtkConvertSelection, "1.17");
vtkStandardNewMacro(vtkConvertSelection);
//----------------------------------------------------------------------------
vtkConvertSelection::vtkConvertSelection()
......@@ -198,15 +199,6 @@ int vtkConvertSelection::ConvertToIndexSelection(
return 1;
}
//----------------------------------------------------------------------------
template <class T>
void vtkConvertSelectionLookup(
T* selArr,
T* dataArr,
vtkIdTypeArray* indices)
{
}
//----------------------------------------------------------------------------
int vtkConvertSelection::ConvertToBlockSelection(
vtkSelection* input, vtkCompositeDataSet* data, vtkSelection* output)
......@@ -448,6 +440,67 @@ int vtkConvertSelection::Convert(
}
output->AddChild(outputChild);
}
#if 0
// If converting to raw indices, check whether the children
// are all "compatible". If so, create one selection object
// containing all the indices.
if (this->OutputType == vtkSelection::INDICES && output->GetNumberOfChildren() > 0)
{
vtkSelection* first = output->GetChild(0);
bool match = true;
int hind = first->GetProperties()->Get(vtkSelection::HIERARCHICAL_INDEX());
int hlev = first->GetProperties()->Get(vtkSelection::HIERARCHICAL_LEVEL());
int inv = first->GetProperties()->Get(vtkSelection::INVERSE());
int pid = first->GetProperties()->Get(vtkSelection::PROCESS_ID());
int cind = first->GetProperties()->Get(vtkSelection::COMPOSITE_INDEX());
int ft = first->GetFieldType();
for (unsigned int i = 1; i < output->GetNumberOfChildren(); ++i)
{
vtkSelection* cur = output->GetChild(i);
int cur_hind = cur->GetProperties()->Get(vtkSelection::HIERARCHICAL_INDEX());
int cur_hlev = cur->GetProperties()->Get(vtkSelection::HIERARCHICAL_LEVEL());
int cur_inv = cur->GetProperties()->Get(vtkSelection::INVERSE());
int cur_pid = cur->GetProperties()->Get(vtkSelection::PROCESS_ID());
int cur_cind = cur->GetProperties()->Get(vtkSelection::COMPOSITE_INDEX());
int cur_ft = cur->GetFieldType();
if (cur_hind != hind ||
cur_hlev != hlev ||
cur_inv != inv ||
cur_pid != pid ||
cur_cind != cind ||
cur_ft != ft)
{
match = false;
break;
}
}
if (match)
{
vtkSmartPointer<vtkIdTypeArray> ids =
vtkSmartPointer<vtkIdTypeArray>::New();
vtkSmartPointer<vtkSelection> collapsed =
vtkSmartPointer<vtkSelection>::New();
collapsed->ShallowCopy(first);
for (unsigned int i = 0; i < output->GetNumberOfChildren(); ++i)
{
vtkIdTypeArray* curIds = vtkIdTypeArray::SafeDownCast(output->GetChild(i)->GetSelectionList());
if (!curIds)
{
vtkWarningMacro("INDICES selection should contain vtkIdTypeArray.");
continue;
}
vtkIdType numTuples = curIds->GetNumberOfTuples();
for (vtkIdType j = 0; j < numTuples; ++j)
{
ids->InsertNextValue(curIds->GetValue(j));
}
}
collapsed->SetSelectionList(ids);
output->ShallowCopy(collapsed);
}
}
#endif
return 1;
}
......@@ -709,17 +762,42 @@ int vtkConvertSelection::Convert(
vtkErrorMacro("Selection array does not exist in input dataset.");
return 0;
}
// Perform the lookup
vtkIdType numTuples = selArr->GetNumberOfTuples();
VTK_CREATE(vtkIdList, list);
for (vtkIdType i = 0; i < numTuples; i++)
{
dataArr->LookupValue(selArr->GetVariantValue(i), list);
vtkIdType numIds = list->GetNumberOfIds();
for (vtkIdType j = 0; j < numIds; j++)
// Handle the special case where we have a domain array.
vtkStringArray* domainArr = dsa ? vtkStringArray::SafeDownCast(dsa->GetAbstractArray("domain")) : 0;
if (input->GetContentType() == vtkSelection::PEDIGREEIDS &&
domainArr && selArr->GetName())
{
// Perform the lookup, keeping only those items in the correct domain.
vtkStdString domain = selArr->GetName();
vtkIdType numTuples = selArr->GetNumberOfTuples();
VTK_CREATE(vtkIdList, list);
for (vtkIdType i = 0; i < numTuples; i++)
{
indices->InsertNextValue(list->GetId(j));
dataArr->LookupValue(selArr->GetVariantValue(i), list);
vtkIdType numIds = list->GetNumberOfIds();
for (vtkIdType j = 0; j < numIds; j++)
{
if (domainArr->GetValue(list->GetId(j)) == domain)
{
indices->InsertNextValue(list->GetId(j));
}
}
}
}
else
{
// Perform the lookup
vtkIdType numTuples = selArr->GetNumberOfTuples();
VTK_CREATE(vtkIdList, list);
for (vtkIdType i = 0; i < numTuples; i++)
{
dataArr->LookupValue(selArr->GetVariantValue(i), list);
vtkIdType numIds = list->GetNumberOfIds();
for (vtkIdType j = 0; j < numIds; j++)
{
indices->InsertNextValue(list->GetId(j));
}
}
}
}
......@@ -744,6 +822,59 @@ int vtkConvertSelection::Convert(
{
numOutputArrays = this->ArrayNames->GetNumberOfValues();
}
// Handle the special case where we have a pedigree id selection with a domain array.
vtkStringArray* outputDomainArr = vtkStringArray::SafeDownCast(
dsa->GetAbstractArray("domain"));
if (this->OutputType == vtkSelection::PEDIGREEIDS && outputDomainArr)
{
vtkAbstractArray* outputDataArr = dsa->GetPedigreeIds();
// Check array existence.
if (!outputDataArr)
{
vtkErrorMacro("Output selection array does not exist in input dataset.");
return 0;
}
output->SetContentType(vtkSelection::SELECTIONS);
vtkstd::map<vtkStdString, vtkSmartPointer<vtkAbstractArray> > domainArrays;
vtkIdType numTuples = outputDataArr->GetNumberOfTuples();
vtkIdType numIndices = indices->GetNumberOfTuples();
for (vtkIdType i = 0; i < numIndices; ++i)
{
vtkIdType index = indices->GetValue(i);
if (index >= numTuples)
{
continue;
}
vtkStdString domain = outputDomainArr->GetValue(index);
if (domainArrays.count(domain) == 0)
{
domainArrays[domain].TakeReference(
vtkAbstractArray::CreateArray(outputDataArr->GetDataType()));
domainArrays[domain]->SetName(domain);
}
vtkAbstractArray* domainArr = domainArrays[domain];
domainArr->InsertNextTuple(index, outputDataArr);
if (i % 1000 == 0)
{
progress = 0.8 + (0.2 * i / numIndices);
this->InvokeEvent(vtkCommand::ProgressEvent, &progress);
}
}
output->SetContentType(vtkSelection::SELECTIONS);
vtkstd::map<vtkStdString, vtkSmartPointer<vtkAbstractArray> >::iterator it, itEnd;
it = domainArrays.begin();
itEnd = domainArrays.end();
for (; it != itEnd; ++it)
{
vtkSmartPointer<vtkSelection> child = vtkSmartPointer<vtkSelection>::New();
child->SetContentType(vtkSelection::PEDIGREEIDS);
child->SetSelectionList(it->second);
output->AddChild(child);
}
return 1;
}
VTK_CREATE(vtkFieldData, outputData);
for (vtkIdType ind = 0; ind < numOutputArrays; ind++)
......@@ -779,13 +910,10 @@ int vtkConvertSelection::Convert(
vtkErrorMacro("Output selection array does not exist in input dataset.");
return 0;
}
// Put the array's values into the selection.
vtkAbstractArray* outputArr = vtkAbstractArray::CreateArray(outputDataArr->GetDataType());
if (this->OutputType == vtkSelection::VALUES)
{
outputArr->SetName(outputDataArr->GetName());
}
outputArr->SetName(outputDataArr->GetName());
vtkIdType numTuples = outputDataArr->GetNumberOfTuples();
vtkIdType numIndices = indices->GetNumberOfTuples();
for (vtkIdType i = 0; i < numIndices; ++i)
......
......@@ -16,18 +16,23 @@
#include "vtkSelectionLink.h"
#include "vtkCommand.h"
#include "vtkDataObjectCollection.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkObjectFactory.h"
#include "vtkSelection.h"
#include "vtkTable.h"
vtkCxxRevisionMacro(vtkSelectionLink, "1.1");
vtkCxxRevisionMacro(vtkSelectionLink, "1.2");
vtkStandardNewMacro(vtkSelectionLink);
//----------------------------------------------------------------------------
vtkSelectionLink::vtkSelectionLink()
{
this->SetNumberOfInputPorts(0);
this->SetNumberOfOutputPorts(2);
this->DomainMaps = vtkDataObjectCollection::New();
// Start with an empty index selection
this->Selection = vtkSelection::New();
......@@ -41,6 +46,7 @@ vtkSelectionLink::vtkSelectionLink()
vtkSelectionLink::~vtkSelectionLink()
{
this->Selection->Delete();
this->DomainMaps->Delete();
}
//----------------------------------------------------------------------------
......@@ -56,6 +62,39 @@ void vtkSelectionLink::SetSelection(vtkSelection* selection)
this->InvokeEvent(vtkCommand::SelectionChangedEvent);
}
//----------------------------------------------------------------------------
void vtkSelectionLink::AddDomainMap(vtkTable* map)
{
if (!this->DomainMaps->IsItemPresent(map))
{
this->DomainMaps->AddItem(map);
}
}
//----------------------------------------------------------------------------
void vtkSelectionLink::RemoveDomainMap(vtkTable* map)
{
this->DomainMaps->RemoveItem(map);
}
//----------------------------------------------------------------------------
void vtkSelectionLink::RemoveAllDomainMaps()
{
this->DomainMaps->RemoveAllItems();
}
//----------------------------------------------------------------------------
int vtkSelectionLink::GetNumberOfDomainMaps()
{
return this->DomainMaps->GetNumberOfItems();
}
//----------------------------------------------------------------------------
vtkTable* vtkSelectionLink::GetDomainMap(int i)
{
return vtkTable::SafeDownCast(this->DomainMaps->GetItem(i));
}
//----------------------------------------------------------------------------
int vtkSelectionLink::RequestData(
vtkInformation *vtkNotUsed(info),
......@@ -67,15 +106,39 @@ int vtkSelectionLink::RequestData(
vtkInformation *outInfo = outVector->GetInformationObject(0);
vtkSelection* output = vtkSelection::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
vtkInformation *mapInfo = outVector->GetInformationObject(1);
vtkMultiBlockDataSet* maps = vtkMultiBlockDataSet::SafeDownCast(
mapInfo->Get(vtkDataObject::DATA_OBJECT()));
if (this->Selection)
{
output->ShallowCopy(this->Selection);
}
unsigned int numMaps = static_cast<unsigned int>(this->DomainMaps->GetNumberOfItems());
maps->SetNumberOfBlocks(numMaps);
for (unsigned int i = 0; i < numMaps; ++i)
{
maps->SetBlock(i, this->DomainMaps->GetItem(i));
}
return 1;
}
//----------------------------------------------------------------------------
int vtkSelectionLink::FillOutputPortInformation(int port, vtkInformation* info)
{
if (port == 0)
{
info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkSelection");
}
else
{
info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMultiBlockDataSet");
}
return 1;
}
//----------------------------------------------------------------------------
void vtkSelectionLink::PrintSelf(ostream& os, vtkIndent indent)
{
......@@ -85,5 +148,10 @@ void vtkSelectionLink::PrintSelf(ostream& os, vtkIndent indent)
{
this->Selection->PrintSelf(os, indent.GetNextIndent());
}
os << indent << "DomainMaps: " << (this->DomainMaps ? "" : "null") << endl;
if (this->DomainMaps)
{
this->DomainMaps->PrintSelf(os, indent.GetNextIndent());
}
}
......@@ -25,6 +25,7 @@
#include "vtkSelectionAlgorithm.h"
class vtkDataObjectCollection;
class vtkInformation;
class vtkInformationVector;
class vtkSelection;
......@@ -41,6 +42,14 @@ public:
vtkGetObjectMacro(Selection, vtkSelection);
void SetSelection(vtkSelection* selection);
// Description:
// The domain mappings.
void AddDomainMap(vtkTable* map);
void RemoveDomainMap(vtkTable* map);
void RemoveAllDomainMaps();
int GetNumberOfDomainMaps();
vtkTable* GetDomainMap(int i);
protected:
vtkSelectionLink();
~vtkSelectionLink();
......@@ -51,10 +60,18 @@ protected:
vtkInformation *info,
vtkInformationVector **inVector,
vtkInformationVector *outVector);
// Description:
// Set up output ports.
virtual int FillOutputPortInformation(int, vtkInformation*);
// Description:
// The shared selection.
vtkSelection* Selection;
// Description:
// The mappings between domains.
vtkDataObjectCollection* DomainMaps;
private:
vtkSelectionLink(const vtkSelectionLink&); // Not implemented.
......
......@@ -19,12 +19,16 @@
-------------------------------------------------------------------------*/
#include "vtkDelimitedTextReader.h"
#include "vtkCommand.h"
#include "vtkDataSetAttributes.h"
#include "vtkIdTypeArray.h"
#include "vtkTable.h"
#include "vtkVariantArray.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkInformation.h"
#include "vtkSmartPointer.h"
#include "vtkStringArray.h"
#include "vtkStdString.h"
......@@ -32,7 +36,7 @@
#include <vtkstd/vector>
#include <vtkstd/string>
vtkCxxRevisionMacro(vtkDelimitedTextReader, "1.20");
vtkCxxRevisionMacro(vtkDelimitedTextReader, "1.21");
vtkStandardNewMacro(vtkDelimitedTextReader);
struct vtkDelimitedTextReaderInternals
......@@ -283,6 +287,28 @@ int vtkDelimitedTextReader::RequestData(
table->InsertNextRow(dataArray);
dataArray->Delete();
}
// Use vtkDataSetAttributes to store the data in the table,
// so we get attribute capabilities.