38 #include <geogram/basic/attributes.h> 65 double tetra_insphere_radius(
68 double tet_volume = GEO::Geom::tetra_volume( v0, v1, v2, v3 );
69 double A1 = GEO::Geom::triangle_area( v0, v1, v2 );
70 double A2 = GEO::Geom::triangle_area( v1, v2, v3 );
71 double A3 = GEO::Geom::triangle_area( v2, v3, v0 );
72 double A4 = GEO::Geom::triangle_area( v3, v0, v1 );
74 return ( 3 * tet_volume ) / ( A1 + A2 + A3 + A4 );
93 double tet_quality_insphere_radius_by_circumsphere_radius(
96 const vec3 tetra_circum_center =
97 GEO::Geom::tetra_circum_center( v0, v1, v2, v3 );
98 const double tetra_circum_radius =
99 vec3( tetra_circum_center - v0 ).length();
101 - ( tetra_circum_center - v1 ).length() )
104 - ( tetra_circum_center - v2 ).length() )
107 - ( tetra_circum_center - v3 ).length() )
111 double in_radius = tetra_insphere_radius( v0, v1, v2, v3 );
112 return 3. * in_radius / tetra_circum_radius;
122 double max_tet_edge_length(
125 double l1 = ( v1 - v0 ).length();
126 double l2 = ( v2 - v0 ).length();
127 double l3 = ( v3 - v0 ).length();
128 double l4 = ( v2 - v1 ).length();
129 double l5 = ( v3 - v1 ).length();
130 double l6 = ( v3 - v2 ).length();
133 GEO::geo_max( GEO::geo_max( GEO::geo_max( l1, l2 ), l3 ), l4 ),
161 double tet_quality_insphere_radius_by_max_edge_length(
164 double in_radius = tetra_insphere_radius( v0, v1, v2, v3 );
165 double edge_length = max_tet_edge_length( v0, v1, v2, v3 );
167 return 2 * std::sqrt( 6. ) * in_radius / edge_length;
177 double sum_square_edge_length(
180 double l1 =
vec3( v1 - v0 ).length2();
181 double l2 =
vec3( v2 - v0 ).length2();
182 double l3 =
vec3( v3 - v0 ).length2();
183 double l4 =
vec3( v2 - v1 ).length2();
184 double l5 =
vec3( v3 - v1 ).length2();
185 double l6 =
vec3( v3 - v2 ).length2();
186 return l1 + l2 + l3 + l4 + l5 + l6;
207 double tet_quality_volume_by_sum_square_edges(
210 const double tet_volume = GEO::Geom::tetra_volume( v0, v1, v2, v3 );
211 double sum_square_edge = sum_square_edge_length( v0, v1, v2, v3 );
213 return 12. * std::pow( 3. * tet_volume, 2. / 3. ) / sum_square_edge;
227 double sin_half_solid_angle(
230 double tet_volume = GEO::Geom::tetra_volume( v0, v1, v2, v3 );
231 double l01 = ( v1 - v0 ).length();
232 double l02 = ( v2 - v0 ).length();
233 double l03 = ( v3 - v0 ).length();
234 double l12 = ( v2 - v1 ).length();
235 double l13 = ( v3 - v1 ).length();
236 double l23 = ( v3 - v2 ).length();
237 double denominator = ( l01 + l02 + l12 ) * ( l01 + l02 - l12 )
238 * ( l02 + l03 + l23 ) * ( l02 + l03 - l23 )
239 * ( l03 + l01 + l13 ) * ( l03 + l01 - l13 );
243 denominator = std::sqrt( denominator );
244 return 12 * tet_volume / denominator;
276 double tet_quality_min_solid_angle(
279 double min_sin_half_solid_angle = std::min(
280 std::min( std::min( sin_half_solid_angle( v0, v1, v2, v3 ),
281 sin_half_solid_angle( v1, v0, v2, v3 ) ),
282 sin_half_solid_angle( v2, v0, v1, v3 ) ),
283 sin_half_solid_angle( v3, v0, v1, v2 ) );
284 return 1.5 * std::sqrt( 6. ) * min_sin_half_solid_angle;
292 std::string mesh_qual_mode_to_prop_name(
MeshQualityMode mesh_qual_mode )
294 std::string quality_name =
"";
295 switch( mesh_qual_mode )
298 quality_name =
"INSPHERE_RADIUS_BY_CIRCUMSPHERE_RADIUS";
301 quality_name =
"INSPHERE_RADIUS_BY_MAX_EDGE_LENGTH";
304 quality_name =
"VOLUME_BY_SUM_SQUARE_EDGE";
307 quality_name =
"MIN_SOLID_ANGLE";
329 double get_tet_quality(
const vec3& v0,
336 switch( mesh_qual_mode )
339 quality = tet_quality_insphere_radius_by_circumsphere_radius(
343 quality = tet_quality_insphere_radius_by_max_edge_length(
347 quality = tet_quality_volume_by_sum_square_edges( v0, v1, v2, v3 );
350 quality = tet_quality_min_solid_angle( v0, v1, v2, v3 );
356 quality > -1 * global_epsilon && quality < 1 + global_epsilon );
367 for(
const auto& region : geomodel.regions() )
371 GEO::AttributesManager& reg_attr_mgr =
372 region.cell_attribute_manager();
373 GEO::Attribute< double > attr(
374 reg_attr_mgr, mesh_qual_mode_to_prop_name( mesh_qual_mode ) );
375 for(
auto cell_itr :
range( region.nb_mesh_elements() ) )
378 get_tet_quality( region.mesh_element_vertex(
380 region.mesh_element_vertex(
382 region.mesh_element_vertex(
384 region.mesh_element_vertex(
void RINGMESH_API compute_prop_tet_mesh_quality(MeshQualityMode mesh_qual_mode, const GeoModel3D &geomodel)
Computes and stores mesh quality in the GeoModel.
#define ringmesh_assert(x)
Classes to build GeoModel from various inputs.
#define ringmesh_assert_not_reached