Hello, I am trying to read a unstructuredGrid and display its displacement using vtk. However, when I am building the code using vscode, I encountered an error saying
undefined reference to `vtkAOSDataArrayTemplate::SetValue(long long) const
I use MinGW as CMake Generator and it works fine for the last several days. I searched this problem and I found a similar post here: undefined reference to vtkAOSDataArrayTemplate
however he mentioned that he used MSYS2. I am not sure by following that post I can solve my issue, or if there’s another way to solve it.
BTW here’s my C++ code:
#include <vtkActor.h>
#include <vtkDataSetMapper.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkXMLUnstructuredGridReader.h>
#include <vtkDataset.h>
#include <vtkCellData.h>
// #include <vtkPointData.h>
#include <vtkLookupTable.h>
#include <vtkUnstructuredGrid.h>
#include <vtkPointData.h>
#include <vtkDataArray.h>
#include <vtkScalarBarActor.h>
#include <vtkCameraOrientationWidget.h>
#include <vtkGlyph3D.h>
#include <vtkArrowSource.h>
#include <vtkConeSource.h>
#include <vtkColorTransferFunction.h>
#include <vtkFloatArray.h>
#include <vtkMath.h>
namespace {
//! Create a lookup table.
/*!
@param lut - An indexed lookup table.
*/
void MakeLUT(int const& colorScheme, vtkLookupTable* lut);
}
int main(int argc, char *argv[])
{
// parse command line arguments
// if (argc < 2)
// {
// std::cerr << "Usage: " << argv[0] << " Filename(.vtu) e.g. tetra.vtu"
// << std::endl;
// return EXIT_FAILURE;
// }
// std::string filename = argv[1];
int colorScheme = 0;
if (argc == 3)
{
colorScheme = std::abs(atoi(argv[2]));
colorScheme = (colorScheme > 2) ? 0 : colorScheme;
}
std::string filename ="D:\\Study\\VTK\\VTK-9.2.6-Data\\Testing\\Data\\test.vtu";
// read all the data from the file
vtkNew<vtkXMLUnstructuredGridReader> reader;
reader->SetFileName(filename.c_str());
reader->Update();
vtkNew<vtkNamedColors> colors;
// Create a mapper and actor
vtkNew<vtkDataSetMapper> mapper;
vtkDataSet *dataSet = reader->GetOutputAsDataSet();
//dataSet->Print(std::cout);
mapper->SetInputConnection(reader->GetOutputPort());
mapper->ScalarVisibilityOn();
mapper->SetColorModeToMapScalars();
mapper->UseLookupTableScalarRangeOn();
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->EdgeVisibilityOn();
actor->GetProperty()->SetLineWidth(2.0);
actor->GetProperty()->SetOpacity(0.5);
actor->GetProperty()->SetColor(colors->GetColor3d("Tomato").GetData());
//try to generate cell vector:
vtkNew<vtkGlyph3D> glyph3D;
vtkNew<vtkArrowSource> arrowSource;
glyph3D->SetSourceConnection(arrowSource->GetOutputPort());
glyph3D->OrientOn();
glyph3D->SetVectorModeToUseVector();
vtkDataArraySelection* sel = reader->GetPointDataArraySelection();
glyph3D->SetInputConnection(reader->GetOutputPort());
vtkPointData* ptData = reader->GetOutput()->GetPointData();
ptData->Print(std::cout);
ptData->SetActiveVectors("Displacement");
ptData->Print(std::cout);
glyph3D->SetVectorModeToUseVector();
glyph3D->SetScaleModeToScaleByVector();
glyph3D->SetColorModeToColorByVector();
glyph3D->SetScaleFactor(300);
// glyph3D->SetInputArrayToProcess(0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "Displacement");
glyph3D->Update();
double vectorRange[2];
reader->GetOutput()->GetPointData()->GetVectors()->GetRange(vectorRange);
// vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
vtkNew<vtkLookupTable> lut;
MakeLUT(colorScheme, lut);
lut->SetRange(vectorRange);
mapper->SetLookupTable(lut);
mapper->UseLookupTableScalarRangeOn();
vtkNew<vtkFloatArray> magnitude;
magnitude->SetNumberOfComponents(1);
magnitude->SetName("Magnitude");
vtkIdType num_pts = reader->GetNumberOfPoints();
vtkNew<vtkMath> math;
vtkDataArray* dispArray = ptData->GetArray("Displacement");
int tuples = dispArray->GetNumberOfTuples();
int cns = dispArray->GetNumberOfComponents();
for (vtkIdType i = 0; i < tuples; i++) {
float mag = 0.0;
double* vec = dispArray->GetTuple(i);
mag = math->Norm(dispArray->GetTuple(i));
magnitude->InsertNextValue(mag);
}
// add a scalarBar
vtkNew<vtkScalarBarActor> colBar;
colBar->SetMaximumHeightInPixels(500);
colBar->SetLookupTable(lut);
vtkNew<vtkDataSetMapper> glyphMapper;
glyphMapper->SetInputConnection(glyph3D->GetOutputPort());
vtkNew<vtkActor> glyphActor;
glyphActor->SetMapper(glyphMapper);
// Create a renderer, render window, and interactor
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
renderWindowInteractor->SetRenderWindow(renderWindow);
// Add the actor to the scene
renderer->AddActor(actor);
renderer->AddActor(glyphActor);
renderer->SetBackground(colors->GetColor3d("Black").GetData());
renderer->AddActor2D(colBar);
//add a xyz
vtkNew<vtkCameraOrientationWidget> widgetCam;
widgetCam->SetParentRenderer(renderer);
widgetCam->On();
// Render and interact
renderWindow->SetSize(640, 480);
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
namespace {
void MakeLUT(int const& colorScheme, vtkLookupTable* lut)
{
// See: [Diverging Color Maps for Scientific Visualization]
// (http://www.kennethmoreland.com/color-maps/)
auto nc = 256;
vtkNew<vtkColorTransferFunction> ctf;
switch (colorScheme)
{
case 0:
default:
// Cool to warm diverging.
ctf->SetColorSpaceToDiverging();
ctf->AddRGBPoint(0.0, 0.230, 0.299, 0.754);
ctf->AddRGBPoint(0.5, 0.865, 0.865, 0.865);
ctf->AddRGBPoint(1.0, 0.706, 0.016, 0.150);
lut->SetNumberOfTableValues(nc);
lut->Build();
for (auto i = 0; i < nc; ++i)
{
double rgb[4] = {0.0, 0.0, 0.0, 1.0};
ctf->GetColor(static_cast<double>(i) / nc, rgb);
lut->SetTableValue(i, rgb);
}
break;
case 1:
// Green to purple diverging.
ctf->SetColorSpaceToDiverging();
ctf->AddRGBPoint(0.0, 0.085, 0.532, 0.201);
ctf->AddRGBPoint(1.0, 0.436, 0.308, 0.631);
lut->SetNumberOfTableValues(nc);
lut->Build();
for (auto i = 0; i < nc; ++i)
{
double rgb[4] = {0.0, 0.0, 0.0, 1.0};
ctf->GetColor(static_cast<double>(i) / nc, rgb);
lut->SetTableValue(i, rgb);
}
break;
case 2: {
// Make a lookup table, black in the centre with bright areas
// at the beginning and end of the table.
// This is from the original code.
auto nc2 = nc / 2;
lut->SetNumberOfColors(nc);
lut->Build();
for (auto i = 0; i < nc2; ++i)
{
// White to black.
auto v = (double(nc2) - i) / double(nc2);
lut->SetTableValue(i, v, v, v, 1);
}
for (auto i = nc2; i < nc; ++i)
{
// Black to white.
auto v = (i - double(nc2)) / double(nc2);
lut->SetTableValue(i, v, v, v, 1);
}
break;
}
}
}
} // namespace
and here’s my error messages:
[main] Building folder: ReadUnstructuredGridVector
[build] Starting build
[proc] Executing command: “D:\Program Files\CMake\bin\cmake.EXE” --build d:/Study/VTK/Tutorial-MinGW/ReadUnstructuredGridVector/build --config Debug --target all -j 18 –
[build] [ 50%] Building CXX object CMakeFiles/ReadUnstructuredGridVector.dir/ReadUnstructuredGridVector.cxx.obj
[build] [100%] Linking CXX executable ReadUnstructuredGridVector.exe
[build] CMakeFiles\ReadUnstructuredGridVector.dir/objects.a(ReadUnstructuredGridVector.cxx.obj): In function `vtkGenericDataArray<vtkAOSDataArrayTemplate, float>::SetValue(long long, float)':
[build] C:/PROGRA~1/VTK-MI~1/include/vtk-9.1/vtkGenericDataArray.h:122: undefined reference to `vtkAOSDataArrayTemplate::SetValue(long long, float)’
[build] collect2.exe: error: ld returned 1 exit status
[build] mingw32-make.exe[2]: *** [CMakeFiles\ReadUnstructuredGridVector.dir\build.make:126: ReadUnstructuredGridVector.exe] Error 1
[build] mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/ReadUnstructuredGridVector.dir/all] Error 2
[build] mingw32-make.exe: *** [Makefile:90: all] Error 2
[proc] The command: “D:\Program Files\CMake\bin\cmake.EXE” --build d:/Study/VTK/Tutorial-MinGW/ReadUnstructuredGridVector/build --config Debug --target all -j 18 – exited with code: 2
[driver] Build completed: 00:00:03.104
[build] Build finished with exit code 2