From 6270d7657dcdde667e697e8f8a9a14fc4f2295ea Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 29 Nov 2024 18:50:11 +0100 Subject: [PATCH] Mesh: Reduce time of importing binary PLY files by around 60 percent --- src/Mod/Mesh/App/Core/IO/ReaderPLY.cpp | 120 +++++++++++++------------ src/Mod/Mesh/App/Core/IO/ReaderPLY.h | 42 ++++++--- 2 files changed, 90 insertions(+), 72 deletions(-) diff --git a/src/Mod/Mesh/App/Core/IO/ReaderPLY.cpp b/src/Mod/Mesh/App/Core/IO/ReaderPLY.cpp index abc61b1da1..ff29c4e4d2 100644 --- a/src/Mod/Mesh/App/Core/IO/ReaderPLY.cpp +++ b/src/Mod/Mesh/App/Core/IO/ReaderPLY.cpp @@ -121,6 +121,30 @@ bool ReaderPLY::ReadElement(std::istream& str, std::string& element) return true; } +ReaderPLY::Property ReaderPLY::propertyOfName(const std::string& name) +{ + if (name == "x") { + return coord_x; + } + if (name == "y") { + return coord_y; + } + if (name == "z") { + return coord_z; + } + if (name == "red" || name == "diffuse_red") { + return color_r; + } + if (name == "green" || name == "diffuse_green") { + return color_g; + } + if (name == "blue" || name == "diffuse_blue") { + return color_b; + } + + return generic; +} + bool ReaderPLY::ReadVertexProperty(std::istream& str) { std::string type; @@ -159,7 +183,7 @@ bool ReaderPLY::ReadVertexProperty(std::istream& str) } // store the property name and type - vertex_props.emplace_back(name, number); + vertex_props.emplace_back(propertyOfName(name), number); return true; } @@ -274,23 +298,23 @@ bool ReaderPLY::ReadHeader(std::istream& input) bool ReaderPLY::VerifyVertexProperty() { // check if valid 3d points - Property property; + PropertyComp property; std::size_t num_x = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { - return property(p, "x"); + [&property](const std::pair& p) { + return property(p, coord_x); }); std::size_t num_y = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { - return property(p, "y"); + [&property](const std::pair& p) { + return property(p, coord_y); }); std::size_t num_z = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { - return property(p, "z"); + [&property](const std::pair& p) { + return property(p, coord_z); }); return ((num_x == 1) && (num_y == 1) && (num_z == 1)); @@ -298,36 +322,24 @@ bool ReaderPLY::VerifyVertexProperty() bool ReaderPLY::VerifyColorProperty() { - for (auto& it : vertex_props) { - if (it.first == "diffuse_red") { - it.first = "red"; - } - else if (it.first == "diffuse_green") { - it.first = "green"; - } - else if (it.first == "diffuse_blue") { - it.first = "blue"; - } - } - // check if valid colors are set - Property property; + PropertyComp property; std::size_t num_r = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { - return property(p, "red"); + [&property](const std::pair& p) { + return property(p, color_r); }); std::size_t num_g = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { - return property(p, "green"); + [&property](const std::pair& p) { + return property(p, color_g); }); std::size_t num_b = std::count_if(vertex_props.begin(), vertex_props.end(), - [&property](const std::pair& p) { - return property(p, "blue"); + [&property](const std::pair& p) { + return property(p, color_b); }); std::size_t rgb_colors = num_r + num_g + num_b; @@ -395,7 +407,7 @@ bool ReaderPLY::ReadVertexes(std::istream& input) for (std::size_t i = 0; i < v_count && std::getline(input, line); i++) { // go through the vertex properties - std::map prop_values; + PropertyArray prop_values {}; for (const auto& it : vertex_props) { switch (it.second) { case int8: @@ -441,18 +453,7 @@ bool ReaderPLY::ReadVertexes(std::istream& input) } } - Base::Vector3f pt; - pt.x = (prop_values["x"]); - pt.y = (prop_values["y"]); - pt.z = (prop_values["z"]); - meshPoints.push_back(pt); - - if (_material && _material->binding == MeshIO::PER_VERTEX) { - float r = (prop_values["red"]) / 255.0F; - float g = (prop_values["green"]) / 255.0F; - float b = (prop_values["blue"]) / 255.0F; - _material->diffuseColor.emplace_back(r, g, b); - } + addVertexProperty(prop_values); } return true; @@ -493,17 +494,29 @@ bool ReaderPLY::LoadAscii(std::istream& input) return true; } +void ReaderPLY::addVertexProperty(const PropertyArray& prop) +{ + Base::Vector3f pt; + pt.x = (prop[coord_x]); + pt.y = (prop[coord_y]); + pt.z = (prop[coord_z]); + meshPoints.push_back(pt); + + if (_material && _material->binding == MeshIO::PER_VERTEX) { + // NOLINTBEGIN + float r = (prop[color_r]) / 255.0F; + float g = (prop[color_g]) / 255.0F; + float b = (prop[color_b]) / 255.0F; + // NOLINTEND + _material->diffuseColor.emplace_back(r, g, b); + } +} + bool ReaderPLY::ReadVertexes(Base::InputStream& is) { - std::string prop_x = "x"; - std::string prop_y = "y"; - std::string prop_z = "z"; - std::string prop_r = "red"; - std::string prop_g = "gree"; - std::string prop_b = "blue"; for (std::size_t i = 0; i < v_count; i++) { // go through the vertex properties - std::map prop_values; + PropertyArray prop_values {}; for (const auto& it : vertex_props) { switch (it.second) { case int8: { @@ -551,18 +564,7 @@ bool ReaderPLY::ReadVertexes(Base::InputStream& is) } } - Base::Vector3f pt; - pt.x = (prop_values[prop_x]); - pt.y = (prop_values[prop_y]); - pt.z = (prop_values[prop_z]); - meshPoints.push_back(pt); - - if (_material && _material->binding == MeshIO::PER_VERTEX) { - float r = (prop_values[prop_r]) / 255.0F; - float g = (prop_values[prop_g]) / 255.0F; - float b = (prop_values[prop_b]) / 255.0F; - _material->diffuseColor.emplace_back(r, g, b); - } + addVertexProperty(prop_values); } return true; diff --git a/src/Mod/Mesh/App/Core/IO/ReaderPLY.h b/src/Mod/Mesh/App/Core/IO/ReaderPLY.h index fceb08e210..e4ca967ace 100644 --- a/src/Mod/Mesh/App/Core/IO/ReaderPLY.h +++ b/src/Mod/Mesh/App/Core/IO/ReaderPLY.h @@ -73,21 +73,22 @@ private: void CleanupMesh(); private: - struct Property + enum Property { - using argument_type_1st = std::pair; - using argument_type_2nd = std::string; - using result_type = bool; - - // clang-format off - bool operator()(const argument_type_1st& x, - const argument_type_2nd& y) const - { - return x.first == y; - } - // clang-format on + coord_x, + coord_y, + coord_z, + color_r, + color_g, + color_b, + generic, + num_props }; + static Property propertyOfName(const std::string& name); + using PropertyArray = std::array; + void addVertexProperty(const PropertyArray& prop); + enum Number { int8, @@ -100,6 +101,21 @@ private: float64 }; + struct PropertyComp + { + using argument_type_1st = std::pair; + using argument_type_2nd = Property; + using result_type = bool; + + // clang-format off + bool operator()(const argument_type_1st& x, + const argument_type_2nd& y) const + { + return x.first == y; + } + // clang-format on + }; + enum Format { unknown, @@ -108,7 +124,7 @@ private: binary_big_endian } format = unknown; - std::vector> vertex_props; + std::vector> vertex_props; std::vector face_props; std::size_t v_count = 0;