You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/3rd/VTK7.1/source/VTK-7.1.1/Common/DataModel/vtkSelectionNode.cxx

530 lines
15 KiB
C++

/*=========================================================================
Program: ParaView
Module: vtkSelectionNode.cxx
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "vtkSelectionNode.h"
#include "vtkDataObject.h"
#include "vtkDataSetAttributes.h"
#include "vtkIdTypeArray.h"
#include "vtkInformationDoubleKey.h"
#include "vtkInformation.h"
#include "vtkInformationIntegerKey.h"
#include "vtkInformationIterator.h"
#include "vtkInformationObjectBaseKey.h"
#include "vtkInformationStringKey.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"
#include <algorithm>
#include <set>
#include <iterator>
vtkStandardNewMacro(vtkSelectionNode);
vtkCxxSetObjectMacro(vtkSelectionNode, SelectionData, vtkDataSetAttributes);
vtkInformationKeyMacro(vtkSelectionNode,CONTENT_TYPE,Integer);
vtkInformationKeyMacro(vtkSelectionNode,SOURCE,ObjectBase);
vtkInformationKeyMacro(vtkSelectionNode,SOURCE_ID,Integer);
vtkInformationKeyMacro(vtkSelectionNode,PROP,ObjectBase);
vtkInformationKeyMacro(vtkSelectionNode,PROP_ID,Integer);
vtkInformationKeyMacro(vtkSelectionNode,PROCESS_ID,Integer);
vtkInformationKeyMacro(vtkSelectionNode,COMPOSITE_INDEX,Integer);
vtkInformationKeyMacro(vtkSelectionNode,HIERARCHICAL_LEVEL,Integer);
vtkInformationKeyMacro(vtkSelectionNode,HIERARCHICAL_INDEX,Integer);
vtkInformationKeyMacro(vtkSelectionNode,FIELD_TYPE,Integer);
vtkInformationKeyMacro(vtkSelectionNode,EPSILON,Double);
vtkInformationKeyMacro(vtkSelectionNode,CONTAINING_CELLS,Integer);
vtkInformationKeyMacro(vtkSelectionNode,PIXEL_COUNT,Integer);
vtkInformationKeyMacro(vtkSelectionNode,INVERSE,Integer);
vtkInformationKeyMacro(vtkSelectionNode,INDEXED_VERTICES,Integer);
vtkInformationKeyMacro(vtkSelectionNode,COMPONENT_NUMBER,Integer);
//----------------------------------------------------------------------------
vtkSelectionNode::vtkSelectionNode()
{
this->SelectionData = vtkDataSetAttributes::New();
this->Properties = vtkInformation::New();
this->QueryString = 0;
}
//----------------------------------------------------------------------------
vtkSelectionNode::~vtkSelectionNode()
{
this->Properties->Delete();
if (this->SelectionData)
{
this->SelectionData->Delete();
}
this->SetQueryString(0);
}
//----------------------------------------------------------------------------
void vtkSelectionNode::Initialize()
{
this->Properties->Clear();
if (this->SelectionData)
{
this->SelectionData->Initialize();
}
this->Modified();
}
//----------------------------------------------------------------------------
vtkAbstractArray* vtkSelectionNode::GetSelectionList()
{
if (this->SelectionData && this->SelectionData->GetNumberOfArrays() > 0)
{
return this->SelectionData->GetAbstractArray(0);
}
return 0;
}
//----------------------------------------------------------------------------
void vtkSelectionNode::SetSelectionList(vtkAbstractArray* arr)
{
if (!this->SelectionData)
{
this->SelectionData = vtkDataSetAttributes::New();
}
this->SelectionData->Initialize();
this->SelectionData->AddArray(arr);
}
//----------------------------------------------------------------------------
void vtkSelectionNode::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "ContentType: ";
switch (this->GetContentType())
{
case GLOBALIDS:
os << "GLOBALIDS";
break;
case PEDIGREEIDS:
os << "PEDIGREEIDS";
break;
case VALUES:
os << "VALUES";
break;
case INDICES:
os << "INDICES";
break;
case FRUSTUM:
os << "FRUSTUM";
break;
case LOCATIONS:
os << "LOCATIONS";
break;
case THRESHOLDS:
os << "THRESHOLDS";
break;
case BLOCKS:
os << "BLOCKS";
break;
default:
os << "UNKNOWN";
break;
}
os << endl;
os << indent << "FieldType: ";
switch (this->GetFieldType())
{
case CELL:
os << "CELL";
break;
case POINT:
os << "POINT";
break;
case FIELD:
os << "FIELD";
break;
case VERTEX:
os << "VERTEX";
break;
case EDGE:
os << "EDGE";
break;
case ROW:
os << "ROW";
break;
default:
os << "UNKNOWN";
break;
}
os << endl;
os << indent << "Properties: " << (this->Properties ? "" : "(none)") << endl;
if (this->Properties)
{
this->Properties->PrintSelf(os, indent.GetNextIndent());
}
os << indent << "SelectionData: " << (this->SelectionData ? "" : "(none)") << endl;
if (this->SelectionData)
{
this->SelectionData->PrintSelf(os, indent.GetNextIndent());
}
os << indent << "QueryString: " << (this->QueryString ? this->QueryString : "NULL") << endl;
}
//----------------------------------------------------------------------------
void vtkSelectionNode::ShallowCopy(vtkSelectionNode* input)
{
if (!input)
{
return;
}
this->Initialize();
this->Properties->Copy(input->Properties, 0);
this->SelectionData->ShallowCopy(input->SelectionData);
this->SetQueryString(input->GetQueryString());
this->Modified();
}
//----------------------------------------------------------------------------
void vtkSelectionNode::DeepCopy(vtkSelectionNode* input)
{
if (!input)
{
return;
}
this->Initialize();
this->Properties->Copy(input->Properties, 1);
this->SelectionData->DeepCopy(input->SelectionData);
this->SetQueryString(input->GetQueryString());
this->Modified();
}
//----------------------------------------------------------------------------
void vtkSelectionNode::SetContentType(int type)
{
this->GetProperties()->Set(vtkSelectionNode::CONTENT_TYPE(), type);
}
//----------------------------------------------------------------------------
int vtkSelectionNode::GetContentType()
{
if (this->GetProperties()->Has(vtkSelectionNode::CONTENT_TYPE()))
{
return this->GetProperties()->Get(vtkSelectionNode::CONTENT_TYPE());
}
return -1;
}
//----------------------------------------------------------------------------
void vtkSelectionNode::SetFieldType(int type)
{
this->GetProperties()->Set(vtkSelectionNode::FIELD_TYPE(), type);
}
//----------------------------------------------------------------------------
int vtkSelectionNode::GetFieldType()
{
if (this->GetProperties()->Has(vtkSelectionNode::FIELD_TYPE()))
{
return this->GetProperties()->Get(vtkSelectionNode::FIELD_TYPE());
}
return -1;
}
//----------------------------------------------------------------------------
bool vtkSelectionNode::EqualProperties(vtkSelectionNode* other,
bool fullcompare/*=true*/)
{
if (!other)
{
return false;
}
vtkSmartPointer<vtkInformationIterator> iterSelf =
vtkSmartPointer<vtkInformationIterator>::New();
iterSelf->SetInformation(this->Properties);
vtkInformation* otherProperties = other->GetProperties();
for (iterSelf->InitTraversal(); !iterSelf->IsDoneWithTraversal();
iterSelf->GoToNextItem())
{
vtkInformationKey* key = iterSelf->GetCurrentKey();
vtkInformationIntegerKey* ikey =
vtkInformationIntegerKey::SafeDownCast(key);
vtkInformationObjectBaseKey* okey =
vtkInformationObjectBaseKey::SafeDownCast(key);
if (ikey)
{
if (!otherProperties->Has(ikey) ||
this->Properties->Get(ikey) != otherProperties->Get(ikey))
{
return false;
}
}
if (okey)
{
if (!otherProperties->Has(okey) ||
this->Properties->Get(okey) != otherProperties->Get(okey))
{
return false;
}
}
}
// Also check that array names match for certain content types
// For VALUES and THRESHOLDS, names represent array where values come from.
// For PEDIGREEIDS, names represent the domain of the selection.
if (this->GetContentType() == vtkSelectionNode::VALUES ||
this->GetContentType() == vtkSelectionNode::PEDIGREEIDS ||
this->GetContentType() == vtkSelectionNode::THRESHOLDS)
{
int numArrays = other->SelectionData->GetNumberOfArrays();
if (this->SelectionData->GetNumberOfArrays() != numArrays)
{
return false;
}
for (int a = 0; a < numArrays; ++a)
{
vtkAbstractArray* arr = this->SelectionData->GetAbstractArray(a);
vtkAbstractArray* otherArr = other->SelectionData->GetAbstractArray(a);
if (!arr->GetName() && otherArr->GetName())
{
return false;
}
if (arr->GetName() && !otherArr->GetName())
{
return false;
}
if (arr->GetName() && otherArr->GetName() && strcmp(arr->GetName(), otherArr->GetName()))
{
return false;
}
}
}
if (fullcompare)
{
return other->EqualProperties(this, false);
}
return true;
}
//----------------------------------------------------------------------------
void vtkSelectionNode::UnionSelectionList(vtkSelectionNode* other)
{
int type = this->Properties->Get(CONTENT_TYPE());
switch (type)
{
case GLOBALIDS:
case PEDIGREEIDS:
case VALUES:
case INDICES:
case LOCATIONS:
case THRESHOLDS:
case BLOCKS:
{
vtkDataSetAttributes* fd1 = this->GetSelectionData();
vtkDataSetAttributes* fd2 = other->GetSelectionData();
if (fd1->GetNumberOfArrays() != fd2->GetNumberOfArrays())
{
vtkErrorMacro(<< "Cannot take the union where the number of arrays do not match.");
}
for (int i = 0; i < fd1->GetNumberOfArrays(); i++)
{
vtkAbstractArray* aa1 = fd1->GetAbstractArray(i);
vtkAbstractArray* aa2 = 0;
if (i == 0 && type != VALUES && type != THRESHOLDS)
{
aa2 = fd2->GetAbstractArray(i);
}
else
{
aa2 = fd2->GetAbstractArray(aa1->GetName());
}
if (!aa2)
{
vtkErrorMacro(<< "Could not find array with name "
<< aa1->GetName() << " in other selection.");
return;
}
if (aa1->GetDataType() != aa2->GetDataType())
{
vtkErrorMacro(<< "Cannot take the union where selection list types "
<< "do not match.");
return;
}
if (aa1->GetNumberOfComponents() != aa2->GetNumberOfComponents())
{
vtkErrorMacro(<< "Cannot take the union where selection list number "
<< "of components do not match.");
return;
}
// If it is the same array, we are done.
if (aa1 == aa2)
{
return;
}
int numComps = aa2->GetNumberOfComponents();
vtkIdType numTuples = aa2->GetNumberOfTuples();
for (vtkIdType j = 0; j < numTuples; j++)
{
// Avoid duplicates on single-component arrays.
if (numComps != 1 || aa1->LookupValue(aa2->GetVariantValue(j)) == -1)
{
aa1->InsertNextTuple(j, aa2);
}
}
}
break;
}
case FRUSTUM:
default:
{
vtkErrorMacro(<< "Do not know how to take the union of content type "
<< type << ".");
return;
}
}
}
//----------------------------------------------------------------------------
void vtkSelectionNode::SubtractSelectionList(vtkSelectionNode* other)
{
int type = this->Properties->Get(CONTENT_TYPE());
switch(type)
{
case GLOBALIDS:
case INDICES:
case PEDIGREEIDS:
{
vtkDataSetAttributes * fd1 = this->GetSelectionData();
vtkDataSetAttributes * fd2 = other->GetSelectionData();
if(fd1->GetNumberOfArrays() != fd2->GetNumberOfArrays())
{
vtkErrorMacro(<< "Cannot take subtract selections if the number of arrays do not match.");
}
if( fd1->GetNumberOfArrays() != 1 || fd2->GetNumberOfArrays() != 1)
{
vtkErrorMacro(<<"Cannot subtract selections with more than one array.");
return;
}
if( fd1->GetArray(0)->GetDataType() != VTK_ID_TYPE || fd2->GetArray(0)->GetDataType() != VTK_ID_TYPE )
{
vtkErrorMacro(<<"Can only subtract selections with vtkIdTypeArray lists.");
}
vtkIdTypeArray * fd1_array = (vtkIdTypeArray*)fd1->GetArray(0);
vtkIdTypeArray * fd2_array = (vtkIdTypeArray*)fd2->GetArray(0);
vtkIdType fd1_N = fd1_array->GetNumberOfTuples();
vtkIdType fd2_N = fd2_array->GetNumberOfTuples();
vtkIdType * fd1_P = (vtkIdType*)fd1_array->GetVoidPointer(0);
vtkIdType * fd2_P = (vtkIdType*)fd2_array->GetVoidPointer(0);
// make sure both arrays are sorted
std::sort( fd1_P, fd1_P + fd1_N );
std::sort( fd2_P, fd2_P + fd2_N );
std::set<vtkIdType> result;
std::set_difference(fd1_P, fd1_P + fd1_N,
fd2_P, fd2_P + fd2_N,
std::inserter(result, result.end()));
fd1_array->Reset();
for(std::set<vtkIdType>::const_iterator p = result.begin(); p!=result.end(); ++p)
{
fd1_array->InsertNextValue( *p );
}
break;
}
case BLOCKS:
case FRUSTUM:
case LOCATIONS:
case THRESHOLDS:
case VALUES:
default:
{
vtkErrorMacro(<< "Do not know how to subtract the given content type " << type << ".");
}
};
}
//----------------------------------------------------------------------------
vtkMTimeType vtkSelectionNode::GetMTime()
{
vtkMTimeType mTime = this->MTime.GetMTime();
vtkMTimeType propMTime;
vtkMTimeType fieldMTime;
if (this->Properties)
{
propMTime = this->Properties->GetMTime();
mTime = (propMTime > mTime ? propMTime : mTime);
}
if (this->SelectionData)
{
fieldMTime = this->SelectionData->GetMTime();
mTime = (fieldMTime > mTime ? fieldMTime : mTime);
}
return mTime;
}
//----------------------------------------------------------------------------
int vtkSelectionNode::ConvertSelectionFieldToAttributeType(int selectionField)
{
switch (selectionField)
{
case vtkSelectionNode::CELL:
return vtkDataObject::CELL;
case vtkSelectionNode::POINT:
return vtkDataObject::POINT;
case vtkSelectionNode::FIELD:
return vtkDataObject::FIELD;
case vtkSelectionNode::VERTEX:
return vtkDataObject::VERTEX;
case vtkSelectionNode::EDGE:
return vtkDataObject::EDGE;
case vtkSelectionNode::ROW:
return vtkDataObject::ROW;
default:
vtkGenericWarningMacro("Invalid selection field type: " << selectionField);
return vtkDataObject::NUMBER_OF_ATTRIBUTE_TYPES;
}
}
//----------------------------------------------------------------------------
int vtkSelectionNode::ConvertAttributeTypeToSelectionField(int attrType)
{
switch (attrType)
{
case vtkDataObject::CELL:
return vtkSelectionNode::CELL;
case vtkDataObject::POINT:
return vtkSelectionNode::POINT;
case vtkDataObject::FIELD:
return vtkSelectionNode::FIELD;
case vtkDataObject::VERTEX:
return vtkSelectionNode::VERTEX;
case vtkDataObject::EDGE:
return vtkSelectionNode::EDGE;
case vtkDataObject::ROW:
return vtkSelectionNode::ROW;
default:
vtkGenericWarningMacro("Invalid attribute type: " << attrType);
return vtkSelectionNode::CELL;
}
}