From 6eb52eb350bd184013c8e98c10fd7b2eeb9f64f0 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 8 Jan 2024 16:26:24 -0600 Subject: [PATCH 1/3] Adding area/volume measurement --- CMakeLists.txt | 2 ++ include/xdg/geometry/area.h | 16 +++++++++ include/xdg/mesh_manager_interface.h | 2 ++ include/xdg/moab/mesh_manager.h | 2 ++ include/xdg/xdg.h | 28 +++++++++++---- src/area.cpp | 23 ++++++++++++ src/moab/mesh_manager.cpp | 10 ++++++ src/ray_tracing_interface.cpp | 4 +-- src/xdg.cpp | 54 ++++++++++++++++++++++++++++ tests/CMakeLists.txt | 1 + tests/mesh_mock.h | 4 +++ tests/test_bvh.cpp | 2 -- tests/test_measure.cpp | 28 +++++++++++++++ tests/test_xdg_interface.cpp | 2 +- 14 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 include/xdg/geometry/area.h create mode 100644 src/area.cpp create mode 100644 src/xdg.cpp create mode 100644 tests/test_measure.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 50161ea..5d7d752 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ if (NOT fmt_FOUND) endif() list(APPEND xdg_sources +src/area.cpp src/closest.cpp src/error.cpp src/mesh_manager_interface.cpp @@ -48,6 +49,7 @@ src/plucker.cpp src/ray_tracing_interface.cpp src/triangle_ref.cpp src/util/str_utils.cpp +src/xdg.cpp ) if (XDG_ENABLE_MOAB) diff --git a/include/xdg/geometry/area.h b/include/xdg/geometry/area.h new file mode 100644 index 0000000..35f1cc7 --- /dev/null +++ b/include/xdg/geometry/area.h @@ -0,0 +1,16 @@ +#ifndef _XDG_AREA_H +#define _XDG_AREA_H + +#include "xdg/vec3da.h" + +namespace xdg { + +double triangle_volume_contribution(const std::array& vertices); +double triangle_volume_contribution(const Vertex& v0, const Vertex& v1, const Vertex& v2); + +double triangle_area(const std::array& vertices); +double triangle_area(const Vertex& v0, const Vertex& v1, const Vertex& v2); + +} + +#endif // include guard \ No newline at end of file diff --git a/include/xdg/mesh_manager_interface.h b/include/xdg/mesh_manager_interface.h index 72cc5f0..1d83cf0 100644 --- a/include/xdg/mesh_manager_interface.h +++ b/include/xdg/mesh_manager_interface.h @@ -56,6 +56,8 @@ class MeshManager { virtual std::vector get_volume_surfaces(MeshID volume) const = 0; + virtual Sense surface_sense(MeshID surface, MeshID volume) const = 0; + virtual MeshID create_volume() = 0; virtual void add_surface_to_volume(MeshID volume, MeshID surface, Sense sense, bool overwrite=false) = 0; diff --git a/include/xdg/moab/mesh_manager.h b/include/xdg/moab/mesh_manager.h index b6d7572..5de4c0d 100644 --- a/include/xdg/moab/mesh_manager.h +++ b/include/xdg/moab/mesh_manager.h @@ -76,6 +76,8 @@ class MOABMeshManager : public MeshManager { std::vector get_volume_surfaces(MeshID volume) const override; + Sense surface_sense(MeshID surface, MeshID volume) const override; + // Metadata void parse_metadata() override; diff --git a/include/xdg/xdg.h b/include/xdg/xdg.h index 2a35bcc..b2b8739 100644 --- a/include/xdg/xdg.h +++ b/include/xdg/xdg.h @@ -11,15 +11,26 @@ namespace xdg { class XDG { public: +// Constructors + XDG() = default; + + XDG(std::shared_ptr mesh_manager) : + mesh_manager_(mesh_manager) {} + // Methods void prepare_raytracer() { - ray_tracing_interface_->register_all_volumes(mesh_manager_interface_); + ray_tracing_interface_->register_all_volumes(mesh_manager_); } + double measure_volume(MeshID volume) const; + + double measure_surface_area(MeshID surface) const; + double measure_volume_area(MeshID surface) const; + // Mutators - void set_mesh_manager_interface(std::shared_ptr mesh_manager_interface) { - mesh_manager_interface_ = mesh_manager_interface; + void set_mesh_manager_interface(std::shared_ptr mesh_manager) { + mesh_manager_ = mesh_manager; } // Accessors @@ -27,13 +38,18 @@ class XDG { return ray_tracing_interface_.get(); } - const MeshManager* mesh_manager_interface() const { - return mesh_manager_interface_.get(); + const MeshManager* mesh_manager() const { + return mesh_manager_.get(); } +// Private methods +private: + double _triangle_volume_contribution(const TriangleRef& triangle) const; + double _triangle_area_contribution(const TriangleRef& triangle) const; + private: const std::shared_ptr ray_tracing_interface_ {std::make_shared()}; - std::shared_ptr mesh_manager_interface_ {nullptr}; + std::shared_ptr mesh_manager_ {nullptr}; }; } diff --git a/src/area.cpp b/src/area.cpp new file mode 100644 index 0000000..4d86f17 --- /dev/null +++ b/src/area.cpp @@ -0,0 +1,23 @@ +#include "xdg/geometry/area.h" + +namespace xdg { + double triangle_volume_contribution(const std::array& vertices) + { + return triangle_volume_contribution(vertices[0], vertices[1], vertices[2]); + } + + double triangle_volume_contribution(const Vertex& v0, const Vertex& v1, const Vertex& v2) + { + return v0.dot((v1-v0).cross(v2-v0)); + } + + double triangle_area(const std::array& vertices) + { + return triangle_area(vertices[0], vertices[1], vertices[2]); + } + + double triangle_area(const Vertex& v0, const Vertex& v1, const Vertex& v2) + { + return 0.5 * (v1-v0).cross(v2-v0).length(); + } +} \ No newline at end of file diff --git a/src/moab/mesh_manager.cpp b/src/moab/mesh_manager.cpp index 06d6dcb..bb76d49 100644 --- a/src/moab/mesh_manager.cpp +++ b/src/moab/mesh_manager.cpp @@ -258,6 +258,16 @@ MOABMeshManager::get_parent_volumes(MeshID surface) const return this->surface_senses(surface); } +Sense +MOABMeshManager::surface_sense(MeshID surface, MeshID volume) const +{ + auto sense_data = this->get_parent_volumes(surface); + if (sense_data.first == volume) return Sense::FORWARD; + else if (sense_data.second == volume) return Sense::REVERSE; + else fatal_error("Volume {} is not a parent of surface {}", volume, surface); + return Sense::UNSET; +} + std::vector MOABMeshManager::_ents_of_dim(int dim) const { std::array tags = {geometry_dimension_tag_}; diff --git a/src/ray_tracing_interface.cpp b/src/ray_tracing_interface.cpp index b24026d..7bbcf76 100644 --- a/src/ray_tracing_interface.cpp +++ b/src/ray_tracing_interface.cpp @@ -258,12 +258,10 @@ Direction RayTracer::get_normal(MeshID surface, if (triangle_ref.surface_id != surface) { fatal_error("Point {} was closest to surface {}, not surface {}, in volume {}.", point, triangle_ref.surface_id, surface, surface_vols.first); } - element = triangle_ref.triangle_id; - } - // set the normal based on the triangle + // return the normal of the selected triangle return mesh_manager->triangle_normal(element); } diff --git a/src/xdg.cpp b/src/xdg.cpp new file mode 100644 index 0000000..a2c7779 --- /dev/null +++ b/src/xdg.cpp @@ -0,0 +1,54 @@ +#include + +#include "xdg/xdg.h" + +#include "xdg/constants.h" +#include "xdg/geometry/area.h" + + +namespace xdg { + +double XDG::measure_volume(MeshID volume) const +{ + double volume_total {0.0}; + + auto surfaces = mesh_manager()->get_volume_surfaces(volume); + + std::vector surface_senses; + for (auto surface : surfaces) { + surface_senses.push_back(mesh_manager()->surface_sense(surface, volume)); + } + + for (int i = 0; i < surfaces.size(); ++i) { + MeshID& surface = surfaces[i]; + double surface_contribution {0.0}; + auto triangles = mesh_manager()->get_surface_elements(surface); + for (auto triangle : triangles) { + surface_contribution += triangle_volume_contribution(mesh_manager()->triangle_vertices(triangle)); + } + if (surface_senses[i] == Sense::REVERSE) surface_contribution *= -1.0; + volume_total += surface_contribution; + } + + return volume_total / 6.0; +} + +double XDG::measure_surface_area(MeshID surface) const +{ + double area {0.0}; + for (auto triangle : mesh_manager()->get_surface_elements(surface)) { + area += triangle_area(mesh_manager()->triangle_vertices(triangle)); + } + return area; +} + +double XDG::measure_volume_area(MeshID volume) const +{ + double area {0.0}; + for (auto surface : mesh_manager()->get_volume_surfaces(volume)) { + area += measure_surface_area(surface); + } + return area; +} + +} // namespace xdg \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 74e99fe..fe732fb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,6 +10,7 @@ test_occluded test_ray_fire test_point_in_volume test_normal +test_measure test_xdg_interface ) diff --git a/tests/mesh_mock.h b/tests/mesh_mock.h index 24f8f4b..ebae0af 100644 --- a/tests/mesh_mock.h +++ b/tests/mesh_mock.h @@ -103,6 +103,10 @@ class MeshMock : public MeshManager { return {0, 1, 2, 3, 4, 5}; } + Sense surface_sense(MeshID surface, MeshID volume) const override { + return Sense::FORWARD; + } + virtual MeshID create_volume() override { fatal_error("MockMesh does not support create_volume()"); return ID_NONE; diff --git a/tests/test_bvh.cpp b/tests/test_bvh.cpp index e0d73a0..4944baa 100644 --- a/tests/test_bvh.cpp +++ b/tests/test_bvh.cpp @@ -1,5 +1,3 @@ - - // for testing #include diff --git a/tests/test_measure.cpp b/tests/test_measure.cpp new file mode 100644 index 0000000..f7cc4ae --- /dev/null +++ b/tests/test_measure.cpp @@ -0,0 +1,28 @@ +#include + +// for testing +#include +#include + +#include "xdg/xdg.h" + +// xdg test includes +#include "mesh_mock.h" +#include "util.h" + +using namespace xdg; + +TEST_CASE("Test Mesh Mock") +{ + std::shared_ptr mm = std::make_shared(); + mm->init(); // this should do nothing, but its good practice to call it + + XDG xdg{mm}; + + double volume = xdg.measure_volume(mm->volumes()[0]); + REQUIRE_THAT(volume, Catch::Matchers::WithinAbs(693., 1e-6)); + + double area = xdg.measure_volume_area(mm->volumes()[0]); + REQUIRE_THAT(area, Catch::Matchers::WithinAbs(478., 1e-6)); + +} \ No newline at end of file diff --git a/tests/test_xdg_interface.cpp b/tests/test_xdg_interface.cpp index e0374bb..a68af22 100644 --- a/tests/test_xdg_interface.cpp +++ b/tests/test_xdg_interface.cpp @@ -12,5 +12,5 @@ TEST_CASE("XDG Interface") { std::shared_ptr xdg = std::make_shared(); REQUIRE(xdg->ray_tracing_interface() != nullptr); - REQUIRE(xdg->mesh_manager_interface() == nullptr); + REQUIRE(xdg->mesh_manager() == nullptr); } \ No newline at end of file From 460181b2315a7e0f61207662ab41ae504d1f6a6d Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 8 Jan 2024 16:28:36 -0600 Subject: [PATCH 2/3] Reorganize some files and rename --- CMakeLists.txt | 6 +++--- include/xdg/geometry/{area.h => measure.h} | 0 src/{ => geometry}/closest.cpp | 0 src/{area.cpp => geometry/measure.cpp} | 2 +- src/{ => geometry}/plucker.cpp | 0 src/xdg.cpp | 4 +--- 6 files changed, 5 insertions(+), 7 deletions(-) rename include/xdg/geometry/{area.h => measure.h} (100%) rename src/{ => geometry}/closest.cpp (100%) rename src/{area.cpp => geometry/measure.cpp} (94%) rename src/{ => geometry}/plucker.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d7d752..1c74a03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,11 @@ if (NOT fmt_FOUND) endif() list(APPEND xdg_sources -src/area.cpp -src/closest.cpp +src/geometry/measure.cpp +src/geometry/plucker.cpp +src/geometry/closest.cpp src/error.cpp src/mesh_manager_interface.cpp -src/plucker.cpp src/ray_tracing_interface.cpp src/triangle_ref.cpp src/util/str_utils.cpp diff --git a/include/xdg/geometry/area.h b/include/xdg/geometry/measure.h similarity index 100% rename from include/xdg/geometry/area.h rename to include/xdg/geometry/measure.h diff --git a/src/closest.cpp b/src/geometry/closest.cpp similarity index 100% rename from src/closest.cpp rename to src/geometry/closest.cpp diff --git a/src/area.cpp b/src/geometry/measure.cpp similarity index 94% rename from src/area.cpp rename to src/geometry/measure.cpp index 4d86f17..b3e2148 100644 --- a/src/area.cpp +++ b/src/geometry/measure.cpp @@ -1,4 +1,4 @@ -#include "xdg/geometry/area.h" +#include "xdg/geometry/measure.h" namespace xdg { double triangle_volume_contribution(const std::array& vertices) diff --git a/src/plucker.cpp b/src/geometry/plucker.cpp similarity index 100% rename from src/plucker.cpp rename to src/geometry/plucker.cpp diff --git a/src/xdg.cpp b/src/xdg.cpp index a2c7779..730f269 100644 --- a/src/xdg.cpp +++ b/src/xdg.cpp @@ -3,9 +3,7 @@ #include "xdg/xdg.h" #include "xdg/constants.h" -#include "xdg/geometry/area.h" - - +#include "xdg/geometry/measure.h" namespace xdg { double XDG::measure_volume(MeshID volume) const From 8111077870219f59f36404be7b14d49cac4231bd Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Mon, 8 Jan 2024 16:31:58 -0600 Subject: [PATCH 3/3] A few more tests --- tests/test_measure.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_measure.cpp b/tests/test_measure.cpp index f7cc4ae..e8da1fd 100644 --- a/tests/test_measure.cpp +++ b/tests/test_measure.cpp @@ -1,4 +1,5 @@ #include +#include // for testing #include @@ -25,4 +26,11 @@ TEST_CASE("Test Mesh Mock") double area = xdg.measure_volume_area(mm->volumes()[0]); REQUIRE_THAT(area, Catch::Matchers::WithinAbs(478., 1e-6)); + std::vector surface_areas = {63., 63., 99., 99., 77., 77.}; + + for (int i = 0; i < mm->surfaces().size(); ++i) { + double area = xdg.measure_surface_area(mm->surfaces()[i]); + REQUIRE_THAT(area, Catch::Matchers::WithinAbs(surface_areas[i], 1e-6)); + } + } \ No newline at end of file