2929
3030#include < geode/mesh/builder/hybrid_solid_builder.hpp>
3131#include < geode/mesh/builder/tetrahedral_solid_builder.hpp>
32+ #include < geode/mesh/core/detail/geode_elements.hpp>
3233#include < geode/mesh/core/hybrid_solid.hpp>
3334#include < geode/mesh/core/light_regular_grid.hpp>
3435#include < geode/mesh/core/regular_grid_solid.hpp>
3940
4041namespace
4142{
43+ std::array< geode::index_t , 8 > grid_cell_vertices (
44+ const geode::Grid3D& grid,
45+ const geode::Grid3D::CellIndices& cell_indices )
46+ {
47+ std::array< geode::index_t , 8 > cell_vertices;
48+ const auto vertex_indices = grid.cell_vertices ( cell_indices );
49+ for ( const auto v : geode::LIndices{ cell_vertices } )
50+ {
51+ cell_vertices[v] = grid.vertex_index ( vertex_indices[v] );
52+ }
53+ return cell_vertices;
54+ }
55+
4256 bool all_polyhedra_are_simplex ( const geode::SolidMesh3D& solid )
4357 {
4458 for ( const auto p : geode::Range{ solid.nb_polyhedra () } )
@@ -104,6 +118,36 @@ namespace
104118 return tetras;
105119 }
106120
121+ std::array< geode::index_t , 6 > create_pyramid_pattern (
122+ geode::HybridSolidBuilder3D& builder,
123+ const geode::Grid3D& grid,
124+ const geode::Grid3D::CellIndices& cell_indices,
125+ geode::index_t additional_vertex_id )
126+ {
127+ std::array< geode::index_t , 6 > pyramids;
128+ const auto cell_vertices = grid.cell_vertices ( cell_indices );
129+ std::array< geode::index_t , 8 > cell_mesh_vertices;
130+ for ( const auto v : geode::LIndices{ cell_mesh_vertices } )
131+ {
132+ const auto cell_vertex_id = grid.vertex_index ( cell_vertices[v] );
133+ cell_mesh_vertices[v] = cell_vertex_id;
134+ }
135+ for ( const auto p : geode::LIndices{ pyramids } )
136+ {
137+ pyramids[p] = builder.create_pyramid (
138+ { cell_mesh_vertices
139+ [geode::detail::HEXAHEDRON_FACET_VERTICES[p][0 ]],
140+ cell_mesh_vertices
141+ [geode::detail::HEXAHEDRON_FACET_VERTICES[p][1 ]],
142+ cell_mesh_vertices
143+ [geode::detail::HEXAHEDRON_FACET_VERTICES[p][2 ]],
144+ cell_mesh_vertices
145+ [geode::detail::HEXAHEDRON_FACET_VERTICES[p][3 ]],
146+ additional_vertex_id } );
147+ }
148+ return pyramids;
149+ }
150+
107151 std::array< geode::index_t , 6 > create_tetrahedra_from_pIpI_pattern (
108152 geode::TetrahedralSolidBuilder3D& builder,
109153 const geode::Grid3D& grid,
@@ -191,8 +235,55 @@ namespace
191235 grid.cell_attribute_manager (), old2new_mapping );
192236 }
193237
194- void create_vertices_from_grid ( const geode::TetrahedralSolid3D& tet_solid,
195- geode::TetrahedralSolidBuilder3D& builder,
238+ void create_hexahedra_from_grid_cells ( const geode::HybridSolid3D& solid,
239+ geode::HybridSolidBuilder3D& builder,
240+ const geode::Grid3D& grid,
241+ absl::Span< const geode::index_t > cells_to_densify )
242+ {
243+ std::vector< bool > to_densify ( grid.nb_cells (), false );
244+ for ( const auto & cell_id : cells_to_densify )
245+ {
246+ to_densify[cell_id] = true ;
247+ }
248+ geode::GenericMapping< geode::index_t > old2new_mapping;
249+ for ( const auto k : geode::Range{ grid.nb_cells_in_direction ( 2 ) } )
250+ {
251+ for ( const auto j :
252+ geode::Range{ grid.nb_cells_in_direction ( 1 ) } )
253+ {
254+ for ( const auto i :
255+ geode::Range{ grid.nb_cells_in_direction ( 0 ) } )
256+ {
257+ const auto cell_id = grid.cell_index ( { i, j, k } );
258+ if ( to_densify[cell_id] )
259+ {
260+ continue ;
261+ }
262+ const auto hex_id = builder.create_hexahedron (
263+ grid_cell_vertices ( grid, { i, j, k } ) );
264+ old2new_mapping.map ( cell_id, hex_id );
265+ }
266+ }
267+ }
268+ for ( const auto cell_index : geode::Indices{ cells_to_densify } )
269+ {
270+ const auto cell_indices =
271+ grid.cell_indices ( cells_to_densify[cell_index] );
272+ const auto additional_vertex_id =
273+ grid.nb_grid_vertices () + cell_index;
274+ for ( const auto tetra_id : create_pyramid_pattern (
275+ builder, grid, cell_indices, additional_vertex_id ) )
276+ {
277+ old2new_mapping.map ( cells_to_densify[cell_index], tetra_id );
278+ }
279+ }
280+ builder.compute_polyhedron_adjacencies ();
281+ solid.polyhedron_attribute_manager ().import (
282+ grid.cell_attribute_manager (), old2new_mapping );
283+ }
284+
285+ void create_vertices_from_grid ( const geode::SolidMesh3D& solid,
286+ geode::SolidMeshBuilder3D& builder,
196287 const geode::Grid3D& grid,
197288 absl::Span< const geode::index_t > cells_to_densify )
198289 {
@@ -203,7 +294,7 @@ namespace
203294 builder.set_point ( vertex_id,
204295 grid.grid_point ( grid.vertex_indices ( vertex_id ) ) );
205296 }
206- auto & solid_attribute_manager = tet_solid .vertex_attribute_manager ();
297+ auto & solid_attribute_manager = solid .vertex_attribute_manager ();
207298 geode::internal::copy_attributes (
208299 grid.grid_vertex_attribute_manager (), solid_attribute_manager );
209300 geode::index_t counter{ grid.nb_grid_vertices () };
@@ -240,6 +331,18 @@ namespace
240331 return tet_solid;
241332 }
242333
334+ std::unique_ptr< geode::HybridSolid3D > create_hybrid_solid_from_grid (
335+ const geode::Grid3D& grid,
336+ absl::Span< const geode::index_t > cells_to_densify )
337+ {
338+ auto solid = geode::HybridSolid3D::create ();
339+ auto builder = geode::HybridSolidBuilder3D::create ( *solid );
340+ create_vertices_from_grid ( *solid, *builder, grid, cells_to_densify );
341+ create_hexahedra_from_grid_cells (
342+ *solid, *builder, grid, cells_to_densify );
343+ return solid;
344+ }
345+
243346 bool all_polyhedra_are_hybrid ( const geode::SolidMesh3D& solid )
244347 {
245348 for ( const auto p : geode::Range{ solid.nb_polyhedra () } )
@@ -473,6 +576,12 @@ namespace geode
473576 return create_tetrahedral_solid_from_grid ( grid, {} );
474577 }
475578
579+ std::unique_ptr< HybridSolid3D > convert_grid_into_hybrid_solid (
580+ const Grid3D& grid )
581+ {
582+ return create_hybrid_solid_from_grid ( grid, {} );
583+ }
584+
476585 std::unique_ptr< TetrahedralSolid3D >
477586 convert_grid_into_densified_tetrahedral_solid ( const Grid3D& grid,
478587 absl::Span< const geode::index_t > cells_to_densify )
0 commit comments