Commit 7f72369b authored by Emmanuel Promayon's avatar Emmanuel Promayon
Browse files

NEW vector data have 3 different kind of vector representation

Also clarified testdata vtk object name (colors are not yet implemented)
and clean the MeshDataModel - MeshComponent interaction code
parent 9534d1ca
# vtk DataFile Version 3.0
vtk output
color data (not implemented yet!)
ASCII
DATASET POLYDATA
POINTS 25 float
......
......@@ -24,10 +24,13 @@
****************************************************************************/
#include "MeshComponent.h"
#include "Geometry.h"
#include "InteractiveViewer.h"
#include "Property.h"
#include "Application.h"
#include "MeshDataModel.h"
#include "MeshDataView.h"
#include "MeshSelectionView.h"
//-- Qt stuff
#include <QMessageBox>
......@@ -37,6 +40,7 @@
#include <QBoxLayout>
#include <QToolBar>
#include <QList>
#include <QCheckBox>
//-- vtk stuff
#include <vtkPointSet.h>
......@@ -179,8 +183,8 @@ void MeshComponent::init() {
dataView->setSelectionMode(QAbstractItemView::ExtendedSelection);
displayTypePolicyBox = new QComboBox(dataView);
displayTypePolicyBox->setStatusTip(tr("Display type policy for 3D data"));
displayTypePolicyBox->setWhatsThis(tr("Display type policy for 3D data"));
displayTypePolicyBox->setStatusTip(tr("Representation of vector data"));
displayTypePolicyBox->setWhatsThis(tr("Representation of vector data"));
displayTypePolicyBox->addItem("3D Vector", VECTOR_3D);
displayTypePolicyBox->addItem("Norm", NORM);
displayTypePolicyBox->addItem("1st Component", FIRST_COMPONENT);
......@@ -189,17 +193,26 @@ void MeshComponent::init() {
connect(displayTypePolicyBox, SIGNAL(currentIndexChanged(int)), this, SLOT(displayTypePolicyChanged(int)));
vectorRepresentationPolicyBox = new QComboBox(dataView);
vectorRepresentationPolicyBox->setStatusTip(tr("Vector representation for vector data"));
vectorRepresentationPolicyBox->setWhatsThis(tr("Vector representation for vector data"));
vectorRepresentationPolicyBox->addItem("Arrow", ARROW);
vectorRepresentationPolicyBox->addItem("Unscaled", UNSCALED_ARROW);
vectorRepresentationPolicyBox->addItem("Hedge Hog", HEDGE_HOG);
connect(vectorRepresentationPolicyBox, SIGNAL(currentIndexChanged(int)), this, SLOT(vectorRepresentationPolicyChanged(int)));
// build the data widget
QVBoxLayout* dataBox = new QVBoxLayout(dataWidget);
QToolBar* dataToolBar = new QToolBar(dataWidget);
dataToolBar->addAction(removeData);
dataToolBar->addAction(inspectData);
dataToolBar->addWidget(displayTypePolicyBox);
dataToolBar->addWidget(vectorRepresentationPolicyBox);
dataBox->addWidget(dataView);
dataBox->addWidget(dataToolBar);
dataWidget->setLayout(dataBox);
}
// -------------------- initRepresentation --------------------
......@@ -530,6 +543,17 @@ void MeshComponent::displayTypePolicyChanged(int) {
dataModel->refresh();
}
// -------------------- vectorRepresentationPolicyChanged --------------------
void MeshComponent::vectorRepresentationPolicyChanged(int) {
setDataRepresentationOff(VECTORS);
// remove all vector actors
while (!vectorActors.empty()) {
removeProp(vectorActors.takeFirst());
}
dataModel->refresh();
}
// -------------------- removeSelectedSelection --------------------
void MeshComponent::removeSelectedSelections() {
// TODO : handle multiple selection
......@@ -565,6 +589,7 @@ int MeshComponent::getNumberOfDataArray(int fieldFlag) {
// -------------------- createDataRepresentation --------------------
void MeshComponent::createDataRepresentation(FieldType field, const QString& name, SpecificRepresentation representation) {
vtkSmartPointer<vtkDataArray> dataArray = getDataArray(field, name);
vtkSmartPointer<vtkActor> dataActor = vtkSmartPointer< vtkActor >::New();
if (dataArray != nullptr) {
// create the representation depending on the type
......@@ -575,11 +600,11 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
break;
case VECTORS:
if (representation == VECTOR_3D) {
if (vectorRepresentation == HEDGE_HOG) {
VectorRepresentation vectorPolicy = (VectorRepresentation) vectorRepresentationPolicyBox->currentData().toInt();
if (vectorPolicy == HEDGE_HOG) {
// add the corresponding prop, but not visible
vtkSmartPointer<vtkHedgeHog> hedgeHog = vtkSmartPointer<vtkHedgeHog>::New();
vtkSmartPointer<vtkDataSetMapper> dataMapper = vtkSmartPointer< vtkDataSetMapper >::New();
vtkSmartPointer<vtkActor> dataActor = vtkSmartPointer< vtkActor >::New();
if (field == POINTS) {
hedgeHog->SetInputConnection(getDataPort());
......@@ -598,7 +623,9 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
dataActor->GetProperty()->SetColor(0.0, 0.7, 0.0);
dataActor->VisibilityOff();
// add the prop to the component and update the list
addProp(getDataPropName(field, name), dataActor);
vectorActors.append(getDataPropName(field, name));
}
else {
// representation as ARROW
......@@ -607,16 +634,19 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
vtkSmartPointer<vtkActor> dataActor = vtkSmartPointer< vtkActor >::New();
vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New();
vtkSmartPointer<vtkGlyph3D> arrowGlyph = vtkSmartPointer<vtkGlyph3D>::New();
arrowGlyph->ScalingOn();
//arrowGlyph->SetScaleFactor(getBoundingRadius() / 10.0);
//arrowGlyph->SetScaleFactor(getBoundingRadius() / 10.0);
if (vectorPolicy == UNSCALED_ARROW) {
// the best would be to scale to a minimal %age of the bounding radius up to a maximal %age of bounding radius
// unfortunately it not easy to understand the scaling process of vtkGlyph3D
arrowGlyph->SetScaleFactor(getBoundingRadius()/2.0);
arrowGlyph->SetScaleModeToDataScalingOff();
arrowGlyph->ClampingOn();
//arrowGlyph->ScalingOff();
//arrowGlyph->SetRange(getBoundingRadius() / 50.0, getBoundingRadius() / 10.0);
}
arrowGlyph->SetScaleModeToScaleByVector();
//arrowGlyph->SetScaleModeToDataScalingOff();
//arrowGlyph->ScalingOff();
arrowGlyph->SetVectorModeToUseVector();
//arrowGlyph->OrientOn();
arrowGlyph->SetVectorModeToUseVector();
arrowGlyph->SetSourceConnection(arrowSource->GetOutputPort());
// Next line should be able to color the arrow depending on the field,
// Next line should be able to color the arrow depending on the field,
// but the color LUT is inversed, so comment for now
// arrowGlyph->SetColorModeToColorByScalar();
if (field == POINTS) {
......@@ -634,6 +664,7 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
dataActor->VisibilityOff();
addProp(getDataPropName(field, name), dataActor);
vectorActors.append(getDataPropName(field, name));
}
}
else {
......@@ -728,7 +759,7 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
}
// -------------------- getDataRepresentationVisibility --------------------
bool MeshComponent::getDataRepresentationVisibility(FieldType field, const QString& name, SpecificRepresentation representation) {
bool MeshComponent::getDataRepresentationVisibility(FieldType field, const QString& name) {
vtkSmartPointer<vtkDataArray> dataArray = getDataArray(field, name);
DataType type = getDataType(dataArray);
......@@ -736,6 +767,8 @@ bool MeshComponent::getDataRepresentationVisibility(FieldType field, const QStri
return false;
}
SpecificRepresentation representation = (SpecificRepresentation) displayTypePolicyBox->currentData().toInt();
// if type is 1D, 9D or 3D as VECTOR_3D, just check if the data are shown or not
if ((type == SCALARS) || (type == VECTORS && representation == VECTOR_3D) || (type == TENSORS)) {
return dataRepresentationVisibility.value(dataArray);
......@@ -758,7 +791,6 @@ bool MeshComponent::getDataRepresentationVisibility(FieldType field, const QStri
void MeshComponent::setDataRepresentationOff(int dataType) {
//-- update the visibility flags for the given dataType
for (auto it = dataRepresentationVisibility.constBegin(); it != dataRepresentationVisibility.constEnd(); ++it) {
if (getDataType(it.key()) & dataType) {
dataRepresentationVisibility.insert(it.key(), false);
......@@ -826,13 +858,14 @@ void MeshComponent::setScalarDataRepresentationOn(vtkSmartPointer<vtkDataArray>
}
// -------------------- setDataRepresentationVisibility --------------------
void MeshComponent::setDataRepresentationVisibility(FieldType fieldType, const QString& name, bool visibility, SpecificRepresentation representation) {
void MeshComponent::setDataRepresentationVisibility(FieldType fieldType, const QString& name, bool visibility) {
// currently not managed
if (fieldType == MESH) {
return;
}
vtkSmartPointer<vtkDataArray> dataArray = getDataArray(fieldType, name);
SpecificRepresentation representation = (SpecificRepresentation) displayTypePolicyBox->currentData().toInt();
if (dataArray == nullptr) {
setDataRepresentationOff(); // all off
......@@ -902,14 +935,16 @@ void MeshComponent::setDataRepresentationVisibility(FieldType fieldType, const Q
}
// no break here as the action for tensors and 3D vector representation is the same...
case TENSORS:
case TENSORS: {
// ... which means we still need this test here (not elegant but better than repeating the following lines twice)
if (type == TENSORS) {
dataSet->SetActiveTensors(name.toStdString().c_str());
}
// create 3D vectors representation (hedge hog) or tensor representation (tensor glyphs)
if (!dataRepresentationVisibility.contains(dataArray)) {
vtkSmartPointer<vtkProp> representationProp = getProp(getDataPropName(fieldType, name));
if (representationProp == nullptr) {
createDataRepresentation(fieldType, name);
}
......@@ -918,7 +953,8 @@ void MeshComponent::setDataRepresentationVisibility(FieldType fieldType, const Q
// get the prop and set prop->VisibilityOn();
getProp(getDataPropName(fieldType, name))->VisibilityOn();
break;
}
break;
default:
break;
......@@ -993,11 +1029,6 @@ const QString MeshComponent::getDataPropName(FieldType fieldType, const QString&
return QString(getName() + " representation of data array " + arrayName + " in " + getFieldName(fieldType) + " data");
}
// -------------------- getCurrentDisplayTypePolicy --------------------
MeshComponent::SpecificRepresentation MeshComponent::getCurrentDisplayTypePolicy() const {
return (SpecificRepresentation) displayTypePolicyBox->currentData().toInt();
}
// -------------------- getDataModel --------------------
MeshDataModel* MeshComponent::getDataModel() {
return dataModel;
......
......@@ -27,10 +27,9 @@
#define MESHCOMPONENT_H
#include "Component.h"
#include "Geometry.h"
#include "MeshDataView.h"
#include "MeshSelectionModel.h"
#include "MeshSelectionView.h"
#include <QTableView>
class vtkPointSet;
class vtkSelection;
......@@ -42,6 +41,8 @@ class QComboBox;
namespace camitk {
class MeshDataModel;
class MeshDataView;
class MeshSelectionView;
/**
* @ingroup group_sdk_libraries_core_component_mesh
......@@ -81,7 +82,8 @@ public:
///@enum VectorRepresentation how are vector data represented in 3D
enum VectorRepresentation {
HEDGE_HOG, ///< 3D data are represented with hedge hog (simple lines starting from the point or center of the cell)
ARROW ///< 3D data are represented with 3D arrows (nicer hedge hog)
ARROW , ///< 3D data are represented with 3D arrows (nicer hedge hog)
UNSCALED_ARROW ///< same as arrow, but with a scale factor equals to 10% of the bounding radius
};
/** Creates a top-level MeshComponent from a file.
......@@ -342,10 +344,7 @@ public:
*/
void setActiveData(FieldType fieldType, const char* name);
///@endcond
/// Returns the current value of the display type selected by the user
SpecificRepresentation getCurrentDisplayTypePolicy() const;
/// Returns the current data view model (model as the M in Qt MVC design pattern)
MeshDataModel* getDataModel();
......@@ -353,10 +352,10 @@ public:
vtkSmartPointer<vtkFieldData> getFieldData(FieldType);
/// get the current visibility status of a given data (identified with its name) of a given field type
bool getDataRepresentationVisibility(FieldType, const QString&, SpecificRepresentation representation = VECTOR_3D) ;
bool getDataRepresentationVisibility(FieldType, const QString&) ;
/// set the visibility of a given representation for a given data (identified with its name) of a given field type (create it if needed)
void setDataRepresentationVisibility(FieldType, const QString&, bool, SpecificRepresentation representation = VECTOR_3D);
void setDataRepresentationVisibility(FieldType, const QString&, bool);
/// hide all the data representation of a given data type (hide all by default)
void setDataRepresentationOff(int dataType = SCALARS | VECTORS | TENSORS);
......@@ -421,9 +420,12 @@ protected slots:
/// remove the selected selection
void removeSelectedData();
/// called when the datatype of 3D vecors is modified
/// called when the datatype for vector data is modified (refresh the data model)
void displayTypePolicyChanged(int);
/// called when the representation for vector data is modified (remove all actors and refresh the data model)
void vectorRepresentationPolicyChanged(int);
private:
/// the concrete building of the 3D objects (Slice/Geometry): none in this case, everything is done by initRepresentation(vtkPointSet)
......@@ -482,9 +484,12 @@ private:
/// selection widget
QWidget* dataWidget;
/// combo box to select how to display data when then have 3 components
/// combo box to select how to display vector data (data with 3 components)
QComboBox* displayTypePolicyBox;
/// combo box to select how the vector are represented in 3D
QComboBox *vectorRepresentationPolicyBox;
/** map of specific 3D Data representations.
* The value of key is the specific array name that concatenate the 3D data name and the specific representation name.
*/
......@@ -492,13 +497,13 @@ private:
/// number of specific 3D representation for cell data
unsigned int numberOfCellDataSpecificRepresentation;
/// current way of representing 3D vector data
VectorRepresentation vectorRepresentation;
/// map of visibility status of data
QMap<vtkSmartPointer<vtkDataArray>, bool> dataRepresentationVisibility;
/// list of all vector data 3D actors' names (needed for cleaning up)
QStringList vectorActors;
/// create the data representation of a given data (identified with its name) of a given field type, default visibility is off
void createDataRepresentation(FieldType, const QString&, SpecificRepresentation representation = VECTOR_3D) ;
......
......@@ -23,10 +23,8 @@
* $CAMITK_LICENCE_END$
****************************************************************************/
#include "MeshDataModel.h"
#include "MeshComponent.h"
#include "MeshDataModel.h"
#include "InteractiveViewer.h"
#include <vtkCellData.h>
......@@ -129,7 +127,7 @@ QVariant MeshDataModel::data(const QModelIndex& index, int role) const {
case Qt::CheckStateRole:
if ((column == 0) && fieldType != MeshComponent::MESH) {
if (meshComponent->getDataRepresentationVisibility(fieldType,arrayName,meshComponent->getCurrentDisplayTypePolicy())) {
if (meshComponent->getDataRepresentationVisibility(fieldType,arrayName)) {
return Qt::Checked;
}
else {
......@@ -201,7 +199,7 @@ bool MeshDataModel::setData(const QModelIndex& index, const QVariant& value, int
return false;
}
else {
meshComponent->setDataRepresentationVisibility(fieldType,arrayName,(value == Qt::Checked),meshComponent->getCurrentDisplayTypePolicy());
meshComponent->setDataRepresentationVisibility(fieldType,arrayName,(value == Qt::Checked));
return true;
}
......
......@@ -39,58 +39,62 @@
namespace camitk {
MeshSelectionModel::MeshSelectionModel ( MeshComponent* const meshComp ) :
QAbstractTableModel ( meshComp ), meshComponent ( meshComp ) {
fieldName[vtkSelectionNode::POINT] = QString ( "Points" );
fieldName[vtkSelectionNode::CELL] = QString ( "Cells" );
// -------------------- constructor --------------------
MeshSelectionModel::MeshSelectionModel(MeshComponent* const meshComp) :
QAbstractTableModel(meshComp), meshComponent(meshComp) {
fieldName[vtkSelectionNode::POINT] = QString("Points");
fieldName[vtkSelectionNode::CELL] = QString("Cells");
contentName[vtkSelectionNode::INDICES] = "Indices";
}
int MeshSelectionModel::rowCount ( const QModelIndex& parent ) const {
if ( !meshComponent ) {
// -------------------- rowCount --------------------
int MeshSelectionModel::rowCount(const QModelIndex& parent) const {
if (!meshComponent) {
return 0;
}
return meshComponent->getSelections().size();
}
int MeshSelectionModel::columnCount ( const QModelIndex& parent ) const {
// -------------------- columnCount --------------------
int MeshSelectionModel::columnCount(const QModelIndex& parent) const {
return 4;
}
QVariant MeshSelectionModel::data ( const QModelIndex& index, int role ) const {
if ( !meshComponent ) {
// -------------------- data --------------------
QVariant MeshSelectionModel::data(const QModelIndex& index, int role) const {
if (!meshComponent) {
return QVariant();
}
int row = index.row();
int col = index.column();
vtkSmartPointer< vtkSelectionNode > selNode = meshComponent->getSelections().at ( row );
vtkSmartPointer< vtkSelectionNode > selNode = meshComponent->getSelections().at(row);
switch ( role ) {
switch (role) {
case Qt::DisplayRole : {
switch ( col ) {
switch (col) {
case 0 :
if ( selNode->GetSelectionList() ) {
return QString ( selNode->GetSelectionList()->GetName() );
if (selNode->GetSelectionList()) {
return QString(selNode->GetSelectionList()->GetName());
}
else {
return QString ( "Unknown" );
return QString("Unknown");
}
break;
case 1 :
return QString ( fieldName[selNode->GetFieldType()] );
return QString(fieldName[selNode->GetFieldType()]);
break;
case 2 :
return QString ( contentName[selNode->GetContentType()] );
return QString(contentName[selNode->GetContentType()]);
break;
case 3 :
if ( selNode->GetSelectionList() ) {
return QString::number ( selNode->GetSelectionList()->GetNumberOfTuples() );
if (selNode->GetSelectionList()) {
return QString::number(selNode->GetSelectionList()->GetNumberOfTuples());
}
else {
return QString::number ( 0 );
return QString::number(0);
}
break;
default :
......@@ -100,16 +104,17 @@ QVariant MeshSelectionModel::data ( const QModelIndex& index, int role ) const {
break;
}
case Qt::DecorationRole : {
if ( col == 1 ) {
if ( selNode->GetFieldType() == vtkSelectionNode::POINT ) {
return QIcon ( ":/points" );
}
else if ( selNode->GetFieldType() == vtkSelectionNode::CELL ) {
return QIcon ( ":/cell" );
}
else {
return QVariant();
if (col == 1) {
if (selNode->GetFieldType() == vtkSelectionNode::POINT) {
return QIcon(":/points");
}
else
if (selNode->GetFieldType() == vtkSelectionNode::CELL) {
return QIcon(":/cell");
}
else {
return QVariant();
}
}
else {
return QVariant();
......@@ -124,21 +129,22 @@ QVariant MeshSelectionModel::data ( const QModelIndex& index, int role ) const {
return QVariant();
}
QVariant MeshSelectionModel::headerData ( int section, Qt::Orientation orientation, int role ) const {
if ( role == Qt::DisplayRole ) {
if ( orientation == Qt::Horizontal ) {
switch ( section ) {
// -------------------- headerData --------------------
QVariant MeshSelectionModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (role == Qt::DisplayRole) {
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return QString ( "Name" );
return QString("Name");
break;
case 1:
return QString ( "Type" );
return QString("Type");
break;
case 2:
return QString ( "Content" );
return QString("Content");
break;
case 3 :
return QString ( "Count" );
return QString("Count");
break;
default:
return QVariant();
......@@ -149,47 +155,48 @@ QVariant MeshSelectionModel::headerData ( int section, Qt::Orientation orientati
return QVariant();
}
int MeshSelectionModel::insertSelection ( const QString& name, int fieldType, int contentType, vtkSmartPointer< vtkAbstractArray > array, InsertionPolicy policy ) {
// -------------------- insertSelection --------------------
int MeshSelectionModel::insertSelection(const QString& name, int fieldType, int contentType, vtkSmartPointer< vtkAbstractArray > array, InsertionPolicy policy) {
// TODO : check if a selection of the same name already exists ?
int index = meshComponent->getSelectionIndex ( name );
int index = meshComponent->getSelectionIndex(name);
// if no selection with the same name exists, create it and add it to the model
// except if the insertion policy is SUBSTRACT
if ( ( index < 0 ) && ( policy != SUBSTRACT ) ) {
if ((index < 0) && (policy != SUBSTRACT)) {
// insert the new row
beginInsertRows ( QModelIndex(), meshComponent->getSelections().size(), meshComponent->getSelections().size() );
beginInsertRows(QModelIndex(), meshComponent->getSelections().size(), meshComponent->getSelections().size());
vtkSmartPointer< vtkSelectionNode > selNode = vtkSmartPointer< vtkSelectionNode >::New();
array->SetName ( name.toStdString().c_str() );
selNode->SetFieldType ( fieldType );
selNode->SetContentType ( contentType );
selNode->SetSelectionList ( array );
array->SetName(name.toStdString().c_str());
selNode->SetFieldType(fieldType);
selNode->SetContentType(contentType);
selNode->SetSelectionList(array);
// TODO direct manipulation of selection list should not be allowed outside MeshComponent
// meshComponent->addSelection(name,fieldType,contentType,array);
meshComponent->getSelections().append ( selNode );
meshComponent->getSelections().append(selNode);
endInsertRows();
index = meshComponent->getSelections().size() - 1;
}
// else update the selection data according to insertion policy
else {
vtkSmartPointer< vtkSelectionNode > selNode = meshComponent->getSelections().at ( index );
vtkSmartPointer< vtkSelectionNode > selNode = meshComponent->getSelections().at(index);
// if the field types are different, the selection data cannot be merged or substracted
if ( fieldType != selNode->GetFieldType() && ( policy == MERGE || policy == SUBSTRACT ) ) {
if (fieldType != selNode->GetFieldType() && (policy == MERGE || policy == SUBSTRACT)) {
index = -1;
}
else {
switch ( policy ) {
switch (policy) {
case REPLACE : {
// replace the selection data
array->SetName ( name.toStdString().c_str() );
selNode->SetFieldType ( fieldType );
selNode->SetContentType ( contentType );
selNode->SetSelectionList ( array );
array->SetName(name.toStdString().c_str());
selNode->SetFieldType(fieldType);
selNode->SetContentType(contentType);
selNode->SetSelectionList(array);
emit ( dataChanged ( this->index ( index, 1 ), this->index ( index, 3 ) ) );
emit(dataChanged(this->index(index, 1), this->index(index, 3)));
}
break;
// TODO the selection content must be the same
......@@ -197,23 +204,23 @@ int MeshSelectionModel::insertSelection ( const QString& name, int fieldType, in
// merge the selection list
// in this case, the content type of the new selection list are indices
vtkSmartPointer< vtkSelectionNode > newSelNode = vtkSmartPointer< vtkSelectionNode >::New();
newSelNode->SetFieldType ( fieldType );
newSelNode->SetContentType ( contentType );
newSelNode->SetSelectionList ( array );
newSelNode->SetFieldType(fieldType);
newSelNode->SetContentType(contentType);
newSelNode->SetSelectionList(array);
selNode->UnionSelectionList ( newSelNode );
selNode->UnionSelectionList(newSelNode);
emit ( dataChanged ( this->index ( index, 1 ), this->index ( index, 3 ) ) );
emit(dataChanged(this->index(index, 1), this->index(index, 3)));
}
break;
case SUBSTRACT : {
// substract the selection list
// in this case, the content type of the new selection list are indices
vtkSmartPointer< vtkIdTypeArray > oldIdsArray = vtkIdTypeArray::SafeDownCast ( selNode->GetSelectionList() );
vtkSmartPointer< vtkIdTypeArray > newIdsArray = vtkIdTypeArray::SafeDownCast ( array );
vtkSmartPointer< vtkIdTypeArray > oldIdsArray = vtkIdTypeArray::SafeDownCast(selNode->GetSelectionList());
vtkSmartPointer< vtkIdTypeArray > newIdsArray = vtkIdTypeArray::SafeDownCast(array);
if ( ( !newIdsArray )