如何处理 reading/writing 层的 vtk 中的精度损失?

How to deal with precision loss in vtk for reading/writing 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 中的精度损失?

正如我在最新评论中建议的那样,如果您使用原始的 PLY 文件库,则可以确保不会丢失任何精度。显然 VTK 内部某个地方正在将你的双打投射到花车上。原始 PLY 代码非常简单,因此您可以弄清楚它的作用并确保它不会执行该转换。

这是 PLY 文件 C 库的 link: https://www.cc.gatech.edu/projects/large_models/ply.html