@@ -458,7 +458,7 @@ namespace geode
458458 }
459459
460460 std::optional< PolyhedronVertex > polyhedron_around_vertex (
461- const index_t vertex_id ) const
461+ index_t vertex_id ) const
462462 {
463463 const auto & value = polyhedron_around_vertex_->value ( vertex_id );
464464 if ( value.polyhedron_id != NO_ID )
@@ -468,6 +468,46 @@ namespace geode
468468 return std::nullopt ;
469469 }
470470
471+ double polyhedron_minimum_height (
472+ const geode::SolidMesh< dimension >& mesh,
473+ const index_t polyhedron_id ) const
474+ {
475+ double max_area{ 0 . };
476+ local_index_t max_area_facet{ 0 };
477+ for ( const auto f :
478+ LRange{ mesh.nb_polyhedron_facets ( polyhedron_id ) } )
479+ {
480+ const auto cur_area =
481+ mesh.polyhedron_facet_area ( { polyhedron_id, f } );
482+ if ( cur_area > max_area )
483+ {
484+ max_area = cur_area;
485+ max_area_facet = f;
486+ }
487+ }
488+ const auto vertices = mesh.polyhedron_vertices ( polyhedron_id );
489+ const auto normal = mesh.polyhedron_facet_normal (
490+ { polyhedron_id, max_area_facet } );
491+ if ( !normal )
492+ {
493+ return true ;
494+ }
495+ const auto facet_vertices = mesh.polyhedron_facet_vertices (
496+ { polyhedron_id, max_area_facet } );
497+ Plane plane{ normal.value (), mesh.point ( facet_vertices[0 ] ) };
498+ auto opposite_vertex{ 0 };
499+ for ( const auto vertex_id : vertices )
500+ {
501+ if ( absl::c_contains ( facet_vertices, vertex_id ) )
502+ {
503+ continue ;
504+ }
505+ opposite_vertex = vertex_id;
506+ }
507+ return std::get< 0 >(
508+ point_plane_distance ( mesh.point ( opposite_vertex ), plane ) );
509+ }
510+
471511 void reset_polyhedra_around_vertex ( index_t vertex_id )
472512 {
473513 polyhedra_around_vertex_->modify_value (
@@ -960,41 +1000,7 @@ namespace geode
9601000 bool SolidMesh< dimension >::is_polyhedron_degenerated(
9611001 index_t polyhedron_id ) const
9621002 {
963- double max_area{ 0 . };
964- local_index_t max_area_facet{ 0 };
965- for ( const auto f : LRange{ nb_polyhedron_facets ( polyhedron_id ) } )
966- {
967- const auto cur_area = polyhedron_facet_area ( { polyhedron_id, f } );
968- if ( cur_area > max_area )
969- {
970- max_area = cur_area;
971- max_area_facet = f;
972- }
973- }
974- const auto vertices = polyhedron_vertices ( polyhedron_id );
975- const auto normal =
976- polyhedron_facet_normal ( { polyhedron_id, max_area_facet } );
977- if ( !normal )
978- {
979- return true ;
980- }
981- const auto facet_vertices =
982- polyhedron_facet_vertices ( { polyhedron_id, max_area_facet } );
983- Plane plane{ normal.value (), this ->point ( facet_vertices[0 ] ) };
984- for ( const auto vertex_id : vertices )
985- {
986- if ( absl::c_contains ( facet_vertices, vertex_id ) )
987- {
988- continue ;
989- }
990- if ( std::get< 0 >(
991- point_plane_distance ( this ->point ( vertex_id ), plane ) )
992- > GLOBAL_EPSILON )
993- {
994- return false ;
995- }
996- }
997- return true ;
1003+ return polyhedron_minimum_height ( polyhedron_id ) < GLOBAL_EPSILON;
9981004 }
9991005
10001006 template < index_t dimension >
@@ -1358,6 +1364,13 @@ namespace geode
13581364 return get_polyhedron_around_vertex ( vertex_id );
13591365 }
13601366
1367+ template < index_t dimension >
1368+ double SolidMesh< dimension >::polyhedron_minimum_height(
1369+ const index_t polyhedron_id ) const
1370+ {
1371+ return impl_->polyhedron_minimum_height ( *this , polyhedron_id );
1372+ }
1373+
13611374 template < index_t dimension >
13621375 std::optional< PolyhedronVertex >
13631376 SolidMesh< dimension >::get_polyhedron_around_vertex(
0 commit comments