diff --git a/src/bsdfdata/Serializers.hpp b/src/bsdfdata/Serializers.hpp index 2cd93ac..9e54a01 100644 --- a/src/bsdfdata/Serializers.hpp +++ b/src/bsdfdata/Serializers.hpp @@ -192,7 +192,8 @@ namespace BSDFData } template - NodeAdapter & operator<<(NodeAdapter & node, const BSDFData::LengthWithCavity & lengthWithCavity) + NodeAdapter & operator<<(NodeAdapter & node, + const BSDFData::LengthWithCavity & lengthWithCavity) { using FileParse::operator<<; // operators for basic C++ types are in the FileParse // namespace @@ -389,25 +390,43 @@ namespace BSDFData return result; } + + std::vector> convertToSquareMatrix(std::vector const & v) + { + double intPart; + if(std::modf(std::sqrt(v.size()), &intPart) != 0) + { + throw std::runtime_error("Non-square matrix"); + } + size_t size = static_cast(intPart); + std::vector inner; + inner.resize(size); + std::vector> m(size, inner); + for(size_t row = 0; row < size; ++row) + { + for(size_t col = 0; col < size; ++col) + { + m[row][col] = v[row * size + col]; + } + } + return m; + } } // namespace /// Parses a string representation of scattering data into a vector of vectors of doubles. inline BSDFData::ScatteringData parseScatteringData(const std::string & value) { - BSDFData::ScatteringData scatteringData; + std::vector data; std::istringstream inputStream(value); std::string line; while(std::getline(inputStream, line)) { auto row = parseRow(line); - if(!row.empty()) - { - scatteringData.push_back(row); - } + data.insert(data.end(), row.begin(), row.end()); } - return scatteringData; + return convertToSquareMatrix(data); } template @@ -430,10 +449,10 @@ namespace BSDFData std::ostringstream rowStream; // Transform each element into a formatted string and join them with ", " - std::transform(row.begin(), row.end(), std::ostream_iterator(rowStream, ", "), - [](double value) { - return FileParse::formatDouble(value, 5, 1, 0.99); - }); + std::transform(row.begin(), + row.end(), + std::ostream_iterator(rowStream, ", "), + [](double value) { return FileParse::formatDouble(value, 5, 1, 0.99); }); return rowStream.str(); } @@ -587,4 +606,4 @@ namespace BSDFData return node; } -} // namespace BSDFXML \ No newline at end of file +} // namespace BSDFData \ No newline at end of file diff --git a/test/bsdf_xml_file_serialization.unit.cpp b/test/bsdf_xml_file_serialization.unit.cpp index 8bb9ac4..0410ce0 100644 --- a/test/bsdf_xml_file_serialization.unit.cpp +++ b/test/bsdf_xml_file_serialization.unit.cpp @@ -202,3 +202,41 @@ TEST(BSDFXMLFileSerialization, Save2011SA1Small) std::filesystem::remove(temp_path); } + +TEST(BSDFXMLFileSerialization, Save2011SA1Small_SingleColumnScatteringData) +{ + SCOPED_TRACE("Begin Test: Save 2011-SA1-Small-CommaSeparated-SingleColumnScattering.XML"); + std::filesystem::path product_path(TEST_DATA_DIR); + product_path /= "products"; + product_path /= "2011-SA1-Small-CommaSeparated-SingleColumnScattering.XML"; + + // Load the XML file to create a product object + auto product = BSDFData::loadWindowElementFromFile(product_path.string()); + ASSERT_TRUE(product.has_value()); + + // Save the product object to a temporary file + std::filesystem::path temp_path = "temp_2011-SA1-Small.xml"; + //std::filesystem::temp_directory_path() / "temp_2011-SA1-Small.xml"; + ASSERT_TRUE(BSDFData::saveToFile(*product, temp_path.string()) == 0); + + // Load the serialized file back + auto serialized_product = BSDFData::loadWindowElementFromFile(temp_path.string()); + ASSERT_TRUE(serialized_product.has_value()); + + // Compare the original product with the serialized product + EXPECT_EQ(product->windowElementType, serialized_product->windowElementType); + Helper::compareMaterial(product->optical.layer.material.value(), + serialized_product->optical.layer.material.value()); + Helper::compareDataDefinition(product->optical.layer.dataDefinition.value(), + serialized_product->optical.layer.dataDefinition.value()); + + ASSERT_EQ(product->optical.layer.wavelengthData.size(), + serialized_product->optical.layer.wavelengthData.size()); + for(size_t i = 0; i < product->optical.layer.wavelengthData.size(); ++i) + { + Helper::compareWavelengthData(product->optical.layer.wavelengthData[i], + serialized_product->optical.layer.wavelengthData[i]); + } + + std::filesystem::remove(temp_path); +} \ No newline at end of file diff --git a/test/products/2011-SA1-Small-CommaSeparated-SingleColumnScattering.XML b/test/products/2011-SA1-Small-CommaSeparated-SingleColumnScattering.XML new file mode 100644 index 0000000..0775dea --- /dev/null +++ b/test/products/2011-SA1-Small-CommaSeparated-SingleColumnScattering.XML @@ -0,0 +1,137 @@ + + + System + + + + Satine 5500 5%, White Pearl + Nysan + 1 + Other + 0.15 + 0.79626 + 0.79626 + 0.10916 + 0.049855 + @ + + + Columns + + LBNL/Klems Full + + 0 + + 0 + 5 + + 1 + + + 10 + + 5 + 15 + + 8 + + + 20 + + 15 + 25 + + 16 + + + 30 + + 25 + 35 + + 20 + + + 40 + + 35 + 45 + + 24 + + + 50 + + 45 + 55 + + 24 + + + 60 + + 55 + 65 + + 24 + + + 70 + + 65 + 75 + + 16 + + + 82.5 + + 75 + 90 + + 12 + + + + + System + Visible + CIE Illuminant D65 1nm.ssp + ASTM E308 1931 Y.dsp + + Transmission Front + LBNL/Klems Full + LBNL/Klems Full + BTDF + + 2.063833, + 0.014938, + + 0.014954, + 2.027935, + + + + + System + Visible + CIE Illuminant D65 1nm.ssp + ASTM E308 1931 Y.dsp + + Transmission Back + LBNL/Klems Full + LBNL/Klems Full + BTDF + + 2.063833, + 0.014938, + + 0.014954, + 2.027935, + + + + + +