39#define EDGE_TAG_FROM_SPLIT_ANGLE_BYPASS -FLT_MAX
43 const float split_angle_cos);
56#define BM_LNORSPACE_UPDATE _FLAG_MF
68 const float e1diff[3],
69 const float e2diff[3],
76 float dotprod =
dot_v3v3(e1diff, e2diff);
77 if ((l_iter->
prev->
e->
v1 == l_iter->
prev->
v) ^ (l_iter->
e->
v1 == l_iter->
v)) {
119 if (e_first !=
nullptr) {
120 float e1diff[3], e2diff[3];
124 if (l_first !=
nullptr) {
130 if (l_iter->
v ==
v) {
137 }
while ((l_iter = l_iter->
radial_next) != l_first);
165 if (e_first !=
nullptr) {
166 float e1diff[3], e2diff[3];
170 if (l_first !=
nullptr) {
178 if (l_iter->
v ==
v) {
188 }
while ((l_iter = l_iter->
radial_next) != l_first);
245 if (
params->face_normals) {
261 params.face_normals =
true;
297 const int verts_len = bmpinfo->
verts_len;
298 const int faces_len = bmpinfo->
faces_len;
304 if (
params->face_normals) {
317 params.face_normals =
true;
365 int index_face, index_loop = 0;
372 }
while ((l_curr = l_curr->
next) != l_first);
382 float split_angle_cos,
383 const bool do_sharp_edges_tag)
393 if (do_sharp_edges_tag) {
396 if (
e->l !=
nullptr) {
404 if (
e->l !=
nullptr) {
415 if (split_angle >=
float(
M_PI)) {
431 BMLoop *lfan_pivot_next = l_curr;
447 if (lfan_pivot_next == l_curr) {
476 const short (*clnors_data)[2],
477 const int cd_loop_clnors_offset,
478 const bool has_clnors,
526 if (r_lnors_spacearr) {
527 float vec_curr[3], vec_prev[3];
531 const BMVert *v_pivot = l_curr->
v;
554 const short(*clnor)[2] = clnors_data ?
555 &clnors_data[l_curr_index] :
556 static_cast<const short(*)[2]
>(
583 const BMEdge *e_org = l_curr->
e;
584 BMLoop *lfan_pivot, *lfan_pivot_next;
585 int lfan_pivot_index;
586 float lnor[3] = {0.0f, 0.0f, 0.0f};
587 float vec_curr[3], vec_next[3], vec_org[3];
590 int clnors_avg[2] = {0, 0};
591 const short(*clnor_ref)[2] =
nullptr;
592 int clnors_count = 0;
593 bool clnors_invalid =
false;
605 e_next = lfan_pivot->
e;
619 if (r_lnors_spacearr) {
620 edge_vectors->
append(vec_org);
627 if (lfan_pivot_next) {
632 e_next = (lfan_pivot->
e == e_next) ? lfan_pivot->
prev->
e : lfan_pivot->
e;
652 const BMFace *f = lfan_pivot->
f;
660 const short(*clnor)[2] = clnors_data ?
661 &clnors_data[lfan_pivot_index] :
663 lfan_pivot, cd_loop_clnors_offset));
665 clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
670 clnors_avg[0] += (*clnor)[0];
671 clnors_avg[1] += (*clnor)[1];
681 if (r_lnors_spacearr) {
684 if (e_next != e_org) {
686 edge_vectors->
append(vec_next);
700 lfan_pivot = lfan_pivot_next;
708 if (r_lnors_spacearr) {
716 edge_vectors->
clear();
719 if (clnors_invalid) {
722 clnors_avg[0] /= clnors_count;
723 clnors_avg[1] /= clnors_count;
731 clnor[0] = short(clnors_avg[0]);
732 clnor[1] = short(clnors_avg[1]);
747 if (
LIKELY(lnor_len != 0.0f)) {
765 if (r_lnors_spacearr) {
798 (l_a->
v !=
l_b->
v) &&
807 const float split_angle_cos)
811 bool is_smooth =
false;
813 if (split_angle_cos != -1.0f) {
817 if (
dot >= split_angle_cos) {
835 *hflag_p = *hflag_p & ~BM_ELEM_TAG;
848 const float split_angle_cos)
852 bool is_smooth =
false;
854 if (split_angle_cos != -1.0f) {
858 if (
dot >= split_angle_cos) {
886 const short (*clnors_data)[2],
887 const int cd_loop_clnors_offset,
888 const bool do_rebuild,
889 const float split_angle_cos,
905 const bool has_clnors =
true;
907 int loops_of_vert_count = 0;
917 BMLoop *l_curr = e_curr_iter->
l;
918 if (l_curr ==
nullptr) {
927 if (l_curr->
v !=
v) {
937 loops_of_vert_count += 1;
940 if (index_best > index_test) {
941 index_best = index_test;
942 link_best = loops_of_vert;
944 }
while ((l_curr = l_curr->
radial_next) != e_curr_iter->
l);
947 if (
UNLIKELY(loops_of_vert ==
nullptr)) {
954 if (link_best != loops_of_vert) {
955 std::swap(link_best->
link, loops_of_vert->
link);
959 bool loops_of_vert_is_sorted =
false;
962 int loops_of_vert_handled = 0;
964 while (loops_of_vert !=
nullptr) {
966 loops_of_vert = loops_of_vert->
next;
973 cd_loop_clnors_offset,
983 BLI_assert(loops_of_vert_handled <= loops_of_vert_count);
984 if (loops_of_vert_handled == loops_of_vert_count) {
990 if (!loops_of_vert_is_sorted) {
991 if (loops_of_vert && loops_of_vert->
next) {
993 loops_of_vert_is_sorted =
true;
1008 const bool do_rebuild,
1009 const float split_angle_cos,
1016 const bool has_clnors =
false;
1017 const short(*clnors_data)[2] =
nullptr;
1020 const int cd_loop_clnors_offset = -1;
1027 BMLoop *l_curr = e_curr_iter->
l;
1028 if (l_curr ==
nullptr) {
1037 if (l_curr->
v !=
v) {
1041 }
while ((l_curr = l_curr->
radial_next) != e_curr_iter->
l);
1046 BMLoop *l_curr = e_curr_iter->
l;
1047 if (l_curr ==
nullptr) {
1051 if (l_curr->
v !=
v) {
1063 cd_loop_clnors_offset,
1069 }
while ((l_curr = l_curr->
radial_next) != e_curr_iter->
l);
1086 const short (*clnors_data)[2],
1087 const int cd_loop_clnors_offset,
1088 const bool do_rebuild,
1089 const float split_angle_cos)
1093 const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
1099 std::unique_ptr<blender::Vector<blender::float3, 16>> edge_vectors =
nullptr;
1110 if (!r_lnors_spacearr && has_clnors) {
1112 r_lnors_spacearr = &_lnors_spacearr;
1114 if (r_lnors_spacearr) {
1116 edge_vectors = std::make_unique<blender::Vector<blender::float3, 16>>();
1120 int index_face, index_loop = 0;
1122 BMLoop *l_curr, *l_first;
1130 }
while ((l_curr = l_curr->
next) != l_first);
1145 BMLoop *l_curr, *l_first;
1158 cd_loop_clnors_offset,
1164 }
while ((l_curr = l_curr->
next) != l_first);
1167 if (r_lnors_spacearr) {
1168 if (r_lnors_spacearr == &_lnors_spacearr) {
1198 void *__restrict chunk)
1202 if (data->r_lnors_spacearr) {
1203 tls_data->
edge_vectors = MEM_new<blender::Vector<blender::float3, 16>>(__func__);
1205 tls_data->lnors_spacearr = &tls_data->lnors_spacearr_buf;
1208 tls_data->lnors_spacearr =
nullptr;
1214 void *__restrict chunk)
1219 if (data->r_lnors_spacearr) {
1225 void *__restrict chunk)
1230 if (data->r_lnors_spacearr) {
1231 MEM_delete(tls_data->edge_vectors);
1239 if (
v->
e ==
nullptr) {
1250 data->cd_loop_clnors_offset,
1252 data->split_angle_cos,
1254 tls_data->lnors_spacearr,
1255 tls_data->edge_vectors,
1264 if (
v->
e ==
nullptr) {
1275 data->split_angle_cos,
1277 tls_data->lnors_spacearr,
1278 tls_data->edge_vectors,
1288 const short (*clnors_data)[2],
1289 const int cd_loop_clnors_offset,
1290 const bool do_rebuild,
1291 const float split_angle_cos)
1293 const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
1308 if (!r_lnors_spacearr && has_clnors) {
1310 r_lnors_spacearr = &_lnors_spacearr;
1312 if (r_lnors_spacearr) {
1326 settings.userdata_chunk = &tls;
1327 settings.userdata_chunk_size =
sizeof(tls);
1337 data.r_lnos = r_lnos;
1338 data.r_lnors_spacearr = r_lnors_spacearr;
1339 data.clnors_data = clnors_data;
1340 data.cd_loop_clnors_offset = cd_loop_clnors_offset;
1341 data.do_rebuild = do_rebuild;
1342 data.split_angle_cos = split_angle_cos;
1344 BM_iter_parallel(
bm,
1351 if (r_lnors_spacearr) {
1352 if (r_lnors_spacearr == &_lnors_spacearr) {
1363 const short (*clnors_data)[2],
1364 const int cd_loop_clnors_offset,
1365 const bool do_rebuild,
1366 const float split_angle_cos)
1375 cd_loop_clnors_offset,
1386 cd_loop_clnors_offset,
1393#define LNOR_SPACE_TRIGO_THRESHOLD (1.0f - 1e-4f)
1401 const float (*new_lnors)[3])
1404 bool changed =
false;
1416 printf(
"WARNING! Getting invalid nullptr loop space for loop %d!\n", i);
1437 BMLoop *prev_ml =
nullptr;
1438 const float *org_nor =
nullptr;
1443 const float *
nor = new_lnors[lidx];
1463 loops = loops->
next;
1472 if (loops && org_nor) {
1475 const float *
nor = new_lnors[lidx];
1497 short (*r_clnors_data)[2],
1498 const int cd_loop_clnors_offset,
1499 const float (*new_lnors)[3])
1511 printf(
"WARNING! Still getting invalid nullptr loop space in second loop for loop %d!\n",
1530 const float *
nor = new_lnors[lidx];
1531 short *clnor =
static_cast<short *
>(r_clnors_data ?
1532 &r_clnors_data[lidx] :
1539 int avg_nor_count = 0;
1541 short clnor_data_tmp[2], *clnor_data;
1548 const float *
nor = new_lnors[lidx];
1549 short *clnor =
static_cast<short *
>(
1550 r_clnors_data ? &r_clnors_data[lidx] :
1557 loops = loops->next;
1561 mul_v3_fl(avg_nor, 1.0f /
float(avg_nor_count));
1563 lnors_spacearr->
lspacearr[i], avg_nor, clnor_data_tmp);
1566 clnor_data[0] = clnor_data_tmp[0];
1567 clnor_data[1] = clnor_data_tmp[1];
1587 short (*r_clnors_data)[2],
1588 const int cd_loop_clnors_offset,
1589 float (*new_lnors)[3],
1590 const int cd_new_lnors_offset,
1612 cd_loop_clnors_offset,
1617 float(*custom_lnors)[3] = new_lnors;
1619 if (new_lnors ==
nullptr) {
1620 custom_lnors =
static_cast<float(*)[3]
>(
1654 cd_loop_clnors_offset,
1662 bm, r_lnors_spacearr, r_clnors_data, cd_loop_clnors_offset, custom_lnors);
1664 if (custom_lnors != new_lnors) {
1689 BMLoop *l_curr, *l_first;
1700 }
while ((l_curr = l_curr->
next) != l_first);
1708 const bool use_split_normals,
1711 short (*clnors_data)[2],
1712 const int cd_loop_clnors_offset,
1713 const bool do_rebuild)
1716 if (use_split_normals) {
1723 cd_loop_clnors_offset,
1750 bm, {}, {}, {},
true, r_lnors,
bm->
lnor_spacearr,
nullptr, cd_loop_clnors_offset,
false);
1754#define CLEAR_SPACEARRAY_THRESHOLD(x) ((x) / 2)
1844 if (preserve_clnor) {
1852 short(*clnor)[2] =
static_cast<short(*)[2]
>(
1867 bm, {}, {}, {},
true, r_lnors,
bm->
lnor_spacearr,
nullptr, cd_loop_clnors_offset,
true);
1874 if (preserve_clnor) {
1875 short(*clnor)[2] =
static_cast<short(*)[2]
>(
1934 bm, {}, {}, {},
true, lnors, temp,
nullptr, cd_loop_clnors_offset,
true);
1966 const bool do_all_loops_of_vert)
1976 if (do_all_loops_of_vert) {
2014 const bool use_sel_face_history = sel_faces && (sel_edges || sel_verts);
2021 if (use_sel_face_history) {
2032 if (ese_prev->htype ==
BM_VERT) {
2038 do_all_loops_of_vert);
2040 else if (ese_prev->htype ==
BM_EDGE) {
2046 do_all_loops_of_vert);
2052 do_all_loops_of_vert);
2129 float custom_normal[3];
2141 const bool do_all_loops_of_vert)
2168 MEM_mallocN(
sizeof(*lnor_ed) * totloopsel, __func__));
2179 lnors_ed_arr->
totloop = totloopsel;
2184 return lnors_ed_arr;
2225 const short *clnors_data =
static_cast<const short *
>(
2258 cd_custom_normal_offset,
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
void CustomData_set_layer_flag(CustomData *data, eCustomDataType type, int flag)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void BKE_lnor_space_custom_data_to_normal(const MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3])
MLoopNorSpace * BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
@ MLNOR_SPACEARR_BMLOOP_PTR
void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2])
void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, int corner, void *bm_loop, bool is_single)
void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, int numLoops, char data_type)
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)
void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpaceArray *lnors_spacearr_tls)
void BKE_lnor_spacearr_tls_init(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpaceArray *lnors_spacearr_tls)
#define BLI_BITMAP_NEW(_num, _alloc_string)
#define BLI_BITMAP_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
LinkNode * BLI_linklist_sort(LinkNode *list, int(*cmp)(const void *, const void *)) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2)
#define BLI_linklist_prepend_alloca(listp, ptr)
BLI_LINKSTACK_*** wrapper macros for using a LinkNode to store a stack of pointers,...
#define BLI_SMALLSTACK_DECLARE(var, type)
#define BLI_SMALLSTACK_POP(var)
#define BLI_SMALLSTACK_PUSH(var, data)
#define LISTBASE_FOREACH_BACKWARD(type, var, list)
MINLINE int compare_ff(float a, float b, float max_diff)
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
struct MempoolIterData MempoolIterData
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_mempool_settings_defaults(TaskParallelSettings *settings)
#define UNUSED_VARS_NDEBUG(...)
Read Guarded memory(de)allocation.
#define BM_DISK_EDGE_NEXT(e, v)
#define BM_FACE_FIRST_LOOP(p)
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_index_set(ele, index)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
static void bm_mesh_loops_assign_normal_data(BMesh *bm, MLoopNorSpaceArray *lnors_spacearr, short(*r_clnors_data)[2], const int cd_loop_clnors_offset, const float(*new_lnors)[3])
void BM_mesh_normals_update_with_partial(BMesh *bm, const BMPartialUpdate *bmpinfo)
static int bm_loop_index_cmp(const void *a, const void *b)
static void bm_vert_calc_normals_cb(void *, MempoolIterData *mp_v, const TaskParallelTLS *__restrict)
#define CLEAR_SPACEARRAY_THRESHOLD(x)
static void bm_vert_calc_normals_with_coords(BMVert *v, BMVertsCalcNormalsWithCoordsData *data)
static void bm_mesh_loops_calc_normals_for_vert_with_clnors(BMesh *bm, const Span< float3 > vcos, const Span< float3 > fnos, MutableSpan< float3 > r_lnos, const short(*clnors_data)[2], const int cd_loop_clnors_offset, const bool do_rebuild, const float split_angle_cos, MLoopNorSpaceArray *r_lnors_spacearr, blender::Vector< blender::float3, 16 > *edge_vectors, BMVert *v)
void BM_lnorspace_update(BMesh *bm)
static void bm_mesh_loops_calc_normals_for_vert_free_fn(const void *__restrict userdata, void *__restrict chunk)
void BM_mesh_normals_update_ex(BMesh *bm, const BMeshNormalsUpdate_Params *params)
BMesh Compute Normals.
#define BM_LNORSPACE_UPDATE
void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all)
void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges)
static void bm_mesh_loops_custom_normals_set(BMesh *bm, const Span< float3 > vcos, const Span< float3 > fnos, MLoopNorSpaceArray *r_lnors_spacearr, short(*r_clnors_data)[2], const int cd_loop_clnors_offset, float(*new_lnors)[3], const int cd_new_lnors_offset, bool do_split_fans)
void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor)
bool BM_custom_loop_normals_to_vector_layer(BMesh *bm)
static bool bm_mesh_loops_split_lnor_fans(BMesh *bm, MLoopNorSpaceArray *lnors_spacearr, const float(*new_lnors)[3])
void BM_mesh_normals_update_with_partial_ex(BMesh *, const BMPartialUpdate *bmpinfo, const BMeshNormalsUpdate_Params *params)
static void bm_partial_faces_parallel_range_calc_normals_cb(void *userdata, const int iter, const TaskParallelTLS *__restrict)
#define EDGE_TAG_FROM_SPLIT_ANGLE_BYPASS
static void bm_face_calc_normals_cb(void *, MempoolIterData *mp_f, const TaskParallelTLS *__restrict)
static void bm_mesh_loops_calc_normals_for_vert_init_fn(const void *__restrict userdata, void *__restrict chunk)
static void bm_loop_normal_mark_indiv_do_loop(BMLoop *l, BLI_bitmap *loops, MLoopNorSpaceArray *lnor_spacearr, int *totloopsel, const bool do_all_loops_of_vert)
static void bm_mesh_loops_calc_normals__multi_threaded(BMesh *bm, const Span< float3 > vcos, const Span< float3 > fnos, MutableSpan< float3 > r_lnos, MLoopNorSpaceArray *r_lnors_spacearr, const short(*clnors_data)[2], const int cd_loop_clnors_offset, const bool do_rebuild, const float split_angle_cos)
void BM_mesh_normals_update(BMesh *bm)
BMLoopNorEditDataArray * BM_loop_normal_editdata_array_init(BMesh *bm, const bool do_all_loops_of_vert)
static void bm_mesh_loops_calc_normals_no_autosmooth(BMesh *bm, const Span< float3 > vnos, const Span< float3 > fnos, MutableSpan< float3 > r_lnos)
#define LNOR_SPACE_TRIGO_THRESHOLD
void BM_lnorspace_err(BMesh *bm)
static void bm_partial_verts_parallel_range_calc_normal_cb(void *userdata, const int iter, const TaskParallelTLS *__restrict)
BLI_INLINE bool bm_edge_is_smooth_no_angle_test(const BMEdge *e, const BMLoop *l_a, const BMLoop *l_b)
static void bm_edge_tag_from_smooth_and_set_sharp(Span< float3 > fnos, BMEdge *e, const float split_angle_cos)
static void loop_normal_editdata_init(BMesh *bm, BMLoopNorEditData *lnor_ed, BMVert *v, BMLoop *l, const int offset)
void BM_loop_normal_editdata_array_free(BMLoopNorEditDataArray *lnors_ed_arr)
static void bm_vert_calc_normals_with_coords_cb(void *userdata, MempoolIterData *mp_v, const TaskParallelTLS *__restrict)
void BM_lnorspacearr_store(BMesh *bm, MutableSpan< float3 > r_lnors)
static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops, const bool do_all_loops_of_vert)
static void bm_vert_calc_normals_impl(BMVert *v)
static void bm_mesh_loops_calc_normals__single_threaded(BMesh *bm, const Span< float3 > vcos, const Span< float3 > fnos, MutableSpan< float3 > r_lnos, MLoopNorSpaceArray *r_lnors_spacearr, const short(*clnors_data)[2], const int cd_loop_clnors_offset, const bool do_rebuild, const float split_angle_cos)
static void bm_mesh_loops_calc_normals_for_vert_without_clnors(BMesh *bm, const Span< float3 > vcos, const Span< float3 > fnos, MutableSpan< float3 > r_lnos, const bool do_rebuild, const float split_angle_cos, MLoopNorSpaceArray *r_lnors_spacearr, blender::Vector< blender::float3, 16 > *edge_vectors, BMVert *v)
static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm, const Span< float3 > vcos, const Span< float3 > fnos, const short(*clnors_data)[2], const int cd_loop_clnors_offset, const bool has_clnors, blender::Vector< blender::float3, 16 > *edge_vectors, BMLoop *l_curr, MutableSpan< float3 > r_lnos, MLoopNorSpaceArray *r_lnors_spacearr)
static void bm_edge_tag_from_smooth(Span< float3 > fnos, BMEdge *e, const float split_angle_cos)
static void bm_mesh_loops_calc_normals_for_vert_without_clnors_fn(void *userdata, MempoolIterData *mp_v, const TaskParallelTLS *__restrict tls)
BLI_INLINE void bm_vert_calc_normals_accum_loop(const BMLoop *l_iter, const float e1diff[3], const float e2diff[3], const float f_no[3], float v_no[3])
static void bm_mesh_verts_calc_normals(BMesh *bm, const Span< float3 > fnos, const Span< float3 > vcos, MutableSpan< float3 > vnos)
static void bm_mesh_loops_calc_normals_for_vert_with_clnors_fn(void *userdata, MempoolIterData *mp_v, const TaskParallelTLS *__restrict tls)
bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr)
static void bm_mesh_loops_calc_normals_for_vert_reduce_fn(const void *__restrict userdata, void *__restrict, void *__restrict chunk)
static void bm_mesh_loops_calc_normals(BMesh *bm, const Span< float3 > vcos, const Span< float3 > fnos, MutableSpan< float3 > r_lnos, MLoopNorSpaceArray *r_lnors_spacearr, const short(*clnors_data)[2], const int cd_loop_clnors_offset, const bool do_rebuild, const float split_angle_cos)
static void bm_mesh_edges_sharp_tag(BMesh *bm, const Span< float3 > fnos, float split_angle_cos, const bool do_sharp_edges_tag)
void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle)
void BM_verts_calc_normal_vcos(BMesh *bm, const Span< float3 > fnos, const Span< float3 > vcos, MutableSpan< float3 > vnos)
void BM_loops_calc_normal_vcos(BMesh *bm, const Span< float3 > vcos, const Span< float3 > vnos, const Span< float3 > fnos, const bool use_split_normals, MutableSpan< float3 > r_lnos, MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], const int cd_loop_clnors_offset, const bool do_rebuild)
void BM_custom_loop_normals_from_vector_layer(BMesh *bm, bool add_sharp_edges)
float BM_face_calc_normal(const BMFace *f, float r_no[3])
BMESH UPDATE FACE NORMAL.
#define BM_ELEM_API_FLAG_DISABLE(element, f)
#define BM_ELEM_API_FLAG_TEST(element, f)
#define BM_ELEM_API_FLAG_ENABLE(element, f)
BMLoop * BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step)
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
BMLoop * BM_face_vert_share_loop(BMFace *f, BMVert *v)
Return the Loop Shared by Face and Vertex.
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_vert_in_edge(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMLoop * l_b
ATTR_WARN_UNUSED_RESULT const BMVert * v
constexpr bool is_empty() const
constexpr bool is_empty() const
void append(const T &value)
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
static void clear(Message &msg)
float safe_acos_approx(float x)
Frequency::GEOMETRY nor[]
struct BMEditSelection * prev
BMLoopNorEditData ** lidx_to_lnor_editdata
BMLoopNorEditData * lnor_editdata
int cd_custom_normal_offset
struct BMLoop * radial_next
const short(* clnors_data)[2]
int cd_loop_clnors_offset
MLoopNorSpaceArray * r_lnors_spacearr
MutableSpan< float3 > r_lnos
MLoopNorSpaceArray lnors_spacearr_buf
MLoopNorSpaceArray * lnors_spacearr
blender::Vector< blender::float3, 16 > * edge_vectors
BMPartialUpdate_Params params
MutableSpan< float3 > vnos
struct MLoopNorSpaceArray * lnor_spacearr
MLoopNorSpace ** lspacearr