Blender  V3.3
Macros | Functions
bmo_normals.c File Reference
#include "MEM_guardedalloc.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "bmesh.h"
#include "intern/bmesh_operators_private.h"

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 *UNUSED(user_data))
 
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

normal recalculation.

Definition in file bmo_normals.c.

Macro Definition Documentation

◆ FACE_FLAG

#define FACE_FLAG   (1 << 0)

Definition at line 20 of file bmo_normals.c.

◆ FACE_FLIP

#define FACE_FLIP   (1 << 1)

Definition at line 21 of file bmo_normals.c.

◆ FACE_TEMP

#define FACE_TEMP   (1 << 2)

Definition at line 22 of file bmo_normals.c.

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 188 of file bmo_normals.c.

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, faces, BMLoop::next, NULL, 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 254 of file bmo_normals.c.

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, MEM_freeN, MEM_mallocN, NULL, BMOperator::slots_in, and BMesh::totface.

◆ bmo_recalc_normal_loop_filter_cb()

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

Definition at line 24 of file bmo_normals.c.

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 a\ 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 60 of file bmo_normals.c.

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, faces, float(), 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().