From bceb808aba8a204ef138511d72614a143c5dbc80 Mon Sep 17 00:00:00 2001 From: Cory Quammen Date: Tue, 1 Jan 2019 16:44:07 -0600 Subject: [PATCH] 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::max_digits10 to specify the precision. --- IO/Export/vtkVRMLExporter.cxx | 89 ++++++++++++++++++++------- IO/Export/vtkX3DExporterXMLWriter.cxx | 5 +- IO/Geometry/vtkSTLWriter.cxx | 47 +++++++++++--- IO/PLY/vtkPLY.cxx | 5 +- 4 files changed, 110 insertions(+), 36 deletions(-) diff --git a/IO/Export/vtkVRMLExporter.cxx b/IO/Export/vtkVRMLExporter.cxx index d82bdc8a6a..27de079ba7 100644 --- a/IO/Export/vtkVRMLExporter.cxx +++ b/IO/Export/vtkVRMLExporter.cxx @@ -36,6 +36,13 @@ #include "vtkTexture.h" #include "vtkTransform.h" +#include + +namespace { + // For C format strings + constexpr int max_double_digits = std::numeric_limits::max_digits10; +} + vtkStandardNewMacro(vtkVRMLExporter); vtkVRMLExporter::vtkVRMLExporter() @@ -130,8 +137,11 @@ void vtkVRMLExporter::WriteData() cam->GetPosition()[1], cam->GetPosition()[2]); fprintf(fp," description \"Default View\"\n"); tempd = cam->GetOrientationWXYZ(); - fprintf(fp," orientation %g %g %g %g\n }\n", tempd[1], tempd[2], - tempd[3], tempd[0]*vtkMath::Pi()/180.0); + fprintf(fp," orientation %.*g %.*g %.*g %.*g\n }\n", + 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 fprintf(fp, @@ -300,12 +310,21 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp) fprintf(fp," Transform {\n"); 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(); - fprintf(fp," rotation %g %g %g %g\n", tempd[1], tempd[2], - tempd[3], tempd[0]*vtkMath::Pi()/180.0); + fprintf(fp," rotation %.*g %.*g %.*g %.*g\n", + 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(); - 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"); trans->Delete(); @@ -488,7 +507,10 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp) for (i = 0; i < npts; 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"); @@ -503,8 +525,10 @@ void vtkVRMLExporter::WriteAnActor(vtkActor *anActor, FILE *fp) for (i = 0; i < npts; i++) { c = colors->GetPointer(4*indx[i]); - fprintf (fp," %g %g %g,\n", c[0]/255.0, c[1]/255.0, - c[2]/255.0); + fprintf (fp," %.*g %.*g %.*g,\n", + max_double_digits, c[0]/255.0, + max_double_digits, c[1]/255.0, + max_double_digits, c[2]/255.0); } } fprintf(fp," ]\n"); @@ -533,7 +557,8 @@ void vtkVRMLExporter::WriteShapeBegin( vtkActor* actor, FILE *fileP, // write out the material properties to the mat file fprintf(fileP," appearance Appearance {\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 // use emissive to color them if (!(pntData->GetNormals() || color || polyData->GetNumberOfPolys() || @@ -541,19 +566,27 @@ void vtkVRMLExporter::WriteShapeBegin( vtkActor* actor, FILE *fileP, { tempf2 = props->GetAmbient(); tempd = props->GetAmbientColor(); - fprintf(fileP," emissiveColor %g %g %g\n", - tempd[0]*tempf2, tempd[1]*tempf2, tempd[2]*tempf2); + fprintf(fileP," emissiveColor %.*g %.*g %.*g\n", + max_double_digits, tempd[0]*tempf2, + max_double_digits, tempd[1]*tempf2, + max_double_digits, tempd[2]*tempf2); } tempf2 = props->GetDiffuse(); tempd = props->GetDiffuseColor(); - fprintf(fileP," diffuseColor %g %g %g\n", - tempd[0]*tempf2, tempd[1]*tempf2, tempd[2]*tempf2); + fprintf(fileP," diffuseColor %.*g %.*g %.*g\n", + max_double_digits, tempd[0]*tempf2, + max_double_digits, tempd[1]*tempf2, + max_double_digits, tempd[2]*tempf2); tempf2 = props->GetSpecular(); tempd = props->GetSpecularColor(); - fprintf(fileP," specularColor %g %g %g\n", - tempd[0]*tempf2, tempd[1]*tempf2, tempd[2]*tempf2); - fprintf(fileP," shininess %g\n",props->GetSpecularPower()/128.0); - fprintf(fileP," transparency %g\n",1.0-props->GetOpacity()); + fprintf(fileP," specularColor %.*g %.*g %.*g\n", + max_double_digits, tempd[0]*tempf2, + max_double_digits, tempd[1]*tempf2, + 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 // is there a texture map @@ -681,7 +714,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals, for (i = 0; i < points->GetNumberOfPoints(); 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"); @@ -694,7 +730,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals, for (i = 0; i < normals->GetNumberOfTuples(); 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"); @@ -708,7 +747,9 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals, for (i = 0; i < tcoords->GetNumberOfTuples(); 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"); @@ -722,8 +763,10 @@ void vtkVRMLExporter::WritePointData(vtkPoints *points, vtkDataArray *normals, for (i = 0; i < colors->GetNumberOfTuples(); i++) { c = colors->GetPointer(4*i); - fprintf (fp," %g %g %g,\n", c[0]/255.0, c[1]/255.0, - c[2]/255.0); + fprintf (fp," %.*g %.*g %.*g,\n", + 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"); diff --git a/IO/Export/vtkX3DExporterXMLWriter.cxx b/IO/Export/vtkX3DExporterXMLWriter.cxx index 876034ad26..a7afd7a827 100644 --- a/IO/Export/vtkX3DExporterXMLWriter.cxx +++ b/IO/Export/vtkX3DExporterXMLWriter.cxx @@ -24,6 +24,9 @@ #include #include +#include +#include +#include #include #include @@ -84,6 +87,7 @@ int vtkX3DExporterXMLWriter::OpenFile(const char* file) else { this->OutputStream = fileStream; + *this->OutputStream << std::scientific << std::setprecision(std::numeric_limits::max_digits10); return 1; } } @@ -356,4 +360,3 @@ void vtkX3DExporterXMLWriter::SubDepth() { this->ActTab.erase(0, 2); } - diff --git a/IO/Geometry/vtkSTLWriter.cxx b/IO/Geometry/vtkSTLWriter.cxx index 28d50d6f9d..48e27e8a59 100644 --- a/IO/Geometry/vtkSTLWriter.cxx +++ b/IO/Geometry/vtkSTLWriter.cxx @@ -34,6 +34,11 @@ # include /* unlink */ #endif +namespace { + // For C format strings + constexpr int max_double_digits = std::numeric_limits::max_digits10; +} + vtkStandardNewMacro(vtkSTLWriter); vtkCxxSetObjectMacro(vtkSTLWriter, BinaryHeader, vtkUnsignedCharArray); @@ -152,11 +157,22 @@ void vtkSTLWriter::WriteAsciiSTL( vtkTriangle::ComputeNormal(pts, npts, indx, n); - fprintf(fp, " facet normal %.6g %.6g %.6g\n outer loop\n", - n[0], n[1], n[2]); - fprintf(fp, " vertex %.6g %.6g %.6g\n", v1[0], v1[1], v1[2]); - fprintf(fp, " vertex %.6g %.6g %.6g\n", v2[0], v2[1], v2[2]); - fprintf(fp, " vertex %.6g %.6g %.6g\n", v3[0], v3[1], v3[2]); + fprintf(fp, " facet normal %.*g %.*g %.*g\n outer loop\n", + max_double_digits, n[0], + max_double_digits, n[1], + max_double_digits, n[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"); } @@ -173,11 +189,22 @@ void vtkSTLWriter::WriteAsciiSTL( vtkTriangle::ComputeNormal(pts, npts, indx, n); - fprintf(fp, " facet normal %.6g %.6g %.6g\n outer loop\n", - n[0], n[1], n[2]); - fprintf(fp, " vertex %.6g %.6g %.6g\n", v1[0], v1[1], v1[2]); - fprintf(fp, " vertex %.6g %.6g %.6g\n", v2[0], v2[1], v2[2]); - fprintf(fp, " vertex %.6g %.6g %.6g\n", v3[0], v3[1], v3[2]); + fprintf(fp, " facet normal %.*g %.*g %.*g\n outer loop\n", + max_double_digits, n[0], + max_double_digits, n[1], + max_double_digits, n[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"); } else if (npts > 3) diff --git a/IO/PLY/vtkPLY.cxx b/IO/PLY/vtkPLY.cxx index 4205fa994c..6d19d154d2 100644 --- a/IO/PLY/vtkPLY.cxx +++ b/IO/PLY/vtkPLY.cxx @@ -55,6 +55,7 @@ WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. #include #include #include +#include /* memory allocation */ #define myalloc(mem_size) vtkPLY::my_alloc((mem_size), __LINE__, __FILE__) @@ -2078,7 +2079,8 @@ void vtkPLY::write_ascii_item( case PLY_FLOAT32: case PLY_DOUBLE: case PLY_FLOAT64: - fprintf (fp, "%g ", double_val); + // Use needed precision. + fprintf (fp, "%.*g ", std::numeric_limits::max_digits10, double_val); break; default: 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) return (ptr); } - -- GitLab