From 72b926bc3d5534758937ff33482b08452691bf09 Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Fri, 5 Sep 2025 11:16:04 +0200 Subject: [PATCH 01/10] feat(Implicit): add helper function to compute relationships between blocks and stratigraphic_units if possible --- ...ral_model_stratigraphic_blocks_builder.hpp | 38 ++ .../core/implicit_structural_model.hpp | 3 +- src/geode/geosciences/implicit/CMakeLists.txt | 4 +- ...ral_model_stratigraphic_blocks_builder.cpp | 370 ++++++++++++++++++ 4 files changed, 413 insertions(+), 2 deletions(-) create mode 100644 include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp create mode 100644 src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp diff --git a/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp b/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp new file mode 100644 index 0000000..208862f --- /dev/null +++ b/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 - 2025 Geode-solutions + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#pragma once + +#include + +namespace geode +{ + class ImplicitStructuralModel; +} // namespace geode + +namespace geode +{ + void opengeode_geosciences_implicit_api + complete_stratigraphic_unit_block_relationships_from_available_data( + ImplicitStructuralModel& implicit_model ); +} // namespace geode \ No newline at end of file diff --git a/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp b/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp index 304df5c..f7ef093 100644 --- a/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp +++ b/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp @@ -45,7 +45,8 @@ namespace geode { /*! * An Implicit Model is a Structural model where each block has a specific - * attribute to store the implicit value on its vertices. + * attribute to store the implicit value on its vertices. Moreover, an + * ImplicitStructuralModel is associated to an HorizonsStack. */ class opengeode_geosciences_implicit_api ImplicitStructuralModel : public StructuralModel diff --git a/src/geode/geosciences/implicit/CMakeLists.txt b/src/geode/geosciences/implicit/CMakeLists.txt index 0b3e403..d30bd1b 100755 --- a/src/geode/geosciences/implicit/CMakeLists.txt +++ b/src/geode/geosciences/implicit/CMakeLists.txt @@ -32,6 +32,7 @@ add_geode_library( "representation/builder/stratigraphic_model_builder.cpp" "representation/builder/stratigraphic_section_builder.cpp" "representation/builder/horizons_stack_builder.cpp" + "representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp" "representation/core/detail/helpers.cpp" "representation/core/implicit_cross_section.cpp" "representation/core/implicit_structural_model.cpp" @@ -62,7 +63,8 @@ add_geode_library( "representation/builder/implicit_structural_model_builder.hpp" "representation/builder/stratigraphic_model_builder.hpp" "representation/builder/stratigraphic_section_builder.hpp" - "representation/builder/horizons_stack_builder.hpp" + "representation/builder/horizons_stack_builder.hpp" + "representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp" "representation/core/detail/helpers.hpp" "representation/core/implicit_cross_section.hpp" "representation/core/implicit_structural_model.hpp" diff --git a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp new file mode 100644 index 0000000..a1e9b15 --- /dev/null +++ b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2019 - 2025 Geode-solutions + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +#include + +#include + +#include +#include +#include + +namespace +{ + struct HorizonsData + { + geode::SmallSet< geode::uuid > conformal; + geode::SmallSet< geode::uuid > erosion; + geode::SmallSet< geode::uuid > baselap; + geode::SmallSet< geode::uuid > other; + }; + + class BlockToStratigraphicUnitBuilder + { + public: + BlockToStratigraphicUnitBuilder( geode::ImplicitStructuralModel& model ) + : model_{ model }, + horizons_stack_{ model.horizons_stack() }, + builder_{ model } + { + for( const auto& stratigraphic_unit : + horizons_stack_.stratigraphic_units() ) + { + if( model_.has_stratigraphic_unit( stratigraphic_unit.id() ) ) + { + continue; + } + builder_.add_stratigraphic_unit( stratigraphic_unit.id() ); + builder_.set_stratigraphic_unit_name( + stratigraphic_unit.id(), stratigraphic_unit.name() ); + } + } + + bool assign_blocks_to_stratigraphic_units() + { + bool run_again = true; + while( run_again ) + { + run_again = one_step_assign_blocks_to_stratigraphic_units(); + } + } + + private: + bool one_step_assign_blocks_to_stratigraphic_units() + { + const auto top_horizon = horizons_stack_.top_horizon().value(); + const auto bottom_horizon = + horizons_stack_.bottom_horizon().value(); + bool something_done{ false }; + for( const auto& block : model_.blocks() ) + { + if( skip( block ) ) + { + continue; + } + const auto [horizons_data, block_assigned] = + collect_horizons_data( block ); + if( block_assigned ) + { + something_done = true; + continue; + } + if( process_blocks_with_horizon_data( block, horizons_data ) ) + { + something_done = true; + } + } + } + + bool skip( const geode::Block3D& block ) + { + for( const auto& block_collection : + model_.collections( block.id() ) ) + { + if( block_collection.type() + == geode::StratigraphicUnit3D::component_type_static() ) + { + return true; + } + } + return false; + } + + std::optional< geode::uuid > neighbor_block( + const geode::Block3D& block, + const geode::Surface3D& boundary ) const + { + std::optional< geode::uuid > neighbor_block{ std::nullopt }; + for( const auto& incidence : model_.incidences( boundary ) ) + { + if( incidence.id() != block.id() ) + { + neighbor_block = incidence.id(); + break; + } + } + return neighbor_block; + } + + bool assign_through_conformal_horizon( const geode::Block3D& block, + const geode::Surface3D& block_boundary, + const geode::Horizon3D& conformal_horizon ) + { + const auto neighbor = neighbor_block( block, block_boundary ); + if( !neighbor_block ) + { + return false; + } + const auto& above_stratigraphic_unit = + horizons_stack_.above( conformal_horizon.id() ).value(); + const auto& under_stratigraphic_unit = + horizons_stack_.under( conformal_horizon.id() ).value(); + if( model_.is_item( neighbor.value(), above_stratigraphic_unit ) ) + { + builder_.add_block_in_stratigraphic_unit( block, + model_.stratigraphic_unit( under_stratigraphic_unit ) ); + return true; + } + if( model_.is_item( neighbor.value(), under_stratigraphic_unit ) ) + { + builder_.add_block_in_stratigraphic_unit( block, + model_.stratigraphic_unit( above_stratigraphic_unit ) ); + return true; + } + return false; + } + + bool assign_through_erosion( const geode::Block3D& block, + const geode::Surface3D& block_boundary, + const geode::Horizon3D& erosion ) + { + const auto neighbor = neighbor_block( block, block_boundary ); + if( !neighbor ) + { + return false; + } + const auto& above_stratigraphic_unit = + horizons_stack_.above( erosion.id() ).value(); + const auto& under_stratigraphic_unit = + horizons_stack_.under( erosion.id() ).value(); + if( model_.is_item( neighbor.value(), under_stratigraphic_unit ) ) + { + builder_.add_block_in_stratigraphic_unit( block, + model_.stratigraphic_unit( above_stratigraphic_unit ) ); + return true; + } + return false; + } + + bool assign_through_baselap( const geode::Block3D& block, + const geode::Surface3D& block_boundary, + const geode::Horizon3D& erosion ) + { + const auto neighbor = neighbor_block( block, block_boundary ); + if( !neighbor ) + { + return false; + } + const auto& above_stratigraphic_unit = + horizons_stack_.above( erosion.id() ).value(); + const auto& under_stratigraphic_unit = + horizons_stack_.under( erosion.id() ).value(); + if( model_.is_item( neighbor.value(), above_stratigraphic_unit ) ) + { + builder_.add_block_in_stratigraphic_unit( block, + model_.stratigraphic_unit( under_stratigraphic_unit ) ); + return true; + } + return false; + } + + bool assign_between_two_conformal_horizons( const geode::Block3D& block, + const geode::SmallSet< geode::uuid >& conformal_horizons ) + { + const auto& above_stratigraphic_unit = + horizons_stack_.above( conformal_horizons.at( 0 ) ).value(); + if( above_stratigraphic_unit + == horizons_stack_.under( conformal_horizons.at( 1 ) ).value() ) + { + builder_.add_block_in_stratigraphic_unit( block, + model_.stratigraphic_unit( above_stratigraphic_unit ) ); + return true; + } + const auto& under_stratigraphic_unit = + horizons_stack_.under( conformal_horizons.at( 0 ) ).value(); + if( under_stratigraphic_unit + == horizons_stack_.above( conformal_horizons.at( 1 ) ).value() ) + { + builder_.add_block_in_stratigraphic_unit( block, + model_.stratigraphic_unit( under_stratigraphic_unit ) ); + return true; + } + return false; + } + + bool assign_between_one_conformal_and_one_erosion( + const geode::Block3D& block, + const geode::uuid& conformal_horizon_id, + const geode::uuid& erosion_id ) + { + if( horizons_stack_.is_above( erosion_id, conformal_horizon_id ) ) + { + builder_.add_block_in_stratigraphic_unit( + block, model_.stratigraphic_unit( + horizons_stack_.above( conformal_horizon_id ) + .value() ) ); + return true; + } + return false; + } + + bool assign_between_one_conformal_and_one_baselap( + const geode::Block3D& block, + const geode::uuid& conformal_horizon_id, + const geode::uuid& baselap_id ) + { + if( horizons_stack_.is_above( conformal_horizon_id, baselap_id ) ) + { + builder_.add_block_in_stratigraphic_unit( + block, model_.stratigraphic_unit( + horizons_stack_.under( conformal_horizon_id ) + .value() ) ); + return true; + } + return false; + } + + std::pair< HorizonsData, bool > collect_horizons_data( + const geode::Block3D& block ) + { + HorizonsData horizons_data; + for( const auto& boundary : model_.boundaries( block ) ) + { + for( const auto& collection : + model_.collections( boundary.id() ) ) + { + if( collection.type() + == geode::Horizon3D::component_type_static() ) + { + const auto& horizon = model_.horizon( collection.id() ); + if( horizon.contact_type() + == geode::Horizon3D::CONTACT_TYPE::conformal ) + { + if( assign_through_conformal_horizon( + block, boundary, horizon ) ) + { + return std::pair{ horizons_data, true }; + } + horizons_data.conformal.insert( horizon.id() ); + } + else if( horizon.contact_type() + == geode::Horizon3D::CONTACT_TYPE::erosion ) + { + if( assign_through_erosion( + block, boundary, horizon ) ) + { + return std::pair{ horizons_data, true }; + } + horizons_data.erosion.insert( horizon.id() ); + } + else if( horizon.contact_type() + == geode::Horizon3D::CONTACT_TYPE::baselap ) + { + if( assign_through_baselap( + block, boundary, horizon ) ) + { + return std::pair{ horizons_data, true }; + } + horizons_data.baselap.insert( horizon.id() ); + } + else + { + horizons_data.other.insert( horizon.id() ); + } + } + } + } + return std::pair{ horizons_data, false }; + } + + bool process_blocks_with_horizon_data( + const geode::Block3D& block, const HorizonsData& horizons_data ) + { + if( horizons_data.conformal.empty() ) + { + return false; + } + if( horizons_data.conformal.size() == 2 ) + { + return assign_between_two_conformal_horizons( + block, horizons_data.conformal ); + } + // only one conformal horizon + if( !horizons_data.erosion.empty() ) + { + return assign_between_one_conformal_and_one_erosion( block, + horizons_data.conformal.at( 0 ), + horizons_data.erosion.at( 0 ) ); + } + if( !horizons_data.baselap.empty() ) + { + return assign_between_one_conformal_and_one_baselap( block, + horizons_data.conformal.at( 0 ), + horizons_data.baselap.at( 0 ) ); + } + return false; + } + + private: + const geode::ImplicitStructuralModel& model_; + const geode::HorizonsStack3D& horizons_stack_; + geode::ImplicitStructuralModelBuilder builder_; + }; +} // namespace +namespace geode +{ + void complete_stratigraphic_unit_block_relationships_from_available_data( + ImplicitStructuralModel& implicit_model ) + { + if( implicit_model.nb_horizons() == 0 ) + { + return; + } + const auto& horizons_stack = implicit_model.horizons_stack(); + OPENGEODE_DATA_EXCEPTION( horizons_stack.nb_stratigraphic_units() > 0, + "[complete_stratigraphic_unit_block_relationships_from_available_" + "data] Horizons stack is empty (no stratigraphic units)." ); + OPENGEODE_DATA_EXCEPTION( horizons_stack.nb_horizons() > 0, + "[complete_stratigraphic_unit_block_relationships_from_available_" + "data] Horizons stack is empty (no horizons)." ); + OPENGEODE_DATA_EXCEPTION( + horizons_stack.top_horizon().has_value() + && horizons_stack.bottom_horizon().has_value(), + "[complete_stratigraphic_unit_block_relationships_from_available_" + "data] Horizons stack is empty (no top and bottom horizons)." ); + OPENGEODE_DATA_EXCEPTION( implicit_model.nb_horizons() > 0, + "[complete_stratigraphic_unit_block_relationships_from_available_" + "data] Implicit structural model has no horizons." ); + BlockToStratigraphicUnitBuilder builder{ implicit_model }; + builder.assign_blocks_to_stratigraphic_units(); + } +} // namespace geode \ No newline at end of file From c63241482da49b926e40717f147d2df83c5df04d Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Fri, 5 Sep 2025 11:47:05 +0200 Subject: [PATCH 02/10] fix compiler errors --- ...ral_model_stratigraphic_blocks_builder.cpp | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp index a1e9b15..730e3bb 100644 --- a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp +++ b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp @@ -59,7 +59,7 @@ namespace } } - bool assign_blocks_to_stratigraphic_units() + void assign_blocks_to_stratigraphic_units() { bool run_again = true; while( run_again ) @@ -71,9 +71,6 @@ namespace private: bool one_step_assign_blocks_to_stratigraphic_units() { - const auto top_horizon = horizons_stack_.top_horizon().value(); - const auto bottom_horizon = - horizons_stack_.bottom_horizon().value(); bool something_done{ false }; for( const auto& block : model_.blocks() ) { @@ -93,6 +90,7 @@ namespace something_done = true; } } + return something_done; } bool skip( const geode::Block3D& block ) @@ -130,13 +128,13 @@ namespace const geode::Horizon3D& conformal_horizon ) { const auto neighbor = neighbor_block( block, block_boundary ); - if( !neighbor_block ) + if( !neighbor ) { return false; } - const auto& above_stratigraphic_unit = + const auto above_stratigraphic_unit = horizons_stack_.above( conformal_horizon.id() ).value(); - const auto& under_stratigraphic_unit = + const auto under_stratigraphic_unit = horizons_stack_.under( conformal_horizon.id() ).value(); if( model_.is_item( neighbor.value(), above_stratigraphic_unit ) ) { @@ -162,9 +160,9 @@ namespace { return false; } - const auto& above_stratigraphic_unit = + const auto above_stratigraphic_unit = horizons_stack_.above( erosion.id() ).value(); - const auto& under_stratigraphic_unit = + const auto under_stratigraphic_unit = horizons_stack_.under( erosion.id() ).value(); if( model_.is_item( neighbor.value(), under_stratigraphic_unit ) ) { @@ -184,9 +182,9 @@ namespace { return false; } - const auto& above_stratigraphic_unit = + const auto above_stratigraphic_unit = horizons_stack_.above( erosion.id() ).value(); - const auto& under_stratigraphic_unit = + const auto under_stratigraphic_unit = horizons_stack_.under( erosion.id() ).value(); if( model_.is_item( neighbor.value(), above_stratigraphic_unit ) ) { @@ -200,7 +198,7 @@ namespace bool assign_between_two_conformal_horizons( const geode::Block3D& block, const geode::SmallSet< geode::uuid >& conformal_horizons ) { - const auto& above_stratigraphic_unit = + const auto above_stratigraphic_unit = horizons_stack_.above( conformal_horizons.at( 0 ) ).value(); if( above_stratigraphic_unit == horizons_stack_.under( conformal_horizons.at( 1 ) ).value() ) @@ -209,7 +207,7 @@ namespace model_.stratigraphic_unit( above_stratigraphic_unit ) ); return true; } - const auto& under_stratigraphic_unit = + const auto under_stratigraphic_unit = horizons_stack_.under( conformal_horizons.at( 0 ) ).value(); if( under_stratigraphic_unit == horizons_stack_.above( conformal_horizons.at( 1 ) ).value() ) From 472cfda79c744fcdeb11998956147727d5e2f600 Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Fri, 5 Sep 2025 11:51:00 +0200 Subject: [PATCH 03/10] cmake? --- src/geode/geosciences/implicit/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geode/geosciences/implicit/CMakeLists.txt b/src/geode/geosciences/implicit/CMakeLists.txt index d30bd1b..71d8333 100755 --- a/src/geode/geosciences/implicit/CMakeLists.txt +++ b/src/geode/geosciences/implicit/CMakeLists.txt @@ -63,7 +63,7 @@ add_geode_library( "representation/builder/implicit_structural_model_builder.hpp" "representation/builder/stratigraphic_model_builder.hpp" "representation/builder/stratigraphic_section_builder.hpp" - "representation/builder/horizons_stack_builder.hpp" + "representation/builder/horizons_stack_builder.hpp" "representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp" "representation/core/detail/helpers.hpp" "representation/core/implicit_cross_section.hpp" From 8fc41b4bb9479d416035fa8525cc450ff583864d Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Fri, 5 Sep 2025 13:51:42 +0200 Subject: [PATCH 04/10] fix compilation --- .../io/geode/geode_implicit_cross_section_input.cpp | 1 + .../io/geode/geode_implicit_structural_model_input.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/geode/geosciences/implicit/representation/io/geode/geode_implicit_cross_section_input.cpp b/src/geode/geosciences/implicit/representation/io/geode/geode_implicit_cross_section_input.cpp index c6acf88..51eaa86 100644 --- a/src/geode/geosciences/implicit/representation/io/geode/geode_implicit_cross_section_input.cpp +++ b/src/geode/geosciences/implicit/representation/io/geode/geode_implicit_cross_section_input.cpp @@ -28,6 +28,7 @@ #include +#include #include #include diff --git a/src/geode/geosciences/implicit/representation/io/geode/geode_implicit_structural_model_input.cpp b/src/geode/geosciences/implicit/representation/io/geode/geode_implicit_structural_model_input.cpp index d8641aa..5eb94ff 100644 --- a/src/geode/geosciences/implicit/representation/io/geode/geode_implicit_structural_model_input.cpp +++ b/src/geode/geosciences/implicit/representation/io/geode/geode_implicit_structural_model_input.cpp @@ -28,6 +28,7 @@ #include +#include #include #include From c76ee99a949d266dbb22b7e0d099ca4eb11ddaf9 Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Mon, 8 Sep 2025 16:21:33 +0200 Subject: [PATCH 05/10] Pr review --- ...ral_model_stratigraphic_blocks_builder.hpp | 11 ++++- ...ral_model_stratigraphic_blocks_builder.cpp | 42 +++++++++++++++---- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp b/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp index 208862f..6a8a565 100644 --- a/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp +++ b/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp @@ -32,7 +32,14 @@ namespace geode namespace geode { - void opengeode_geosciences_implicit_api - complete_stratigraphic_unit_block_relationships_from_available_data( + struct opengeode_geosciences_implicit_api StratigraphicUnitToBlockResult + { + std::vector< uuid > already_assigned_blocks; + std::vector< uuid > assigned_blocks; + std::vector< uuid > unassigned_blocks; + }; + + StratigraphicUnitToBlockResult opengeode_geosciences_implicit_api + complete_stratigraphic_unit_block_relationships( ImplicitStructuralModel& implicit_model ); } // namespace geode \ No newline at end of file diff --git a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp index 730e3bb..b1e52b7 100644 --- a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp +++ b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp @@ -59,13 +59,33 @@ namespace } } - void assign_blocks_to_stratigraphic_units() + geode::StratigraphicUnitToBlockResult + assign_blocks_to_stratigraphic_units() { - bool run_again = true; - while( run_again ) + bool run{ false }; + for( const auto& block : model_.blocks() ) + { + if( is_in_stratigraphic_unit( block ) ) + { + result_.already_assigned_blocks.push_back( block.id() ); + } + else + { + run = true; + } + } + while( run ) + { + run = one_step_assign_blocks_to_stratigraphic_units(); + } + for( const auto& block : model_.blocks() ) { - run_again = one_step_assign_blocks_to_stratigraphic_units(); + if( !is_in_stratigraphic_unit( block ) ) + { + result_.unassigned_blocks.push_back( block.id() ); + } } + return result_; } private: @@ -74,7 +94,7 @@ namespace bool something_done{ false }; for( const auto& block : model_.blocks() ) { - if( skip( block ) ) + if( is_in_stratigraphic_unit( block ) ) { continue; } @@ -82,18 +102,20 @@ namespace collect_horizons_data( block ); if( block_assigned ) { + result_.assigned_blocks.push_back( block.id() ); something_done = true; continue; } if( process_blocks_with_horizon_data( block, horizons_data ) ) { + result_.assigned_blocks.push_back( block.id() ); something_done = true; } } return something_done; } - bool skip( const geode::Block3D& block ) + bool is_in_stratigraphic_unit( const geode::Block3D& block ) { for( const auto& block_collection : model_.collections( block.id() ) ) @@ -336,12 +358,14 @@ namespace const geode::ImplicitStructuralModel& model_; const geode::HorizonsStack3D& horizons_stack_; geode::ImplicitStructuralModelBuilder builder_; + geode::StratigraphicUnitToBlockResult result_; }; } // namespace namespace geode { - void complete_stratigraphic_unit_block_relationships_from_available_data( - ImplicitStructuralModel& implicit_model ) + StratigraphicUnitToBlockResult + complete_stratigraphic_unit_block_relationships( + ImplicitStructuralModel& implicit_model ) { if( implicit_model.nb_horizons() == 0 ) { @@ -363,6 +387,6 @@ namespace geode "[complete_stratigraphic_unit_block_relationships_from_available_" "data] Implicit structural model has no horizons." ); BlockToStratigraphicUnitBuilder builder{ implicit_model }; - builder.assign_blocks_to_stratigraphic_units(); + return builder.assign_blocks_to_stratigraphic_units(); } } // namespace geode \ No newline at end of file From 1e1b860783d86c9b828a00eb84e37aa46cdf1828 Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Mon, 8 Sep 2025 16:24:06 +0200 Subject: [PATCH 06/10] fix compil --- .../implicit_structural_model_stratigraphic_blocks_builder.hpp | 2 ++ .../implicit_structural_model_stratigraphic_blocks_builder.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp b/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp index 6a8a565..31b4a01 100644 --- a/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp +++ b/include/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.hpp @@ -23,6 +23,8 @@ #pragma once +#include + #include namespace geode diff --git a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp index b1e52b7..57190ed 100644 --- a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp +++ b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp @@ -369,7 +369,7 @@ namespace geode { if( implicit_model.nb_horizons() == 0 ) { - return; + return {}; } const auto& horizons_stack = implicit_model.horizons_stack(); OPENGEODE_DATA_EXCEPTION( horizons_stack.nb_stratigraphic_units() > 0, From a985297b0c04e8fd7748d5808ba08f59120a8dc8 Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Tue, 9 Sep 2025 14:07:00 +0200 Subject: [PATCH 07/10] PR review --- .../core/implicit_structural_model.hpp | 6 +- ...ral_model_stratigraphic_blocks_builder.cpp | 147 +++++++++++------- 2 files changed, 98 insertions(+), 55 deletions(-) diff --git a/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp b/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp index f7ef093..5f11b34 100644 --- a/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp +++ b/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp @@ -46,7 +46,11 @@ namespace geode /*! * An Implicit Model is a Structural model where each block has a specific * attribute to store the implicit value on its vertices. Moreover, an - * ImplicitStructuralModel is associated to an HorizonsStack. + * ImplicitStructuralModel is associated to a HorizonsStack. If one or + * several horizons of the HorizonsStack is explicited in the model, they + * have the same uuid as in the HorizonsStack. Either way, each horizon of + * the HorizonsStack is associated to a specific value of the Implicit + * attribute. */ class opengeode_geosciences_implicit_api ImplicitStructuralModel : public StructuralModel diff --git a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp index 57190ed..87242f8 100644 --- a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp +++ b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp @@ -59,6 +59,23 @@ namespace } } + ~BlockToStratigraphicUnitBuilder() + { + std::vector< geode::uuid > to_remove; + for( const auto& stratigraphic_unit : model_.stratigraphic_units() ) + { + if( model_.nb_items( stratigraphic_unit.id() ) == 0 ) + { + to_remove.push_back( stratigraphic_unit.id() ); + } + } + for( const auto& stratigraphic_unit_id : to_remove ) + { + builder_.remove_stratigraphic_unit( + model_.stratigraphic_unit( stratigraphic_unit_id ) ); + } + } + geode::StratigraphicUnitToBlockResult assign_blocks_to_stratigraphic_units() { @@ -91,28 +108,35 @@ namespace private: bool one_step_assign_blocks_to_stratigraphic_units() { - bool something_done{ false }; + bool block_assigned_in_step{ false }; for( const auto& block : model_.blocks() ) { if( is_in_stratigraphic_unit( block ) ) { continue; } - const auto [horizons_data, block_assigned] = - collect_horizons_data( block ); - if( block_assigned ) - { - result_.assigned_blocks.push_back( block.id() ); - something_done = true; - continue; - } - if( process_blocks_with_horizon_data( block, horizons_data ) ) + if( process_block( block ) ) { result_.assigned_blocks.push_back( block.id() ); - something_done = true; + block_assigned_in_step = true; } } - return something_done; + return block_assigned_in_step; + } + + bool process_block( const geode::Block3D& block ) + { + const auto horizons_data = assign_or_collect_horizons_data( block ); + if( !horizons_data ) + { + return true; + } + if( process_block_with_horizon_data( + block, horizons_data.value() ) ) + { + return true; + } + return false; } bool is_in_stratigraphic_unit( const geode::Block3D& block ) @@ -133,16 +157,14 @@ namespace const geode::Block3D& block, const geode::Surface3D& boundary ) const { - std::optional< geode::uuid > neighbor_block{ std::nullopt }; for( const auto& incidence : model_.incidences( boundary ) ) { if( incidence.id() != block.id() ) { - neighbor_block = incidence.id(); - break; + return incidence.id(); } } - return neighbor_block; + return std::nullopt; } bool assign_through_conformal_horizon( const geode::Block3D& block, @@ -182,12 +204,12 @@ namespace { return false; } - const auto above_stratigraphic_unit = - horizons_stack_.above( erosion.id() ).value(); const auto under_stratigraphic_unit = horizons_stack_.under( erosion.id() ).value(); if( model_.is_item( neighbor.value(), under_stratigraphic_unit ) ) { + const auto above_stratigraphic_unit = + horizons_stack_.above( erosion.id() ).value(); builder_.add_block_in_stratigraphic_unit( block, model_.stratigraphic_unit( above_stratigraphic_unit ) ); return true; @@ -206,10 +228,10 @@ namespace } const auto above_stratigraphic_unit = horizons_stack_.above( erosion.id() ).value(); - const auto under_stratigraphic_unit = - horizons_stack_.under( erosion.id() ).value(); if( model_.is_item( neighbor.value(), above_stratigraphic_unit ) ) { + const auto under_stratigraphic_unit = + horizons_stack_.under( erosion.id() ).value(); builder_.add_block_in_stratigraphic_unit( block, model_.stratigraphic_unit( under_stratigraphic_unit ) ); return true; @@ -254,6 +276,15 @@ namespace .value() ) ); return true; } + if( horizons_stack_.is_directly_above( + conformal_horizon_id, erosion_id ) ) + { + builder_.add_block_in_stratigraphic_unit( + block, model_.stratigraphic_unit( + horizons_stack_.under( conformal_horizon_id ) + .value() ) ); + return true; + } return false; } @@ -270,63 +301,71 @@ namespace .value() ) ); return true; } + if( horizons_stack_.is_directly_above( + baselap_id, conformal_horizon_id ) ) + { + builder_.add_block_in_stratigraphic_unit( + block, model_.stratigraphic_unit( + horizons_stack_.above( conformal_horizon_id ) + .value() ) ); + return true; + } return false; } - std::pair< HorizonsData, bool > collect_horizons_data( + std::optional< HorizonsData > assign_or_collect_horizons_data( const geode::Block3D& block ) { - HorizonsData horizons_data; + std::optional< HorizonsData > horizons_data{ std::in_place }; for( const auto& boundary : model_.boundaries( block ) ) { for( const auto& collection : model_.collections( boundary.id() ) ) { if( collection.type() - == geode::Horizon3D::component_type_static() ) + != geode::Horizon3D::component_type_static() ) { - const auto& horizon = model_.horizon( collection.id() ); - if( horizon.contact_type() - == geode::Horizon3D::CONTACT_TYPE::conformal ) - { - if( assign_through_conformal_horizon( - block, boundary, horizon ) ) - { - return std::pair{ horizons_data, true }; - } - horizons_data.conformal.insert( horizon.id() ); - } - else if( horizon.contact_type() - == geode::Horizon3D::CONTACT_TYPE::erosion ) + continue; + } + const auto& horizon = model_.horizon( collection.id() ); + if( horizon.contact_type() + == geode::Horizon3D::CONTACT_TYPE::conformal ) + { + if( assign_through_conformal_horizon( + block, boundary, horizon ) ) { - if( assign_through_erosion( - block, boundary, horizon ) ) - { - return std::pair{ horizons_data, true }; - } - horizons_data.erosion.insert( horizon.id() ); + return std::nullopt; } - else if( horizon.contact_type() - == geode::Horizon3D::CONTACT_TYPE::baselap ) + horizons_data->conformal.insert( horizon.id() ); + } + else if( horizon.contact_type() + == geode::Horizon3D::CONTACT_TYPE::erosion ) + { + if( assign_through_erosion( block, boundary, horizon ) ) { - if( assign_through_baselap( - block, boundary, horizon ) ) - { - return std::pair{ horizons_data, true }; - } - horizons_data.baselap.insert( horizon.id() ); + return std::nullopt; } - else + horizons_data->erosion.insert( horizon.id() ); + } + else if( horizon.contact_type() + == geode::Horizon3D::CONTACT_TYPE::baselap ) + { + if( assign_through_baselap( block, boundary, horizon ) ) { - horizons_data.other.insert( horizon.id() ); + return std::nullopt; } + horizons_data->baselap.insert( horizon.id() ); + } + else + { + horizons_data->other.insert( horizon.id() ); } } } - return std::pair{ horizons_data, false }; + return horizons_data; } - bool process_blocks_with_horizon_data( + bool process_block_with_horizon_data( const geode::Block3D& block, const HorizonsData& horizons_data ) { if( horizons_data.conformal.empty() ) From b83e8c5db63d23be71c73838cc3d26d0364ce480 Mon Sep 17 00:00:00 2001 From: Pierre Anquez <32702237+panquez@users.noreply.github.com> Date: Tue, 9 Sep 2025 14:26:00 +0200 Subject: [PATCH 08/10] Update src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp Co-authored-by: Melchior Schuh-Senlis --- .../implicit_structural_model_stratigraphic_blocks_builder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp index 87242f8..cf4e754 100644 --- a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp +++ b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp @@ -277,7 +277,7 @@ namespace return true; } if( horizons_stack_.is_directly_above( - conformal_horizon_id, erosion_id ) ) + horizons_stack_.above( conformal_horizon_id).value(), erosion_id ) ) { builder_.add_block_in_stratigraphic_unit( block, model_.stratigraphic_unit( From 9893d16b66de3874a1be87da1fc36ba30dca3550 Mon Sep 17 00:00:00 2001 From: Pierre Anquez <32702237+panquez@users.noreply.github.com> Date: Tue, 9 Sep 2025 14:26:07 +0200 Subject: [PATCH 09/10] Update src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp Co-authored-by: Melchior Schuh-Senlis --- .../implicit_structural_model_stratigraphic_blocks_builder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp index cf4e754..24d9eb0 100644 --- a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp +++ b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp @@ -302,7 +302,7 @@ namespace return true; } if( horizons_stack_.is_directly_above( - baselap_id, conformal_horizon_id ) ) + horizons_stack_.above( baselap_id).value(), conformal_horizon_id ) ) { builder_.add_block_in_stratigraphic_unit( block, model_.stratigraphic_unit( From c801d340bcb6e0994f516e3f72740f65945d9f01 Mon Sep 17 00:00:00 2001 From: panquez <32702237+panquez@users.noreply.github.com> Date: Tue, 9 Sep 2025 12:26:38 +0000 Subject: [PATCH 10/10] Apply prepare changes --- ...plicit_structural_model_stratigraphic_blocks_builder.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp index 24d9eb0..9ba7da4 100644 --- a/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp +++ b/src/geode/geosciences/implicit/representation/builder/helpers/implicit_structural_model_stratigraphic_blocks_builder.cpp @@ -277,7 +277,8 @@ namespace return true; } if( horizons_stack_.is_directly_above( - horizons_stack_.above( conformal_horizon_id).value(), erosion_id ) ) + horizons_stack_.above( conformal_horizon_id ).value(), + erosion_id ) ) { builder_.add_block_in_stratigraphic_unit( block, model_.stratigraphic_unit( @@ -302,7 +303,8 @@ namespace return true; } if( horizons_stack_.is_directly_above( - horizons_stack_.above( baselap_id).value(), conformal_horizon_id ) ) + horizons_stack_.above( baselap_id ).value(), + conformal_horizon_id ) ) { builder_.add_block_in_stratigraphic_unit( block, model_.stratigraphic_unit(