Blender V4.3
bmo_normals.cc File Reference

Go to the source code of this file.

Macros

#define FACE_FLAG   (1 << 0)
 
#define FACE_FLIP   (1 << 1)
 
#define FACE_TEMP   (1 << 2)
 

Functions

static bool bmo_recalc_normal_loop_filter_cb (const BMLoop *l, void *)
 
static int recalc_face_normals_find_index (BMesh *bm, BMFace **faces, const int faces_len, bool *r_is_flip)
 
static void bmo_recalc_face_normals_array (BMesh *bm, BMFace **faces, const int faces_len, const short oflag)
 
void bmo_recalc_face_normals_exec (BMesh *bm, BMOperator *op)
 

Detailed Description

Functionality for flipping faces to make normals consistent.

Definition in file bmo_normals.cc.

Macro Definition Documentation

◆ FACE_FLAG

#define FACE_FLAG   (1 << 0)

Definition at line 22 of file bmo_normals.cc.

Referenced by bmo_recalc_face_normals_exec().

◆ FACE_FLIP

#define FACE_FLIP   (1 << 1)

Definition at line 23 of file bmo_normals.cc.

Referenced by bmo_recalc_face_normals_array().

◆ FACE_TEMP

#define FACE_TEMP   (1 << 2)

Definition at line 24 of file bmo_normals.cc.

Referenced by bmo_recalc_face_normals_array(), and recalc_face_normals_find_index().

Function Documentation

◆ bmo_recalc_face_normals_array()

static void bmo_recalc_face_normals_array ( BMesh * bm,
BMFace ** faces,
const int faces_len,
const short oflag )
static

Given an array of faces, recalculate their normals. this functions assumes all faces in the array are connected by edges.

Parameters
bm
facesArray of connected faces.
faces_lenLength of faces
oflagFlag to check before doing the actual face flipping.

Definition at line 190 of file bmo_normals.cc.

References BLI_LINKSTACK_DECLARE, BLI_LINKSTACK_FREE, BLI_LINKSTACK_INIT, BLI_LINKSTACK_POP, BLI_LINKSTACK_PUSH, bm, BM_FACE_FIRST_LOOP, BM_face_normal_flip(), BMO_face_flag_disable, BMO_face_flag_enable, BMO_face_flag_set, BMO_face_flag_test, BMO_face_flag_test_bool, bmo_recalc_normal_loop_filter_cb(), BMLoop::f, FACE_FLIP, FACE_TEMP, BMLoop::next, oflag, BMLoop::radial_next, recalc_face_normals_find_index(), and BMLoop::v.

Referenced by bmo_recalc_face_normals_exec().

◆ bmo_recalc_face_normals_exec()

void bmo_recalc_face_normals_exec ( BMesh * bm,
BMOperator * op )

Put normal to the outside, and set the first direction flags in edges

then check the object, and set directions / direction-flags: but only for edges with 1 or 2 faces this is in fact the 'select connected'

in case all faces were not done: start over with 'find the ultimate ...'.

Definition at line 256 of file bmo_normals.cc.

References bm, BM_EDGE, BM_FACE, BM_face_at_index(), BM_mesh_calc_face_groups(), BM_mesh_elem_table_ensure(), BMO_face_flag_test_bool, bmo_recalc_face_normals_array(), bmo_recalc_normal_loop_filter_cb(), BMO_slot_buffer_flag_enable(), FACE_FLAG, int, MEM_freeN(), MEM_mallocN, BMOperator::slots_in, and BMesh::totface.

◆ bmo_recalc_normal_loop_filter_cb()

static bool bmo_recalc_normal_loop_filter_cb ( const BMLoop * l,
void *  )
static

Definition at line 26 of file bmo_normals.cc.

References BM_edge_is_manifold(), BMLoop::e, and l.

Referenced by bmo_recalc_face_normals_array(), and bmo_recalc_face_normals_exec().

◆ recalc_face_normals_find_index()

static int recalc_face_normals_find_index ( BMesh * bm,
BMFace ** faces,
const int faces_len,
bool * r_is_flip )
static

This uses a more comprehensive test to see if the furthest face from the center is pointing towards the center or not.

A simple test could just check the dot product of the faces-normal and the direction from the center, however this can fail for faces which make a sharp spike. eg:

+
|\ <- face
+ +
\ \
  \ \
   \ +--------------+
    \               |
     \ center -> +  |
      \             |
       +------------+

In the example above, the face can point towards the center which would end up flipping the normals inwards.

To take these spikes into account, find the furthest face-loop-vertex.

Returns
a face index in faces and set r_is_flip if the face is flipped away from the center.

Search for the best loop. Members are compared in-order defined here.

Squared distance from the center to the loops vertex 'l->v'. The normalized direction between the center and this vertex is also used for the dot-products below.

Signed dot product using the normalized edge vector, (best of 'l->prev->v' or 'l->next->v').

Unsigned dot product using the loop-normal (sign is used to check if we need to flip).

Find the outer-most vertex, comparing distance to the center, then the outer-most loop attached to that vertex.

Important this is correctly detected, where casting a ray from the center won't hit any loops past this one. Otherwise the result may be incorrect.

Definition at line 62 of file bmo_normals.cc.

References BLI_assert, bm, BM_face_calc_area(), BM_face_calc_center_median_weighted(), BM_FACE_FIRST_LOOP, BM_face_is_normal_valid(), BMO_face_flag_test, BMVert::co, cross_v3_v3v3(), dot_v3v3(), eps, BMLoop::f, fabsf, FACE_TEMP, float, FLT_MAX, len_squared_v3(), madd_v3_v3fl(), max_ff(), mul_v3_fl(), negate_v3(), BMLoop::next, BMFace::no, normalize_v3(), BMLoop::prev, sqrtf, sub_v3_v3v3(), UNLIKELY, UNUSED_VARS_NDEBUG, BMLoop::v, and zero_v3().

Referenced by bmo_recalc_face_normals_array().