Commit 8fe6ff06 authored by Emmanuel Promayon's avatar Emmanuel Promayon

FIXED MeshComponent crash if "3D Viewer" is not loaded

As viewers are not independent from core, make sure it is possible
to use any component without the viewers
parent 9cab1aef
......@@ -270,6 +270,7 @@ void MeshComponent::initData() {
for (vtkIdType i = 0; i < myGeometry->getPointSet()->GetPointData()->GetNumberOfArrays(); i++) {
addPointData(myGeometry->getPointSet()->GetPointData()->GetArrayName(i), myGeometry->getPointSet()->GetPointData()->GetArray(i));
}
for (vtkIdType i = 0; i < myGeometry->getPointSet()->GetCellData()->GetNumberOfArrays(); i++) {
addCellData(myGeometry->getPointSet()->GetCellData()->GetArrayName(i), myGeometry->getPointSet()->GetCellData()->GetArray(i));
}
......@@ -554,10 +555,12 @@ void MeshComponent::displayTypePolicyChanged(int) {
// -------------------- vectorRepresentationPolicyChanged --------------------
void MeshComponent::vectorRepresentationPolicyChanged(int) {
setDataRepresentationOff(VECTORS);
// remove all vector actors
while (!vectorActors.empty()) {
removeProp(vectorActors.takeFirst());
}
dataModel->refresh();
}
......@@ -578,17 +581,21 @@ int MeshComponent::getNumberOfDataArray(int fieldFlag) {
}
else {
int count = 0;
if (fieldFlag & POINTS) {
// remove the number of specific representation inserted in point data
count += + getPointSet()->GetPointData()->GetNumberOfArrays() - specific3DDataRepresentation.size() + numberOfCellDataSpecificRepresentation;
}
if (fieldFlag & CELLS) {
// remove the number of specific representation inserted in cell data
count += getPointSet()->GetCellData()->GetNumberOfArrays() - numberOfCellDataSpecificRepresentation;
}
if (fieldFlag & MESH) {
count += getPointSet()->GetFieldData()->GetNumberOfArrays();
}
return count;
}
}
......@@ -601,13 +608,16 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
if (dataArray != nullptr) {
// create the representation depending on the type
DataType dataType = getDataType(dataArray);
switch (dataType) {
case SCALARS:
// nothing to do, scalar data already preseng in the array and representation managed by the mapper
break;
case VECTORS:
if (representation == VECTOR_3D) {
VectorRepresentation vectorPolicy = (VectorRepresentation) vectorRepresentationPolicyBox->currentData().toInt();
if (vectorPolicy == HEDGE_HOG) {
// add the corresponding prop, but not visible
vtkSmartPointer<vtkHedgeHog> hedgeHog = vtkSmartPointer<vtkHedgeHog>::New();
......@@ -617,12 +627,14 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
hedgeHog->SetInputConnection(getDataPort());
hedgeHog->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, name.toUtf8().constData());
}
else if (field == CELLS) {
vtkSmartPointer<vtkCellCenters> cellCentersFilter = vtkSmartPointer<vtkCellCenters>::New();
cellCentersFilter->SetInputConnection(getDataPort());
hedgeHog->SetInputConnection(cellCentersFilter->GetOutputPort());
hedgeHog->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, name.toUtf8().constData());
}
else
if (field == CELLS) {
vtkSmartPointer<vtkCellCenters> cellCentersFilter = vtkSmartPointer<vtkCellCenters>::New();
cellCentersFilter->SetInputConnection(getDataPort());
hedgeHog->SetInputConnection(cellCentersFilter->GetOutputPort());
hedgeHog->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, name.toUtf8().constData());
}
hedgeHog->SetScaleFactor(getBoundingRadius() / 10.0);
dataMapper->SetInputConnection(hedgeHog->GetOutputPort());
dataActor->SetMapper(dataMapper);
......@@ -640,6 +652,7 @@ 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();
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
......@@ -649,20 +662,24 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
//arrowGlyph->ScalingOff();
//arrowGlyph->SetRange(getBoundingRadius() / 50.0, getBoundingRadius() / 10.0);
}
arrowGlyph->SetScaleModeToScaleByVector();
arrowGlyph->SetVectorModeToUseVector();
arrowGlyph->SetSourceConnection(arrowSource->GetOutputPort());
// 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) {
arrowGlyph->SetInputConnection(getDataPort());
}
else if (field == CELLS) {
vtkSmartPointer<vtkCellCenters> cellCentersFilter = vtkSmartPointer<vtkCellCenters>::New();
cellCentersFilter->SetInputConnection(getDataPort());
arrowGlyph->SetInputConnection(cellCentersFilter->GetOutputPort());
}
else
if (field == CELLS) {
vtkSmartPointer<vtkCellCenters> cellCentersFilter = vtkSmartPointer<vtkCellCenters>::New();
cellCentersFilter->SetInputConnection(getDataPort());
arrowGlyph->SetInputConnection(cellCentersFilter->GetOutputPort());
}
dataMapper->SetInputConnection(arrowGlyph->GetOutputPort());
dataActor->SetMapper(dataMapper);
dataActor->GetProperty()->SetColor(0, 1, 0);
......@@ -694,16 +711,20 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
for (vtkIdType i = 0; i < numberOfValues; ++i) {
double val[3];
dataArray->GetTuple(i, val);
switch (representation) {
case FIRST_COMPONENT:
dataArrayToDisplay->SetValue(i, val[0]);
break;
case SECOND_COMPONENT:
dataArrayToDisplay->SetValue(i, val[1]);
break;
case THIRD_COMPONENT:
dataArrayToDisplay->SetValue(i, val[2]);
break;
case NORM:
default:
// compute 3D norm
......@@ -716,12 +737,15 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
getFieldData(field)->AddArray(dataArrayToDisplay);
// insert it in the specific map
specific3DDataRepresentation.insert(specificName, dataArrayToDisplay);
// update the cell specific representation counter so that getNumberOfDataArray answer is up-to-date
if (field == CELLS) {
numberOfCellDataSpecificRepresentation++;
}
}
break;
case TENSORS: {
double boundingRadius = getBoundingRadius();
vtkSmartPointer<vtkTensorGlyph> tensorGlyph = vtkSmartPointer<vtkTensorGlyph>::New();
......@@ -734,12 +758,13 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
tensorGlyph->SetInputConnection(getDataPort());
tensorGlyph->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, name.toUtf8().constData());
}
else if (field == CELLS) {
vtkSmartPointer<vtkCellCenters> cellCentersFilter = vtkSmartPointer<vtkCellCenters>::New();
cellCentersFilter->SetInputConnection(getDataPort());
tensorGlyph->SetInputConnection(cellCentersFilter->GetOutputPort());
tensorGlyph->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, name.toUtf8().constData());
}
else
if (field == CELLS) {
vtkSmartPointer<vtkCellCenters> cellCentersFilter = vtkSmartPointer<vtkCellCenters>::New();
cellCentersFilter->SetInputConnection(getDataPort());
tensorGlyph->SetInputConnection(cellCentersFilter->GetOutputPort());
tensorGlyph->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_CELLS, name.toUtf8().constData());
}
tensorGlyph->SetSourceConnection(glyphSphere->GetOutputPort());
tensorGlyph->SetColorModeToEigenvalues();
......@@ -756,6 +781,7 @@ void MeshComponent::createDataRepresentation(FieldType field, const QString& nam
addProp(getDataPropName(field, name), dataActor);
}
break;
default:
break;
}
......@@ -808,9 +834,12 @@ void MeshComponent::setDataRepresentationOff(int dataType) {
if (dataType & SCALARS) {
pointDataSet->SetActiveScalars(nullptr);
cellDataSet->SetActiveScalars(nullptr);
// remove all color bar
dynamic_cast<InteractiveViewer*>(Application::getViewer("3D Viewer"))->setColorScaleTitle("");
dynamic_cast<InteractiveViewer*>(Application::getViewer("3D Viewer"))->setColorScale(false);
if (Application::getViewer("3D Viewer") != nullptr) {
dynamic_cast<InteractiveViewer*>(Application::getViewer("3D Viewer"))->setColorScaleTitle("");
dynamic_cast<InteractiveViewer*>(Application::getViewer("3D Viewer"))->setColorScale(false);
}
}
if (dataType & VECTORS) {
......@@ -830,10 +859,13 @@ void MeshComponent::setDataRepresentationOff(int dataType) {
if (getDataType(it.key()) & dataType) {
// get the corresponding props
vtkSmartPointer<vtkProp> prop = getProp(getDataPropName(POINTS, it.key()->GetName()));
if (prop != nullptr) {
prop->VisibilityOff();
}
prop = getProp(getDataPropName(CELLS, it.key()->GetName()));
if (prop != nullptr) {
prop->VisibilityOff();
}
......@@ -856,9 +888,11 @@ void MeshComponent::setScalarDataRepresentationOn(vtkSmartPointer<vtkDataArray>
setMapperScalarRange(range[0], range[1]);
//-- show the color scale in 3D
/*Application::getViewer<InteractiveViewer>("3D Viewer")->setColorScale(true);
Application::getViewer<InteractiveViewer>("3D Viewer")->setColorScaleTitle(dataArray->GetName());
Application::getViewer<InteractiveViewer>("3D Viewer")->setColorScaleMinMax(range[0], range[1]);*/
if (Application::getViewer("3D Viewer") != nullptr) {
dynamic_cast<InteractiveViewer*>(Application::getViewer("3D Viewer"))->setColorScale(true);
dynamic_cast<InteractiveViewer*>(Application::getViewer("3D Viewer"))->setColorScaleTitle(dataArray->GetName());
dynamic_cast<InteractiveViewer*>(Application::getViewer("3D Viewer"))->setColorScaleMinMax(range[0], range[1]);
}
}
// -------------------- setDataRepresentationVisibility --------------------
......@@ -877,6 +911,7 @@ void MeshComponent::setDataRepresentationVisibility(FieldType fieldType, const Q
}
DataType type = getDataType(dataArray);
if (!visibility) {
if ((type == SCALARS) || (type == VECTORS && representation == VECTOR_3D) || (type == TENSORS)) {
setDataRepresentationOff(type);
......@@ -915,6 +950,7 @@ void MeshComponent::setDataRepresentationVisibility(FieldType fieldType, const Q
// create 1D representation (color map)
QString specificName(name + getSpecificRepresentationName(representation));
if (!specific3DDataRepresentation.contains(specificName)) {
createDataRepresentation(fieldType, name, representation);
}
......@@ -940,6 +976,7 @@ void MeshComponent::setDataRepresentationVisibility(FieldType fieldType, const Q
// just update the data set state for now (see case TENSORS for the rest)
dataSet->SetActiveVectors(name.toStdString().c_str());
}
// no break here as the action for tensors and 3D vector representation is the same...
case TENSORS: {
......@@ -1157,6 +1194,7 @@ const QString MeshComponent::getDataTypeName(const DataType dataType) {
// -------------------- getDataType --------------------
const MeshComponent::DataType MeshComponent::getDataType(vtkSmartPointer<vtkDataArray> array) {
int numberOfComponents = array->GetNumberOfComponents();
switch (numberOfComponents) {
case 1:
return MeshComponent::SCALARS;
......@@ -1180,6 +1218,7 @@ const MeshComponent::DataType MeshComponent::getDataType(vtkSmartPointer<vtkData
// -------------------- getDataTypeName --------------------
const QString MeshComponent::getDataTypeName(vtkSmartPointer<vtkDataArray> array) {
MeshComponent::DataType dataType = getDataType(array);
if (dataType != MeshComponent::OTHERS) {
return getDataTypeName(dataType);
}
......@@ -1194,15 +1233,19 @@ const QString MeshComponent::getSpecificRepresentationName(const SpecificReprese
case MeshComponent::NORM:
return " norm";
break;
case MeshComponent::FIRST_COMPONENT:
return "[0]";
break;
case MeshComponent::SECOND_COMPONENT:
return "[1]";
break;
case MeshComponent::THIRD_COMPONENT:
return "[2]";
break;
case MeshComponent::VECTOR_3D:
default:
return "";
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment