From 745b7cdaf7262d4f38cd28ca9cb57465b5c26cfa Mon Sep 17 00:00:00 2001 From: lab pc Date: Wed, 1 Dec 2021 16:22:53 +0800 Subject: [PATCH] add udf and format the project --- CMakeLists.txt | 8 + include/Octree/AABB.h | 34 ++- include/Octree/BaseOctree.h | 7 + include/Octree/OctreeIO.h | 52 ----- include/Octree/{ => sdf}/SDFData.h | 2 +- include/Octree/{ => sdf}/SDFOctree.h | 2 +- .../Octree/{ => sdf}/SDFTraversalSampler.h | 2 +- include/Octree/{ => udf}/UDFData.h | 2 +- include/Octree/{ => udf}/UDFOctree.h | 7 +- .../Octree/{ => udf}/UDFTraversalSampler.h | 2 +- src/AABB.cpp | 45 ++-- src/OctreeIO.cpp | 29 --- src/{ => sdf}/SDFData.cpp | 2 +- src/{ => sdf}/SDFOctree.cpp | 6 +- src/{ => sdf}/SDFTraversalSampler.cpp | 18 +- src/{ => udf}/UDFData.cpp | 2 +- src/{ => udf}/UDFOctree.cpp | 9 +- src/{ => udf}/UDFTraversalSampler.cpp | 18 +- tests/octree_test/.gitignore | 1 + tests/octree_test/CMakeLists.txt | 5 +- tests/octree_test/main.cpp | 21 +- tests/octree_test/test-path.h.in | 16 ++ tests/sdf_test/.gitignore | 1 + tests/sdf_test/CMakeLists.txt | 5 +- tests/sdf_test/main.cpp | 7 +- tests/sdf_test/test-path.h.in | 16 ++ tests/udf_test/.gitignore | 1 + tests/udf_test/CMakeLists.txt | 6 + tests/udf_test/main.cpp | 198 ++++++++++++++++++ tests/udf_test/test-path.h.in | 16 ++ 30 files changed, 379 insertions(+), 161 deletions(-) delete mode 100644 include/Octree/OctreeIO.h rename include/Octree/{ => sdf}/SDFData.h (94%) rename include/Octree/{ => sdf}/SDFOctree.h (97%) rename include/Octree/{ => sdf}/SDFTraversalSampler.h (97%) rename include/Octree/{ => udf}/UDFData.h (94%) rename include/Octree/{ => udf}/UDFOctree.h (96%) rename include/Octree/{ => udf}/UDFTraversalSampler.h (97%) delete mode 100644 src/OctreeIO.cpp rename src/{ => sdf}/SDFData.cpp (91%) rename src/{ => sdf}/SDFOctree.cpp (89%) rename src/{ => sdf}/SDFTraversalSampler.cpp (92%) rename src/{ => udf}/UDFData.cpp (91%) rename src/{ => udf}/UDFOctree.cpp (78%) rename src/{ => udf}/UDFTraversalSampler.cpp (92%) create mode 100644 tests/octree_test/.gitignore create mode 100644 tests/octree_test/test-path.h.in create mode 100644 tests/sdf_test/.gitignore create mode 100644 tests/sdf_test/test-path.h.in create mode 100644 tests/udf_test/.gitignore create mode 100644 tests/udf_test/CMakeLists.txt create mode 100644 tests/udf_test/main.cpp create mode 100644 tests/udf_test/test-path.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index a6500aa..4f6c09e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,13 +27,21 @@ add_library(Octree SHARED ${headers} ${sources}) target_link_libraries(Octree igl::core ${Boost_LIBRARIES} Eigen3::Eigen pMesh) target_include_directories(Octree PUBLIC ${PROJECT_SOURCE_DIR}/include) + +# --------------------- TEST -------------------- +if(Octree_BUILD_TEST) + set(TEST_DATA_BASE_PATH ${PROJECT_SOURCE_DIR}/data) +endif() + if(Octree_BUILD_TEST) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests/octree_test) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests/sdf_test) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tests/udf_test) endif() enable_testing() if(Octree_BUILD_TEST) add_test(NAME octree_test COMMAND $) add_test(NAME sdf_test COMMAND $) + add_test(NAME udf_test COMMAND $) endif() \ No newline at end of file diff --git a/include/Octree/AABB.h b/include/Octree/AABB.h index 2246e8c..f9e5bd1 100644 --- a/include/Octree/AABB.h +++ b/include/Octree/AABB.h @@ -16,7 +16,7 @@ namespace Octree { class AABB { - Eigen::Vector3d min, max; + Eigen::Vector3d _min, _max; public: explicit AABB(const Eigen::Vector3d &min, const Eigen::Vector3d &max); @@ -30,11 +30,11 @@ namespace Octree { public: Eigen::Vector3d size() const; - Eigen::Vector3d get_min() const; + Eigen::Vector3d min() const; - Eigen::Vector3d get_max() const; + Eigen::Vector3d max() const; - Eigen::Vector3d get_center() const; + Eigen::Vector3d center() const; /** * @reference: https://github.com/diwi/Space_Partitioning_Octree_BVH @@ -45,14 +45,36 @@ namespace Octree { */ bool intersect_triangle(const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c) const; + /** + * If the AABB contains the point v + * @param v + * @return + */ bool contains(const Eigen::Vector3d &v) const; - bool - fully_contains_triangle(const Eigen::Vector3d &a, const Eigen::Vector3d &b, const Eigen::Vector3d &c) const; + /** + * If the AABB fully contains a triangle + * @param a + * @param b + * @param c + * @return + */ + bool fully_contains_triangle(const Eigen::Vector3d &a, + const Eigen::Vector3d &b, + const Eigen::Vector3d &c) const; + /** + * Divide this AABB into 8 parts + * @return + */ std::array half_divide() const; public: + + /** + * Extend boundary with @param step + * @param step + */ void extend(double step); }; } diff --git a/include/Octree/BaseOctree.h b/include/Octree/BaseOctree.h index 1c2cefe..540b10b 100644 --- a/include/Octree/BaseOctree.h +++ b/include/Octree/BaseOctree.h @@ -48,6 +48,8 @@ namespace Octree { array children; ocnode_ptr father; AABB aabb; + + public: set tri_ids; public: @@ -90,6 +92,11 @@ namespace Octree { * @return */ ocnode_sptr map_node(const Eigen::Vector3d &pos); + + public: //Getter + uint32_t get_level(){ return level; } + + AABB get_aabb() { return aabb; } }; class BaseOctree { diff --git a/include/Octree/OctreeIO.h b/include/Octree/OctreeIO.h deleted file mode 100644 index 2dda1b2..0000000 --- a/include/Octree/OctreeIO.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * ------------------------------------ - * @author: Weipeng Kong - * @date: 2021/11/22 - * @email: yjxkwp@foxmail.com - * @site: https://donot.fit - * @description: - * ------------------------------------ -**/ - -#ifndef OCTREE_OCTREEIO_H -#define OCTREE_OCTREEIO_H - -#include - - -namespace Octree { - - class BaseOctree; - class OctreeNode; - - class OctreeIO { - protected: - using fs_path = boost::filesystem::path; - }; - - class OctreeSaver : public OctreeIO { - private: - const BaseOctree &octree; - - public: - explicit OctreeSaver(const BaseOctree &octree); - - void save(const fs_path &path); - - private: - void save_recursively(const OctreeNode &node); - }; - - class OctreeLoader : public OctreeIO { - private: - BaseOctree &octree; - - public: - explicit OctreeLoader(BaseOctree &octree); - - void load(const fs_path &path); - }; - -} - -#endif //OCTREE_OCTREEIO_H diff --git a/include/Octree/SDFData.h b/include/Octree/sdf/SDFData.h similarity index 94% rename from include/Octree/SDFData.h rename to include/Octree/sdf/SDFData.h index bf9ddc4..2285c15 100644 --- a/include/Octree/SDFData.h +++ b/include/Octree/sdf/SDFData.h @@ -14,7 +14,7 @@ #include #include #include -#include "VoxelDenseData.h" +#include "Octree/VoxelDenseData.h" namespace Octree { class SDFData: public VoxelDenseData{ diff --git a/include/Octree/SDFOctree.h b/include/Octree/sdf/SDFOctree.h similarity index 97% rename from include/Octree/SDFOctree.h rename to include/Octree/sdf/SDFOctree.h index c5134bc..3816928 100644 --- a/include/Octree/SDFOctree.h +++ b/include/Octree/sdf/SDFOctree.h @@ -11,7 +11,7 @@ #ifndef OCTREE_SDFOCTREE_H #define OCTREE_SDFOCTREE_H -#include "BaseOctree.h" +#include "Octree/BaseOctree.h" namespace Octree { diff --git a/include/Octree/SDFTraversalSampler.h b/include/Octree/sdf/SDFTraversalSampler.h similarity index 97% rename from include/Octree/SDFTraversalSampler.h rename to include/Octree/sdf/SDFTraversalSampler.h index a9fa3ce..60d332f 100644 --- a/include/Octree/SDFTraversalSampler.h +++ b/include/Octree/sdf/SDFTraversalSampler.h @@ -11,7 +11,7 @@ #ifndef OCTREE_SDFTRAVERSALSAMPLER_H #define OCTREE_SDFTRAVERSALSAMPLER_H -#include "OctreeTraverser.h" +#include "Octree/OctreeTraverser.h" #include "SDFData.h" #include #include diff --git a/include/Octree/UDFData.h b/include/Octree/udf/UDFData.h similarity index 94% rename from include/Octree/UDFData.h rename to include/Octree/udf/UDFData.h index dc67c9c..215d46a 100644 --- a/include/Octree/UDFData.h +++ b/include/Octree/udf/UDFData.h @@ -14,7 +14,7 @@ #include #include #include -#include "VoxelDenseData.h" +#include "Octree/VoxelDenseData.h" namespace Octree { diff --git a/include/Octree/UDFOctree.h b/include/Octree/udf/UDFOctree.h similarity index 96% rename from include/Octree/UDFOctree.h rename to include/Octree/udf/UDFOctree.h index 75edff3..a5b81db 100644 --- a/include/Octree/UDFOctree.h +++ b/include/Octree/udf/UDFOctree.h @@ -12,10 +12,10 @@ #define OCTREE_UDFOCTREE_H -#include "BaseOctree.h" +#include "Octree/BaseOctree.h" -namespace Octree { +namespace Octree{ class UDFData; class UDFOctreeNode; @@ -24,6 +24,9 @@ namespace Octree { using ocudfnode_sptr = shared_ptr; using ocudfnode_wptr = weak_ptr; using ocudfnode_ptr = UDFOctreeNode *; +} + +namespace Octree { struct UDFOctreeNode : public OctreeNode { public: diff --git a/include/Octree/UDFTraversalSampler.h b/include/Octree/udf/UDFTraversalSampler.h similarity index 97% rename from include/Octree/UDFTraversalSampler.h rename to include/Octree/udf/UDFTraversalSampler.h index b6c8135..79e3ed5 100644 --- a/include/Octree/UDFTraversalSampler.h +++ b/include/Octree/udf/UDFTraversalSampler.h @@ -11,7 +11,7 @@ #ifndef OCTREE_SDFTRAVERSALSAMPLER_H #define OCTREE_SDFTRAVERSALSAMPLER_H -#include "OctreeTraverser.h" +#include "Octree/OctreeTraverser.h" #include "UDFData.h" #include #include diff --git a/src/AABB.cpp b/src/AABB.cpp index c69edf4..97f3e08 100644 --- a/src/AABB.cpp +++ b/src/AABB.cpp @@ -47,12 +47,12 @@ namespace AABBTools { -Octree::AABB::AABB(const Eigen::Vector3d &min, const Eigen::Vector3d &max) : min(min), max(max) { +Octree::AABB::AABB(const Eigen::Vector3d &min, const Eigen::Vector3d &max) : _min(min), _max(max) { } Octree::AABB::AABB(double minx, double maxx, double miny, double maxy, double minz, double maxz) : - min(minx, miny, minz), max(maxx, maxy, maxz) { + _min(minx, miny, minz), _max(maxx, maxy, maxz) { } @@ -62,28 +62,28 @@ Octree::AABB::AABB(const std::array &aabb) : Eigen::Vector3d Octree::AABB::size() const { - return max - min; + return _max - _min; } -Eigen::Vector3d Octree::AABB::get_center() const { - return (max + min) / 2.0; +Eigen::Vector3d Octree::AABB::center() const { + return (_max + _min) / 2.0; } -Eigen::Vector3d Octree::AABB::get_min() const { - return min; +Eigen::Vector3d Octree::AABB::min() const { + return _min; } -Eigen::Vector3d Octree::AABB::get_max() const { - return max; +Eigen::Vector3d Octree::AABB::max() const { + return _max; } bool Octree::AABB::intersect_triangle(const Eigen::Vector3d &a, - const Eigen::Vector3d &b, - const Eigen::Vector3d &c) const { + const Eigen::Vector3d &b, + const Eigen::Vector3d &c) const { using Eigen::Vector3d; - Vector3d center = this->get_center(); + Vector3d center = this->center(); Vector3d hs = this->size() / 2; Vector3d v0 = a - center; Vector3d v1 = b - center; @@ -125,7 +125,7 @@ bool Octree::AABB::intersect_triangle(const Eigen::Vector3d &a, // Bullet 1: // First test overlap in the {x,y,z}-directions. - // Find min, max of the triangle each direction, and test for overlap in that + // Find _min, _max of the triangle each direction, and test for overlap in that // direction -- this is equivalent to testing a minimal AABB around the triangle against the AABB. if (AABBTools::directionTest(v0[0], v1[0], v2[0], hs[0])) return false; // Test in X-direction. if (AABBTools::directionTest(v0[1], v1[1], v2[1], hs[1])) return false; // Test in Y-direction. @@ -143,12 +143,13 @@ bool Octree::AABB::intersect_triangle(const Eigen::Vector3d &a, bool Octree::AABB::contains(const Eigen::Vector3d &v) const { - return (v.x() >= min.x() && v.y() >= min.y() && v.z() >= min.z()) && - (v.x() <= max.x() && v.y() <= max.y() && v.z() <= max.z()); + return (v.x() >= _min.x() && v.y() >= _min.y() && v.z() >= _min.z()) && + (v.x() <= _max.x() && v.y() <= _max.y() && v.z() <= _max.z()); } -bool Octree::AABB::fully_contains_triangle(const Eigen::Vector3d &a, const Eigen::Vector3d &b, - const Eigen::Vector3d &c) const { +bool Octree::AABB::fully_contains_triangle(const Eigen::Vector3d &a, + const Eigen::Vector3d &b, + const Eigen::Vector3d &c) const { return contains(a) && contains(b) && contains(c); } @@ -156,9 +157,9 @@ std::array Octree::AABB::half_divide() const { std::array aabbs; auto half_size = this->size() / 2.0; for (int i = 0; i < 8; ++i) { - Eigen::Vector3d sub_min = {min[0] + (((i & 4) > 0) ? half_size[0] : 0), - min[1] + (((i & 2) > 0) ? half_size[1] : 0), - min[2] + (((i & 1) > 0) ? half_size[2] : 0)}; + Eigen::Vector3d sub_min = {_min[0] + (((i & 4) > 0) ? half_size[0] : 0), + _min[1] + (((i & 2) > 0) ? half_size[1] : 0), + _min[2] + (((i & 1) > 0) ? half_size[2] : 0)}; Eigen::Vector3d sub_max = sub_min + half_size; aabbs[i] = AABB(sub_min, sub_max); } @@ -166,6 +167,6 @@ std::array Octree::AABB::half_divide() const { } void Octree::AABB::extend(double step) { - this->min -= Eigen::Vector3d(step, step, step); - this->max += Eigen::Vector3d(step, step, step); + this->_min -= Eigen::Vector3d(step, step, step); + this->_max += Eigen::Vector3d(step, step, step); } diff --git a/src/OctreeIO.cpp b/src/OctreeIO.cpp deleted file mode 100644 index e1c1117..0000000 --- a/src/OctreeIO.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/** - * ------------------------------------ - * @author: Weipeng Kong - * @date: 2021/11/22 - * @email: yjxkwp@foxmail.com - * @site: https://donot.fit - * @description: - * ------------------------------------ -**/ - -#include "../include/Octree/OctreeIO.h" -#include "Octree/BaseOctree.h" - -namespace SerializationTool{ - - -} - -Octree::OctreeSaver::OctreeSaver(const Octree::BaseOctree &octree): octree(octree) { - -} - -void Octree::OctreeSaver::save(const Octree::OctreeIO::fs_path &path) { - -} - -void Octree::OctreeSaver::save_recursively(const Octree::OctreeNode &node) { - -} \ No newline at end of file diff --git a/src/SDFData.cpp b/src/sdf/SDFData.cpp similarity index 91% rename from src/SDFData.cpp rename to src/sdf/SDFData.cpp index 8b82e2a..403f58b 100644 --- a/src/SDFData.cpp +++ b/src/sdf/SDFData.cpp @@ -8,7 +8,7 @@ * ------------------------------------ **/ -#include "Octree/SDFData.h" +#include "Octree/sdf/SDFData.h" Octree::SDFData::SDFData(const std::vector &value, int _x, int _y, int _z) : VoxelDenseData(value, _x, _y, _z) { diff --git a/src/SDFOctree.cpp b/src/sdf/SDFOctree.cpp similarity index 89% rename from src/SDFOctree.cpp rename to src/sdf/SDFOctree.cpp index 1258d48..be923bb 100644 --- a/src/SDFOctree.cpp +++ b/src/sdf/SDFOctree.cpp @@ -8,12 +8,12 @@ * ------------------------------------ **/ -#include "Octree/SDFOctree.h" -#include "Octree/SDFData.h" +#include "Octree/sdf/SDFOctree.h" +#include "Octree/sdf/SDFData.h" double Octree::SDFOctreeNode::get_sdf(const Eigen::Vector3d &pos) { - Eigen::Vector3d relative = pos - aabb.get_min(); + Eigen::Vector3d relative = pos - aabb.min(); auto size = aabb.size(); relative.x() = relative.x() / size.x(); relative.y() = relative.y() / size.y(); diff --git a/src/SDFTraversalSampler.cpp b/src/sdf/SDFTraversalSampler.cpp similarity index 92% rename from src/SDFTraversalSampler.cpp rename to src/sdf/SDFTraversalSampler.cpp index 093185d..39b77d0 100644 --- a/src/SDFTraversalSampler.cpp +++ b/src/sdf/SDFTraversalSampler.cpp @@ -8,9 +8,9 @@ * ------------------------------------ **/ -#include "Octree/SDFTraversalSampler.h" -#include "Octree/SDFData.h" -#include "Octree/SDFOctree.h" +#include "Octree/sdf/SDFTraversalSampler.h" +#include "Octree/sdf/SDFData.h" +#include "Octree/sdf/SDFOctree.h" #include #include #include @@ -26,9 +26,9 @@ void Octree::SDFTraversalBuilder::visit_node(Octree::OctreeNode &node) { // if (not node.is_leaf()) return; auto &sdf_node = (SDFOctreeNode &)node; - if (node.level >= octree.get_max_level()) { + if (node.get_level() >= octree.get_max_level()) { // deepest voxel - auto aabb_size = node.aabb.size(); + auto aabb_size = node.get_aabb().size(); #if 0 BOOST_LOG_TRIVIAL(debug) << "aabb_size = " << aabb_size.transpose(); BOOST_LOG_TRIVIAL(debug) << "\t\t\t\t = " << (aabb_size / sample_step).transpose(); @@ -81,16 +81,16 @@ void Octree::SDFTraversalBuilder::build() { int index_base = 0; for (const auto &qbox: this->query_boxes) { auto &sdf = *qbox.node.sdf; - auto &aabb = qbox.node.aabb; - const auto pos_base = aabb.get_min(); - const auto pos_max = aabb.get_max(); + auto aabb = qbox.node.get_aabb(); + const auto pos_base = aabb.min(); + const auto pos_max = aabb.max(); const auto aabb_size = aabb.size(); const int _x = sdf._x - 1, _y = sdf._y - 1, _z = sdf._z - 1; const Eigen::Vector3d local_step(aabb_size.x() / _x, aabb_size.y() / _y, aabb_size.z() / _z); for (int z = 0; z <= _z; ++z) { -// double pos_z = std::min(pos_base.z() + z * local_step.x(), pos_max.z()); +// double pos_z = std::_min(pos_base.z() + z * local_step.x(), pos_max.z()); double pos_z = pos_base.z() + z * local_step.z(); for (int y = 0; y <= _y; ++y) { double pos_y = pos_base.y() + y * local_step.y(); diff --git a/src/UDFData.cpp b/src/udf/UDFData.cpp similarity index 91% rename from src/UDFData.cpp rename to src/udf/UDFData.cpp index 38f6356..f4cd057 100644 --- a/src/UDFData.cpp +++ b/src/udf/UDFData.cpp @@ -8,7 +8,7 @@ * ------------------------------------ **/ -#include "Octree/UDFData.h" +#include "Octree/udf/UDFData.h" Octree::UDFData::UDFData(const std::vector &value, int _x, int _y, int _z) : VoxelDenseData(value, _x, _y, _z) { diff --git a/src/UDFOctree.cpp b/src/udf/UDFOctree.cpp similarity index 78% rename from src/UDFOctree.cpp rename to src/udf/UDFOctree.cpp index c1d4e1a..f0b762c 100644 --- a/src/UDFOctree.cpp +++ b/src/udf/UDFOctree.cpp @@ -8,8 +8,8 @@ * ------------------------------------ **/ -#include "Octree/UDFOctree.h" -#include "Octree/UDFData.h" +#include "Octree/udf/UDFOctree.h" +#include "Octree/udf/UDFData.h" Octree::UDFOctreeNode::UDFOctreeNode(Octree::ocnode_ptr father, const Octree::AABB &aabb, uint32_t level) : OctreeNode( father, aabb, level) { @@ -17,7 +17,7 @@ Octree::UDFOctreeNode::UDFOctreeNode(Octree::ocnode_ptr father, const Octree::AA } double Octree::UDFOctreeNode::get_udf(const Eigen::Vector3d &pos) { - Eigen::Vector3d relative = pos - aabb.get_min(); + Eigen::Vector3d relative = pos - aabb.min(); auto size = aabb.size(); relative.x() = relative.x() / size.x(); relative.y() = relative.y() / size.y(); @@ -29,6 +29,7 @@ Octree::ocnode_sptr Octree::UDFOctreeNode::make_child(const Octree::AABB &aabb) return std::make_shared(this, aabb, level + 1); } -Octree::UDFOctree::UDFOctree(uint32_t max_level, const Octree::AABB &aabb) : BaseOctree(max_level, aabb) { +Octree::UDFOctree::UDFOctree(uint32_t max_level, const Octree::AABB &aabb) : + BaseOctree(max_level, std::static_pointer_cast(std::make_shared(nullptr, aabb, 0))) { } diff --git a/src/UDFTraversalSampler.cpp b/src/udf/UDFTraversalSampler.cpp similarity index 92% rename from src/UDFTraversalSampler.cpp rename to src/udf/UDFTraversalSampler.cpp index 3ad3111..66cca11 100644 --- a/src/UDFTraversalSampler.cpp +++ b/src/udf/UDFTraversalSampler.cpp @@ -8,9 +8,9 @@ * ------------------------------------ **/ -#include "Octree/UDFTraversalSampler.h" -#include "Octree/UDFData.h" -#include "Octree/UDFOctree.h" +#include "Octree/udf/UDFTraversalSampler.h" +#include "Octree/udf/UDFData.h" +#include "Octree/udf/UDFOctree.h" #include #include #include @@ -28,9 +28,9 @@ void Octree::UDFTraversalBuilder::visit_node(Octree::OctreeNode &node) { auto &udf_node = (UDFOctreeNode &)node; // if (not node.is_leaf()) return; - if (node.level >= octree.max_level) { + if (node.get_level() >= octree.max_level) { // deepest voxel - auto aabb_size = node.aabb.size(); + auto aabb_size = node.get_aabb().size(); #if 0 BOOST_LOG_TRIVIAL(debug) << "aabb_size = " << aabb_size.transpose(); BOOST_LOG_TRIVIAL(debug) << "\t\t\t\t = " << (aabb_size / sample_step).transpose(); @@ -83,16 +83,16 @@ void Octree::UDFTraversalBuilder::build() { int index_base = 0; for (const auto &qbox: this->query_boxes) { auto &sdf = *qbox.node.udf; - auto &aabb = qbox.node.aabb; - const auto pos_base = aabb.get_min(); - const auto pos_max = aabb.get_max(); + auto aabb = qbox.node.get_aabb(); + const auto pos_base = aabb.min(); + const auto pos_max = aabb.max(); const auto aabb_size = aabb.size(); const int _x = sdf._x - 1, _y = sdf._y - 1, _z = sdf._z - 1; const Eigen::Vector3d local_step(aabb_size.x() / _x, aabb_size.y() / _y, aabb_size.z() / _z); for (int z = 0; z <= _z; ++z) { -// double pos_z = std::min(pos_base.z() + z * local_step.x(), pos_max.z()); +// double pos_z = std::_min(pos_base.z() + z * local_step.x(), pos_max.z()); double pos_z = pos_base.z() + z * local_step.z(); for (int y = 0; y <= _y; ++y) { double pos_y = pos_base.y() + y * local_step.y(); diff --git a/tests/octree_test/.gitignore b/tests/octree_test/.gitignore new file mode 100644 index 0000000..298482a --- /dev/null +++ b/tests/octree_test/.gitignore @@ -0,0 +1 @@ +test-path.h \ No newline at end of file diff --git a/tests/octree_test/CMakeLists.txt b/tests/octree_test/CMakeLists.txt index aec0e2c..3b87f8f 100644 --- a/tests/octree_test/CMakeLists.txt +++ b/tests/octree_test/CMakeLists.txt @@ -1,3 +1,6 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/) +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/test-path.h.in" + "${CMAKE_CURRENT_SOURCE_DIR}/test-path.h" +) add_executable(octree_test main.cpp) target_link_libraries(octree_test Octree pMesh) diff --git a/tests/octree_test/main.cpp b/tests/octree_test/main.cpp index d061aa3..e81c975 100644 --- a/tests/octree_test/main.cpp +++ b/tests/octree_test/main.cpp @@ -9,10 +9,10 @@ **/ #include -#include "Octree/SDFOctree.h" +#include "Octree/sdf/SDFOctree.h" #include "Octree/OctreeBuilder.h" #include "Octree/OctreeTraverser.h" -#include "Octree/SDFTraversalSampler.h" +#include "Octree/sdf/SDFTraversalSampler.h" #include #include #include @@ -27,6 +27,7 @@ #include #include #include +#include "test-path.h" class VTKTraverser : public pMesh::io::BaseReader, public Octree::OctreeTraverser { @@ -42,8 +43,7 @@ public: }; int main() { - BOOST_LOG_TRIVIAL(debug) << "cwd is " << boost::filesystem::current_path(); - pMesh::io::fs_path data_base_path = "../../../data"; + pMesh::io::fs_path data_base_path = TEST_DATA_BASE_PATH; BOOST_LOG_TRIVIAL(debug) << "base data path is " << boost::filesystem::absolute(data_base_path); auto mesh_path = data_base_path / "stanford-bunny.obj"; @@ -51,17 +51,14 @@ int main() { auto out_mc_path = data_base_path / "stanford-bunny-mc.obj"; auto out_error_path = data_base_path / "stanford-bunny-error_points.vtk"; - - pMesh::Triangle3dMesh<> mesh; pMesh::io::OBJReader(mesh_path) >> pMesh::io::DefaultSurfaceReadAdapter<>(mesh, false)(); BOOST_LOG_TRIVIAL(info) << "Load Face #" << mesh.f_size(); -// pMesh::io::VTKReader("/Users/kwp/Projects/Porous/models/v8/tris.vtk") >> pMesh::io::DefaultSurfaceReadAdapter<>(mesh)(); const int level = 4; - const double sample_step = 0.004; + const double sample_step = 0.003; boost::timer t; Octree::AABB aabb(mesh.aabb()); @@ -72,7 +69,7 @@ int main() { builder.build(); BOOST_LOG_TRIVIAL(debug) << "time elapse " << t.elapsed(); - auto aabb_size = octree.get_root()->aabb.size(); + auto aabb_size = octree.aabb().size(); BOOST_LOG_TRIVIAL(debug) << "Global AABB " << aabb_size.transpose(); auto final_aabb_size = aabb_size / pow(2, level); @@ -173,14 +170,14 @@ int main() { void VTKTraverser::visit_node(Octree::OctreeNode &node) { - if (node.level != octree.get_max_level()) { + if (node.get_level() != octree.get_max_level()) { // assert(!node.is_leaf()); assert(node.tri_ids.empty()); return; } - auto min = node.aabb.get_min(); - auto max = node.aabb.get_max(); + auto min = node.get_aabb().min(); + auto max = node.get_aabb().max(); reader_adapter->feed_vertex({min.x(), min.y(), min.z()}); reader_adapter->feed_vertex({max.x(), min.y(), min.z()}); reader_adapter->feed_vertex({max.x(), max.y(), min.z()}); diff --git a/tests/octree_test/test-path.h.in b/tests/octree_test/test-path.h.in new file mode 100644 index 0000000..0e3ea76 --- /dev/null +++ b/tests/octree_test/test-path.h.in @@ -0,0 +1,16 @@ +/** + * ------------------------------------ + * @author: Weipeng Kong + * @date: 2021/12/1 + * @email: yjxkwp@foxmail.com + * @site: https://donot.fit + * @description: + * ------------------------------------ +**/ + +#ifndef OCTREE_SDF_TEST_PATH_H +#define OCTREE_SDF_TEST_PATH_H + +#define TEST_DATA_BASE_PATH "@TEST_DATA_BASE_PATH@" + +#endif //OCTREE_SDF_TEST_PATH_H diff --git a/tests/sdf_test/.gitignore b/tests/sdf_test/.gitignore new file mode 100644 index 0000000..298482a --- /dev/null +++ b/tests/sdf_test/.gitignore @@ -0,0 +1 @@ +test-path.h \ No newline at end of file diff --git a/tests/sdf_test/CMakeLists.txt b/tests/sdf_test/CMakeLists.txt index ba19aac..80a0c77 100644 --- a/tests/sdf_test/CMakeLists.txt +++ b/tests/sdf_test/CMakeLists.txt @@ -1,3 +1,6 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/) +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/test-path.h.in" + "${CMAKE_CURRENT_SOURCE_DIR}/test-path.h" +) add_executable(sdf_test main.cpp) target_link_libraries(sdf_test Octree pMesh) diff --git a/tests/sdf_test/main.cpp b/tests/sdf_test/main.cpp index ae66f42..93def21 100644 --- a/tests/sdf_test/main.cpp +++ b/tests/sdf_test/main.cpp @@ -12,7 +12,7 @@ #include "Octree/BaseOctree.h" #include "Octree/OctreeBuilder.h" #include "Octree/OctreeTraverser.h" -#include "Octree/SDFTraversalSampler.h" +#include "Octree/sdf/SDFTraversalSampler.h" #include #include #include @@ -27,11 +27,10 @@ #include #include #include - +#include "test-path.h" int main() { - BOOST_LOG_TRIVIAL(debug) << "cwd is " << boost::filesystem::current_path(); - pMesh::io::fs_path data_base_path = "../../../data"; + pMesh::io::fs_path data_base_path = TEST_DATA_BASE_PATH; BOOST_LOG_TRIVIAL(debug) << "base data path is " << boost::filesystem::absolute(data_base_path); auto mesh_path = data_base_path / "stanford-bunny.obj"; diff --git a/tests/sdf_test/test-path.h.in b/tests/sdf_test/test-path.h.in new file mode 100644 index 0000000..0e3ea76 --- /dev/null +++ b/tests/sdf_test/test-path.h.in @@ -0,0 +1,16 @@ +/** + * ------------------------------------ + * @author: Weipeng Kong + * @date: 2021/12/1 + * @email: yjxkwp@foxmail.com + * @site: https://donot.fit + * @description: + * ------------------------------------ +**/ + +#ifndef OCTREE_SDF_TEST_PATH_H +#define OCTREE_SDF_TEST_PATH_H + +#define TEST_DATA_BASE_PATH "@TEST_DATA_BASE_PATH@" + +#endif //OCTREE_SDF_TEST_PATH_H diff --git a/tests/udf_test/.gitignore b/tests/udf_test/.gitignore new file mode 100644 index 0000000..298482a --- /dev/null +++ b/tests/udf_test/.gitignore @@ -0,0 +1 @@ +test-path.h \ No newline at end of file diff --git a/tests/udf_test/CMakeLists.txt b/tests/udf_test/CMakeLists.txt new file mode 100644 index 0000000..b807a83 --- /dev/null +++ b/tests/udf_test/CMakeLists.txt @@ -0,0 +1,6 @@ +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/test-path.h.in" + "${CMAKE_CURRENT_SOURCE_DIR}/test-path.h" +) +add_executable(udf_test main.cpp) +target_link_libraries(udf_test Octree pMesh) diff --git a/tests/udf_test/main.cpp b/tests/udf_test/main.cpp new file mode 100644 index 0000000..cfbbe29 --- /dev/null +++ b/tests/udf_test/main.cpp @@ -0,0 +1,198 @@ +/** + * ------------------------------------ + * @author: Weipeng Kong + * @date: 2021/11/17 + * @email: yjxkwp@foxmail.com + * @site: https://donot.fit + * @description: + * ------------------------------------ +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Octree/udf/UDFOctree.h" +#include "Octree/OctreeBuilder.h" +#include "Octree/OctreeTraverser.h" +#include "Octree/udf/UDFTraversalSampler.h" +#include "test-path.h" + + +class VTKTraverser : public pMesh::io::BaseReader, public Octree::OctreeTraverser { + int node_cnt = 0; +public: + explicit VTKTraverser(const Octree::UDFOctree &octree, const TraverseStrategy strategy = DFS); + + void visit_node(Octree::OctreeNode &node) override; + + pMesh::io::ReadAdapter *reader_adapter; + + bool operator>>(pMesh::io::ReadAdapter &adapter) override; +}; + +int main() { + pMesh::io::fs_path data_base_path = TEST_DATA_BASE_PATH; + BOOST_LOG_TRIVIAL(debug) << "base data path is " << boost::filesystem::absolute(data_base_path); + + auto mesh_path = data_base_path / "stanford-bunny.obj"; + auto out_octree_path = data_base_path / "stanford-bunny-octree.vtk"; + auto out_mc_path = data_base_path / "stanford-bunny-mc.obj"; + auto out_error_path = data_base_path / "stanford-bunny-error_points.vtk"; + + pMesh::Triangle3dMesh<> mesh; + pMesh::io::OBJReader(mesh_path) + >> pMesh::io::DefaultSurfaceReadAdapter<>(mesh, false)(); + + BOOST_LOG_TRIVIAL(info) << "Load Face #" << mesh.f_size(); + + const int level = 2; + const double sample_step = 0.004; + + boost::timer t; + Octree::AABB aabb(mesh.aabb()); + + Octree::UDFOctree octree(level, aabb); + Octree::OctreeBuilder builder(mesh, octree); + builder.build(); + BOOST_LOG_TRIVIAL(debug) << "time elapse " << t.elapsed(); + + auto aabb_size = octree.aabb().size(); + BOOST_LOG_TRIVIAL(debug) << "Global AABB " << aabb_size.transpose(); + + auto final_aabb_size = aabb_size / pow(2, level); + BOOST_LOG_TRIVIAL(debug) << "Local AABB " << final_aabb_size.transpose(); + + // origin points of model + int opm = std::ceil(aabb_size.x() / sample_step) * + std::ceil(aabb_size.y() / sample_step) * + std::ceil(aabb_size.z() / sample_step); + + BOOST_LOG_TRIVIAL(debug) << "Origin Points of model = " << opm; + + // points per voxel + int ppv = std::ceil(final_aabb_size.x() / sample_step) * + std::ceil(final_aabb_size.y() / sample_step) * + std::ceil(final_aabb_size.z() / sample_step); + + BOOST_LOG_TRIVIAL(debug) << "Points per voxel = " << ppv; + + pMesh::HexahedronMesh<> hexahedron_mesh; + VTKTraverser(octree) >> pMesh::io::DefaultVolumeReadAdapter<>(hexahedron_mesh)(); + + pMesh::io::VTKWriter(12, out_octree_path) + << pMesh::io::DefaultVolumeWriteAdapter<>(hexahedron_mesh)(); + + BOOST_LOG_TRIVIAL(debug) << "Total Points = " << hexahedron_mesh.c_size() * ppv; + + BOOST_LOG_TRIVIAL(debug) << "Compression ratio = " << (double) hexahedron_mesh.c_size() * ppv / opm; + + BOOST_LOG_TRIVIAL(debug) << "Calculating UDF"; + Octree::UDFTraversalBuilder udf_builder(octree, mesh, sample_step); + udf_builder.build(); + BOOST_LOG_TRIVIAL(debug) << "End computing UDF"; + + if (1) { + Eigen::MatrixXd V = Eigen::MatrixXd(mesh.v_size(), 3); + Eigen::MatrixXi F = Eigen::MatrixXi(mesh.f_size(), 3); + + for (int i = 0; i < mesh.v_size(); ++i) { + V.row(i) = mesh.vertices[i].attr.coordinate; + } + + for (int i = 0; i < mesh.f_size(); ++i) { + const auto &face = mesh.faces[i].attr.vertices; + F.row(i) << face[0].id(), face[1].id(), face[2].id(); + } + + Eigen::MatrixXd GV; + Eigen::RowVector3i res; + const int s = 100; + igl::voxel_grid(V, 0, s, 1, GV, res); + + // compute values + std::cout << "Computing distances..." << std::endl; + Eigen::VectorXd S = Eigen::VectorXd(GV.rows()), B; + +#if 0 + pMesh::Triangle3dMesh<> error_points; +#endif + + { + for (int i = 0; i < GV.rows(); ++i) { + auto node = octree.map_node(GV.row(i)); + if (node == nullptr) { + S[i] = 1000; + } else { + S[i] = node->get_udf(GV.row(i)); + } + } + } + +#if 0 + pMesh::io::VTKWriter(1, out_error_path) << pMesh::io::DefaultSurfaceWriteAdapter(error_points)(); +#endif + + std::cout << "Marching cubes..." << std::endl; + Eigen::MatrixXd SV, BV; + Eigen::MatrixXi SF, BF; + + igl::marching_cubes(S, GV, res(0), res(1), res(2), 0, SV, SF); + igl::writeOBJ(out_mc_path.string(), SV, SF); + } + return 0; +} + + +void VTKTraverser::visit_node(Octree::OctreeNode &node) { + if (node.get_level() != octree.get_max_level()) { +// assert(!node.is_leaf()); + assert(node.tri_ids.empty()); + return; + } + + auto min = node.get_aabb().min(); + auto max = node.get_aabb().max(); + reader_adapter->feed_vertex({min.x(), min.y(), min.z()}); + reader_adapter->feed_vertex({max.x(), min.y(), min.z()}); + reader_adapter->feed_vertex({max.x(), max.y(), min.z()}); + reader_adapter->feed_vertex({min.x(), max.y(), min.z()}); + reader_adapter->feed_vertex({min.x(), min.y(), max.z()}); + reader_adapter->feed_vertex({max.x(), min.y(), max.z()}); + reader_adapter->feed_vertex({max.x(), max.y(), max.z()}); + reader_adapter->feed_vertex({min.x(), max.y(), max.z()}); + + reader_adapter->feed_collection( + { + 0 + node_cnt, 1 + node_cnt, 2 + node_cnt, 3 + node_cnt, 4 + node_cnt, + 5 + node_cnt, 6 + node_cnt, 7 + node_cnt + }); + node_cnt += 8; +} + +bool VTKTraverser::operator>>(pMesh::io::ReadAdapter &adapter) { + reader_adapter = &adapter; + node_cnt = 0; + adapter.start(); + + this->traverse(); + + adapter.end(); + return true; +} + + +VTKTraverser::VTKTraverser(const Octree::UDFOctree &octree, const OctreeTraverser::TraverseStrategy strategy) + : OctreeTraverser( + octree, strategy) { +} diff --git a/tests/udf_test/test-path.h.in b/tests/udf_test/test-path.h.in new file mode 100644 index 0000000..0e3ea76 --- /dev/null +++ b/tests/udf_test/test-path.h.in @@ -0,0 +1,16 @@ +/** + * ------------------------------------ + * @author: Weipeng Kong + * @date: 2021/12/1 + * @email: yjxkwp@foxmail.com + * @site: https://donot.fit + * @description: + * ------------------------------------ +**/ + +#ifndef OCTREE_SDF_TEST_PATH_H +#define OCTREE_SDF_TEST_PATH_H + +#define TEST_DATA_BASE_PATH "@TEST_DATA_BASE_PATH@" + +#endif //OCTREE_SDF_TEST_PATH_H