From 26bde533e3132e14670be69c1b4d65ce148049ac Mon Sep 17 00:00:00 2001 From: Pierre Anquez Date: Tue, 6 Jan 2026 10:04:16 +0100 Subject: [PATCH] fix(Model): add API helper function to create a surface BRep from a given BoundingBox3D --- .../model/helpers/simplicial_brep_creator.hpp | 5 ++ .../model/helpers/simplicial_brep_creator.cpp | 86 +++++++++++++++++++ tests/model/test-model-creator.cpp | 39 ++++++--- 3 files changed, 120 insertions(+), 10 deletions(-) diff --git a/include/geode/model/helpers/simplicial_brep_creator.hpp b/include/geode/model/helpers/simplicial_brep_creator.hpp index 97a4bac97..a6c4895fe 100644 --- a/include/geode/model/helpers/simplicial_brep_creator.hpp +++ b/include/geode/model/helpers/simplicial_brep_creator.hpp @@ -33,7 +33,9 @@ namespace geode { FORWARD_DECLARATION_DIMENSION_CLASS( Point ); + FORWARD_DECLARATION_DIMENSION_CLASS( BoundingBox ); ALIAS_3D( Point ); + ALIAS_3D( BoundingBox ); class BRep; struct uuid; } // namespace geode @@ -76,4 +78,7 @@ namespace geode private: IMPLEMENTATION_MEMBER( impl_ ); }; + + BRep opengeode_model_api create_model_from_bounding_box( + const BoundingBox3D& box ); } // namespace geode \ No newline at end of file diff --git a/src/geode/model/helpers/simplicial_brep_creator.cpp b/src/geode/model/helpers/simplicial_brep_creator.cpp index 731875109..5fb4054ad 100644 --- a/src/geode/model/helpers/simplicial_brep_creator.cpp +++ b/src/geode/model/helpers/simplicial_brep_creator.cpp @@ -25,6 +25,9 @@ #include +#include +#include + #include #include @@ -33,6 +36,73 @@ #include #include +namespace +{ + std::vector< geode::Point3D > create_bbox_points( + const geode::BoundingBox3D& bbox ) + { + std::vector< geode::Point3D > points; + points.reserve( 8 ); + points.emplace_back( bbox.min() ); + points.emplace_back( geode::Point3D{ { bbox.max().value( 0 ), + bbox.min().value( 1 ), bbox.min().value( 2 ) } } ); + points.emplace_back( geode::Point3D{ { bbox.max().value( 0 ), + bbox.max().value( 1 ), bbox.min().value( 2 ) } } ); + points.emplace_back( geode::Point3D{ { bbox.min().value( 0 ), + bbox.max().value( 1 ), bbox.min().value( 2 ) } } ); + points.emplace_back( geode::Point3D{ { bbox.min().value( 0 ), + bbox.min().value( 1 ), bbox.max().value( 2 ) } } ); + points.emplace_back( geode::Point3D{ { bbox.max().value( 0 ), + bbox.min().value( 1 ), bbox.max().value( 2 ) } } ); + points.emplace_back( bbox.max() ); + points.emplace_back( geode::Point3D{ { bbox.min().value( 0 ), + bbox.max().value( 1 ), bbox.max().value( 2 ) } } ); + return points; + } + + std::vector< geode::CornerDefinition > create_corner_definitions() + { + return std::vector< geode::CornerDefinition >{ { 0 }, { 1 }, { 2 }, + { 3 }, { 4 }, { 5 }, { 6 }, { 7 } }; + } + + std::vector< geode::LineDefinition > create_line_definitions() + { + return std::vector< geode::LineDefinition >{ + { { 0, 1 } }, + { { 1, 2 } }, + { { 2, 3 } }, + { { 3, 0 } }, + { { 4, 5 } }, + { { 5, 6 } }, + { { 6, 7 } }, + { { 7, 4 } }, + { { 0, 4 } }, + { { 1, 5 } }, + { { 2, 6 } }, + { { 3, 7 } }, + }; + } + + std::vector< geode::SurfaceDefinition > create_surface_definitions() + { + return std::vector< geode::SurfaceDefinition >{ + { { 0, 1, 2, 3 }, { 0, 1, 2, 0, 2, 3 }, { 0, 1, 2, 3 }, {}, {} }, + { { 4, 5, 6, 7 }, { 0, 1, 2, 0, 2, 3 }, { 4, 5, 6, 7 }, {}, {} }, + { { 0, 1, 5, 4 }, { 0, 1, 2, 0, 2, 3 }, { 0, 9, 4, 8 }, {}, {} }, + { { 1, 2, 6, 5 }, { 0, 1, 2, 0, 2, 3 }, { 1, 10, 5, 9 }, {}, {} }, + { { 2, 3, 7, 6 }, { 0, 1, 2, 0, 2, 3 }, { 2, 11, 6, 10 }, {}, {} }, + { { 3, 0, 4, 7 }, { 0, 1, 2, 0, 2, 3 }, { 3, 8, 7, 11 }, {}, {} }, + }; + } + + std::vector< geode::BlockDefinition > create_block_definitions() + { + return std::vector< geode::BlockDefinition >{ { {}, {}, + { 0, 1, 2, 3, 4, 5 }, {}, {}, {} } }; + } +} // namespace + namespace geode { class SimplicialBRepCreator::Impl @@ -191,4 +261,20 @@ namespace geode { return impl_->create_model_boundaries( surfaces, definitions ); } + + BRep create_model_from_bounding_box( const BoundingBox3D& box ) + { + BRep brep; + const auto points = create_bbox_points( box ); + SimplicialBRepCreator creator{ brep, points }; + const auto corners = + creator.create_corners( create_corner_definitions() ); + const auto lines = + creator.create_lines( corners, create_line_definitions() ); + const auto surfaces = + creator.create_surfaces( lines, create_surface_definitions() ); + const auto blocks = + creator.create_blocks( surfaces, create_block_definitions() ); + return brep; + } } // namespace geode \ No newline at end of file diff --git a/tests/model/test-model-creator.cpp b/tests/model/test-model-creator.cpp index 89845ff17..f9d0363c6 100644 --- a/tests/model/test-model-creator.cpp +++ b/tests/model/test-model-creator.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -39,9 +40,20 @@ #include #include #include +#include +#include #include +void test_create_brep_from_bbox() +{ + geode::BoundingBox3D box; + box.add_point( geode::Point3D{ { 0, 0, 0 } } ); + box.add_point( geode::Point3D{ { 1, 1, 1 } } ); + const auto brep = geode::create_model_from_bounding_box( box ); + geode::save_brep( brep, "brep_from_bbox.og_brep" ); +} + void test_create_brep_with_dangling_components() { std::vector< geode::Point3D > points{ @@ -100,12 +112,12 @@ void test_create_brep_with_dangling_components() const auto line_uuids = creator.create_lines( corner_uuids, lines ); std::vector< geode::SurfaceDefinition > surfaces{ - { { 0, 1, 2, 3 }, { 0, 1, 2, 0, 3, 2 }, { 0, 1, 2, 3 }, {}, {} }, - { { 0, 1, 5, 4 }, { 0, 1, 2, 0, 3, 2 }, { 0, 4, 8, 9 }, {}, {} }, - { { 1, 2, 6, 5 }, { 0, 1, 2, 0, 3, 2 }, { 1, 5, 9, 10 }, {}, {} }, - { { 2, 3, 7, 6 }, { 0, 1, 2, 0, 3, 2 }, { 2, 6, 10, 11 }, {}, {} }, - { { 0, 3, 7, 4 }, { 0, 1, 2, 0, 3, 2 }, { 3, 7, 11, 8 }, {}, {} }, - { { 4, 5, 6, 7 }, { 0, 1, 2, 0, 3, 2 }, {}, {}, {} }, + { { 0, 1, 2, 3 }, { 0, 1, 2, 0, 2, 3 }, { 0, 1, 2, 3 }, {}, {} }, + { { 0, 1, 5, 4 }, { 0, 1, 2, 0, 2, 3 }, { 0, 4, 8, 9 }, {}, {} }, + { { 1, 2, 6, 5 }, { 0, 1, 2, 0, 2, 3 }, { 1, 5, 9, 10 }, {}, {} }, + { { 2, 3, 7, 6 }, { 0, 1, 2, 0, 2, 3 }, { 2, 6, 10, 11 }, {}, {} }, + { { 0, 3, 7, 4 }, { 0, 1, 2, 0, 2, 3 }, { 3, 7, 11, 8 }, {}, {} }, + { { 4, 5, 6, 7 }, { 0, 1, 2, 0, 2, 3 }, {}, {}, {} }, { { 5, 6, 10, 9, 12 }, { 0, 1, 4, 1, 2, 4, 2, 3, 4, 3, 0, 4 }, { 5, 12, 13, 14 }, {}, { 12 } }, }; @@ -129,11 +141,11 @@ void test_create_brep_with_dangling_components() "[Test] Wrong number of corner embedding blocks" ); OPENGEODE_EXCEPTION( nb_embedding_surfaces == 1, "[Test] Wrong number of corner embedding surfaces" ); + geode::save_brep( brep, "test.og_brep" ); } -void test() +void test_section() { - geode::OpenGeodeModelLibrary::initialize(); std::vector< geode::Point2D > points{ geode::Point2D{ { 0, 0 } }, geode::Point2D{ { 1, 0 } }, @@ -198,8 +210,8 @@ void test() std::vector< geode::SurfaceDefinition > surface_definitions{ { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10 }, - { 0, 4, 7, 7, 4, 1, 1, 4, 8, 4, 10, 8, 8, 10, 5, 8, 5, 2, 2, 5, 9, - 9, 5, 3, 3, 5, 6, 6, 5, 11, 6, 11, 4, 6, 4, 0 }, + { 0, 7, 4, 7, 1, 4, 1, 8, 4, 4, 8, 10, 8, 5, 10, 8, 2, 5, 2, 9, 5, + 9, 3, 5, 3, 6, 5, 6, 11, 5, 6, 4, 11, 6, 0, 4 }, { 0, 1, 2, 3 }, { 4 }, {} }, }; const auto surfaces = creator.create_surfaces( lines, surface_definitions ); @@ -273,8 +285,15 @@ void test() found, "[Test] Missing Line in ModelBoundary" ); } } + geode::save_section( section, "test_section.og_sctn" ); +} +void test() +{ + geode::OpenGeodeModelLibrary::initialize(); + test_create_brep_from_bbox(); test_create_brep_with_dangling_components(); + test_section(); } OPENGEODE_TEST( "model-creator" ) \ No newline at end of file