Как справиться с потерей точности в vtk для чтения/записи?

Я пытаюсь разобрать данные бинарной сетки (ply) в текст ply, и мне нужно поддерживать точность до 3-х знаков после запятой. Приведенный ниже код создает действительный файл ply. Данные, с которыми я имею дело, имеют до 10 цифр. Проблема в том, что выходные координаты привязаны к некоторой сетке, что может быть связано с некоторой потерей точности.

# Expected X, Y, Z values
587028.529 1052864.229 307.586
587026.316 1052869.535 306.553

# Output X, Y, Z values
587028.500 1052864.250 307.586
587026.312 1052869.500 306.553

Version: vtk-devel-8.2.0-23 (Fedora 33)
#include <iomanip>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vtkPLYReader.h>
#include <vtkPLYWriter.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkTriangleFilter.h>

int main ( int argc, char *argv[] )
{
  if(argc != 2)
  {
    std::cout << "Usage: " << argv[0] << "  Filename(.ply)" << std::endl;
    return EXIT_FAILURE;
  }
  std::string inputFilename = argv[1];
  vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
  reader->SetFileName( inputFilename.c_str() );
  vtkSmartPointer<vtkPolyData> mesh;
  vtkSmartPointer<vtkTriangleFilter> triangles = vtkSmartPointer<vtkTriangleFilter>::New();
  triangles->SetInputConnection( reader->GetOutputPort() );
  triangles->Update();
  mesh = triangles->GetOutput();
  std::ofstream ply;
  ply.open( "new.ply" );
  ply << "ply\n"
      << "format ascii 1.0\n"
      << "comment TMC generated PLY File\n"
      << "element vertex " << mesh->GetNumberOfPoints() << "\n"
      << "property double x\n"
      << "property double y\n"
      << "property double z\n"
      << "element face " << mesh->GetNumberOfCells() << "\n"
      << "property list uchar int vertex_indices\n"
      << "end_header\n";
  vtkIdType i;
  for( i = 0; i < mesh->GetNumberOfPoints(); i++ )
  {
    double p[3];
    std::stringstream x, y, z;
    mesh->GetPoint( i, p );
    x << std::fixed << std::setprecision( 3 ) << p[0];
    y << std::fixed << std::setprecision( 3 ) << p[1];
    z << std::fixed << std::setprecision( 3 ) << p[2];
    ply << x.str() << " " << y.str() << " " << z.str() << "\n";
  }
  vtkCell* face;
  for( i = 0; i < mesh->GetNumberOfCells(); i++ )
  {
    face = mesh->GetCell( i );
    ply << face->GetNumberOfPoints();
    for( int j = 0; j < face->GetNumberOfPoints(); j++ )
      ply << " " << face->GetPointId( j );
    ply << "\n";
  }
  ply.close();

  return EXIT_SUCCESS;
}

Как избежать потери точности в VTK?


person Basil Eric Rabi    schedule 05.12.2020    source источник


Ответы (1)


Как я предлагаю в своем последнем комментарии, если вы используете оригинальную библиотеку файлов PLY, вы можете быть уверены, что не потеряете точность. По-видимому, где-то внутри VTK переводит ваши двойники в числа с плавающей запятой. Исходный код PLY довольно прост, так что вы можете понять, что он делает, и быть уверенным, что он не будет делать это приведение.

Вот ссылка на библиотеку C файла PLY: https://www.cc.gatech.edu/projects/large_models/ply.html

person Dave Chen    schedule 07.12.2020
comment
Я могу выводить с желаемой точностью. Проблема в том, что при чтении через VTK значения типа double становятся плавающими. Вот почему значения для X и Y изменены. - person Basil Eric Rabi; 08.12.2020
comment
Например, я ожидаю значение 587026.316, но на выходе 587026.312. - person Basil Eric Rabi; 08.12.2020
comment
О, мой плохой. Я неправильно понял ваш вопрос. Мое предложение состояло бы в том, чтобы получить исходный код файла ply C для чтения/записи. Ясно, что они переводят ваши двойники в числа с плавающей запятой где-то внутри, поэтому маловероятно, что вы сможете это отменить. cc.gatech.edu/projects/large_models/ply.html - person Dave Chen; 08.12.2020