diff --git a/src/ReaderImpl.cpp b/src/ReaderImpl.cpp index df2f8eb9..474b47a0 100644 --- a/src/ReaderImpl.cpp +++ b/src/ReaderImpl.cpp @@ -834,7 +834,6 @@ namespace e57 data3DHeader.pointFields.cartesianZField = proto.isDefined( "cartesianZ" ); data3DHeader.pointFields.cartesianInvalidStateField = proto.isDefined( "cartesianInvalidState" ); - data3DHeader.pointFields.pointRangeScaledInteger = E57_NOT_SCALED_USE_FLOAT; // FloatNode data3DHeader.pointFields.pointRangeMinimum = 0.0; data3DHeader.pointFields.pointRangeMaximum = 0.0; @@ -860,7 +859,11 @@ namespace e57 data3DHeader.pointFields.pointRangeMinimum = floatCartesianX.minimum(); data3DHeader.pointFields.pointRangeMaximum = floatCartesianX.maximum(); - data3DHeader.pointFields.pointRangeScaledInteger = E57_NOT_SCALED_USE_FLOAT; + + if ( floatCartesianX.precision() == E57_DOUBLE ) + { + data3DHeader.pointFields.pointRangeScaledInteger = -1.0; + } } } else if ( proto.isDefined( "sphericalRange" ) ) diff --git a/test/src/test_SimpleData.cpp b/test/src/test_SimpleData.cpp index 7a9cc6d8..dbd47211 100644 --- a/test/src/test_SimpleData.cpp +++ b/test/src/test_SimpleData.cpp @@ -4,8 +4,11 @@ #include "gtest/gtest.h" #include "E57SimpleData.h" +#include "E57SimpleReader.h" +#include "E57SimpleWriter.h" #include "Helpers.h" +#include "TestData.h" TEST( SimpleDataHeader, InvalidPointSize ) { @@ -61,3 +64,161 @@ TEST( SimpleDataHeader, HeaderMinMaxDouble ) EXPECT_EQ( dataHeader.pointFields.timeMinimum, e57::E57_DOUBLE_MIN ); EXPECT_EQ( dataHeader.pointFields.timeMaximum, e57::E57_DOUBLE_MAX ); } + +// Checks that the header and the the cartesianX FloatNode data are the same when read, written, and read again. +// https://github.com/asmaloney/libE57Format/issues/126 +TEST( SimpleData, ReadWrite ) +{ + e57::Reader *originalReader = nullptr; + e57::E57Root originalFileHeader; + e57::Data3D originalData3DHeader; + e57::Data3DPointsData_d *originalPointsData = nullptr; + + // 1. Read in original file + { + E57_ASSERT_NO_THROW( originalReader = new e57::Reader( TestData::Path() + "/self/ColouredCubeDouble.e57", {} ) ); + + ASSERT_TRUE( originalReader->GetE57Root( originalFileHeader ) ); + ASSERT_TRUE( originalReader->ReadData3D( 0, originalData3DHeader ) ); + + const uint64_t cNumPoints = originalData3DHeader.pointsSize; + + originalPointsData = new e57::Data3DPointsData_d( originalData3DHeader ); + + auto vectorReader = originalReader->SetUpData3DPointsData( 0, cNumPoints, *originalPointsData ); + + const uint64_t cNumRead = vectorReader.read(); + + vectorReader.close(); + + EXPECT_EQ( cNumRead, cNumPoints ); + } + + // 2. Write it out again using the Data3D header from the reader + { + e57::WriterOptions options; + options.guid = originalFileHeader.guid; + + e57::Writer *writer = nullptr; + E57_ASSERT_NO_THROW( writer = new e57::Writer( "./ColouredCubeDoubleCopy.e57", options ) ); + + const int64_t cScanIndex1 = writer->NewData3D( originalData3DHeader ); + const uint16_t cNumPoints = originalData3DHeader.pointsSize; + + e57::CompressedVectorWriter dataWriter = + writer->SetUpData3DPointsData( cScanIndex1, cNumPoints, *originalPointsData ); + + dataWriter.write( cNumPoints ); + dataWriter.close(); + + delete writer; + } + + e57::Reader *copyReader = nullptr; + e57::E57Root copyFileHeader; + e57::Data3D copyData3DHeader; + e57::Data3DPointsData_d *copyPointsData = nullptr; + + // 3. Read in what we just wrote + { + E57_ASSERT_NO_THROW( copyReader = new e57::Reader( "./ColouredCubeDoubleCopy.e57", {} ) ); + + ASSERT_TRUE( copyReader->GetE57Root( copyFileHeader ) ); + ASSERT_TRUE( copyReader->ReadData3D( 0, copyData3DHeader ) ); + + const uint64_t cNumPoints = copyData3DHeader.pointsSize; + + copyPointsData = new e57::Data3DPointsData_d( copyData3DHeader ); + + auto vectorReader = copyReader->SetUpData3DPointsData( 0, cNumPoints, *copyPointsData ); + + const uint64_t cNumRead = vectorReader.read(); + + vectorReader.close(); + + EXPECT_EQ( cNumRead, cNumPoints ); + } + + // 4. Compare the header data + EXPECT_EQ( originalData3DHeader.name, copyData3DHeader.name ); + EXPECT_EQ( originalData3DHeader.guid, copyData3DHeader.guid ); + + EXPECT_EQ( originalData3DHeader.description, copyData3DHeader.description ); + + EXPECT_EQ( originalData3DHeader.colorLimits, copyData3DHeader.colorLimits ); + + EXPECT_EQ( originalData3DHeader.pointFields.cartesianXField, copyData3DHeader.pointFields.cartesianXField ); + EXPECT_EQ( originalData3DHeader.pointFields.cartesianYField, copyData3DHeader.pointFields.cartesianYField ); + EXPECT_EQ( originalData3DHeader.pointFields.cartesianZField, copyData3DHeader.pointFields.cartesianZField ); + EXPECT_EQ( originalData3DHeader.pointFields.cartesianInvalidStateField, + copyData3DHeader.pointFields.cartesianInvalidStateField ); + + EXPECT_EQ( originalData3DHeader.pointFields.sphericalRangeField, copyData3DHeader.pointFields.sphericalRangeField ); + EXPECT_EQ( originalData3DHeader.pointFields.sphericalAzimuthField, + copyData3DHeader.pointFields.sphericalAzimuthField ); + EXPECT_EQ( originalData3DHeader.pointFields.sphericalElevationField, + copyData3DHeader.pointFields.sphericalElevationField ); + EXPECT_EQ( originalData3DHeader.pointFields.sphericalInvalidStateField, + copyData3DHeader.pointFields.sphericalInvalidStateField ); + + EXPECT_EQ( originalData3DHeader.pointFields.pointRangeMinimum, copyData3DHeader.pointFields.pointRangeMinimum ); + EXPECT_EQ( originalData3DHeader.pointFields.pointRangeMaximum, copyData3DHeader.pointFields.pointRangeMaximum ); + EXPECT_EQ( originalData3DHeader.pointFields.pointRangeScaledInteger, + copyData3DHeader.pointFields.pointRangeScaledInteger ); + + EXPECT_EQ( originalData3DHeader.pointFields.angleMinimum, copyData3DHeader.pointFields.angleMinimum ); + EXPECT_EQ( originalData3DHeader.pointFields.angleMaximum, copyData3DHeader.pointFields.angleMaximum ); + EXPECT_EQ( originalData3DHeader.pointFields.angleScaledInteger, copyData3DHeader.pointFields.angleScaledInteger ); + + EXPECT_EQ( originalData3DHeader.pointFields.rowIndexField, copyData3DHeader.pointFields.rowIndexField ); + EXPECT_EQ( originalData3DHeader.pointFields.rowIndexMaximum, copyData3DHeader.pointFields.rowIndexMaximum ); + + EXPECT_EQ( originalData3DHeader.pointFields.columnIndexField, copyData3DHeader.pointFields.columnIndexField ); + EXPECT_EQ( originalData3DHeader.pointFields.columnIndexMaximum, copyData3DHeader.pointFields.columnIndexMaximum ); + + EXPECT_EQ( originalData3DHeader.pointFields.returnIndexField, copyData3DHeader.pointFields.returnIndexField ); + EXPECT_EQ( originalData3DHeader.pointFields.returnCountField, copyData3DHeader.pointFields.returnCountField ); + EXPECT_EQ( originalData3DHeader.pointFields.returnMaximum, copyData3DHeader.pointFields.returnMaximum ); + + EXPECT_EQ( originalData3DHeader.pointFields.timeStampField, copyData3DHeader.pointFields.timeStampField ); + EXPECT_EQ( originalData3DHeader.pointFields.isTimeStampInvalidField, + copyData3DHeader.pointFields.isTimeStampInvalidField ); + EXPECT_EQ( originalData3DHeader.pointFields.timeMinimum, copyData3DHeader.pointFields.timeMinimum ); + EXPECT_EQ( originalData3DHeader.pointFields.timeMaximum, copyData3DHeader.pointFields.timeMaximum ); + + EXPECT_EQ( originalData3DHeader.pointFields.intensityField, copyData3DHeader.pointFields.intensityField ); + EXPECT_EQ( originalData3DHeader.pointFields.isIntensityInvalidField, + copyData3DHeader.pointFields.isIntensityInvalidField ); + EXPECT_EQ( originalData3DHeader.pointFields.intensityScaledInteger, + copyData3DHeader.pointFields.intensityScaledInteger ); + + EXPECT_EQ( originalData3DHeader.pointFields.colorRedField, copyData3DHeader.pointFields.colorRedField ); + EXPECT_EQ( originalData3DHeader.pointFields.colorGreenField, copyData3DHeader.pointFields.colorGreenField ); + EXPECT_EQ( originalData3DHeader.pointFields.colorBlueField, copyData3DHeader.pointFields.colorBlueField ); + EXPECT_EQ( originalData3DHeader.pointFields.isColorInvalidField, copyData3DHeader.pointFields.isColorInvalidField ); + + EXPECT_EQ( originalData3DHeader.pointFields.normalXField, copyData3DHeader.pointFields.normalXField ); + EXPECT_EQ( originalData3DHeader.pointFields.normalYField, copyData3DHeader.pointFields.normalYField ); + EXPECT_EQ( originalData3DHeader.pointFields.normalZField, copyData3DHeader.pointFields.normalZField ); + + EXPECT_EQ( originalData3DHeader.pointsSize, copyData3DHeader.pointsSize ); + + // 5. Compare the cartesianX FloatNode data + e57::CompressedVectorNode originalPointsStructureNode( originalReader->GetRawData3D().get( "/data3D/0/points" ) ); + e57::CompressedVectorNode copyPointsStructureNode( copyReader->GetRawData3D().get( "/data3D/0/points" ) ); + + const e57::StructureNode originalProto( originalPointsStructureNode.prototype() ); + const e57::StructureNode copyProto( copyPointsStructureNode.prototype() ); + + e57::FloatNode originalCartesianXNode( originalProto.get( "cartesianX" ) ); + e57::FloatNode copyCartesianXNode( copyProto.get( "cartesianX" ) ); + + EXPECT_EQ( originalCartesianXNode.precision(), copyCartesianXNode.precision() ); + EXPECT_EQ( originalCartesianXNode.minimum(), copyCartesianXNode.minimum() ); + EXPECT_EQ( originalCartesianXNode.maximum(), copyCartesianXNode.maximum() ); + + // 6. Cleanup + delete originalPointsData; + delete originalReader; + delete copyReader; +}