Blender V4.3
mesh_normals.cc File Reference
#include <climits>
#include "MEM_guardedalloc.h"
#include "BLI_math_geom.h"
#include "BLI_math_vector.h"
#include "BLI_array_utils.hh"
#include "BLI_bit_vector.hh"
#include "BLI_linklist.h"
#include "BLI_math_base.hh"
#include "BLI_math_vector.hh"
#include "BLI_memarena.h"
#include "BLI_span.hh"
#include "BLI_task.hh"
#include "BLI_utildefines.h"
#include "BKE_attribute.hh"
#include "BKE_customdata.hh"
#include "BKE_global.hh"
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.hh"

Go to the source code of this file.

Classes

struct  blender::bke::mesh::CornerSplitTaskDataCommon
 

Namespaces

namespace  blender
 
namespace  blender::bke
 
namespace  blender::bke::mesh
 

Macros

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

Functions

void blender::bke::mesh_vert_normals_assign (Mesh &mesh, Span< float3 > vert_normals)
 
void blender::bke::mesh_vert_normals_assign (Mesh &mesh, Vector< float3 > vert_normals)
 
static CornerNormalSpace blender::bke::mesh::corner_fan_space_define (const float3 &lnor, const float3 &vec_ref, const float3 &vec_other, const Span< float3 > edge_vectors)
 
static float3 blender::bke::mesh::corner_space_custom_data_to_normal (const CornerNormalSpace &lnor_space, const short2 clnor_data)
 
static void blender::bke::mesh::mesh_edges_sharp_tag (const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > corner_edges, const Span< int > corner_to_face_map, const Span< float3 > face_normals, const Span< bool > sharp_faces, const Span< bool > sharp_edges, const float split_angle, MutableSpan< int2 > edge_to_corners, MutableSpan< bool > r_sharp_edges)
 
static void blender::bke::mesh::build_edge_to_corner_map_with_flip_and_sharp (const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > corner_edges, const Span< bool > sharp_faces, const Span< bool > sharp_edges, MutableSpan< int2 > edge_to_corners)
 
static void blender::bke::mesh::corner_manifold_fan_around_vert_next (const Span< int > corner_verts, const OffsetIndices< int > faces, const Span< int > corner_to_face, const int2 e2lfan_curr, const int vert_pivot, int *r_fan_corner, int *r_vert_corner)
 
static void blender::bke::mesh::lnor_space_for_single_fan (CornerSplitTaskDataCommon *common_data, const int corner, const int space_index)
 
static void blender::bke::mesh::split_corner_normal_fan_do (CornerSplitTaskDataCommon *common_data, const int corner, const int space_index, Vector< float3, 16 > *edge_vectors)
 
static bool blender::bke::mesh::corner_split_generator_check_cyclic_smooth_fan (const Span< int > corner_verts, const Span< int > corner_edges, const OffsetIndices< int > faces, const Span< int2 > edge_to_corners, const Span< int > corner_to_face, const int2 e2l_prev, MutableBitSpan skip_corners, const int corner, const int corner_prev)
 
static void blender::bke::mesh::corner_split_generator (CornerSplitTaskDataCommon *common_data, Vector< int, 32 > &r_single_corners, Vector< int, 32 > &r_fan_corners)
 
static void blender::bke::mesh::mesh_normals_corner_custom_set (const Span< float3 > positions, const Span< int2 > edges, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > corner_edges, const Span< float3 > vert_normals, const Span< float3 > face_normals, const Span< bool > sharp_faces, const bool use_vertices, MutableSpan< float3 > r_custom_corner_normals, MutableSpan< bool > sharp_edges, MutableSpan< short2 > r_clnors_data)
 
static void blender::bke::mesh::mesh_set_custom_normals (Mesh *mesh, float(*r_custom_nors)[3], const bool use_vertices)
 
Public Utility Functions

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

bool BKE_mesh_vert_normals_are_dirty (const Mesh *mesh)
 
bool BKE_mesh_face_normals_are_dirty (const Mesh *mesh)
 
Mesh Normal Calculation (Polygons)
static float3 blender::bke::mesh::normal_calc_ngon (const Span< float3 > vert_positions, const Span< int > face_verts)
 
Polygon Data Evaluation
float3 blender::bke::mesh::face_normal_calc (Span< float3 > vert_positions, Span< int > face_verts)
 
Medium-Level Normals Calculation
void blender::bke::mesh::normals_calc_faces (Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, MutableSpan< float3 > face_normals)
 
void blender::bke::mesh::normals_calc_verts (Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face_map, Span< float3 > face_normals, MutableSpan< float3 > vert_normals)
 
Face Corner Normal Calculation
short2 blender::bke::mesh::corner_space_custom_normal_to_data (const CornerNormalSpace &lnor_space, const float3 &custom_lnor)
 
void blender::bke::mesh::edges_sharp_from_angle_set (OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, Span< float3 > face_normals, Span< int > corner_to_face, Span< bool > sharp_faces, const float split_angle, MutableSpan< bool > sharp_edges)
 
void blender::bke::mesh::normals_calc_corners (Span< float3 > vert_positions, Span< int2 > edges, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, Span< int > corner_to_face_map, Span< float3 > vert_normals, Span< float3 > face_normals, Span< bool > sharp_edges, Span< bool > sharp_faces, const short2 *clnors_data, CornerNormalSpaceArray *r_lnors_spacearr, MutableSpan< float3 > r_corner_normals)
 
void blender::bke::mesh::normals_corner_custom_set (Span< float3 > vert_positions, Span< int2 > edges, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, Span< float3 > vert_normals, Span< float3 > face_normals, Span< bool > sharp_faces, MutableSpan< bool > sharp_edges, MutableSpan< float3 > r_custom_corner_normals, MutableSpan< short2 > r_clnors_data)
 
void blender::bke::mesh::normals_corner_custom_set_from_verts (Span< float3 > vert_positions, Span< int2 > edges, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, Span< float3 > vert_normals, Span< float3 > face_normals, Span< bool > sharp_faces, MutableSpan< bool > sharp_edges, MutableSpan< float3 > r_custom_vert_normals, MutableSpan< short2 > r_clnors_data)
 

Mesh Normal Calculation

#define LNOR_SPACE_TRIGO_THRESHOLD   (1.0f - 1e-4f)
 
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], const float vec_ref[3], const float vec_other[3], const blender::Span< blender::float3 > edge_vectors)
 
void BKE_lnor_space_add_loop (MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, const int corner, 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 (const MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3])
 
void BKE_lnor_space_custom_normal_to_data (const MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2])
 
static void normalize_vecs (blender::MutableSpan< blender::float3 > normals)
 
void BKE_mesh_set_custom_normals (Mesh *mesh, float(*r_custom_corner_normals)[3])
 
void BKE_mesh_set_custom_normals_normalized (Mesh *mesh, float(*r_custom_corner_normals)[3])
 
void BKE_mesh_set_custom_normals_from_verts (Mesh *mesh, float(*r_custom_vert_normals)[3])
 
void BKE_mesh_set_custom_normals_from_verts_normalized (Mesh *mesh, float(*r_custom_vert_normals)[3])
 
void BKE_mesh_normals_loop_to_vertex (const int numVerts, const int *corner_verts, const int numLoops, const float(*clnors)[3], float(*r_vert_clnors)[3])
 

Detailed Description

Mesh normal calculation functions.

See also
bmesh_mesh_normals.cc for the equivalent BMesh functionality.

Definition in file mesh_normals.cc.

Macro Definition Documentation

◆ INDEX_INVALID

◆ INDEX_UNSET

◆ IS_EDGE_SHARP

◆ LNOR_SPACE_TRIGO_THRESHOLD

Function Documentation

◆ BKE_lnor_space_add_loop()

void BKE_lnor_space_add_loop ( MLoopNorSpaceArray * lnors_spacearr,
MLoopNorSpace * lnor_space,
int corner,
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 469 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().

◆ BKE_lnor_space_create()

MLoopNorSpace * BKE_lnor_space_create ( MLoopNorSpaceArray * lnors_spacearr)

◆ BKE_lnor_space_custom_data_to_normal()

◆ BKE_lnor_space_custom_normal_to_data()

◆ BKE_lnor_space_define()

void BKE_lnor_space_define ( MLoopNorSpace * lnor_space,
const float lnor[3],
const float vec_ref[3],
const float vec_other[3],
blender::Span< blender::float3 > edge_vectors )

Should only be called once. Beware, this modifies ref_vec and other_vec in place! In case no valid space can be generated, ref_alpha and ref_beta are set to zero (which means 'use auto lnors').

Definition at line 454 of file mesh_normals.cc.

References copy_v3_v3(), MLoopNorSpace::ref_alpha, MLoopNorSpace::ref_beta, MLoopNorSpace::vec_lnor, MLoopNorSpace::vec_ortho, and MLoopNorSpace::vec_ref.

Referenced by bm_mesh_loops_calc_normals_for_loop().

◆ BKE_lnor_spacearr_clear()

◆ BKE_lnor_spacearr_free()

◆ BKE_lnor_spacearr_init()

◆ 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 341 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 348 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_face_normals_are_dirty()

bool BKE_mesh_face_normals_are_dirty ( const Mesh * mesh)

Return true if the mesh face normals either are not stored or are dirty.

Definition at line 68 of file mesh_normals.cc.

Referenced by C_BVHTree_FromObject(), and mesh_calc_tri_tessface().

◆ BKE_mesh_normals_loop_to_vertex()

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

Computes average per-vertex normals from given custom loop normals.

Parameters
clnorsThe computed custom loop normals.
r_vert_clnorsThe (already allocated) array where to store averaged per-vertex normals.

Definition at line 1602 of file mesh_normals.cc.

References add_v3_v3(), copy_vn_fl(), MEM_calloc_arrayN, MEM_freeN(), and mul_v3_fl().

Referenced by displaceModifier_do().

◆ BKE_mesh_set_custom_normals()

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

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

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

Definition at line 1576 of file mesh_normals.cc.

References blender::bke::mesh::mesh_set_custom_normals(), and normalize_vecs().

Referenced by mesh_wrapper_ensure_subdivision(), blender::io::alembic::process_loop_normals(), blender::io::stl::STLMeshHelper::to_mesh(), and MeshImporter::write_geometry().

◆ BKE_mesh_set_custom_normals_from_verts()

void BKE_mesh_set_custom_normals_from_verts ( Mesh * mesh,
float(*) r_custom_vert_normals[3] )

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

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

Definition at line 1589 of file mesh_normals.cc.

References blender::bke::mesh::mesh_set_custom_normals(), and normalize_vecs().

Referenced by blender::io::ply::convert_ply_to_mesh(), and blender::io::alembic::process_vertex_normals().

◆ BKE_mesh_set_custom_normals_from_verts_normalized()

void BKE_mesh_set_custom_normals_from_verts_normalized ( Mesh * mesh,
float(*) r_custom_vert_normals[3] )

Definition at line 1596 of file mesh_normals.cc.

References blender::bke::mesh::mesh_set_custom_normals().

◆ BKE_mesh_set_custom_normals_normalized()

void BKE_mesh_set_custom_normals_normalized ( Mesh * mesh,
float(*) r_custom_corner_normals[3] )

◆ BKE_mesh_vert_normals_are_dirty()

bool BKE_mesh_vert_normals_are_dirty ( const Mesh * mesh)

Return true if the mesh vertex normals either are not stored or are dirty.

Definition at line 63 of file mesh_normals.cc.

Referenced by arrayModifier_doArray().

◆ normalize_vecs()

static void normalize_vecs ( blender::MutableSpan< blender::float3 > normals)
static

◆ unit_float_to_short()

MINLINE short unit_float_to_short ( const float val)

Definition at line 498 of file mesh_normals.cc.

References floorf.

Referenced by blender::bke::mesh::corner_space_custom_normal_to_data().

◆ unit_short_to_float()

MINLINE float unit_short_to_float ( const short val)

Definition at line 493 of file mesh_normals.cc.

References float.

Referenced by blender::bke::mesh::corner_space_custom_data_to_normal().