Blender  V3.3
Classes | Macros
mesh_normals.cc File Reference
#include <climits>
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "BLI_alloca.h"
#include "BLI_bitmap.h"
#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_math_vec_types.hh"
#include "BLI_memarena.h"
#include "BLI_span.hh"
#include "BLI_stack.h"
#include "BLI_task.h"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_editmesh_cache.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "atomic_ops.h"

Go to the source code of this file.

Classes

struct  MeshCalcNormalsData_Poly
 
struct  MeshCalcNormalsData_PolyAndVertex
 
struct  LoopSplitTaskData
 
struct  LoopSplitTaskDataCommon
 

Macros

#define FLT_EQ_NONAN(_fa, _fb)   (*((const uint32_t *)&_fa) == *((const uint32_t *)&_fb))
 

Functions

Private Utility Functions
static void add_v3_v3_atomic (float r[3], const float a[3])
 
Public Utility Functions

Related to managing normals but not directly related to calculating normals.

void BKE_mesh_normals_tag_dirty (Mesh *mesh)
 
float(* BKE_mesh_vertex_normals_for_write (Mesh *mesh))[3]
 
float(* BKE_mesh_poly_normals_for_write (Mesh *mesh))[3]
 
void BKE_mesh_vertex_normals_clear_dirty (Mesh *mesh)
 
void BKE_mesh_poly_normals_clear_dirty (Mesh *mesh)
 
bool BKE_mesh_vertex_normals_are_dirty (const Mesh *mesh)
 
bool BKE_mesh_poly_normals_are_dirty (const Mesh *mesh)
 
void BKE_mesh_clear_derived_normals (Mesh *mesh)
 
void BKE_mesh_assert_normals_dirty_or_calculated (const Mesh *mesh)
 
Mesh Normal Calculation (Polygons)
static void mesh_calc_normals_poly_fn (void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls))
 
void BKE_mesh_calc_normals_poly (const MVert *mvert, int UNUSED(mvert_len), const MLoop *mloop, int UNUSED(mloop_len), const MPoly *mpoly, int mpoly_len, float(*r_poly_normals)[3])
 
Mesh Normal Calculation (Polygons & Vertices)

Take care making optimizations to this function as improvements to low-poly meshes can slow down high-poly meshes. For details on performance, see D11993.

static void mesh_calc_normals_poly_and_vertex_accum_fn (void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls))
 
static void mesh_calc_normals_poly_and_vertex_finalize_fn (void *__restrict userdata, const int vidx, const TaskParallelTLS *__restrict UNUSED(tls))
 
void BKE_mesh_calc_normals_poly_and_vertex (const MVert *mvert, const int mvert_len, const MLoop *mloop, const int UNUSED(mloop_len), const MPoly *mpoly, const int mpoly_len, float(*r_poly_normals)[3], float(*r_vert_normals)[3])
 

Mesh Normal Calculation

#define LNOR_SPACE_TRIGO_THRESHOLD   (1.0f - 1e-4f)
 
#define LOOP_SPLIT_TASK_BLOCK_SIZE   1024
 
#define INDEX_UNSET   INT_MIN
 
#define INDEX_INVALID   -1
 
#define IS_EDGE_SHARP(_e2l)   (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))
 
const float(* BKE_mesh_vertex_normals_ensure (const Mesh *mesh))[3]
 
const float(* BKE_mesh_poly_normals_ensure (const Mesh *mesh))[3]
 
void BKE_mesh_ensure_normals_for_display (Mesh *mesh)
 
void BKE_mesh_calc_normals (Mesh *mesh)
 
void BKE_mesh_calc_normals_looptri (MVert *mverts, int numVerts, const MLoop *mloop, const MLoopTri *looptri, int looptri_num, float(*r_tri_nors)[3])
 
void BKE_lnor_spacearr_init (MLoopNorSpaceArray *lnors_spacearr, const int numLoops, const char data_type)
 
void BKE_lnor_spacearr_tls_init (MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpaceArray *lnors_spacearr_tls)
 
void BKE_lnor_spacearr_tls_join (MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpaceArray *lnors_spacearr_tls)
 
void BKE_lnor_spacearr_clear (MLoopNorSpaceArray *lnors_spacearr)
 
void BKE_lnor_spacearr_free (MLoopNorSpaceArray *lnors_spacearr)
 
MLoopNorSpaceBKE_lnor_space_create (MLoopNorSpaceArray *lnors_spacearr)
 
void BKE_lnor_space_define (MLoopNorSpace *lnor_space, const float lnor[3], float vec_ref[3], float vec_other[3], BLI_Stack *edge_vectors)
 
void BKE_lnor_space_add_loop (MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, const int ml_index, void *bm_loop, const bool is_single)
 
MINLINE float unit_short_to_float (const short val)
 
MINLINE short unit_float_to_short (const float val)
 
void BKE_lnor_space_custom_data_to_normal (MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3])
 
void BKE_lnor_space_custom_normal_to_data (MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2])
 
static void mesh_edges_sharp_tag (LoopSplitTaskDataCommon *data, const bool check_angle, const float split_angle, const bool do_sharp_edges_tag)
 
void BKE_edges_sharp_from_angle_set (const struct MVert *mverts, const int UNUSED(numVerts), struct MEdge *medges, const int numEdges, struct MLoop *mloops, const int numLoops, struct MPoly *mpolys, const float(*polynors)[3], const int numPolys, const float split_angle)
 
void BKE_mesh_loop_manifold_fan_around_vert_next (const MLoop *mloops, const MPoly *mpolys, const int *loop_to_poly, const int *e2lfan_curr, const uint mv_pivot_index, const MLoop **r_mlfan_curr, int *r_mlfan_curr_index, int *r_mlfan_vert_index, int *r_mpfan_curr_index)
 
static void split_loop_nor_single_do (LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
 
static void split_loop_nor_fan_do (LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
 
static void loop_split_worker_do (LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data, BLI_Stack *edge_vectors)
 
static void loop_split_worker (TaskPool *__restrict pool, void *taskdata)
 
static bool loop_split_generator_check_cyclic_smooth_fan (const MLoop *mloops, const MPoly *mpolys, const int(*edge_to_loops)[2], const int *loop_to_poly, const int *e2l_prev, BLI_bitmap *skip_loops, const MLoop *ml_curr, const MLoop *ml_prev, const int ml_curr_index, const int ml_prev_index, const int mp_curr_index)
 
static void loop_split_generator (TaskPool *pool, LoopSplitTaskDataCommon *common_data)
 
void BKE_mesh_normals_loop_split (const MVert *mverts, const float(*vert_normals)[3], const int UNUSED(numVerts), MEdge *medges, const int numEdges, MLoop *mloops, float(*r_loopnors)[3], const int numLoops, MPoly *mpolys, const float(*polynors)[3], const int numPolys, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], int *r_loop_to_poly)
 
static void mesh_normals_loop_custom_set (const MVert *mverts, const float(*vert_normals)[3], const int numVerts, MEdge *medges, const int numEdges, MLoop *mloops, float(*r_custom_loopnors)[3], const int numLoops, MPoly *mpolys, const float(*polynors)[3], const int numPolys, short(*r_clnors_data)[2], const bool use_vertices)
 
void BKE_mesh_normals_loop_custom_set (const MVert *mverts, const float(*vert_normals)[3], const int numVerts, MEdge *medges, const int numEdges, MLoop *mloops, float(*r_custom_loopnors)[3], const int numLoops, MPoly *mpolys, const float(*polynors)[3], const int numPolys, short(*r_clnors_data)[2])
 
void BKE_mesh_normals_loop_custom_from_vertices_set (const MVert *mverts, const float(*vert_normals)[3], float(*r_custom_vertnors)[3], const int numVerts, MEdge *medges, const int numEdges, MLoop *mloops, const int numLoops, MPoly *mpolys, const float(*polynors)[3], const int numPolys, short(*r_clnors_data)[2])
 
static void mesh_set_custom_normals (Mesh *mesh, float(*r_custom_nors)[3], const bool use_vertices)
 
void BKE_mesh_set_custom_normals (Mesh *mesh, float(*r_custom_loopnors)[3])
 
void BKE_mesh_set_custom_normals_from_vertices (Mesh *mesh, float(*r_custom_vertnors)[3])
 
void BKE_mesh_normals_loop_to_vertex (const int numVerts, const MLoop *mloops, const int numLoops, const float(*clnors)[3], float(*r_vert_clnors)[3])
 

Detailed Description

Mesh normal calculation functions.

See also
bmesh_mesh_normals.c for the equivalent BMesh functionality.

Definition in file mesh_normals.cc.

Macro Definition Documentation

◆ FLT_EQ_NONAN

#define FLT_EQ_NONAN (   _fa,
  _fb 
)    (*((const uint32_t *)&_fa) == *((const uint32_t *)&_fb))

◆ INDEX_INVALID

#define INDEX_INVALID   -1

Definition at line 829 of file mesh_normals.cc.

◆ INDEX_UNSET

#define INDEX_UNSET   INT_MIN

Definition at line 828 of file mesh_normals.cc.

◆ IS_EDGE_SHARP

#define IS_EDGE_SHARP (   _e2l)    (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))

Definition at line 831 of file mesh_normals.cc.

◆ LNOR_SPACE_TRIGO_THRESHOLD

#define LNOR_SPACE_TRIGO_THRESHOLD   (1.0f - 1e-4f)

Definition at line 586 of file mesh_normals.cc.

◆ LOOP_SPLIT_TASK_BLOCK_SIZE

#define LOOP_SPLIT_TASK_BLOCK_SIZE   1024

Definition at line 782 of file mesh_normals.cc.

Function Documentation

◆ add_v3_v3_atomic()

static void add_v3_v3_atomic ( float  r[3],
const float  a[3] 
)
static

A thread-safe version of add_v3_v3 that uses a spin-lock.

Note
Avoid using this when the chance of contention is high.

Definition at line 58 of file mesh_normals.cc.

References _ATOMIC_LIKELY, Freestyle::a, atomic_cas_float(), BLI_assert, FLT_EQ_NONAN, and r.

Referenced by mesh_calc_normals_poly_and_vertex_accum_fn().

◆ BKE_edges_sharp_from_angle_set()

void BKE_edges_sharp_from_angle_set ( const struct MVert mverts,
const int   UNUSEDnumVerts,
struct MEdge medges,
const int  numEdges,
struct MLoop mloops,
const int  numLoops,
struct MPoly mpolys,
const float(*)  polynors[3],
const int  numPolys,
const float  split_angle 
)

◆ BKE_lnor_space_add_loop()

void BKE_lnor_space_add_loop ( MLoopNorSpaceArray lnors_spacearr,
MLoopNorSpace lnor_space,
int  ml_index,
void bm_loop,
bool  is_single 
)

Add a new given loop to given lnor_space. Depending on lnor_space->data_type, we expect bm_loop to be a pointer to BMLoop struct (in case of BMLOOP_PTR), or nullptr (in case of LOOP_INDEX), loop index is then stored in pointer. If is_single is set, the BMLoop or loop index is directly stored in lnor_space->loops pointer (since there is only one loop in this fan), else it is added to the linked list of loops in the fan.

Definition at line 660 of file mesh_normals.cc.

References BLI_assert, BLI_linklist_prepend_nlink(), MLoopNorSpaceArray::data_type, MLoopNorSpace::flags, MLoopNorSpace::loops, MLoopNorSpaceArray::loops_pool, MLoopNorSpaceArray::lspacearr, MLNOR_SPACE_IS_SINGLE, MLNOR_SPACEARR_BMLOOP_PTR, MLNOR_SPACEARR_LOOP_INDEX, and POINTER_FROM_INT.

Referenced by bm_mesh_loops_calc_normals_for_loop(), split_loop_nor_fan_do(), and split_loop_nor_single_do().

◆ BKE_lnor_space_create()

MLoopNorSpace* BKE_lnor_space_create ( MLoopNorSpaceArray lnors_spacearr)

◆ BKE_lnor_space_custom_data_to_normal()

void BKE_lnor_space_custom_data_to_normal ( MLoopNorSpace lnor_space,
const short  clnor_data[2],
float  r_custom_lnor[3] 
)

◆ BKE_lnor_space_custom_normal_to_data()

void BKE_lnor_space_custom_normal_to_data ( MLoopNorSpace lnor_space,
const float  custom_lnor[3],
short  r_clnor_data[2] 
)

◆ BKE_lnor_space_define()

void BKE_lnor_space_define ( MLoopNorSpace lnor_space,
const float  lnor[3],
float  vec_ref[3],
float  vec_other[3],
struct BLI_Stack edge_vectors 
)

◆ BKE_lnor_spacearr_clear()

void BKE_lnor_spacearr_clear ( MLoopNorSpaceArray lnors_spacearr)

◆ BKE_lnor_spacearr_free()

void BKE_lnor_spacearr_free ( MLoopNorSpaceArray lnors_spacearr)

◆ BKE_lnor_spacearr_init()

void BKE_lnor_spacearr_init ( MLoopNorSpaceArray lnors_spacearr,
const int  numLoops,
const char  data_type 
)

◆ BKE_lnor_spacearr_tls_init()

void BKE_lnor_spacearr_tls_init ( MLoopNorSpaceArray lnors_spacearr,
MLoopNorSpaceArray lnors_spacearr_tls 
)

Utility for multi-threaded calculation that ensures lnors_spacearr_tls doesn't share memory with lnors_spacearr that would cause it not to be thread safe.

Note
This works as long as threads never operate on the same loops at once.

Definition at line 541 of file mesh_normals.cc.

References BLI_memarena_new(), BLI_MEMARENA_STD_BUFSIZE, and MLoopNorSpaceArray::mem.

Referenced by bm_mesh_loops_calc_normals_for_vert_init_fn().

◆ BKE_lnor_spacearr_tls_join()

void BKE_lnor_spacearr_tls_join ( MLoopNorSpaceArray lnors_spacearr,
MLoopNorSpaceArray lnors_spacearr_tls 
)

Utility for multi-threaded calculation that merges lnors_spacearr_tls into lnors_spacearr.

Definition at line 548 of file mesh_normals.cc.

References BKE_lnor_spacearr_clear(), BLI_assert, BLI_memarena_free(), BLI_memarena_merge(), MLoopNorSpaceArray::data_type, MLoopNorSpaceArray::mem, and MLoopNorSpaceArray::spaces_num.

Referenced by bm_mesh_loops_calc_normals_for_vert_reduce_fn().

◆ BKE_mesh_assert_normals_dirty_or_calculated()

void BKE_mesh_assert_normals_dirty_or_calculated ( const Mesh mesh)

◆ BKE_mesh_calc_normals()

void BKE_mesh_calc_normals ( struct Mesh me)

Calculate vertex and face normals, storing the result in custom data layers on the mesh.

Note
It is usually preferable to calculate normals lazily with BKE_mesh_vertex_normals_ensure, but some areas (perhaps unnecessarily) can also calculate them eagerly.

Definition at line 454 of file mesh_normals.cc.

References BKE_mesh_calc_normals(), BKE_mesh_vertex_normals_ensure(), mesh, TIMEIT_END_AVERAGED, and TIMEIT_START_AVERAGED.

Referenced by BKE_mesh_calc_normals().

◆ BKE_mesh_calc_normals_looptri()

void BKE_mesh_calc_normals_looptri ( MVert mverts,
int  numVerts,
const MLoop mloop,
const MLoopTri looptri,
int  looptri_num,
float(*)  r_tri_nors[3] 
)

◆ BKE_mesh_calc_normals_poly()

void BKE_mesh_calc_normals_poly ( const MVert mvert,
int   UNUSEDmvert_len,
const MLoop mloop,
int   UNUSEDmloop_len,
const MPoly mpoly,
int  mpoly_len,
float(*)  r_poly_normals[3] 
)

◆ BKE_mesh_calc_normals_poly_and_vertex()

void BKE_mesh_calc_normals_poly_and_vertex ( const MVert mvert,
const int  mvert_len,
const MLoop mloop,
const int   UNUSEDmloop_len,
const MPoly mpoly,
const int  mpoly_len,
float(*)  r_poly_normals[3],
float(*)  r_vert_normals[3] 
)

◆ BKE_mesh_clear_derived_normals()

void BKE_mesh_clear_derived_normals ( struct Mesh mesh)

Free any cached vertex or poly normals. Face corner (loop) normals are also derived data, but are not handled with the same method yet, so they are not included. It's important that this is called after the mesh changes size, since otherwise cached normal arrays might not be large enough (though it may be called indirectly by other functions).

Note
Normally it's preferred to call BKE_mesh_normals_tag_dirty instead, but this can be used in specific situations to reset a mesh or reduce memory usage.

Definition at line 147 of file mesh_normals.cc.

References MEM_SAFE_FREE, mesh, Mesh_Runtime::poly_normals, Mesh_Runtime::poly_normals_dirty, Mesh::runtime, Mesh_Runtime::vert_normals, and Mesh_Runtime::vert_normals_dirty.

Referenced by BKE_mesh_nomain_to_mesh(), BKE_mesh_runtime_clear_cache(), BM_mesh_bm_to_me(), BM_mesh_bm_to_me_for_eval(), and ED_mesh_join_objects_exec().

◆ BKE_mesh_ensure_normals_for_display()

void BKE_mesh_ensure_normals_for_display ( struct Mesh mesh)

◆ BKE_mesh_loop_manifold_fan_around_vert_next()

void BKE_mesh_loop_manifold_fan_around_vert_next ( const MLoop mloops,
const MPoly mpolys,
const int *  loop_to_poly,
const int *  e2lfan_curr,
const uint  mv_pivot_index,
const MLoop **  r_mlfan_curr,
int *  r_mlfan_curr_index,
int *  r_mlfan_vert_index,
int *  r_mpfan_curr_index 
)

◆ BKE_mesh_normals_loop_custom_from_vertices_set()

void BKE_mesh_normals_loop_custom_from_vertices_set ( const MVert mverts,
const float(*)  vert_normals[3],
float(*)  r_custom_vertnors[3],
const int  numVerts,
MEdge medges,
const int  numEdges,
MLoop mloops,
const int  numLoops,
MPoly mpolys,
const float(*)  polynors[3],
const int  numPolys,
short(*)  r_clnors_data[2] 
)

Definition at line 2018 of file mesh_normals.cc.

References mesh_normals_loop_custom_set().

◆ BKE_mesh_normals_loop_custom_set()

void BKE_mesh_normals_loop_custom_set ( const MVert mverts,
const float(*)  vert_normals[3],
const int  numVerts,
MEdge medges,
const int  numEdges,
MLoop mloops,
float(*)  r_custom_loopnors[3],
const int  numLoops,
MPoly mpolys,
const float(*)  polynors[3],
const int  numPolys,
short(*)  r_clnors_data[2] 
)

Definition at line 1990 of file mesh_normals.cc.

References mesh_normals_loop_custom_set().

◆ BKE_mesh_normals_loop_split()

void BKE_mesh_normals_loop_split ( const MVert mverts,
const float(*)  vert_normals[3],
const int   UNUSEDnumVerts,
MEdge medges,
const int  numEdges,
MLoop mloops,
float(*)  r_loopnors[3],
const int  numLoops,
MPoly mpolys,
const float(*)  polynors[3],
const int  numPolys,
const bool  use_split_normals,
const float  split_angle,
MLoopNorSpaceArray r_lnors_spacearr,
short(*)  clnors_data[2],
int *  r_loop_to_poly 
)

Mapping edge -> loops. If that edge is used by more than two loops (polys), it is always sharp (and tagged as such, see below). We also use the second loop index as a kind of flag:

  • smooth edge: > 0.
  • sharp edge: < 0 (INDEX_INVALID || INDEX_UNSET).
  • unset: INDEX_UNSET.

Note that currently we only have two values for second loop of sharp edges. However, if needed, we can store the negated value of loop index instead of INDEX_INVALID to retrieve the real value later in code). Note also that loose edges always have both values set to 0!

Definition at line 1600 of file mesh_normals.cc.

References BKE_lnor_spacearr_free(), BKE_lnor_spacearr_init(), BLI_assert, BLI_task_pool_create(), BLI_task_pool_free(), BLI_task_pool_work_and_wait(), LoopSplitTaskDataCommon::clnors_data, copy_v3_v3(), LoopSplitTaskDataCommon::edge_to_loops, MPoly::flag, float(), LoopSplitTaskDataCommon::lnors_spacearr, loop_split_generator(), LOOP_SPLIT_TASK_BLOCK_SIZE, LoopSplitTaskDataCommon::loop_to_poly, LoopSplitTaskDataCommon::loopnors, MPoly::loopstart, M_PI, ME_SMOOTH, LoopSplitTaskDataCommon::medges, MEM_calloc_arrayN, MEM_freeN, MEM_malloc_arrayN, mesh_edges_sharp_tag(), MLNOR_SPACEARR_LOOP_INDEX, LoopSplitTaskDataCommon::mloops, LoopSplitTaskDataCommon::mpolys, LoopSplitTaskDataCommon::mverts, LoopSplitTaskDataCommon::numEdges, LoopSplitTaskDataCommon::numLoops, LoopSplitTaskDataCommon::numPolys, LoopSplitTaskDataCommon::polynors, task_pool, TASK_PRIORITY_HIGH, TIMEIT_END_AVERAGED, TIMEIT_START_AVERAGED, MPoly::totloop, v, and LoopSplitTaskDataCommon::vert_normals.

Referenced by mesh_normals_loop_custom_set().

◆ BKE_mesh_normals_loop_to_vertex()

void BKE_mesh_normals_loop_to_vertex ( const int  numVerts,
const MLoop mloops,
const int  numLoops,
const float(*)  clnors[3],
float(*)  r_vert_clnors[3] 
)

Definition at line 2085 of file mesh_normals.cc.

References add_v3_v3(), copy_vn_fl(), MEM_calloc_arrayN, MEM_freeN, mul_v3_fl(), v, and MLoop::v.

◆ BKE_mesh_normals_tag_dirty()

void BKE_mesh_normals_tag_dirty ( struct Mesh mesh)

Tag mesh vertex and face normals to be recalculated when/if they are needed later.

Note
Dirty tagged normals are the default state of a new mesh, so tagging them dirty explicitly is not always necessary if the mesh is created locally.

Definition at line 95 of file mesh_normals.cc.

References mesh, Mesh_Runtime::poly_normals_dirty, Mesh::runtime, and Mesh_Runtime::vert_normals_dirty.

Referenced by BKE_mesh_tag_coords_changed(), ED_mesh_join_objects_exec(), ED_mesh_update(), Freestyle::BlenderStrokeRenderer::GenerateStrokeMesh(), mesh_blend_read_data(), mesh_copy_data(), mesh_init_data(), MOD_solidify_extrude_modifyMesh(), normalEditModifier_do_directional(), normalEditModifier_do_radial(), blender::io::alembic::process_no_normals(), and sculpt_symmetrize_exec().

◆ BKE_mesh_poly_normals_are_dirty()

bool BKE_mesh_poly_normals_are_dirty ( const Mesh mesh)

Definition at line 142 of file mesh_normals.cc.

References mesh, Mesh_Runtime::poly_normals_dirty, and Mesh::runtime.

Referenced by BKE_mesh_poly_normals_ensure().

◆ BKE_mesh_poly_normals_clear_dirty()

void BKE_mesh_poly_normals_clear_dirty ( struct Mesh mesh)

Mark the mesh's poly normals non-dirty, for when they are calculated or assigned manually.

Definition at line 131 of file mesh_normals.cc.

References BKE_mesh_assert_normals_dirty_or_calculated(), mesh, Mesh_Runtime::poly_normals_dirty, and Mesh::runtime.

Referenced by BKE_mesh_poly_normals_ensure(), BKE_mesh_tag_coords_changed_uniformly(), and BKE_mesh_vertex_normals_ensure().

◆ BKE_mesh_poly_normals_ensure()

const float(* BKE_mesh_poly_normals_ensure ( const Mesh mesh) )[3]

◆ BKE_mesh_poly_normals_for_write()

float(* BKE_mesh_poly_normals_for_write ( struct Mesh mesh) )[3]

Retrieve write access to the poly normal layer, ensuring that it exists and that it is not shared. The provided poly normals should be the same as if they were calculated automatically.

Note
In order to clear the dirty flag, this function should be followed by a call to BKE_mesh_poly_normals_clear_dirty. This is separate so that normals are still tagged dirty while they are being assigned.
Warning
The memory returned by this function is not initialized if it was not previously allocated.

Definition at line 113 of file mesh_normals.cc.

References BLI_assert, float(), MEM_allocN_len, MEM_malloc_arrayN, mesh, Mesh_Runtime::poly_normals, Mesh::runtime, and Mesh::totpoly.

Referenced by BKE_mesh_poly_normals_ensure(), BKE_mesh_vertex_normals_ensure(), normalEditModifier_do_directional(), and normalEditModifier_do_radial().

◆ BKE_mesh_set_custom_normals()

void BKE_mesh_set_custom_normals ( struct Mesh mesh,
float(*)  r_custom_loopnors[3] 
)

Higher level functions hiding most of the code needed around call to BKE_mesh_normals_loop_custom_set().

Parameters
r_custom_loopnorsis not const, since code will replace zero_v3 normals there with automatically computed vectors.

Definition at line 2075 of file mesh_normals.cc.

References mesh, and mesh_set_custom_normals().

Referenced by mesh_wrapper_ensure_subdivision(), modifyMesh(), blender::io::alembic::process_loop_normals(), and triangulate_mesh().

◆ BKE_mesh_set_custom_normals_from_vertices()

void BKE_mesh_set_custom_normals_from_vertices ( struct Mesh mesh,
float(*)  r_custom_vertnors[3] 
)

Higher level functions hiding most of the code needed around call to BKE_mesh_normals_loop_custom_from_vertices_set().

Parameters
r_custom_vertnorsis not const, since code will replace zero_v3 normals there with automatically computed vectors.

Definition at line 2080 of file mesh_normals.cc.

References mesh, and mesh_set_custom_normals().

Referenced by blender::io::alembic::process_vertex_normals().

◆ BKE_mesh_vertex_normals_are_dirty()

bool BKE_mesh_vertex_normals_are_dirty ( const Mesh mesh)

Definition at line 137 of file mesh_normals.cc.

References mesh, Mesh::runtime, and Mesh_Runtime::vert_normals_dirty.

Referenced by BKE_mesh_vertex_normals_ensure().

◆ BKE_mesh_vertex_normals_clear_dirty()

void BKE_mesh_vertex_normals_clear_dirty ( struct Mesh mesh)

◆ BKE_mesh_vertex_normals_ensure()

const float(* BKE_mesh_vertex_normals_ensure ( const Mesh mesh) )[3]

◆ BKE_mesh_vertex_normals_for_write()

float(* BKE_mesh_vertex_normals_for_write ( struct Mesh mesh) )[3]

Retrieve write access to the vertex normal layer, ensuring that it exists and that it is not shared. The provided vertex normals should be the same as if they were calculated automatically.

Note
In order to clear the dirty flag, this function should be followed by a call to BKE_mesh_vertex_normals_clear_dirty. This is separate so that normals are still tagged dirty while they are being assigned.
Warning
The memory returned by this function is not initialized if it was not previously allocated.

Definition at line 101 of file mesh_normals.cc.

References BLI_assert, float(), MEM_allocN_len, MEM_malloc_arrayN, mesh, Mesh::runtime, Mesh::totvert, and Mesh_Runtime::vert_normals.

Referenced by arrayModifier_doArray(), BKE_mesh_vertex_normals_ensure(), BKE_pbvh_build_mesh(), blender::nodes::node_geo_mesh_primitive_uv_sphere_cc::create_uv_sphere_mesh(), mesh_merge_transform(), blender::io::alembic::read_mverts(), split_faces_prepare_new_verts(), and split_faces_split_new_verts().

◆ loop_split_generator()

static void loop_split_generator ( TaskPool pool,
LoopSplitTaskDataCommon common_data 
)
static

◆ loop_split_generator_check_cyclic_smooth_fan()

static bool loop_split_generator_check_cyclic_smooth_fan ( const MLoop mloops,
const MPoly mpolys,
const int(*)  edge_to_loops[2],
const int *  loop_to_poly,
const int *  e2l_prev,
BLI_bitmap skip_loops,
const MLoop ml_curr,
const MLoop ml_prev,
const int  ml_curr_index,
const int  ml_prev_index,
const int  mp_curr_index 
)
static

Check whether given loop is part of an unknown-so-far cyclic smooth fan, or not. Needed because cyclic smooth fans have no obvious 'entry point', and yet we need to walk them once, and only once.

Definition at line 1352 of file mesh_normals.cc.

References BKE_mesh_loop_manifold_fan_around_vert_next(), BLI_assert, BLI_BITMAP_ENABLE, BLI_BITMAP_TEST, MLoop::e, IS_EDGE_SHARP, and MLoop::v.

Referenced by loop_split_generator().

◆ loop_split_worker()

static void loop_split_worker ( TaskPool *__restrict  pool,
void taskdata 
)
static

◆ loop_split_worker_do()

static void loop_split_worker_do ( LoopSplitTaskDataCommon common_data,
LoopSplitTaskData data,
BLI_Stack edge_vectors 
)
static

◆ mesh_calc_normals_poly_and_vertex_accum_fn()

static void mesh_calc_normals_poly_and_vertex_accum_fn ( void *__restrict  userdata,
const int  pidx,
const TaskParallelTLS *__restrict   UNUSEDtls 
)
static

◆ mesh_calc_normals_poly_and_vertex_finalize_fn()

static void mesh_calc_normals_poly_and_vertex_finalize_fn ( void *__restrict  userdata,
const int  vidx,
const TaskParallelTLS *__restrict   UNUSEDtls 
)
static

Definition at line 295 of file mesh_normals.cc.

References data, normalize_v3(), normalize_v3_v3(), and UNLIKELY.

Referenced by BKE_mesh_calc_normals_poly_and_vertex().

◆ mesh_calc_normals_poly_fn()

static void mesh_calc_normals_poly_fn ( void *__restrict  userdata,
const int  pidx,
const TaskParallelTLS *__restrict   UNUSEDtls 
)
static

Definition at line 181 of file mesh_normals.cc.

References BKE_mesh_calc_poly_normal(), data, and MPoly::loopstart.

Referenced by BKE_mesh_calc_normals_poly().

◆ mesh_edges_sharp_tag()

static void mesh_edges_sharp_tag ( LoopSplitTaskDataCommon data,
const bool  check_angle,
const float  split_angle,
const bool  do_sharp_edges_tag 
)
static

◆ mesh_normals_loop_custom_set()

static void mesh_normals_loop_custom_set ( const MVert mverts,
const float(*)  vert_normals[3],
const int  numVerts,
MEdge medges,
const int  numEdges,
MLoop mloops,
float(*)  r_custom_loopnors[3],
const int  numLoops,
MPoly mpolys,
const float(*)  polynors[3],
const int  numPolys,
short(*)  r_clnors_data[2],
const bool  use_vertices 
)
static

Compute internal representation of given custom normals (as an array of float[2]). It also makes sure the mesh matches those custom normals, by setting sharp edges flag as needed to get a same custom lnor for all loops sharing a same smooth fan. If use_vertices if true, r_custom_loopnors is assumed to be per-vertex, not per-loop (this allows to set whole vert's normals at once, useful in some cases). r_custom_loopnors is expected to have normalized normals, or zero ones, in which case they will be replaced by default loop/vertex normal.

Definition at line 1753 of file mesh_normals.cc.

References add_v3_v3(), BKE_lnor_space_custom_normal_to_data(), BKE_lnor_spacearr_clear(), BKE_lnor_spacearr_free(), BKE_mesh_normals_loop_split(), BLI_assert, BLI_BITMAP_DISABLE, BLI_BITMAP_ENABLE, BLI_BITMAP_NEW, BLI_bitmap_set_all(), BLI_BITMAP_TEST, BLI_BITMAP_TEST_BOOL, BLI_SMALLSTACK_DECLARE, BLI_SMALLSTACK_POP, BLI_SMALLSTACK_PUSH, copy_v3_v3(), MLoopNorSpaceArray::data_type, dot_v3v3(), MLoop::e, MEdge::flag, MLoopNorSpace::flags, float(), G, G_DEBUG, is_zero_v3(), LinkNode::link, LNOR_SPACE_TRIGO_THRESHOLD, MLoopNorSpace::loops, MPoly::loopstart, MLoopNorSpaceArray::lspacearr, M_PI, ME_SHARP, MEM_calloc_arrayN, MEM_freeN, MEM_malloc_arrayN, MLNOR_SPACE_IS_SINGLE, MLNOR_SPACEARR_LOOP_INDEX, mul_v3_fl(), LinkNode::next, nor, POINTER_AS_INT, MPoly::totloop, v, and zero_v3().

Referenced by BKE_mesh_normals_loop_custom_from_vertices_set(), BKE_mesh_normals_loop_custom_set(), and mesh_set_custom_normals().

◆ mesh_set_custom_normals()

static void mesh_set_custom_normals ( Mesh mesh,
float(*)  r_custom_nors[3],
const bool  use_vertices 
)
static

◆ split_loop_nor_fan_do()

static void split_loop_nor_fan_do ( LoopSplitTaskDataCommon common_data,
LoopSplitTaskData data 
)
static

◆ split_loop_nor_single_do()

static void split_loop_nor_single_do ( LoopSplitTaskDataCommon common_data,
LoopSplitTaskData data 
)
static

◆ unit_float_to_short()

MINLINE short unit_float_to_short ( const float  val)

Definition at line 689 of file mesh_normals.cc.

References floorf.

Referenced by BKE_lnor_space_custom_normal_to_data().

◆ unit_short_to_float()

MINLINE float unit_short_to_float ( const short  val)

Definition at line 684 of file mesh_normals.cc.

References float().

Referenced by BKE_lnor_space_custom_data_to_normal().