user3288829
user3288829

Reputation: 1275

Read in .vtk binary file using vtkGenericDataObjectReader

I'm trying to read a legacy .vtk file in c++ and populate my data structures using vtkGenericDataObjectReader (for a Molecular Dynamics simulation). I've searched through the documentation and incorporated answers from similar SO questions, but I'm still misunderstanding something. Here's the file. Forgive the binary, I think it's written correctly but I wouldn't rule out it as the problem.

# vtk DataFile Version 3.0
vtk output
BINARY
DATASET POLYDATA
FIELD FieldData 2
TIME 1 1  double
\00\00\00\00\00\00\00\00CYCLE 1 1 int
\00\00\00\00POINTS 8 double
\BF\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2\BF\F0\ED\E4m    \D3B2?\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2\BF\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2?\F0\ED\E4m\D3B2VERTICES 8 16
\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00POINT_DATA 8
SCALARS mass  double
LOOKUP_TABLE default
@H\00\00\00\00\00\00@H\00\00\00\00\00\00@H\00\00\00\00\00\00@H\00\00\00\00\00\00@H\00\00\00\00\00\00@H\00\00\00\00\00\00@H\00\00\00\00\00\00@H\00\00\00\00\00\00VECTORS velocity  double
\BF\C0\9E   b\D8_\BFp\B4Mz\8B\BF\C1\A3|9?\B5\81`\FA\CAk?\C7N\A4ig\BF\94\E5R,\BE瀿\C5wSbK\8E?\98l?\E0\AFϿ\CC3\81\EE\F1n*\BF\C3\DA6\EArf?\B5Ж\CD\EF\99?\C1\F1,\9E\F3\CF?\99=Aɕm"?\B2\87l\89\96eU?\A9\E9cA\A4[?\BD\D6\FD\A2Ϳ\C5\E9r}\93\B1\BF\B8X:a\B86\A4?\BDB\CE\DBV֓\BF\A4\AAa,~,?Č7\CCR{?\BC\F4\99L\B7Y\BF\C3\CD    W\E4v(?\BFOS\D4f\8B

This is my code. It segfaults in vtkDataReader::ReadString(char*) from /usr/lib/libvtkIO.so.5.8 while trying to execute the line 'int rv = reader->ReadPoints(ps, int(num_particles));'

vtkSmartPointer<vtkGenericDataObjectReader> reader = 
      vtkSmartPointer<vtkGenericDataObjectReader>::New();
reader->SetFileName(in_rel_path.c_str());
reader->Update();

vtkPolyData* output = reader->GetPolyDataOutput();
vtkPointSet *ps = NULL;
size_t num_particles = output->GetNumberOfPoints();
int rv = reader->ReadPoints(ps, int(num_particles));

vtkPointData* pd = output->GetPointData();
vtkDoubleArray* vel_data = vtkDoubleArray::SafeDownCast(pd->GetVectors());
vtkDoubleArray* mass_data = vtkDoubleArray::SafeDownCast(pd->GetScalars());
vtkDoubleArray* time_data = vtkDoubleArray::SafeDownCast(pd->GetArray("TIME"));
vtkIntArray* cycle_data = vtkIntArray::SafeDownCast(pd->GetArray("CYCLE"));

tot_iters = cycle_data->GetValue(0);
particles.resize(0);
double* position = new double[3];
double* velocity = new double[3];
for( size_t i = 0; i < num_particles; i++ )
{
  ps->GetPoint(int(i), position);
  vel_data->GetTupleValue(int(i), velocity);
  double pmass = mass_data->GetValue(int(i));
  particles.push_back(Particle(vec3(position[0],position[1],position[2]),
                 vec3(velocity[0],velocity[1],velocity[2]),
             pmass));
}
delete[] position;
delete[] velocity;

I admit I don't know much about VTK. If anyone can help explain what I'm doing wrong, or a better way to go about this, I'd really appreciate it.

Upvotes: 1

Views: 1917

Answers (1)

cycopepe
cycopepe

Reputation: 551

The best option to read a PolyData is using the vtkPolyDataReader class. But if you read the class documentation they give the following warning about BINARY files "Binary files written on one system may not be readable on other systems."

Here is an example, taken from VTK Wiki that reads .vtk file

#include <vtkPolyDataReader.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>

int main ( int argc, char *argv[] )
{
   // Parse command line arguments
   if(argc != 2)
   {
   std::cerr << "Usage: " << argv[0]
             << " Filename(.vtk)" << std::endl;
   return EXIT_FAILURE;
   }

   std::string filename = argv[1];  

   // Read all the data from the file
  vtkSmartPointer<vtkPolyDataReader> reader =
  vtkSmartPointer<vtkPolyDataReader>::New();
  reader->SetFileName(filename.c_str());
  reader->Update();

  // Visualize
  vtkSmartPointer<vtkPolyDataMapper> mapper =
  vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(reader->GetOutputPort());

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); 
  actor->SetMapper(mapper);

  vtkSmartPointer<vtkRenderer> renderer =
  vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow =
  vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
  vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  renderer->AddActor(actor);
  renderer->SetBackground(.3, .6, .3); // Background color green

  renderWindow->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

Upvotes: 1

Related Questions