diff --git a/bindings/python/tests/model/test-py-convert-to-mesh.py b/bindings/python/tests/model/test-py-convert-to-mesh.py index 6f71dbe00..fae249631 100644 --- a/bindings/python/tests/model/test-py-convert-to-mesh.py +++ b/bindings/python/tests/model/test-py-convert-to-mesh.py @@ -67,7 +67,7 @@ def run_test_section(): if curve.nb_edges() != 0: raise ValueError("[Test] Section - Wrong number of curve edges") - if surface.nb_vertices() != 1: + if surface.nb_vertices() != 4: raise ValueError("[Test] Section - Wrong number of surface vertices") if surface.nb_polygons() != 1: raise ValueError("[Test] Section - Wrong number of surface polygons") diff --git a/include/geode/model/helpers/convert_to_mesh.h b/include/geode/model/helpers/convert_to_mesh.h index ef18fb1c9..2575067de 100644 --- a/include/geode/model/helpers/convert_to_mesh.h +++ b/include/geode/model/helpers/convert_to_mesh.h @@ -45,6 +45,9 @@ namespace geode static constexpr auto uuid_from_conversion_attribute_name = "uuid_from_conversion"; using uuid_from_conversion_attribute_type = uuid; + static constexpr auto unique_vertex_from_conversion_attribute_name = + "unique_vertex_from_conversion"; + using unique_vertex_from_conversion_attribute_type = index_t; std::unique_ptr< EdgedCurve2D > opengeode_model_api convert_section_into_curve( const Section& section ); diff --git a/src/geode/model/helpers/convert_to_mesh.cpp b/src/geode/model/helpers/convert_to_mesh.cpp index 3bb8ef4c9..7f2ac1708 100644 --- a/src/geode/model/helpers/convert_to_mesh.cpp +++ b/src/geode/model/helpers/convert_to_mesh.cpp @@ -51,7 +51,12 @@ namespace class FromModel { public: - FromModel( const Model& model ) : model_( model ) {} + FromModel( const Model& model ) : model_( model ) + { + OPENGEODE_EXCEPTION( model.nb_unique_vertices() > 0, + "[Convert Model to Mesh(es)] Given model should have unique " + "vertices" ); + } const Model& model() const { @@ -71,6 +76,9 @@ namespace geode::index_t create_vertex( geode::index_t vertex_id ) { + OPENGEODE_EXCEPTION( vertex_id != geode::NO_ID, + "[Convert Model to Mesh(es)] At least one Component Mesh " + "Vertex is not link to a unique vertex" ); const geode::index_t new_id = vertices_.size(); vertices_.emplace( vertex_id, new_id ); return new_id; @@ -88,6 +96,12 @@ namespace return points; } + const absl::flat_hash_map< geode::index_t, geode::index_t >& + vertices() const + { + return vertices_; + } + private: const Model& model_; absl::flat_hash_map< geode::index_t, geode::index_t > vertices_; @@ -135,6 +149,10 @@ namespace const auto polyhedra = build_polyhedra( block ); set_polyhedra_adjacency( block, polyhedra ); } + for( const auto& v2uv : model_.vertices() ) + { + attribute_unique_vertex_->set_value( v2uv.first, v2uv.second ); + } } std::unique_ptr< SolidType > get_result() @@ -147,12 +165,21 @@ namespace : model_( model ), mesh_{ SolidType::create() }, builder_{ geode::SolidMeshBuilder3D::create( *mesh_ ) }, - attribute_{ mesh_->polyhedron_attribute_manager() - .template find_or_create_attribute< - geode::VariableAttribute, - geode::uuid_from_conversion_attribute_type >( - geode::uuid_from_conversion_attribute_name, - {} ) } + attribute_uuid_{ + mesh_->polyhedron_attribute_manager() + .template find_or_create_attribute< + geode::VariableAttribute, + geode::uuid_from_conversion_attribute_type >( + geode::uuid_from_conversion_attribute_name, {} ) + }, + attribute_unique_vertex_{ + mesh_->vertex_attribute_manager() + .template find_or_create_attribute< + geode::VariableAttribute, + geode::unique_vertex_from_conversion_attribute_type >( + geode::unique_vertex_from_conversion_attribute_name, + geode::NO_ID ) + } { } @@ -219,7 +246,7 @@ namespace } polyhedra[p] = builder_->create_polyhedron( polyhedron_vertices, polyhedron_facet_vertices ); - attribute_->set_value( polyhedra[p], block.id() ); + attribute_uuid_->set_value( polyhedra[p], block.id() ); } return polyhedra; } @@ -230,7 +257,10 @@ namespace std::unique_ptr< geode::SolidMeshBuilder3D > builder_; std::shared_ptr< geode::VariableAttribute< geode::uuid_from_conversion_attribute_type > > - attribute_; + attribute_uuid_; + std::shared_ptr< geode::VariableAttribute< + geode::unique_vertex_from_conversion_attribute_type > > + attribute_unique_vertex_; }; template < typename SurfaceType, typename Model, geode::index_t dimension > @@ -242,12 +272,21 @@ namespace mesh_{ SurfaceType::create() }, builder_{ geode::SurfaceMeshBuilder< dimension >::create( *mesh_ ) }, - attribute_{ mesh_->polygon_attribute_manager() - .template find_or_create_attribute< - geode::VariableAttribute, - geode::uuid_from_conversion_attribute_type >( - geode::uuid_from_conversion_attribute_name, - {} ) } + attribute_uuid_{ + mesh_->polygon_attribute_manager() + .template find_or_create_attribute< + geode::VariableAttribute, + geode::uuid_from_conversion_attribute_type >( + geode::uuid_from_conversion_attribute_name, {} ) + }, + attribute_unique_vertex_{ + mesh_->vertex_attribute_manager() + .template find_or_create_attribute< + geode::VariableAttribute, + geode::unique_vertex_from_conversion_attribute_type >( + geode::unique_vertex_from_conversion_attribute_name, + geode::NO_ID ) + } { } @@ -268,6 +307,10 @@ namespace const auto polygons = build_polygons( surface ); set_polygons_adjacency( surface, polygons ); } + for( const auto& v2uv : model_.vertices() ) + { + attribute_unique_vertex_->set_value( v2uv.first, v2uv.second ); + } } std::unique_ptr< SurfaceType > get_result() @@ -320,7 +363,7 @@ namespace } } polygons[p] = builder_->create_polygon( polygon ); - attribute_->set_value( polygons[p], surface.id() ); + attribute_uuid_->set_value( polygons[p], surface.id() ); } return polygons; } @@ -331,7 +374,10 @@ namespace std::unique_ptr< geode::SurfaceMeshBuilder< dimension > > builder_; std::shared_ptr< geode::VariableAttribute< geode::uuid_from_conversion_attribute_type > > - attribute_; + attribute_uuid_; + std::shared_ptr< geode::VariableAttribute< + geode::unique_vertex_from_conversion_attribute_type > > + attribute_unique_vertex_; }; template < typename SurfaceType > @@ -349,12 +395,21 @@ namespace mesh_{ geode::EdgedCurve< dimension >::create() }, builder_{ geode::EdgedCurveBuilder< dimension >::create( *mesh_ ) }, - attribute_{ mesh_->edge_attribute_manager() - .template find_or_create_attribute< - geode::VariableAttribute, - geode::uuid_from_conversion_attribute_type >( - geode::uuid_from_conversion_attribute_name, - {} ) } + attribute_uuid_{ + mesh_->edge_attribute_manager() + .template find_or_create_attribute< + geode::VariableAttribute, + geode::uuid_from_conversion_attribute_type >( + geode::uuid_from_conversion_attribute_name, {} ) + }, + attribute_unique_vertex_{ + mesh_->vertex_attribute_manager() + .template find_or_create_attribute< + geode::VariableAttribute, + geode::unique_vertex_from_conversion_attribute_type >( + geode::unique_vertex_from_conversion_attribute_name, + geode::NO_ID ) + } { } @@ -364,6 +419,10 @@ namespace { build_edges( line ); } + for( const auto& v2uv : model_.vertices() ) + { + attribute_unique_vertex_->set_value( v2uv.first, v2uv.second ); + } } std::unique_ptr< geode::EdgedCurve< dimension > > get_result() @@ -395,7 +454,7 @@ namespace } const auto edge = builder_->create_edge( vertices[0], vertices[1] ); - attribute_->set_value( edge, line.id() ); + attribute_uuid_->set_value( edge, line.id() ); } } @@ -405,7 +464,10 @@ namespace std::unique_ptr< geode::EdgedCurveBuilder< dimension > > builder_; std::shared_ptr< geode::VariableAttribute< geode::uuid_from_conversion_attribute_type > > - attribute_; + attribute_uuid_; + std::shared_ptr< geode::VariableAttribute< + geode::unique_vertex_from_conversion_attribute_type > > + attribute_unique_vertex_; }; using CurveFromBRep = CurveFromModel< geode::BRep, 3 >; diff --git a/tests/data/quad.og_sctn b/tests/data/quad.og_sctn index 94d2156c6..d5721e27b 100644 Binary files a/tests/data/quad.og_sctn and b/tests/data/quad.og_sctn differ diff --git a/tests/model/test-convert-to-mesh.cpp b/tests/model/test-convert-to-mesh.cpp index 21ece2da2..ba99a95da 100644 --- a/tests/model/test-convert-to-mesh.cpp +++ b/tests/model/test-convert-to-mesh.cpp @@ -40,7 +40,7 @@ void run_test_brep() { - auto model = + const auto model = geode::load_brep( absl::StrCat( geode::data_path, "layers.og_brep" ) ); const auto output = @@ -66,7 +66,7 @@ void run_test_brep() void run_test_section() { - auto model = + const auto model = geode::load_section( absl::StrCat( geode::data_path, "quad.og_sctn" ) ); const auto output = geode::convert_section_into_curve_and_surface( model ); @@ -77,7 +77,7 @@ void run_test_section() "[Test] Section - Wrong number of curve edges" ); const auto& surface = std::get< 1 >( output ); - OPENGEODE_EXCEPTION( surface->nb_vertices() == 1, + OPENGEODE_EXCEPTION( surface->nb_vertices() == 4, "[Test] Section - Wrong number of surface vertices" ); OPENGEODE_EXCEPTION( surface->nb_polygons() == 1, "[Test] Section - Wrong number of surface polygons" );