Commit 03e7730a authored by Bill Lorensen's avatar Bill Lorensen

ENH: OBJWriter-Improve precision of saved points, normals and tcoords

OBJWriter saves points, normals and vectors in ASCII. This can limit
the precision of the written coordinates. When they are read using
vtkOBJWriter, the coordinates may not match the original values.

This MR uses vtkNumberToString to convert the floating point values
to high precision. When they are read back, there is 0 difference in
the
original values.

TestOBJPolyDataWriter was changed to set the tolerance for error to 0.
parent 2eb55b05
......@@ -31,6 +31,8 @@
#include <vtkTexture.h>
#include <vtkTexturedSphereSource.h>
#include <vtkNumberToString.h>
#include <string>
int TestOBJPolyDataWriter(int argc, char* argv[])
......@@ -86,6 +88,10 @@ int TestOBJPolyDataWriter(int argc, char* argv[])
}
// check values
vtkNumberToString convert;
int numberOfDifferentPoints = 0;
int numberOfDifferentNormals = 0;
int numberOfDifferentTCoords = 0;
for (vtkIdType i = 0; i < polyInput->GetNumberOfPoints(); i++)
{
double pi[3], po[3];
......@@ -93,37 +99,43 @@ int TestOBJPolyDataWriter(int argc, char* argv[])
// check positions
positionsInput->GetTuple(i, pi);
positionsOutput->GetTuple(i, po);
if (vtkMath::Distance2BetweenPoints(pi, po) > 1e-4)
if (vtkMath::Distance2BetweenPoints(pi, po) > 0.0)
{
cerr << "One point is different.\n";
cerr << "Input: " << pi[0] << " " << pi[1] << " " << pi[2] << "\n";
cerr << "Output: " << po[0] << " " << po[1] << " " << po[2] << "\n";
return EXIT_FAILURE;
cerr << "Point is different.\n";
cerr << " Input: " << convert(pi[0]) << " " << convert(pi[1]) << " " << convert(pi[2]) << "\n";
cerr << " Output: " << convert(po[0]) << " " << convert(po[1]) << " " << convert(po[2]) << "\n";
numberOfDifferentPoints++;
}
// check normals
normalsInput->GetTuple(i, pi);
normalsOutput->GetTuple(i, po);
if (vtkMath::AngleBetweenVectors(pi, po) > 1e-6)
if (vtkMath::AngleBetweenVectors(pi, po) > 0)
{
cerr << "One normal is different:\n";
cerr << "Input: " << pi[0] << " " << pi[1] << " " << pi[2] << "\n";
cerr << "Output: " << po[0] << " " << po[1] << " " << po[2] << "\n";
return EXIT_FAILURE;
cerr << "Normal is different:\n";
cerr << " Input: " << convert(pi[0]) << " " << convert(pi[1]) << " " << convert(pi[2]) << "\n";
cerr << " Output: " << convert(po[0]) << " " << convert(po[1]) << " " << convert(po[2]) << "\n";
numberOfDifferentNormals++;
}
// check texture coords
tcoordsInput->GetTuple(i, pi);
tcoordsOutput->GetTuple(i, po);
pi[2] = po[2] = 0.0;
if (vtkMath::Distance2BetweenPoints(pi, po) > 1e-4)
if (vtkMath::Distance2BetweenPoints(pi, po) > 0.0)
{
cerr << "One texture coord is different:\n";
cerr << "Input: " << pi[0] << " " << pi[1] << "\n";
cerr << "Output: " << po[0] << " " << po[1] << "\n";
return EXIT_FAILURE;
cerr << "Texture coord is different:\n";
cerr << "Input: " << convert(pi[0]) << " " << convert(pi[1]) << "\n";
cerr << "Output: " << convert(po[0]) << " " << convert(po[1]) << "\n";
numberOfDifferentTCoords++;
}
}
if (numberOfDifferentPoints != 0 ||
numberOfDifferentNormals != 0 ||
numberOfDifferentTCoords != 0)
{
return EXIT_FAILURE;
}
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(reader->GetOutputPort());
......
......@@ -23,6 +23,8 @@
#include "vtkPolyData.h"
#include "vtkSmartPointer.h"
#include "vtkTriangleStrip.h"
#include "vtkNumberToString.h"
#include "vtksys/SystemTools.hxx"
namespace
......@@ -74,13 +76,15 @@ void WriteLines(std::ofstream& f, vtkCellArray* lines)
//----------------------------------------------------------------------------
void WritePoints(std::ofstream& f, vtkPoints* pts, vtkDataArray* normals, vtkDataArray* tcoords)
{
vtkNumberToString convert;
vtkIdType nbPts = pts->GetNumberOfPoints();
// Positions
for (vtkIdType i = 0; i < nbPts; i++)
{
double p[3];
pts->GetPoint(i, p);
f << "v " << p[0] << " " << p[1] << " " << p[2] << "\n";
f << "v " << convert(p[0]) << " " << convert(p[1]) << " " << convert(p[2]) << "\n";
}
// Normals
......@@ -90,7 +94,7 @@ void WritePoints(std::ofstream& f, vtkPoints* pts, vtkDataArray* normals, vtkDat
{
double p[3];
normals->GetTuple(i, p);
f << "vn " << p[0] << " " << p[1] << " " << p[2] << "\n";
f << "vn " << convert(p[0]) << " " << convert(p[1]) << " " << convert(p[2]) << "\n";
}
}
......@@ -101,7 +105,7 @@ void WritePoints(std::ofstream& f, vtkPoints* pts, vtkDataArray* normals, vtkDat
{
double p[2];
tcoords->GetTuple(i, p);
f << "vt " << p[0] << " " << p[1] << "\n";
f << "vt " << convert(p[0]) << " " << convert(p[1]) << "\n";
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment