如何处理 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
我正在尝试将二进制网格数据(层)解析为文本 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