diff --git a/bindings/python/src/implicit/representation/builder/horizons_stack_builder.hpp b/bindings/python/src/implicit/representation/builder/horizons_stack_builder.hpp index ad051810..efb5806d 100644 --- a/bindings/python/src/implicit/representation/builder/horizons_stack_builder.hpp +++ b/bindings/python/src/implicit/representation/builder/horizons_stack_builder.hpp @@ -54,10 +54,10 @@ HorizonsStackBuilder##dimension##D::*) () >( \ &HorizonsStackBuilder##dimension##D:: \ add_stratigraphic_unit ) ) \ - .def( "add_horizon_above", \ - &HorizonsStackBuilder##dimension##D::add_horizon_above ) \ - .def( "add_horizon_under", \ - &HorizonsStackBuilder##dimension##D::add_horizon_under ) \ + .def( "set_horizon_above", \ + &HorizonsStackBuilder##dimension##D::set_horizon_above ) \ + .def( "set_horizon_under", \ + &HorizonsStackBuilder##dimension##D::set_horizon_under ) \ .def( "remove_horizon", \ &HorizonsStackBuilder##dimension##D::remove_horizon ) \ .def( "remove_stratigraphic_unit", \ diff --git a/bindings/python/tests/implicit/test-py-horizons-stack.py b/bindings/python/tests/implicit/test-py-horizons-stack.py index ce1b8393..23abd59f 100644 --- a/bindings/python/tests/implicit/test-py-horizons-stack.py +++ b/bindings/python/tests/implicit/test-py-horizons-stack.py @@ -43,10 +43,10 @@ def test_horizons_stack(): raise ValueError( "[TEST] Stratigraphic Units Stack should have 3 horizons." ) if horizons_stack.nb_stratigraphic_units() != 2: raise ValueError( "[TEST] Stratigraphic Units Stack should have 2 Stratigraphic Units." ) - stack_builder.add_horizon_under( horizons_stack.horizon( hor0 ), horizons_stack.stratigraphic_unit( unit0 ) ) - stack_builder.add_horizon_above( horizons_stack.horizon( hor1 ), horizons_stack.stratigraphic_unit( unit0 ) ) - stack_builder.add_horizon_under( horizons_stack.horizon( hor1 ), horizons_stack.stratigraphic_unit( unit1 ) ) - stack_builder.add_horizon_above( horizons_stack.horizon( hor2 ), horizons_stack.stratigraphic_unit( unit1 ) ) + stack_builder.set_horizon_under( horizons_stack.horizon( hor0 ), horizons_stack.stratigraphic_unit( unit0 ) ) + stack_builder.set_horizon_above( horizons_stack.horizon( hor1 ), horizons_stack.stratigraphic_unit( unit0 ) ) + stack_builder.set_horizon_under( horizons_stack.horizon( hor1 ), horizons_stack.stratigraphic_unit( unit1 ) ) + stack_builder.set_horizon_above( horizons_stack.horizon( hor2 ), horizons_stack.stratigraphic_unit( unit1 ) ) for unit in horizons_stack.stratigraphic_units(): unit_id = unit.id() diff --git a/include/geode/geosciences/explicit/mixin/core/fault_blocks.hpp b/include/geode/geosciences/explicit/mixin/core/fault_blocks.hpp index 8ca23f63..2f1eaef1 100644 --- a/include/geode/geosciences/explicit/mixin/core/fault_blocks.hpp +++ b/include/geode/geosciences/explicit/mixin/core/fault_blocks.hpp @@ -23,6 +23,7 @@ #pragma once +#include #include #include @@ -41,10 +42,10 @@ namespace geode class opengeode_geosciences_explicit_api FaultBlocks { OPENGEODE_DISABLE_COPY( FaultBlocks ); + PASSKEY( FaultBlocksBuilder< dimension >, FaultBlocksBuilderKey ); public: using Builder = FaultBlocksBuilder< dimension >; - friend Builder; class opengeode_geosciences_explicit_api FaultBlockRangeBase { @@ -124,19 +125,24 @@ namespace geode [[nodiscard]] FaultBlock< dimension >& operator*() const; }; - private: - [[nodiscard]] const uuid& create_fault_block(); + public: + [[nodiscard]] const uuid& create_fault_block( + FaultBlocksBuilderKey key ); - void create_fault_block( uuid fault_block_id ); + void create_fault_block( + uuid fault_block_id, FaultBlocksBuilderKey key ); - void delete_fault_block( const FaultBlock< dimension >& fault_block ); + void delete_fault_block( const FaultBlock< dimension >& fault_block, + FaultBlocksBuilderKey key ); - void load_fault_blocks( std::string_view directory ); + void load_fault_blocks( + std::string_view directory, FaultBlocksBuilderKey key ); - [[nodiscard]] ModifiableFaultBlockRange modifiable_fault_blocks(); + [[nodiscard]] ModifiableFaultBlockRange modifiable_fault_blocks( + FaultBlocksBuilderKey key ); [[nodiscard]] FaultBlock< dimension >& modifiable_fault_block( - const uuid& id ); + const uuid& id, FaultBlocksBuilderKey key ); private: IMPLEMENTATION_MEMBER( impl_ ); diff --git a/include/geode/geosciences/explicit/mixin/core/faults.hpp b/include/geode/geosciences/explicit/mixin/core/faults.hpp index 7e1b3197..dd66e25d 100644 --- a/include/geode/geosciences/explicit/mixin/core/faults.hpp +++ b/include/geode/geosciences/explicit/mixin/core/faults.hpp @@ -23,6 +23,7 @@ #pragma once +#include #include #include @@ -41,10 +42,10 @@ namespace geode class opengeode_geosciences_explicit_api Faults { OPENGEODE_DISABLE_COPY( Faults ); + PASSKEY( FaultsBuilder< dimension >, FaultsBuilderKey ); public: using Builder = FaultsBuilder< dimension >; - friend Builder; class opengeode_geosciences_explicit_api FaultRangeBase { @@ -123,24 +124,29 @@ namespace geode [[nodiscard]] Fault< dimension >& operator*() const; }; - private: - [[nodiscard]] const uuid& create_fault(); + public: + [[nodiscard]] const uuid& create_fault( FaultsBuilderKey key ); [[nodiscard]] const uuid& create_fault( - typename Fault< dimension >::FAULT_TYPE type ); + typename Fault< dimension >::FAULT_TYPE type, + FaultsBuilderKey key ); - void create_fault( uuid fault_id ); + void create_fault( uuid fault_id, FaultsBuilderKey key ); - void create_fault( - uuid fault_id, typename Fault< dimension >::FAULT_TYPE type ); + void create_fault( uuid fault_id, + typename Fault< dimension >::FAULT_TYPE type, + FaultsBuilderKey key ); - void delete_fault( const Fault< dimension >& fault ); + void delete_fault( + const Fault< dimension >& fault, FaultsBuilderKey key ); - void load_faults( std::string_view directory ); + void load_faults( std::string_view directory, FaultsBuilderKey key ); - [[nodiscard]] ModifiableFaultRange modifiable_faults(); + [[nodiscard]] ModifiableFaultRange modifiable_faults( + FaultsBuilderKey key ); - [[nodiscard]] Fault< dimension >& modifiable_fault( const uuid& id ); + [[nodiscard]] Fault< dimension >& modifiable_fault( + const uuid& id, FaultsBuilderKey key ); private: IMPLEMENTATION_MEMBER( impl_ ); diff --git a/include/geode/geosciences/explicit/mixin/core/horizons.hpp b/include/geode/geosciences/explicit/mixin/core/horizons.hpp index 3e6bc2cc..9f55dcb3 100644 --- a/include/geode/geosciences/explicit/mixin/core/horizons.hpp +++ b/include/geode/geosciences/explicit/mixin/core/horizons.hpp @@ -23,6 +23,7 @@ #pragma once +#include #include #include @@ -38,9 +39,10 @@ namespace geode namespace geode { template < index_t dimension > - class opengeode_geosciences_explicit_api Horizons + class Horizons { OPENGEODE_DISABLE_COPY( Horizons ); + PASSKEY( HorizonsBuilder< dimension >, HorizonsBuilderKey ); public: using Builder = HorizonsBuilder< dimension >; @@ -99,7 +101,6 @@ namespace geode void save_horizons( std::string_view directory ) const; protected: - friend class HorizonsBuilder< dimension >; Horizons(); Horizons( Horizons&& other ) noexcept; @@ -125,25 +126,30 @@ namespace geode [[nodiscard]] Horizon< dimension >& operator*() const; }; - private: - [[nodiscard]] const uuid& create_horizon(); + public: + [[nodiscard]] const uuid& create_horizon( HorizonsBuilderKey key ); [[nodiscard]] const uuid& create_horizon( - typename Horizon< dimension >::HORIZON_TYPE type ); + typename Horizon< dimension >::HORIZON_TYPE type, + HorizonsBuilderKey key ); - void create_horizon( uuid horizon_id ); + void create_horizon( uuid horizon_id, HorizonsBuilderKey key ); - void create_horizon( - uuid horizon_id, typename Horizon< dimension >::HORIZON_TYPE type ); + void create_horizon( uuid horizon_id, + typename Horizon< dimension >::HORIZON_TYPE type, + HorizonsBuilderKey key ); - void delete_horizon( const Horizon< dimension >& horizon ); + void delete_horizon( + const Horizon< dimension >& horizon, HorizonsBuilderKey key ); - void load_horizons( std::string_view directory ); + void load_horizons( + std::string_view directory, HorizonsBuilderKey key ); - [[nodiscard]] ModifiableHorizonRange modifiable_horizons(); + [[nodiscard]] ModifiableHorizonRange modifiable_horizons( + HorizonsBuilderKey key ); [[nodiscard]] Horizon< dimension >& modifiable_horizon( - const uuid& id ); + const uuid& id, HorizonsBuilderKey key ); private: IMPLEMENTATION_MEMBER( impl_ ); diff --git a/include/geode/geosciences/explicit/mixin/core/stratigraphic_units.hpp b/include/geode/geosciences/explicit/mixin/core/stratigraphic_units.hpp index 0a6f9795..dde0eea9 100644 --- a/include/geode/geosciences/explicit/mixin/core/stratigraphic_units.hpp +++ b/include/geode/geosciences/explicit/mixin/core/stratigraphic_units.hpp @@ -23,6 +23,7 @@ #pragma once +#include #include #include @@ -41,10 +42,11 @@ namespace geode class opengeode_geosciences_explicit_api StratigraphicUnits { OPENGEODE_DISABLE_COPY( StratigraphicUnits ); + PASSKEY( StratigraphicUnitsBuilder< dimension >, + StratigraphicUnitsBuilderKey ); public: using Builder = StratigraphicUnitsBuilder< dimension >; - friend Builder; class opengeode_geosciences_explicit_api StratigraphicUnitRangeBase { @@ -104,7 +106,6 @@ namespace geode void save_stratigraphic_units( std::string_view directory ) const; protected: - friend class StratigraphicUnitsBuilder< dimension >; StratigraphicUnits(); StratigraphicUnits( StratigraphicUnits&& other ) noexcept; @@ -132,21 +133,26 @@ namespace geode [[nodiscard]] StratigraphicUnit< dimension >& operator*() const; }; - private: - [[nodiscard]] const uuid& create_stratigraphic_unit(); + public: + [[nodiscard]] const uuid& create_stratigraphic_unit( + StratigraphicUnitsBuilderKey key ); - void create_stratigraphic_unit( uuid stratigraphic_unit_id ); + void create_stratigraphic_unit( + uuid stratigraphic_unit_id, StratigraphicUnitsBuilderKey key ); void delete_stratigraphic_unit( - const StratigraphicUnit< dimension >& stratigraphic_unit ); + const StratigraphicUnit< dimension >& stratigraphic_unit, + StratigraphicUnitsBuilderKey key ); - void load_stratigraphic_units( std::string_view directory ); + void load_stratigraphic_units( + std::string_view directory, StratigraphicUnitsBuilderKey key ); [[nodiscard]] ModifiableStratigraphicUnitRange - modifiable_stratigraphic_units(); + modifiable_stratigraphic_units( StratigraphicUnitsBuilderKey key ); [[nodiscard]] StratigraphicUnit< dimension >& - modifiable_stratigraphic_unit( const uuid& id ); + modifiable_stratigraphic_unit( + const uuid& id, StratigraphicUnitsBuilderKey key ); private: IMPLEMENTATION_MEMBER( impl_ ); diff --git a/include/geode/geosciences/implicit/representation/builder/horizons_stack_builder.hpp b/include/geode/geosciences/implicit/representation/builder/horizons_stack_builder.hpp index cb399050..e55ec2ba 100644 --- a/include/geode/geosciences/implicit/representation/builder/horizons_stack_builder.hpp +++ b/include/geode/geosciences/implicit/representation/builder/horizons_stack_builder.hpp @@ -103,16 +103,16 @@ namespace geode InsertedHorizonInfo add_horizon_in_stratigraphic_unit( const StratigraphicUnit< dimension >& strati_unit ); - void add_horizon_above( const Horizon< dimension >& horizon_above, + void set_horizon_above( const Horizon< dimension >& horizon_above, const StratigraphicUnit< dimension >& strati_unit_under ); - void add_horizon_under( const Horizon< dimension >& horizon_under, + void set_horizon_under( const Horizon< dimension >& horizon_under, const StratigraphicUnit< dimension >& strati_unit_above ); - void add_erosion_above( const Horizon< dimension >& erosion_horizon, + void set_as_erosion_above( const Horizon< dimension >& erosion_horizon, const StratigraphicUnit< dimension >& eroded_unit ); - void add_baselap_under( const Horizon< dimension >& baselap_horizon, + void set_as_baselap_under( const Horizon< dimension >& baselap_horizon, const StratigraphicUnit< dimension >& baselaping_unit ); void remove_horizon( const Horizon< dimension >& horizon ); @@ -120,6 +120,8 @@ namespace geode void remove_stratigraphic_unit( const StratigraphicUnit< dimension >& stratigraphic_unit ); + void compute_top_and_bottom_horizons(); + private: HorizonsStack< dimension >& horizons_stack_; }; diff --git a/include/geode/geosciences/implicit/representation/core/horizons_stack.hpp b/include/geode/geosciences/implicit/representation/core/horizons_stack.hpp index c3f23b92..1c0a9c1f 100644 --- a/include/geode/geosciences/implicit/representation/core/horizons_stack.hpp +++ b/include/geode/geosciences/implicit/representation/core/horizons_stack.hpp @@ -24,6 +24,7 @@ #pragma once #include +#include #include #include @@ -48,14 +49,76 @@ namespace geode * and under which horizon, and inversely). */ template < index_t dimension > - class opengeode_geosciences_implicit_api HorizonsStack - : public StratigraphicRelationships, - public Horizons< dimension >, - public StratigraphicUnits< dimension >, - public Identifier + class HorizonsStack : public StratigraphicRelationships, + public Horizons< dimension >, + public StratigraphicUnits< dimension >, + public Identifier { PASSKEY( HorizonsStackBuilder< dimension >, HorizonsStackBuilderKey ); + public: + class opengeode_geosciences_implicit_api HorizonOrderedRange + { + public: + HorizonOrderedRange( const HorizonsStack& horizons_stack ); + HorizonOrderedRange( HorizonOrderedRange&& other ) noexcept; + HorizonOrderedRange( const HorizonOrderedRange& other ); + ~HorizonOrderedRange(); + + [[nodiscard]] bool operator!=( + const HorizonOrderedRange& /*unused*/ ) const; + + void operator++(); + + [[nodiscard]] const HorizonOrderedRange& begin() const + { + return *this; + } + + [[nodiscard]] const HorizonOrderedRange& end() const + { + return *this; + } + + [[nodiscard]] const Horizon< dimension >& operator*() const; + + protected: + IMPLEMENTATION_MEMBER( impl_ ); + }; + + class opengeode_geosciences_implicit_api StratigraphicUnitOrderedRange + { + public: + StratigraphicUnitOrderedRange( + const HorizonsStack& horizons_stack ); + StratigraphicUnitOrderedRange( + StratigraphicUnitOrderedRange&& other ) noexcept; + StratigraphicUnitOrderedRange( + const StratigraphicUnitOrderedRange& other ); + ~StratigraphicUnitOrderedRange(); + + [[nodiscard]] bool operator!=( + const StratigraphicUnitOrderedRange& /*unused*/ ) const; + + void operator++(); + + [[nodiscard]] const StratigraphicUnitOrderedRange& begin() const + { + return *this; + } + + [[nodiscard]] const StratigraphicUnitOrderedRange& end() const + { + return *this; + } + + [[nodiscard]] const StratigraphicUnit< dimension >& + operator*() const; + + protected: + IMPLEMENTATION_MEMBER( impl_ ); + }; + public: using Builder = HorizonsStackBuilder< dimension >; static constexpr auto dim = dimension; @@ -81,9 +144,13 @@ namespace geode return native_extension_static(); } - [[nodiscard]] uuid top_horizon() const; + [[nodiscard]] std::optional< uuid > top_horizon() const; + + [[nodiscard]] std::optional< uuid > bottom_horizon() const; - [[nodiscard]] uuid bottom_horizon() const; + [[nodiscard]] HorizonOrderedRange bottom_to_top_horizons() const; + + [[nodiscard]] StratigraphicUnitOrderedRange bottom_to_top_units() const; [[nodiscard]] bool is_eroded_by( const StratigraphicUnit< dimension >& eroded, @@ -91,6 +158,18 @@ namespace geode [[nodiscard]] bool is_baselap_of( const Horizon< dimension >& baselap, const StratigraphicUnit< dimension >& baselap_top ) const; + + public: + void compute_top_and_bottom_horizons( HorizonsStackBuilderKey key ); + + void set_top_horizon( + const uuid& horizon_id, HorizonsStackBuilderKey key ); + + void set_bottom_horizon( + const uuid& horizon_id, HorizonsStackBuilderKey key ); + + protected: + IMPLEMENTATION_MEMBER( impl_ ); }; ALIAS_2D_AND_3D( HorizonsStack ); } // 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 4d23a465..e966b03f 100644 --- a/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp +++ b/include/geode/geosciences/implicit/representation/core/implicit_structural_model.hpp @@ -34,8 +34,10 @@ namespace geode { FORWARD_DECLARATION_DIMENSION_CLASS( Point ); FORWARD_DECLARATION_DIMENSION_CLASS( HorizonsStack ); + FORWARD_DECLARATION_DIMENSION_CLASS( Horizon ); ALIAS_3D( Point ); ALIAS_3D( HorizonsStack ); + ALIAS_3D( Horizon ); class ImplicitStructuralModelBuilder; } // namespace geode diff --git a/src/geode/geosciences/explicit/mixin/builder/fault_blocks_builder.cpp b/src/geode/geosciences/explicit/mixin/builder/fault_blocks_builder.cpp index d0545d62..d46212ed 100644 --- a/src/geode/geosciences/explicit/mixin/builder/fault_blocks_builder.cpp +++ b/src/geode/geosciences/explicit/mixin/builder/fault_blocks_builder.cpp @@ -31,35 +31,35 @@ namespace geode template < index_t dimension > const uuid& FaultBlocksBuilder< dimension >::create_fault_block() { - return fault_blocks_.create_fault_block(); + return fault_blocks_.create_fault_block( {} ); } template < index_t dimension > void FaultBlocksBuilder< dimension >::create_fault_block( uuid fault_block_id ) { - fault_blocks_.create_fault_block( std::move( fault_block_id ) ); + fault_blocks_.create_fault_block( std::move( fault_block_id ), {} ); } template < index_t dimension > void FaultBlocksBuilder< dimension >::delete_fault_block( const FaultBlock< dimension >& fault_block ) { - fault_blocks_.delete_fault_block( fault_block ); + fault_blocks_.delete_fault_block( fault_block, {} ); } template < index_t dimension > void FaultBlocksBuilder< dimension >::load_fault_blocks( std::string_view directory ) { - return fault_blocks_.load_fault_blocks( directory ); + return fault_blocks_.load_fault_blocks( directory, {} ); } template < index_t dimension > void FaultBlocksBuilder< dimension >::set_fault_block_name( const uuid& id, std::string_view name ) { - fault_blocks_.modifiable_fault_block( id ).set_fault_block_name( + fault_blocks_.modifiable_fault_block( id, {} ).set_fault_block_name( name, typename FaultBlock< dimension >::FaultBlocksBuilderKey{} ); } diff --git a/src/geode/geosciences/explicit/mixin/builder/faults_builder.cpp b/src/geode/geosciences/explicit/mixin/builder/faults_builder.cpp index 50cd6b82..330d8f12 100644 --- a/src/geode/geosciences/explicit/mixin/builder/faults_builder.cpp +++ b/src/geode/geosciences/explicit/mixin/builder/faults_builder.cpp @@ -31,47 +31,47 @@ namespace geode template < index_t dimension > const uuid& FaultsBuilder< dimension >::create_fault() { - return faults_.create_fault(); + return faults_.create_fault( {} ); } template < index_t dimension > const uuid& FaultsBuilder< dimension >::create_fault( typename Fault< dimension >::FAULT_TYPE type ) { - return faults_.create_fault( type ); + return faults_.create_fault( type, {} ); } template < index_t dimension > void FaultsBuilder< dimension >::create_fault( uuid fault_id ) { - faults_.create_fault( std::move( fault_id ) ); + faults_.create_fault( std::move( fault_id ), {} ); } template < index_t dimension > void FaultsBuilder< dimension >::create_fault( uuid fault_id, typename Fault< dimension >::FAULT_TYPE type ) { - faults_.create_fault( std::move( fault_id ), type ); + faults_.create_fault( std::move( fault_id ), type, {} ); } template < index_t dimension > void FaultsBuilder< dimension >::delete_fault( const Fault< dimension >& fault ) { - faults_.delete_fault( fault ); + faults_.delete_fault( fault, {} ); } template < index_t dimension > void FaultsBuilder< dimension >::load_faults( std::string_view directory ) { - return faults_.load_faults( directory ); + return faults_.load_faults( directory, {} ); } template < index_t dimension > void FaultsBuilder< dimension >::set_fault_type( const uuid& fault_id, typename Fault< dimension >::FAULT_TYPE type ) { - faults_.modifiable_fault( fault_id ) + faults_.modifiable_fault( fault_id, {} ) .set_type( type, typename Fault< dimension >::FaultsBuilderKey{} ); } @@ -79,7 +79,7 @@ namespace geode void FaultsBuilder< dimension >::set_fault_name( const uuid& id, std::string_view name ) { - faults_.modifiable_fault( id ).set_fault_name( + faults_.modifiable_fault( id, {} ).set_fault_name( name, typename Fault< dimension >::FaultsBuilderKey{} ); } diff --git a/src/geode/geosciences/explicit/mixin/builder/horizons_builder.cpp b/src/geode/geosciences/explicit/mixin/builder/horizons_builder.cpp index 9afd4bd5..212c378b 100644 --- a/src/geode/geosciences/explicit/mixin/builder/horizons_builder.cpp +++ b/src/geode/geosciences/explicit/mixin/builder/horizons_builder.cpp @@ -31,48 +31,48 @@ namespace geode template < index_t dimension > const uuid& HorizonsBuilder< dimension >::create_horizon() { - return horizons_.create_horizon(); + return horizons_.create_horizon( {} ); } template < index_t dimension > const uuid& HorizonsBuilder< dimension >::create_horizon( typename Horizon< dimension >::HORIZON_TYPE type ) { - return horizons_.create_horizon( type ); + return horizons_.create_horizon( type, {} ); } template < index_t dimension > void HorizonsBuilder< dimension >::create_horizon( uuid horizon_id ) { - horizons_.create_horizon( std::move( horizon_id ) ); + horizons_.create_horizon( std::move( horizon_id ), {} ); } template < index_t dimension > void HorizonsBuilder< dimension >::create_horizon( uuid horizon_id, typename Horizon< dimension >::HORIZON_TYPE type ) { - horizons_.create_horizon( std::move( horizon_id ), type ); + horizons_.create_horizon( std::move( horizon_id ), type, {} ); } template < index_t dimension > void HorizonsBuilder< dimension >::delete_horizon( const Horizon< dimension >& horizon ) { - horizons_.delete_horizon( horizon ); + horizons_.delete_horizon( horizon, {} ); } template < index_t dimension > void HorizonsBuilder< dimension >::load_horizons( std::string_view directory ) { - return horizons_.load_horizons( directory ); + return horizons_.load_horizons( directory, {} ); } template < index_t dimension > void HorizonsBuilder< dimension >::set_horizon_type( const uuid& horizon_id, typename Horizon< dimension >::HORIZON_TYPE type ) { - horizons_.modifiable_horizon( horizon_id ) + horizons_.modifiable_horizon( horizon_id, {} ) .set_type( type, typename Horizon< dimension >::HorizonsBuilderKey{} ); } @@ -81,7 +81,7 @@ namespace geode void HorizonsBuilder< dimension >::set_horizon_name( const uuid& id, std::string_view name ) { - horizons_.modifiable_horizon( id ).set_horizon_name( + horizons_.modifiable_horizon( id, {} ).set_horizon_name( name, typename Horizon< dimension >::HorizonsBuilderKey{} ); } diff --git a/src/geode/geosciences/explicit/mixin/builder/stratigraphic_units_builder.cpp b/src/geode/geosciences/explicit/mixin/builder/stratigraphic_units_builder.cpp index 2ab0cfdc..0b61c9f6 100644 --- a/src/geode/geosciences/explicit/mixin/builder/stratigraphic_units_builder.cpp +++ b/src/geode/geosciences/explicit/mixin/builder/stratigraphic_units_builder.cpp @@ -32,35 +32,37 @@ namespace geode const uuid& StratigraphicUnitsBuilder< dimension >::create_stratigraphic_unit() { - return stratigraphic_units_.create_stratigraphic_unit(); + return stratigraphic_units_.create_stratigraphic_unit( {} ); } template < index_t dimension > void StratigraphicUnitsBuilder< dimension >::create_stratigraphic_unit( uuid stratigraphic_unit_id ) { - stratigraphic_units_.create_stratigraphic_unit( stratigraphic_unit_id ); + stratigraphic_units_.create_stratigraphic_unit( + stratigraphic_unit_id, {} ); } template < index_t dimension > void StratigraphicUnitsBuilder< dimension >::delete_stratigraphic_unit( const StratigraphicUnit< dimension >& stratigraphic_unit ) { - stratigraphic_units_.delete_stratigraphic_unit( stratigraphic_unit ); + stratigraphic_units_.delete_stratigraphic_unit( + stratigraphic_unit, {} ); } template < index_t dimension > void StratigraphicUnitsBuilder< dimension >::load_stratigraphic_units( std::string_view directory ) { - return stratigraphic_units_.load_stratigraphic_units( directory ); + return stratigraphic_units_.load_stratigraphic_units( directory, {} ); } template < index_t dimension > void StratigraphicUnitsBuilder< dimension >::set_stratigraphic_unit_name( const uuid& id, std::string_view name ) { - stratigraphic_units_.modifiable_stratigraphic_unit( id ) + stratigraphic_units_.modifiable_stratigraphic_unit( id, {} ) .set_stratigraphic_unit_name( name, typename StratigraphicUnit< dimension >::StratigraphicUnitsBuilderKey{} ); diff --git a/src/geode/geosciences/explicit/mixin/core/fault_blocks.cpp b/src/geode/geosciences/explicit/mixin/core/fault_blocks.cpp index c5196ca2..174b3891 100644 --- a/src/geode/geosciences/explicit/mixin/core/fault_blocks.cpp +++ b/src/geode/geosciences/explicit/mixin/core/fault_blocks.cpp @@ -73,7 +73,7 @@ namespace geode template < index_t dimension > FaultBlock< dimension >& FaultBlocks< dimension >::modifiable_fault_block( - const uuid& id ) + const uuid& id, FaultBlocksBuilderKey /*unused*/ ) { return impl_->component( id ); } @@ -87,7 +87,7 @@ namespace geode template < index_t dimension > void FaultBlocks< dimension >::load_fault_blocks( - std::string_view directory ) + std::string_view directory, FaultBlocksBuilderKey /*unused*/ ) { impl_->load_components( absl::StrCat( directory, "/fault_blocks" ) ); } @@ -101,13 +101,15 @@ namespace geode template < index_t dimension > typename FaultBlocks< dimension >::ModifiableFaultBlockRange - FaultBlocks< dimension >::modifiable_fault_blocks() + FaultBlocks< dimension >::modifiable_fault_blocks( + FaultBlocksBuilderKey /*unused*/ ) { return { *this }; } template < index_t dimension > - const uuid& FaultBlocks< dimension >::create_fault_block() + const uuid& FaultBlocks< dimension >::create_fault_block( + FaultBlocksBuilderKey /*unused*/ ) { typename FaultBlocks< dimension >::Impl::ComponentPtr fault_block{ new FaultBlock< dimension >{ @@ -119,7 +121,8 @@ namespace geode } template < index_t dimension > - void FaultBlocks< dimension >::create_fault_block( uuid fault_block_id ) + void FaultBlocks< dimension >::create_fault_block( + uuid fault_block_id, FaultBlocksBuilderKey /*unused*/ ) { typename FaultBlocks< dimension >::Impl::ComponentPtr fault_block{ new FaultBlock< dimension >{ @@ -131,7 +134,8 @@ namespace geode template < index_t dimension > void FaultBlocks< dimension >::delete_fault_block( - const FaultBlock< dimension >& fault_block ) + const FaultBlock< dimension >& fault_block, + FaultBlocksBuilderKey /*unused*/ ) { impl_->delete_component( fault_block.id() ); } diff --git a/src/geode/geosciences/explicit/mixin/core/faults.cpp b/src/geode/geosciences/explicit/mixin/core/faults.cpp index c006ea83..a88ecfc2 100644 --- a/src/geode/geosciences/explicit/mixin/core/faults.cpp +++ b/src/geode/geosciences/explicit/mixin/core/faults.cpp @@ -71,7 +71,8 @@ namespace geode } template < index_t dimension > - Fault< dimension >& Faults< dimension >::modifiable_fault( const uuid& id ) + Fault< dimension >& Faults< dimension >::modifiable_fault( + const uuid& id, FaultsBuilderKey /*unused*/ ) { return impl_->component( id ); } @@ -83,7 +84,8 @@ namespace geode } template < index_t dimension > - void Faults< dimension >::load_faults( std::string_view directory ) + void Faults< dimension >::load_faults( + std::string_view directory, FaultsBuilderKey /*unused*/ ) { impl_->load_components( absl::StrCat( directory, "/faults" ) ); } @@ -96,13 +98,13 @@ namespace geode template < index_t dimension > typename Faults< dimension >::ModifiableFaultRange - Faults< dimension >::modifiable_faults() + Faults< dimension >::modifiable_faults( FaultsBuilderKey /*unused*/ ) { return { *this }; } template < index_t dimension > - const uuid& Faults< dimension >::create_fault() + const uuid& Faults< dimension >::create_fault( FaultsBuilderKey /*unused*/ ) { typename Faults< dimension >::Impl::ComponentPtr fault{ new Fault< dimension >{ typename Fault< dimension >::FaultsKey{} } @@ -114,7 +116,8 @@ namespace geode template < index_t dimension > const uuid& Faults< dimension >::create_fault( - typename Fault< dimension >::FAULT_TYPE type ) + typename Fault< dimension >::FAULT_TYPE type, + FaultsBuilderKey /*unused*/ ) { typename Faults< dimension >::Impl::ComponentPtr fault{ new Fault< dimension >{ @@ -126,7 +129,8 @@ namespace geode } template < index_t dimension > - void Faults< dimension >::create_fault( uuid fault_id ) + void Faults< dimension >::create_fault( + uuid fault_id, FaultsBuilderKey /*unused*/ ) { typename Faults< dimension >::Impl::ComponentPtr fault{ new Fault< dimension >{ typename Fault< dimension >::FaultsKey{} } @@ -136,8 +140,9 @@ namespace geode } template < index_t dimension > - void Faults< dimension >::create_fault( - uuid fault_id, typename Fault< dimension >::FAULT_TYPE type ) + void Faults< dimension >::create_fault( uuid fault_id, + typename Fault< dimension >::FAULT_TYPE type, + FaultsBuilderKey /*unused*/ ) { typename Faults< dimension >::Impl::ComponentPtr fault{ new Fault< dimension >{ @@ -148,7 +153,8 @@ namespace geode } template < index_t dimension > - void Faults< dimension >::delete_fault( const Fault< dimension >& fault ) + void Faults< dimension >::delete_fault( + const Fault< dimension >& fault, FaultsBuilderKey /*unused*/ ) { impl_->delete_component( fault.id() ); } diff --git a/src/geode/geosciences/explicit/mixin/core/horizons.cpp b/src/geode/geosciences/explicit/mixin/core/horizons.cpp index 6d285f3a..54e66622 100644 --- a/src/geode/geosciences/explicit/mixin/core/horizons.cpp +++ b/src/geode/geosciences/explicit/mixin/core/horizons.cpp @@ -73,7 +73,7 @@ namespace geode template < index_t dimension > Horizon< dimension >& Horizons< dimension >::modifiable_horizon( - const uuid& id ) + const uuid& id, HorizonsBuilderKey /*unused*/ ) { return impl_->component( id ); } @@ -86,7 +86,8 @@ namespace geode } template < index_t dimension > - void Horizons< dimension >::load_horizons( std::string_view directory ) + void Horizons< dimension >::load_horizons( + std::string_view directory, HorizonsBuilderKey /*unused*/ ) { impl_->load_components( absl::StrCat( directory, "/horizons" ) ); } @@ -100,13 +101,15 @@ namespace geode template < index_t dimension > typename Horizons< dimension >::ModifiableHorizonRange - Horizons< dimension >::modifiable_horizons() + Horizons< dimension >::modifiable_horizons( + HorizonsBuilderKey /*unused*/ ) { return { *this }; } template < index_t dimension > - const uuid& Horizons< dimension >::create_horizon() + const uuid& Horizons< dimension >::create_horizon( + HorizonsBuilderKey /*unused*/ ) { typename Horizons< dimension >::Impl::ComponentPtr horizon{ new Horizon< dimension >{ @@ -119,7 +122,8 @@ namespace geode template < index_t dimension > const uuid& Horizons< dimension >::create_horizon( - typename Horizon< dimension >::HORIZON_TYPE type ) + typename Horizon< dimension >::HORIZON_TYPE type, + HorizonsBuilderKey /*unused*/ ) { typename Horizons< dimension >::Impl::ComponentPtr horizon{ new Horizon< dimension >{ @@ -131,7 +135,8 @@ namespace geode } template < index_t dimension > - void Horizons< dimension >::create_horizon( uuid horizon_id ) + void Horizons< dimension >::create_horizon( + uuid horizon_id, HorizonsBuilderKey /*unused*/ ) { typename Horizons< dimension >::Impl::ComponentPtr horizon{ new Horizon< dimension >{ @@ -142,8 +147,9 @@ namespace geode } template < index_t dimension > - void Horizons< dimension >::create_horizon( - uuid horizon_id, typename Horizon< dimension >::HORIZON_TYPE type ) + void Horizons< dimension >::create_horizon( uuid horizon_id, + typename Horizon< dimension >::HORIZON_TYPE type, + HorizonsBuilderKey /*unused*/ ) { typename Horizons< dimension >::Impl::ComponentPtr horizon{ new Horizon< dimension >{ @@ -155,7 +161,7 @@ namespace geode template < index_t dimension > void Horizons< dimension >::delete_horizon( - const Horizon< dimension >& horizon ) + const Horizon< dimension >& horizon, HorizonsBuilderKey /*unused*/ ) { impl_->delete_component( horizon.id() ); } diff --git a/src/geode/geosciences/explicit/mixin/core/stratigraphic_units.cpp b/src/geode/geosciences/explicit/mixin/core/stratigraphic_units.cpp index 05ae86f1..c45da22f 100644 --- a/src/geode/geosciences/explicit/mixin/core/stratigraphic_units.cpp +++ b/src/geode/geosciences/explicit/mixin/core/stratigraphic_units.cpp @@ -77,7 +77,7 @@ namespace geode template < index_t dimension > StratigraphicUnit< dimension >& StratigraphicUnits< dimension >::modifiable_stratigraphic_unit( - const uuid& id ) + const uuid& id, StratigraphicUnitsBuilderKey /*unused*/ ) { return impl_->component( id ); } @@ -92,7 +92,7 @@ namespace geode template < index_t dimension > void StratigraphicUnits< dimension >::load_stratigraphic_units( - std::string_view directory ) + std::string_view directory, StratigraphicUnitsBuilderKey /*unused*/ ) { impl_->load_components( absl::StrCat( directory, "/stratigraphic_units" ) ); @@ -107,13 +107,15 @@ namespace geode template < index_t dimension > typename StratigraphicUnits< dimension >::ModifiableStratigraphicUnitRange - StratigraphicUnits< dimension >::modifiable_stratigraphic_units() + StratigraphicUnits< dimension >::modifiable_stratigraphic_units( + StratigraphicUnitsBuilderKey /*unused*/ ) { return { *this }; } template < index_t dimension > - const uuid& StratigraphicUnits< dimension >::create_stratigraphic_unit() + const uuid& StratigraphicUnits< dimension >::create_stratigraphic_unit( + StratigraphicUnitsBuilderKey /*unused*/ ) { typename StratigraphicUnits< dimension >::Impl::ComponentPtr stratigraphic_unit{ new StratigraphicUnit< dimension >{ @@ -126,7 +128,7 @@ namespace geode template < index_t dimension > void StratigraphicUnits< dimension >::create_stratigraphic_unit( - uuid stratigraphic_unit_id ) + uuid stratigraphic_unit_id, StratigraphicUnitsBuilderKey /*unused*/ ) { typename StratigraphicUnits< dimension >::Impl::ComponentPtr stratigraphic_unit{ new StratigraphicUnit< dimension >{ @@ -139,7 +141,8 @@ namespace geode template < index_t dimension > void StratigraphicUnits< dimension >::delete_stratigraphic_unit( - const StratigraphicUnit< dimension >& stratigraphic_unit ) + const StratigraphicUnit< dimension >& stratigraphic_unit, + StratigraphicUnitsBuilderKey /*unused*/ ) { impl_->delete_component( stratigraphic_unit.id() ); } diff --git a/src/geode/geosciences/implicit/representation/builder/horizons_stack_builder.cpp b/src/geode/geosciences/implicit/representation/builder/horizons_stack_builder.cpp index ea995a81..824a7da2 100644 --- a/src/geode/geosciences/implicit/representation/builder/horizons_stack_builder.cpp +++ b/src/geode/geosciences/implicit/representation/builder/horizons_stack_builder.cpp @@ -171,6 +171,7 @@ namespace geode void HorizonsStackBuilder< dimension >::remove_horizon( const Horizon< dimension >& horizon ) { + /// Change top/bottom horizon or recompute ? unregister_component( horizon.id() ); this->delete_horizon( horizon ); } @@ -184,7 +185,7 @@ namespace geode } template < index_t dimension > - void HorizonsStackBuilder< dimension >::add_horizon_above( + void HorizonsStackBuilder< dimension >::set_horizon_above( const Horizon< dimension >& horizon_above, const StratigraphicUnit< dimension >& strati_unit_under ) { @@ -193,7 +194,7 @@ namespace geode } template < index_t dimension > - void HorizonsStackBuilder< dimension >::add_horizon_under( + void HorizonsStackBuilder< dimension >::set_horizon_under( const Horizon< dimension >& horizon_under, const StratigraphicUnit< dimension >& strati_unit_above ) { @@ -202,7 +203,7 @@ namespace geode } template < index_t dimension > - void HorizonsStackBuilder< dimension >::add_erosion_above( + void HorizonsStackBuilder< dimension >::set_as_erosion_above( const Horizon< dimension >& erosion_horizon, const StratigraphicUnit< dimension >& eroded_unit ) { @@ -211,7 +212,7 @@ namespace geode } template < index_t dimension > - void HorizonsStackBuilder< dimension >::add_baselap_under( + void HorizonsStackBuilder< dimension >::set_as_baselap_under( const Horizon< dimension >& baselap_horizon, const StratigraphicUnit< dimension >& baselaping_unit ) { @@ -219,6 +220,12 @@ namespace geode baselaping_unit.component_id(), baselap_horizon.component_id() ); } + template < index_t dimension > + void HorizonsStackBuilder< dimension >::compute_top_and_bottom_horizons() + { + horizons_stack_.compute_top_and_bottom_horizons( {} ); + } + template class opengeode_geosciences_implicit_api HorizonsStackBuilder< 2 >; template class opengeode_geosciences_implicit_api HorizonsStackBuilder< 3 >; } // namespace geode diff --git a/src/geode/geosciences/implicit/representation/core/detail/helpers.cpp b/src/geode/geosciences/implicit/representation/core/detail/helpers.cpp index 44d33472..767c8a2f 100644 --- a/src/geode/geosciences/implicit/representation/core/detail/helpers.cpp +++ b/src/geode/geosciences/implicit/representation/core/detail/helpers.cpp @@ -294,7 +294,7 @@ namespace geode auto current_horizon = builder.add_horizon(); builder.set_horizon_name( current_horizon, horizons_names[0] ); const auto& su_under = builder.add_stratigraphic_unit(); - builder.add_horizon_above( stack.horizon( current_horizon ), + builder.set_horizon_above( stack.horizon( current_horizon ), stack.stratigraphic_unit( su_under ) ); bool lowest_unit_to_create{ nb_units < nb_horizons }; if( !lowest_unit_to_create ) @@ -307,22 +307,23 @@ namespace geode builder.set_stratigraphic_unit_name( su_above, units_names[lowest_unit_to_create ? counter - 1 : counter] ); - builder.add_horizon_under( stack.horizon( current_horizon ), + builder.set_horizon_under( stack.horizon( current_horizon ), stack.stratigraphic_unit( su_above ) ); current_horizon = builder.add_horizon(); builder.set_horizon_name( current_horizon, horizons_names[counter] ); - builder.add_horizon_above( stack.horizon( current_horizon ), + builder.set_horizon_above( stack.horizon( current_horizon ), stack.stratigraphic_unit( su_above ) ); } const auto& su_above = builder.add_stratigraphic_unit(); - builder.add_horizon_under( stack.horizon( current_horizon ), + builder.set_horizon_under( stack.horizon( current_horizon ), stack.stratigraphic_unit( su_above ) ); if( nb_units > nb_horizons ) { builder.set_stratigraphic_unit_name( su_above, units_names.back() ); } + builder.compute_top_and_bottom_horizons(); return stack; } @@ -334,11 +335,12 @@ namespace geode const auto nb_horizons = horizon_stack.nb_horizons(); check_number_of_horizons_and_stratigraphic_units( nb_horizons, horizon_stack.nb_stratigraphic_units() ); - const auto bottom_horizon = horizon_stack.bottom_horizon(); + builder.compute_top_and_bottom_horizons(); + const auto bottom_horizon = horizon_stack.bottom_horizon().value(); if( !horizon_stack.under( bottom_horizon ) ) { const auto& unit_under = builder.add_stratigraphic_unit(); - builder.add_horizon_above( + builder.set_horizon_above( horizon_stack.horizon( bottom_horizon ), horizon_stack.stratigraphic_unit( unit_under ) ); } @@ -362,7 +364,7 @@ namespace geode if( !su_above ) { const auto& unit_above = builder.add_stratigraphic_unit(); - builder.add_horizon_under( + builder.set_horizon_under( horizon_stack.horizon( current_horizon.value() ), horizon_stack.stratigraphic_unit( unit_above ) ); } diff --git a/src/geode/geosciences/implicit/representation/core/horizons_stack.cpp b/src/geode/geosciences/implicit/representation/core/horizons_stack.cpp index db9d6104..31477e38 100644 --- a/src/geode/geosciences/implicit/representation/core/horizons_stack.cpp +++ b/src/geode/geosciences/implicit/representation/core/horizons_stack.cpp @@ -23,11 +23,43 @@ #include +#include +#include + #include #include namespace geode { + template < index_t dimension > + class HorizonsStack< dimension >::Impl + { + public: + std::optional< uuid > top_horizon() const + { + return top_horizon_; + } + + std::optional< uuid > bottom_horizon() const + { + return bottom_horizon_; + } + + void set_top_horizon( uuid horizon_id ) + { + top_horizon_ = horizon_id; + } + + void set_bottom_horizon( uuid horizon_id ) + { + bottom_horizon_ = horizon_id; + } + + private: + std::optional< uuid > top_horizon_{ std::nullopt }; + std::optional< uuid > bottom_horizon_{ std::nullopt }; + }; + template < index_t dimension > HorizonsStack< dimension >::HorizonsStack() = default; @@ -56,15 +88,75 @@ namespace geode geode::StratigraphicUnit< dimension >::component_type_static(), detail::clone_stratigraphic_unit_mapping( *this ) ); clone_builder.copy( clone_mapping, *this ); + if( impl_->top_horizon() && impl_->bottom_horizon() ) + { + clone_builder.compute_top_and_bottom_horizons(); + } return stack_clone; } template < index_t dimension > - uuid HorizonsStack< dimension >::top_horizon() const + std::optional< uuid > HorizonsStack< dimension >::top_horizon() const + { + return impl_->top_horizon(); + } + + template < index_t dimension > + std::optional< uuid > HorizonsStack< dimension >::bottom_horizon() const + { + return impl_->bottom_horizon(); + } + + template < index_t dimension > + auto HorizonsStack< dimension >::bottom_to_top_horizons() const + -> HorizonOrderedRange + { + OPENGEODE_EXCEPTION( impl_->top_horizon() && impl_->bottom_horizon(), + "[HorizonsStack::bottom_to_top_horizons] Cannot iterate on " + "HorizonsStack: top and bottom horizons have not been computed." ); + return { *this }; + } + + template < index_t dimension > + auto HorizonsStack< dimension >::bottom_to_top_units() const + -> StratigraphicUnitOrderedRange + { + OPENGEODE_EXCEPTION( impl_->top_horizon() && impl_->bottom_horizon(), + "[HorizonsStack::bottom_to_top_units] Cannot iterate on " + "HorizonsStack: top and bottom horizons have not been computed." ); + return { *this }; + } + + template < index_t dimension > + bool HorizonsStack< dimension >::is_eroded_by( + const StratigraphicUnit< dimension >& eroded, + const Horizon< dimension >& erosion ) const + { + return StratigraphicRelationships::is_eroded_by( + eroded.id(), erosion.id() ); + } + + template < index_t dimension > + bool HorizonsStack< dimension >::is_baselap_of( + const Horizon< dimension >& baselap, + const StratigraphicUnit< dimension >& baselap_top ) const { - OPENGEODE_EXCEPTION( this->nb_horizons() != 0, - "[HorizonsStack::top_horizon] Cannot determine top horizon: " - "no horizons were provided in the HorizonsStack." ); + return StratigraphicRelationships::is_baselap_of( + baselap.id(), baselap_top.id() ); + } + + template < index_t dimension > + void HorizonsStack< dimension >::compute_top_and_bottom_horizons( + HorizonsStackBuilderKey /*unused*/ ) + { + if( this->nb_horizons() == 0 ) + { + Logger::warn( + "[HorizonsStack::compute_top_and_bottom_horizons] No horizons " + "were provided in the HorizonsStack, top and bottom horizons " + "will be set to std::nullopt." ); + return; + } auto current_horizon_id = ( *this->horizons().begin() ).id(); while( const auto su_above = this->above( current_horizon_id ) ) { @@ -75,16 +167,7 @@ namespace geode } current_horizon_id = horizon_above.value(); } - return current_horizon_id; - } - - template < index_t dimension > - uuid HorizonsStack< dimension >::bottom_horizon() const - { - OPENGEODE_EXCEPTION( this->nb_horizons() != 0, - "[HorizonsStack::bottom_horizon] Cannot determine bottom horizon: " - "no horizons were provided in the HorizonsStack." ); - auto current_horizon_id = ( *this->horizons().begin() ).id(); + impl_->set_top_horizon( current_horizon_id ); while( const auto su_under = this->under( current_horizon_id ) ) { const auto horizon_under = this->under( su_under.value() ); @@ -94,25 +177,177 @@ namespace geode } current_horizon_id = horizon_under.value(); } - return current_horizon_id; + impl_->set_bottom_horizon( current_horizon_id ); } template < index_t dimension > - bool HorizonsStack< dimension >::is_eroded_by( - const StratigraphicUnit< dimension >& eroded, - const Horizon< dimension >& erosion ) const + void HorizonsStack< dimension >::set_top_horizon( + const uuid& horizon_id, HorizonsStackBuilderKey /*unused*/ ) { - return StratigraphicRelationships::is_eroded_by( - eroded.id(), erosion.id() ); + impl_->set_top_horizon( horizon_id ); } template < index_t dimension > - bool HorizonsStack< dimension >::is_baselap_of( - const Horizon< dimension >& baselap, - const StratigraphicUnit< dimension >& baselap_top ) const + void HorizonsStack< dimension >::set_bottom_horizon( + const uuid& horizon_id, HorizonsStackBuilderKey /*unused*/ ) { - return StratigraphicRelationships::is_baselap_of( - baselap.id(), baselap_top.id() ); + impl_->set_bottom_horizon( horizon_id ); + } + + template < index_t dimension > + class HorizonsStack< dimension >::HorizonOrderedRange::Impl + { + public: + Impl( const HorizonsStack< dimension >& stack ) + : stack_( stack ), iter_( stack.bottom_horizon().value() ) + { + } + + constexpr bool operator!=( const Impl& /*unused*/ ) const + { + return stack_.has_horizon( iter_ ); + } + + void operator++() + { + if( iter_ != stack_.top_horizon().value() ) + { + iter_ = stack_.above( stack_.above( iter_ ).value() ).value(); + return; + } + iter_ = uuid{}; + } + + const Horizon< dimension >& current_horizon() const + { + return stack_.horizon( iter_ ); + } + + private: + const HorizonsStack< dimension >& stack_; + uuid iter_; + }; + + template < index_t dimension > + HorizonsStack< dimension >::HorizonOrderedRange::HorizonOrderedRange( + const HorizonsStack& horizons_stack ) + : impl_( horizons_stack ) + { + } + + template < index_t dimension > + HorizonsStack< dimension >::HorizonOrderedRange::HorizonOrderedRange( + HorizonOrderedRange&& ) noexcept = default; + + template < index_t dimension > + HorizonsStack< dimension >::HorizonOrderedRange::HorizonOrderedRange( + const HorizonOrderedRange& other ) + : impl_( *other.impl_ ) + { + } + + template < index_t dimension > + HorizonsStack< dimension >::HorizonOrderedRange::~HorizonOrderedRange() = + default; + + template < index_t dimension > + bool HorizonsStack< dimension >::HorizonOrderedRange::operator!=( + const HorizonOrderedRange& /*unused*/ ) const + { + return impl_->operator!=( *impl_ ); + } + + template < index_t dimension > + void HorizonsStack< dimension >::HorizonOrderedRange::operator++() + { + return impl_->operator++(); + } + + template < index_t dimension > + const Horizon< dimension >& + HorizonsStack< dimension >::HorizonOrderedRange::operator*() const + { + return impl_->current_horizon(); + } + + template < index_t dimension > + class HorizonsStack< dimension >::StratigraphicUnitOrderedRange::Impl + { + public: + Impl( const HorizonsStack< dimension >& stack ) + : stack_( stack ), + iter_( stack.under( stack.bottom_horizon().value() ).value() ) + { + } + + constexpr bool operator!=( const Impl& /*unused*/ ) const + { + return stack_.has_stratigraphic_unit( iter_ ); + } + + void operator++() + { + if( iter_ != stack_.above( stack_.top_horizon().value() ).value() ) + { + iter_ = stack_.above( stack_.above( iter_ ).value() ).value(); + return; + } + iter_ = uuid{}; + } + + const StratigraphicUnit< dimension >& current_stratigraphic_unit() const + { + return stack_.stratigraphic_unit( iter_ ); + } + + private: + const HorizonsStack< dimension >& stack_; + uuid iter_; + }; + + template < index_t dimension > + HorizonsStack< dimension >::StratigraphicUnitOrderedRange:: + StratigraphicUnitOrderedRange( const HorizonsStack& horizons_stack ) + : impl_( horizons_stack ) + { + } + + template < index_t dimension > + HorizonsStack< dimension >::StratigraphicUnitOrderedRange:: + StratigraphicUnitOrderedRange( + StratigraphicUnitOrderedRange&& ) noexcept = default; + + template < index_t dimension > + HorizonsStack< dimension >::StratigraphicUnitOrderedRange:: + StratigraphicUnitOrderedRange( + const StratigraphicUnitOrderedRange& other ) + : impl_( *other.impl_ ) + { + } + + template < index_t dimension > + HorizonsStack< dimension >::StratigraphicUnitOrderedRange:: + ~StratigraphicUnitOrderedRange() = default; + + template < index_t dimension > + bool HorizonsStack< dimension >::StratigraphicUnitOrderedRange::operator!=( + const StratigraphicUnitOrderedRange& /*unused*/ ) const + { + return impl_->operator!=( *impl_ ); + } + + template < index_t dimension > + void HorizonsStack< dimension >::StratigraphicUnitOrderedRange::operator++() + { + return impl_->operator++(); + } + + template < index_t dimension > + const StratigraphicUnit< dimension >& + HorizonsStack< dimension >::StratigraphicUnitOrderedRange::operator*() + const + { + return impl_->current_stratigraphic_unit(); } template class opengeode_geosciences_implicit_api HorizonsStack< 2 >; diff --git a/tests/implicit/test-horizons-stack.cpp b/tests/implicit/test-horizons-stack.cpp index f2b90a30..af096015 100644 --- a/tests/implicit/test-horizons-stack.cpp +++ b/tests/implicit/test-horizons-stack.cpp @@ -48,13 +48,13 @@ void test_horizons_stack() "[Test] Horizons Stack should have 3 horizons." ); OPENGEODE_EXCEPTION( horizons_stack.nb_stratigraphic_units() == 2, "[Test] Horizons Stack should have 2 Stratigraphic Units." ); - stack_builder.add_horizon_under( horizons_stack.horizon( hor0 ), + stack_builder.set_horizon_under( horizons_stack.horizon( hor0 ), horizons_stack.stratigraphic_unit( unit0 ) ); - stack_builder.add_horizon_above( horizons_stack.horizon( hor1 ), + stack_builder.set_horizon_above( horizons_stack.horizon( hor1 ), horizons_stack.stratigraphic_unit( unit0 ) ); - stack_builder.add_horizon_under( horizons_stack.horizon( hor1 ), + stack_builder.set_horizon_under( horizons_stack.horizon( hor1 ), horizons_stack.stratigraphic_unit( unit1 ) ); - stack_builder.add_horizon_above( horizons_stack.horizon( hor2 ), + stack_builder.set_horizon_above( horizons_stack.horizon( hor2 ), horizons_stack.stratigraphic_unit( unit1 ) ); for( const auto& unit : horizons_stack.stratigraphic_units() ) @@ -108,11 +108,11 @@ void test_create_horizons_stack() const auto horizons_stack = geode::detail::horizons_stack_from_name_list< 2 >( horizons_list, units_list ); - OPENGEODE_EXCEPTION( horizons_stack.nb_horizons() == 3, + OPENGEODE_EXCEPTION( horizons_stack.nb_horizons() == 4, "[Test] Created Horizons Stack should have 4 horizons." ); OPENGEODE_EXCEPTION( horizons_stack.nb_stratigraphic_units() == 5, "[Test] Created Horizons Stack should have 5 Stratigraphic Units." ); - const auto bot_horizon = horizons_stack.bottom_horizon(); + const auto bot_horizon = horizons_stack.bottom_horizon().value(); OPENGEODE_EXCEPTION( horizons_stack.horizon( bot_horizon ).name() == horizons_list[0], "[Test] Wrong name for bottom horizon." ); @@ -134,6 +134,30 @@ void test_create_horizons_stack() top_horizon_id && top_horizon_id.value() == horizons_stack.top_horizon(), "[Test] Should have found top horizon from last horizon name" ); + geode::index_t counter{ 0 }; + for( const auto& horizon : horizons_stack.bottom_to_top_horizons() ) + { + OPENGEODE_EXCEPTION( horizon.name() == horizons_list[counter], + "[Test] Should have found horizon ", horizons_list[counter], + " as horizon number ", counter, ", not ", horizon.name() ); + counter++; + } + OPENGEODE_EXCEPTION( + counter == 4, "[Test] Range did not pass through all horizons" ); + counter = 0; + for( const auto& s_unit : horizons_stack.bottom_to_top_units() ) + { + if( counter != 0 && counter < 4 ) + { + OPENGEODE_EXCEPTION( s_unit.name() == units_list[counter - 1], + "[Test] Should have found stratigraphic unit ", + units_list[counter - 1], " as unit number ", counter, ", not ", + s_unit.name() ); + } + counter++; + } + OPENGEODE_EXCEPTION( counter == 5, + "[Test] Range did not pass through all stratigraphic units" ); } int main() @@ -143,6 +167,7 @@ int main() geode::Logger::info( "Starting test" ); geode::GeosciencesImplicitLibrary::initialize(); test_horizons_stack(); + test_create_horizons_stack(); geode::Logger::info( "TEST SUCCESS" ); return 0; diff --git a/tests/implicit/test-stratigraphic-model.cpp b/tests/implicit/test-stratigraphic-model.cpp index e9e300bc..54faa754 100644 --- a/tests/implicit/test-stratigraphic-model.cpp +++ b/tests/implicit/test-stratigraphic-model.cpp @@ -71,7 +71,7 @@ void add_horizons_stack_to_model( { if( model.horizon_implicit_value( horizon ).value() == 3 ) { - horizons_stack_builder.add_horizon_above( + horizons_stack_builder.set_horizon_above( horizon, model.stratigraphic_unit( unit_id ) ); } }