Commit bceb808a authored by Cory Quammen's avatar Cory Quammen

Change %g format specifier to %.*g with full double precision

Sometimes we need more decimal digits of precision when converting
double values to ASCII than what is afforded by %g, so use %.*g with
std::numeric_limits<double>::max_digits10 to specify the precision.
parent b1dffbe3
...@@ -36,6 +36,13 @@ ...@@ -36,6 +36,13 @@
#include "vtkTexture.h" #include "vtkTexture.h"
#include "vtkTransform.h" #include "vtkTransform.h"
#include <limits>
namespace {
// For C format strings
constexpr int max_double_digits = std::numeric_limits<double>::max_digits10;
}
vtkStandardNewMacro(vtkVRMLExporter); vtkStandardNewMacro(vtkVRMLExporter);
vtkVRMLExporter::vtkVRMLExporter() vtkVRMLExporter::vtkVRMLExporter()
...@@ -130,8 +137,11 @@ void vtkVRMLExporter::WriteData() ...@@ -130,8 +137,11 @@ void vtkVRMLExporter::WriteData()
cam->GetPosition()[1], cam->GetPosition()[2]); cam->GetPosition()[1], cam->GetPosition()[2]);
fprintf(fp," description \"Default View\"\n"); fprintf(fp," description \"Default View\"\n");
tempd = cam->GetOrientationWXYZ(); tempd = cam->GetOrientationWXYZ();
fprintf(fp," orientation %g %g %g %g\n }\n", tempd[1], tempd[2], fprintf(fp," orientation %.*g %.*g %.*g %.*g\n }\n",
tempd[3], tempd[0]*vtkMath::Pi()/180.0); max_double_digits, tempd[1],
max_double_digits, tempd[2],
max_double_digits, tempd[3],
max_double_digits, tempd[0]*vtkMath::Pi()/180.0);
// do the lights first the ambient then the others // do the lights first the ambient then the others
fprintf(fp, fprintf(fp,
...@@ -300,12 +310,21 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp) ...@@ -300,12 +310,21 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp)
fprintf(fp," Transform {\n"); fprintf(fp," Transform {\n");
tempd = trans->GetPosition(); tempd = trans->GetPosition();
fprintf(fp," translation %g %g %g\n", tempd[0], tempd[1], tempd[2]); fprintf(fp," translation %.*g %.*g %.*g\n",
max_double_digits, tempd[0],
max_double_digits, tempd[1],
max_double_digits, tempd[2]);
tempd = trans->GetOrientationWXYZ(); tempd = trans->GetOrientationWXYZ();
fprintf(fp," rotation %g %g %g %g\n", tempd[1], tempd[2], fprintf(fp," rotation %.*g %.*g %.*g %.*g\n",
tempd[3], tempd[0]*vtkMath::Pi()/180.0); max_double_digits, tempd[1],
max_double_digits, tempd[2],
max_double_digits, tempd[3],
max_double_digits, tempd[0]*vtkMath::Pi()/180.0);
tempd = trans->GetScale(); tempd = trans->GetScale();
fprintf(fp," scale %g %g %g\n", tempd[0], tempd[1], tempd[2]); fprintf(fp," scale %.*g %.*g %.*g\n",
max_double_digits, tempd[0],
max_double_digits, tempd[1],
max_double_digits, tempd[2]);
fprintf(fp," children [\n"); fprintf(fp," children [\n");
trans->Delete(); trans->Delete();
...@@ -488,7 +507,10 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp) ...@@ -488,7 +507,10 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp)
for (i = 0; i < npts; i++) for (i = 0; i < npts; i++)
{ {
p = points->GetPoint(indx[i]); p = points->GetPoint(indx[i]);
fprintf (fp," %g %g %g,\n", p[0], p[1], p[2]); fprintf (fp," %.*g %.*g %.*g,\n",
max_double_digits, p[0],
max_double_digits, p[1],
max_double_digits, p[2]);
} }
} }
fprintf(fp," ]\n"); fprintf(fp," ]\n");
...@@ -503,8 +525,10 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp) ...@@ -503,8 +525,10 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp)
for (i = 0; i < npts; i++) for (i = 0; i < npts; i++)
{ {
c = colors->GetPointer(4*indx[i]); c = colors->GetPointer(4*indx[i]);
fprintf (fp," %g %g %g,\n", c[0]/255.0, c[1]/255.0, fprintf (fp," %.*g %.*g %.*g,\n",
c[2]/255.0); max_double_digits, c[0]/255.0,
max_double_digits, c[1]/255.0,
max_double_digits, c[2]/255.0);
} }
} }
fprintf(fp," ]\n"); fprintf(fp," ]\n");
...@@ -533,7 +557,8 @@ void vtkVRMLExporter::WriteShapeBegin( vtkActor* actor, FILE *fileP, ...@@ -533,7 +557,8 @@ void vtkVRMLExporter::WriteShapeBegin( vtkActor* actor, FILE *fileP,
// write out the material properties to the mat file // write out the material properties to the mat file
fprintf(fileP," appearance Appearance {\n"); fprintf(fileP," appearance Appearance {\n");
fprintf(fileP," material Material {\n"); fprintf(fileP," material Material {\n");
fprintf(fileP," ambientIntensity %g\n", props->GetAmbient()); fprintf(fileP," ambientIntensity %.*g\n",
max_double_digits, props->GetAmbient());
// if we don't have colors and we have only lines & points // if we don't have colors and we have only lines & points
// use emissive to color them // use emissive to color them
if (!(pntData->GetNormals() || color || polyData->GetNumberOfPolys() || if (!(pntData->GetNormals() || color || polyData->GetNumberOfPolys() ||
...@@ -541,19 +566,27 @@ void vtkVRMLExporter::WriteShapeBegin( vtkActor* actor, FILE *fileP, ...@@ -541,19 +566,27 @@ void vtkVRMLExporter::WriteShapeBegin( vtkActor* actor, FILE *fileP,
{ {
tempf2 = props->GetAmbient(); tempf2 = props->GetAmbient();
tempd = props->GetAmbientColor(); tempd = props->GetAmbientColor();
fprintf(fileP," emissiveColor %g %g %g\n", fprintf(fileP," emissiveColor %.*g %.*g %.*g\n",
tempd[0]*tempf2, tempd[1]*tempf2, tempd[2]*tempf2); max_double_digits, tempd[0]*tempf2,
max_double_digits, tempd[1]*tempf2,
max_double_digits, tempd[2]*tempf2);
} }
tempf2 = props->GetDiffuse(); tempf2 = props->GetDiffuse();
tempd = props->GetDiffuseColor(); tempd = props->GetDiffuseColor();
fprintf(fileP," diffuseColor %g %g %g\n", fprintf(fileP," diffuseColor %.*g %.*g %.*g\n",
tempd[0]*tempf2, tempd[1]*tempf2, tempd[2]*tempf2); max_double_digits, tempd[0]*tempf2,
max_double_digits, tempd[1]*tempf2,
max_double_digits, tempd[2]*tempf2);
tempf2 = props->GetSpecular(); tempf2 = props->GetSpecular();
tempd = props->GetSpecularColor(); tempd = props->GetSpecularColor();
fprintf(fileP," specularColor %g %g %g\n", fprintf(fileP," specularColor %.*g %.*g %.*g\n",
tempd[0]*tempf2, tempd[1]*tempf2, tempd[2]*tempf2); max_double_digits, tempd[0]*tempf2,
fprintf(fileP," shininess %g\n",props->GetSpecularPower()/128.0); max_double_digits, tempd[1]*tempf2,
fprintf(fileP," transparency %g\n",1.0-props->GetOpacity()); max_double_digits, tempd[2]*tempf2);
fprintf(fileP," shininess %.*g\n",
max_double_digits, props->GetSpecularPower()/128.0);
fprintf(fileP," transparency %.*g\n",
max_double_digits, 1.0-props->GetOpacity());
fprintf(fileP," }\n"); // close matrial fprintf(fileP," }\n"); // close matrial
// is there a texture map // is there a texture map
...@@ -681,7 +714,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals, ...@@ -681,7 +714,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals,
for (i = 0; i < points->GetNumberOfPoints(); i++) for (i = 0; i < points->GetNumberOfPoints(); i++)
{ {
p = points->GetPoint(i); p = points->GetPoint(i);
fprintf (fp," %g %g %g,\n", p[0], p[1], p[2]); fprintf (fp," %.*g %.*g %.*g,\n",
max_double_digits, p[0],
max_double_digits, p[1],
max_double_digits, p[2]);
} }
fprintf(fp," ]\n"); fprintf(fp," ]\n");
fprintf(fp," }\n"); fprintf(fp," }\n");
...@@ -694,7 +730,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals, ...@@ -694,7 +730,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals,
for (i = 0; i < normals->GetNumberOfTuples(); i++) for (i = 0; i < normals->GetNumberOfTuples(); i++)
{ {
p = normals->GetTuple(i); p = normals->GetTuple(i);
fprintf (fp," %g %g %g,\n", p[0], p[1], p[2]); fprintf (fp," %.*g %.*g %.*g,\n",
max_double_digits, p[0],
max_double_digits, p[1],
max_double_digits, p[2]);
} }
fprintf(fp," ]\n"); fprintf(fp," ]\n");
fprintf(fp," }\n"); fprintf(fp," }\n");
...@@ -708,7 +747,9 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals, ...@@ -708,7 +747,9 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals,
for (i = 0; i < tcoords->GetNumberOfTuples(); i++) for (i = 0; i < tcoords->GetNumberOfTuples(); i++)
{ {
p = tcoords->GetTuple(i); p = tcoords->GetTuple(i);
fprintf (fp," %g %g,\n", p[0], p[1]); fprintf (fp," %.*g %.*g,\n",
max_double_digits, p[0],
max_double_digits, p[1]);
} }
fprintf(fp," ]\n"); fprintf(fp," ]\n");
fprintf(fp," }\n"); fprintf(fp," }\n");
...@@ -722,8 +763,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals, ...@@ -722,8 +763,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals,
for (i = 0; i < colors->GetNumberOfTuples(); i++) for (i = 0; i < colors->GetNumberOfTuples(); i++)
{ {
c = colors->GetPointer(4*i); c = colors->GetPointer(4*i);
fprintf (fp," %g %g %g,\n", c[0]/255.0, c[1]/255.0, fprintf (fp," %.*g %.*g %.*g,\n",
c[2]/255.0); max_double_digits, c[0]/255.0,
max_double_digits, c[1]/255.0,
max_double_digits, c[2]/255.0);
} }
fprintf(fp," ]\n"); fprintf(fp," ]\n");
fprintf(fp," }\n"); fprintf(fp," }\n");
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <iomanip>
#include <ios>
#include <limits>
#include <string> #include <string>
#include <cassert> #include <cassert>
...@@ -84,6 +87,7 @@ int vtkX3DExporterXMLWriter::OpenFile(const char* file) ...@@ -84,6 +87,7 @@ int vtkX3DExporterXMLWriter::OpenFile(const char* file)
else else
{ {
this->OutputStream = fileStream; this->OutputStream = fileStream;
*this->OutputStream << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10);
return 1; return 1;
} }
} }
...@@ -356,4 +360,3 @@ void vtkX3DExporterXMLWriter::SubDepth() ...@@ -356,4 +360,3 @@ void vtkX3DExporterXMLWriter::SubDepth()
{ {
this->ActTab.erase(0, 2); this->ActTab.erase(0, 2);
} }
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
# include <io.h> /* unlink */ # include <io.h> /* unlink */
#endif #endif
namespace {
// For C format strings
constexpr int max_double_digits = std::numeric_limits<double>::max_digits10;
}
vtkStandardNewMacro(vtkSTLWriter); vtkStandardNewMacro(vtkSTLWriter);
vtkCxxSetObjectMacro(vtkSTLWriter, BinaryHeader, vtkUnsignedCharArray); vtkCxxSetObjectMacro(vtkSTLWriter, BinaryHeader, vtkUnsignedCharArray);
...@@ -152,11 +157,22 @@ void vtkSTLWriter::WriteAsciiSTL( ...@@ -152,11 +157,22 @@ void vtkSTLWriter::WriteAsciiSTL(
vtkTriangle::ComputeNormal(pts, npts, indx, n); vtkTriangle::ComputeNormal(pts, npts, indx, n);
fprintf(fp, " facet normal %.6g %.6g %.6g\n outer loop\n", fprintf(fp, " facet normal %.*g %.*g %.*g\n outer loop\n",
n[0], n[1], n[2]); max_double_digits, n[0],
fprintf(fp, " vertex %.6g %.6g %.6g\n", v1[0], v1[1], v1[2]); max_double_digits, n[1],
fprintf(fp, " vertex %.6g %.6g %.6g\n", v2[0], v2[1], v2[2]); max_double_digits, n[2]);
fprintf(fp, " vertex %.6g %.6g %.6g\n", v3[0], v3[1], v3[2]); fprintf(fp, " vertex %.*g %.*g %.*g\n",
max_double_digits, v1[0],
max_double_digits, v1[1],
max_double_digits, v1[2]);
fprintf(fp, " vertex %.*g %.*g %.*g\n",
max_double_digits, v2[0],
max_double_digits, v2[1],
max_double_digits, v2[2]);
fprintf(fp, " vertex %.*g %.*g %.*g\n",
max_double_digits, v3[0],
max_double_digits, v3[1],
max_double_digits, v3[2]);
fprintf(fp, " endloop\n endfacet\n"); fprintf(fp, " endloop\n endfacet\n");
} }
...@@ -173,11 +189,22 @@ void vtkSTLWriter::WriteAsciiSTL( ...@@ -173,11 +189,22 @@ void vtkSTLWriter::WriteAsciiSTL(
vtkTriangle::ComputeNormal(pts, npts, indx, n); vtkTriangle::ComputeNormal(pts, npts, indx, n);
fprintf(fp, " facet normal %.6g %.6g %.6g\n outer loop\n", fprintf(fp, " facet normal %.*g %.*g %.*g\n outer loop\n",
n[0], n[1], n[2]); max_double_digits, n[0],
fprintf(fp, " vertex %.6g %.6g %.6g\n", v1[0], v1[1], v1[2]); max_double_digits, n[1],
fprintf(fp, " vertex %.6g %.6g %.6g\n", v2[0], v2[1], v2[2]); max_double_digits, n[2]);
fprintf(fp, " vertex %.6g %.6g %.6g\n", v3[0], v3[1], v3[2]); fprintf(fp, " vertex %.*g %.*g %.*g\n",
max_double_digits, v1[0],
max_double_digits, v1[1],
max_double_digits, v1[2]);
fprintf(fp, " vertex %.*g %.*g %.*g\n",
max_double_digits, v2[0],
max_double_digits, v2[1],
max_double_digits, v2[2]);
fprintf(fp, " vertex %.*g %.*g %.*g\n",
max_double_digits, v3[0],
max_double_digits, v3[1],
max_double_digits, v3[2]);
fprintf(fp, " endloop\n endfacet\n"); fprintf(fp, " endloop\n endfacet\n");
} }
else if (npts > 3) else if (npts > 3)
......
...@@ -55,6 +55,7 @@ WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ...@@ -55,6 +55,7 @@ WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <cassert> #include <cassert>
#include <limits>
/* memory allocation */ /* memory allocation */
#define myalloc(mem_size) vtkPLY::my_alloc((mem_size), __LINE__, __FILE__) #define myalloc(mem_size) vtkPLY::my_alloc((mem_size), __LINE__, __FILE__)
...@@ -2078,7 +2079,8 @@ void vtkPLY::write_ascii_item( ...@@ -2078,7 +2079,8 @@ void vtkPLY::write_ascii_item(
case PLY_FLOAT32: case PLY_FLOAT32:
case PLY_DOUBLE: case PLY_DOUBLE:
case PLY_FLOAT64: case PLY_FLOAT64:
fprintf (fp, "%g ", double_val); // Use needed precision.
fprintf (fp, "%.*g ", std::numeric_limits<double>::max_digits10, double_val);
break; break;
default: default:
fprintf (stderr, "write_ascii_item: bad type = %d\n", type); fprintf (stderr, "write_ascii_item: bad type = %d\n", type);
...@@ -2803,4 +2805,3 @@ void *vtkPLY::my_alloc(size_t size, int lnum, const char *fname) ...@@ -2803,4 +2805,3 @@ void *vtkPLY::my_alloc(size_t size, int lnum, const char *fname)
return (ptr); return (ptr);
} }
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