Blender V4.5
bmesh_polygon.cc File Reference
#include "DNA_modifier_types.h"
#include "BLI_alloca.h"
#include "BLI_linklist.h"
#include "BLI_math_base.hh"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
#include "BLI_memarena.h"
#include "BLI_polyfill_2d.h"
#include "BLI_polyfill_2d_beautify.h"
#include "bmesh.hh"
#include "bmesh_tools.hh"
#include "BKE_customdata.hh"
#include "intern/bmesh_private.hh"

Go to the source code of this file.

Macros

#define EDGE_SHARE_VERT(e1, e2)

Typedefs

using float3

Functions

static float bm_face_calc_poly_normal (const BMFace *f, float n[3])
 COMPUTE POLY NORMAL (BMFace).
static float bm_face_calc_poly_normal_vertex_cos (const BMFace *f, float r_no[3], const Span< float3 > vertexCos)
 COMPUTE POLY NORMAL (BMFace).
static void bm_face_calc_poly_center_median_vertex_cos (const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
 COMPUTE POLY CENTER (BMFace).
void BM_face_calc_tessellation (const BMFace *f, const bool use_fixed_quad, BMLoop **r_loops, uint(*r_index)[3])
void BM_face_calc_point_in_face (const BMFace *f, float r_co[3])
float BM_face_calc_area (const BMFace *f)
float BM_face_calc_area_with_mat3 (const BMFace *f, const float mat3[3][3])
float BM_face_calc_area_uv_signed (const BMFace *f, int cd_loop_uv_offset)
float BM_face_calc_area_uv (const BMFace *f, int cd_loop_uv_offset)
float BM_face_calc_perimeter (const BMFace *f)
float BM_face_calc_perimeter_with_mat3 (const BMFace *f, const float mat3[3][3])
static int bm_vert_tri_find_unique_edge (BMVert *verts[3])
void BM_vert_tri_calc_tangent_from_edge (BMVert *verts[3], float r_tangent[3])
void BM_vert_tri_calc_tangent_pair_from_edge (BMVert *verts[3], float r_tangent_a[3], float r_tangent_b[3])
void BM_vert_tri_calc_tangent_edge_pair (BMVert *verts[3], float r_tangent[3])
void BM_face_calc_tangent_from_edge (const BMFace *f, float r_tangent[3])
static void bm_face_calc_tangent_from_quad_edge_pair (const BMFace *f, float r_tangent[3])
static void bm_face_calc_tangent_pair_from_quad_edge_pair (const BMFace *f, float r_tangent_a[3], float r_tangent_b[3])
void BM_face_calc_tangent_pair_from_edge (const BMFace *f, float r_tangent_a[3], float r_tangent_b[3])
void BM_face_calc_tangent_from_edge_pair (const BMFace *f, float r_tangent[3])
void BM_face_calc_tangent_from_edge_diagonal (const BMFace *f, float r_tangent[3])
void BM_face_calc_tangent_from_vert_diagonal (const BMFace *f, float r_tangent[3])
void BM_face_calc_tangent_auto (const BMFace *f, float r_tangent[3])
void BM_face_calc_tangent_pair_auto (const BMFace *f, float r_tangent_a[3], float r_tangent_b[3])
void BM_face_calc_bounds_expand (const BMFace *f, float min[3], float max[3])
void BM_face_calc_center_bounds (const BMFace *f, float r_cent[3])
void BM_face_calc_center_bounds_vcos (const BMesh *bm, const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
void BM_face_calc_center_median (const BMFace *f, float r_cent[3])
void BM_face_calc_center_median_weighted (const BMFace *f, float r_cent[3])
void poly_rotate_plane (const float normal[3], float(*verts)[3], const uint nverts)
 POLY ROTATE PLANE.
void BM_edge_normals_update (BMEdge *e)
static void bm_loop_normal_accum (const BMLoop *l, float no[3])
bool BM_vert_calc_normal_ex (const BMVert *v, const char hflag, float r_no[3])
bool BM_vert_calc_normal (const BMVert *v, float r_no[3])
void BM_vert_normal_update_all (BMVert *v)
void BM_vert_normal_update (BMVert *v)
float BM_face_calc_normal (const BMFace *f, float r_no[3])
 BMESH UPDATE FACE NORMAL.
void BM_face_normal_update (BMFace *f)
float BM_face_calc_normal_vcos (const BMesh *bm, const BMFace *f, float r_no[3], const Span< float3 > vertexCos)
void BM_verts_calc_normal_from_cloud_ex (BMVert **varr, int varr_len, float r_normal[3], float r_center[3], int *r_index_tangent)
void BM_verts_calc_normal_from_cloud (BMVert **varr, int varr_len, float r_normal[3])
float BM_face_calc_normal_subset (const BMLoop *l_first, const BMLoop *l_last, float r_no[3])
void BM_face_calc_center_median_vcos (const BMesh *bm, const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
void BM_face_normal_flip_ex (BMesh *bm, BMFace *f, const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
 Face Flip Normal.
void BM_face_normal_flip (BMesh *bm, BMFace *f)
bool BM_face_point_inside_test (const BMFace *f, const float co[3])
void BM_face_triangulate (BMesh *bm, BMFace *f, BMFace **r_faces_new, int *r_faces_new_tot, BMEdge **r_edges_new, int *r_edges_new_tot, LinkNode **r_faces_double, const int quad_method, const int ngon_method, const bool use_tag, MemArena *pf_arena, Heap *pf_heap)
void BM_face_splits_check_legal (BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
void BM_face_splits_check_optimal (BMFace *f, BMLoop *(*loops)[2], int len)
void BM_face_as_array_vert_tri (BMFace *f, BMVert *r_verts[3])
void BM_face_as_array_vert_quad (BMFace *f, BMVert *r_verts[4])
void BM_face_as_array_loop_tri (BMFace *f, BMLoop *r_loops[3])
void BM_face_as_array_loop_quad (BMFace *f, BMLoop *r_loops[4])

Detailed Description

This file contains code for dealing with polygons (normal/area calculation, tessellation, etc)

Definition in file bmesh_polygon.cc.

Macro Definition Documentation

◆ EDGE_SHARE_VERT

#define EDGE_SHARE_VERT ( e1,
e2 )
Value:
(ELEM((e1)[0], (e2)[0], (e2)[1]) || ELEM((e1)[1], (e2)[0], (e2)[1]))
#define ELEM(...)

Referenced by BM_face_splits_check_legal().

Typedef Documentation

◆ float3

Definition at line 619 of file BLI_math_vector_types.hh.

Function Documentation

◆ BM_edge_normals_update()

void BM_edge_normals_update ( BMEdge * e)

updates face and vertex normals incident on an edge

Definition at line 690 of file bmesh_polygon.cc.

References BM_edge_normals_update(), BM_face_normal_update(), BM_FACES_OF_EDGE, BM_ITER_ELEM, BM_vert_normal_update(), and e.

Referenced by BM_edge_normals_update(), BM_face_calc_normal_vcos(), and bpy_bmedge_normal_update().

◆ BM_face_as_array_loop_quad()

void BM_face_as_array_loop_quad ( BMFace * f,
BMLoop * r_loops[4] )

faster alternative to: BM_iter_as_array(bm, BM_LOOPS_OF_FACE, f, (void **)l, 4);

Definition at line 1427 of file bmesh_polygon.cc.

References BLI_assert, BM_face_as_array_loop_quad(), BM_FACE_FIRST_LOOP, l, BMFace::len, and BMLoop::next.

Referenced by BM_face_as_array_loop_quad(), BM_face_triangulate(), bm_grid_fill_array(), and reprioritize_face_neighbors().

◆ BM_face_as_array_loop_tri()

void BM_face_as_array_loop_tri ( BMFace * f,
BMLoop * r_loops[3] )

Small utility functions for fast access

faster alternative to: BM_iter_as_array(bm, BM_LOOPS_OF_FACE, f, (void **)l, 3);

Definition at line 1414 of file bmesh_polygon.cc.

References BLI_assert, BM_face_as_array_loop_tri(), BM_FACE_FIRST_LOOP, l, BMFace::len, and BMLoop::next.

Referenced by BM_face_as_array_loop_tri(), and BM_face_triangulate().

◆ BM_face_as_array_vert_quad()

void BM_face_as_array_vert_quad ( BMFace * f,
BMVert * r_verts[4] )

◆ BM_face_as_array_vert_tri()

◆ BM_face_calc_area()

◆ BM_face_calc_area_uv()

float BM_face_calc_area_uv ( const BMFace * f,
int cd_loop_uv_offset )

◆ BM_face_calc_area_uv_signed()

float BM_face_calc_area_uv_signed ( const BMFace * f,
int cd_loop_uv_offset )

◆ BM_face_calc_area_with_mat3()

◆ BM_face_calc_bounds_expand()

void BM_face_calc_bounds_expand ( const BMFace * f,
float min[3],
float max[3] )

◆ BM_face_calc_center_bounds()

void BM_face_calc_center_bounds ( const BMFace * f,
float r_cent[3] )

◆ BM_face_calc_center_bounds_vcos()

void BM_face_calc_center_bounds_vcos ( const BMesh * bm,
const BMFace * f,
float r_center[3],
blender::Span< blender::float3 > vert_positions )

◆ BM_face_calc_center_median()

◆ BM_face_calc_center_median_vcos()

◆ BM_face_calc_center_median_weighted()

◆ BM_face_calc_normal()

float BM_face_calc_normal ( const BMFace * f,
float r_no[3] )

BMESH UPDATE FACE NORMAL.

Updates the stored normal for the given face. Requires that a buffer of sufficient length to store projected coordinates for all of the face's vertices is passed in as well.

Definition at line 808 of file bmesh_polygon.cc.

References BM_face_calc_normal(), bm_face_calc_poly_normal(), BM_FACE_FIRST_LOOP, BMVert::co, l, BMFace::len, BMLoop::next, normal_quad_v3(), normal_tri_v3(), and v.

Referenced by BM_face_calc_normal(), bm_face_calc_normals_cb(), BM_face_is_normal_valid(), BM_face_normal_update(), bm_mesh_calc_tessellation__single_threaded(), bmesh_calc_tessellation_for_face_impl(), and bmo_vert_calc_edge_angle_blended().

◆ BM_face_calc_normal_subset()

float BM_face_calc_normal_subset ( const BMLoop * l_first,
const BMLoop * l_last,
float r_no[3] )

◆ BM_face_calc_normal_vcos()

◆ BM_face_calc_perimeter()

float BM_face_calc_perimeter ( const BMFace * f)

◆ BM_face_calc_perimeter_with_mat3()

float BM_face_calc_perimeter_with_mat3 ( const BMFace * f,
const float mat3[3][3] )

◆ BM_face_calc_point_in_face()

void BM_face_calc_point_in_face ( const BMFace * f,
float r_co[3] )

◆ bm_face_calc_poly_center_median_vertex_cos()

void bm_face_calc_poly_center_median_vertex_cos ( const BMFace * f,
float r_cent[3],
const blender::Span< blender::float3 > vert_positions )
static

◆ bm_face_calc_poly_normal()

float bm_face_calc_poly_normal ( const BMFace * f,
float n[3] )
static

COMPUTE POLY NORMAL (BMFace).

Same as normal_poly_v3 but operates directly on a bmesh face.

Definition at line 39 of file bmesh_polygon.cc.

References add_newell_cross_v3_v3v3(), bm_face_calc_poly_normal(), BM_FACE_FIRST_LOOP, BMVert::co, BMLoop::next, normalize_v3(), BMLoop::prev, BMLoop::v, and zero_v3().

Referenced by BM_face_calc_normal(), and bm_face_calc_poly_normal().

◆ bm_face_calc_poly_normal_vertex_cos()

float bm_face_calc_poly_normal_vertex_cos ( const BMFace * f,
float r_no[3],
const Span< float3 > vertexCos )
static

◆ BM_face_calc_tangent_auto()

void BM_face_calc_tangent_auto ( const BMFace * f,
float r_tangent[3] )

Compute a meaningful direction along the face (use for gizmo axis).

Note
Callers shouldn't depend on the exact method used here.

Definition at line 556 of file bmesh_polygon.cc.

References BM_face_as_array_vert_tri(), BM_face_calc_tangent_auto(), BM_face_calc_tangent_from_edge(), bm_face_calc_tangent_from_quad_edge_pair(), BM_vert_tri_calc_tangent_from_edge(), and BMFace::len.

Referenced by BM_editselection_plane(), BM_face_calc_normal_vcos(), and BM_face_calc_tangent_auto().

◆ BM_face_calc_tangent_from_edge()

void BM_face_calc_tangent_from_edge ( const BMFace * f,
float r_tangent[3] )

◆ BM_face_calc_tangent_from_edge_diagonal()

void BM_face_calc_tangent_from_edge_diagonal ( const BMFace * f,
float r_tangent[3] )

Compute the tangent of the face, using the edge farthest away from any vertex in the face.

Parameters
r_tangentCalculated unit length tangent (return value).

Definition at line 496 of file bmesh_polygon.cc.

References BLI_assert, BM_face_calc_tangent_from_edge_diagonal(), BM_FACE_FIRST_LOOP, closest_to_line_segment_v3(), BMVert::co, copy_v3_v3(), ELEM, len_squared_v3(), BMLoop::next, normalize_v3(), BMLoop::prev, sub_v3_v3v3(), BMLoop::v, and zero_v3().

Referenced by BM_face_calc_normal_vcos(), BM_face_calc_tangent_from_edge_diagonal(), and bpy_bmface_calc_tangent_edge_diagonal().

◆ BM_face_calc_tangent_from_edge_pair()

void BM_face_calc_tangent_from_edge_pair ( const BMFace * f,
float r_tangent[3] )

◆ bm_face_calc_tangent_from_quad_edge_pair()

void bm_face_calc_tangent_from_quad_edge_pair ( const BMFace * f,
float r_tangent[3] )
static

◆ BM_face_calc_tangent_from_vert_diagonal()

void BM_face_calc_tangent_from_vert_diagonal ( const BMFace * f,
float r_tangent[3] )

Compute the tangent of the face, using longest distance between vertices on the face.

Note
The logic is almost identical to #BM_face_calc_tangent_edge_diagonal

Definition at line 528 of file bmesh_polygon.cc.

References BM_face_calc_tangent_from_vert_diagonal(), BM_FACE_FIRST_LOOP, BMVert::co, copy_v3_v3(), len_squared_v3(), BMLoop::next, normalize_v3(), sub_v3_v3v3(), BMLoop::v, and zero_v3().

Referenced by BM_face_calc_normal_vcos(), BM_face_calc_tangent_from_vert_diagonal(), and bpy_bmface_calc_tangent_vert_diagonal().

◆ BM_face_calc_tangent_pair_auto()

void BM_face_calc_tangent_pair_auto ( const BMFace * f,
float r_tangent_a[3],
float r_tangent_b[3] )

◆ BM_face_calc_tangent_pair_from_edge()

◆ bm_face_calc_tangent_pair_from_quad_edge_pair()

void bm_face_calc_tangent_pair_from_quad_edge_pair ( const BMFace * f,
float r_tangent_a[3],
float r_tangent_b[3] )
static

◆ BM_face_calc_tessellation()

void BM_face_calc_tessellation ( const BMFace * f,
bool use_fixed_quad,
BMLoop ** r_loops,
uint(*) r_index[3] )

For tools that insist on using triangles, ideally we would cache this data.

Parameters
use_fixed_quadWhen true, always split quad along (0 -> 2) regardless of concave corners, (as done in BM_mesh_calc_tessellation).
r_loopsStore face loop pointers, (f->len)
r_indexStore triangle triples, indices into r_loops, ((f->len - 2) * 3)

Definition at line 108 of file bmesh_polygon.cc.

References axis_dominant_v3_to_m3_negate(), BLI_array_alloca, BLI_polyfill_calc(), BM_face_calc_tessellation(), BM_FACE_FIRST_LOOP, BMVert::co, BMFace::len, mul_v2_m3v3(), BMLoop::next, BMFace::no, and BMLoop::v.

Referenced by BM_face_calc_point_in_face(), BM_face_calc_tessellation(), and bm_mesh_calc_volume_face().

◆ BM_face_normal_flip()

◆ BM_face_normal_flip_ex()

void BM_face_normal_flip_ex ( BMesh * bm,
BMFace * f,
int cd_loop_mdisp_offset,
bool use_loop_mdisp_flip )

◆ BM_face_normal_update()

◆ BM_face_point_inside_test()

bool BM_face_point_inside_test ( const BMFace * f,
const float co[3] )

BM POINT IN FACE

Projects co onto face f, and returns true if it is inside the face bounds.

Note
this uses a best-axis projection test, instead of projecting co directly into f's orientation space, so there might be accuracy issues.

Definition at line 1023 of file bmesh_polygon.cc.

References axis_dominant_v3_to_m3(), BLI_array_alloca, BLI_assert, BM_FACE_FIRST_LOOP, BM_face_is_normal_valid(), BM_face_point_inside_test(), BMVert::co, i, isect_point_poly_v2(), BMFace::len, mul_v2_m3v3(), BMLoop::next, BMFace::no, and BMLoop::v.

Referenced by BM_face_calc_normal_vcos(), BM_face_point_inside_test(), bm_vert_pair_share_best_splittable_face_cb(), bpy_bm_geometry_intersect_face_point(), find_face_internal_boundverts(), and knife_verts_edge_in_face().

◆ BM_face_splits_check_legal()

void BM_face_splits_check_legal ( BMesh * bm,
BMFace * f,
BMLoop *(*) loops[2],
int len )

each pair of loops defines a new edge, a split. this function goes through and sets pairs that are geometrically invalid to null. a split is invalid, if it forms a concave angle or it intersects other edges in the face, or it intersects another split. in the case of intersecting splits, only the first of the set of intersecting splits survives

Definition at line 1274 of file bmesh_polygon.cc.

References add_v2_v2(), axis_dominant_v3_to_m3(), BLI_array_alloca, BLI_assert, bm, BM_elem_index_get, BM_elem_index_set, BM_FACE_FIRST_LOOP, BM_face_is_normal_valid(), BM_face_splits_check_legal(), BM_LOOP, BMVert::co, EDGE_SHARE_VERT, BMesh::elem_index_dirty, FLT_MAX, i, is_poly_convex_v2(), ISECT_LINE_LINE_CROSS, isect_seg_seg_v2(), l, BMFace::len, len(), max_ff(), mid_v2_v2v2(), mul_v2_fl(), mul_v2_m3v3(), BMLoop::next, BMFace::no, out, sub_v2_v2(), UNPACK2, and BMLoop::v.

Referenced by bm_face_connect_verts(), bm_face_split_find(), BM_face_splits_check_legal(), and BM_face_triangulate().

◆ BM_face_splits_check_optimal()

void BM_face_splits_check_optimal ( BMFace * f,
BMLoop *(*) loops[2],
int len )

This simply checks that the verts don't connect faces which would have more optimal splits. but not check for correctness.

Definition at line 1372 of file bmesh_polygon.cc.

References BM_face_splits_check_optimal(), BM_vert_pair_share_face_by_angle(), i, len(), and v.

Referenced by bm_face_connect_verts(), BM_face_splits_check_optimal(), and BM_face_triangulate().

◆ BM_face_triangulate()

◆ bm_loop_normal_accum()

◆ BM_vert_calc_normal()

◆ BM_vert_calc_normal_ex()

◆ BM_vert_normal_update()

◆ BM_vert_normal_update_all()

◆ BM_vert_tri_calc_tangent_edge_pair()

void BM_vert_tri_calc_tangent_edge_pair ( BMVert * verts[3],
float r_tangent[3] )

Calculate a tangent from any 3 vertices,

The tangent follows the center-line formed by the most unique edges center and the opposite vertex.

Parameters
r_tangentCalculated unit length tangent (return value).

Definition at line 359 of file bmesh_polygon.cc.

References BM_vert_tri_calc_tangent_edge_pair(), bm_vert_tri_find_unique_edge(), BMVert::co, mid_v3_v3v3(), normalize_v3(), and sub_v3_v3v3().

Referenced by BM_face_calc_tangent_from_edge_pair(), BM_face_triangulate(), and BM_vert_tri_calc_tangent_edge_pair().

◆ BM_vert_tri_calc_tangent_from_edge()

void BM_vert_tri_calc_tangent_from_edge ( BMVert * verts[3],
float r_tangent[3] )

Calculate a tangent from any 3 vertices.

The tangent aligns to the most unique edge (the edge most unlike the other two).

Parameters
r_tangentCalculated unit length tangent (return value).

Definition at line 325 of file bmesh_polygon.cc.

References BM_vert_tri_calc_tangent_from_edge(), bm_vert_tri_find_unique_edge(), normalize_v3(), and sub_v3_v3v3().

Referenced by BM_face_calc_tangent_auto(), BM_face_triangulate(), BM_vert_tri_calc_tangent_from_edge(), and blender::ed::transform::getTransformOrientation_ex().

◆ BM_vert_tri_calc_tangent_pair_from_edge()

void BM_vert_tri_calc_tangent_pair_from_edge ( BMVert * verts[3],
float r_tangent_a[3],
float r_tangent_b[3] )

◆ bm_vert_tri_find_unique_edge()

int bm_vert_tri_find_unique_edge ( BMVert * verts[3])
static

Utility function to calculate the edge which is most different from the other two.

Returns
The first edge index, where the second vertex is (index + 1) % 3.

Definition at line 288 of file bmesh_polygon.cc.

References axis_sort_v3(), bm_vert_tri_find_unique_edge(), BMVert::co, fabsf, len_squared_v3v3(), len_v3v3(), mid_v3_v3v3(), project_v3_v3v3(), and sub_v3_v3().

Referenced by BM_vert_tri_calc_tangent_edge_pair(), BM_vert_tri_calc_tangent_from_edge(), BM_vert_tri_calc_tangent_pair_from_edge(), and bm_vert_tri_find_unique_edge().

◆ BM_verts_calc_normal_from_cloud()

void BM_verts_calc_normal_from_cloud ( BMVert ** varr,
int varr_len,
float r_normal[3] )

◆ BM_verts_calc_normal_from_cloud_ex()

void BM_verts_calc_normal_from_cloud_ex ( BMVert ** varr,
int varr_len,
float r_normal[3],
float r_center[3],
int * r_index_tangent )

Calculate a normal from a vertex cloud.

Note
We could make a higher quality version that takes all vertices into account. Currently it finds 4 outer most points returning its normal.

Definition at line 873 of file bmesh_polygon.cc.

References BM_verts_calc_normal_from_cloud_ex(), BMVert::co, copy_v3_v3(), dot_v3v3(), FLT_MAX, i, len_squared_v3(), len_squared_v3v3(), madd_v3_v3fl(), normal_quad_v3(), normal_tri_v3(), normalize_v3(), project_plane_normalized_v3_v3v3(), and sub_v3_v3v3().

Referenced by BM_face_calc_normal_vcos(), BM_verts_calc_normal_from_cloud(), BM_verts_calc_normal_from_cloud_ex(), and BM_verts_sort_radial_plane().

◆ poly_rotate_plane()

void poly_rotate_plane ( const float normal[3],
float(*) verts[3],
uint nverts )

POLY ROTATE PLANE.

Rotates a polygon so that its normal is pointing towards the mesh Z axis

Definition at line 675 of file bmesh_polygon.cc.

References axis_dominant_v3_to_m3(), copy_v3_v3(), i, mul_v2_m3v3(), and poly_rotate_plane().

Referenced by poly_rotate_plane(), and quad_co().