42#define EDGE_TAG_FROM_SPLIT_ANGLE_BYPASS -FLT_MAX
46 const float split_angle_cos);
59#define BM_LNORSPACE_UPDATE _FLAG_MF
71 const float e1diff[3],
72 const float e2diff[3],
79 float dotprod =
dot_v3v3(e1diff, e2diff);
80 if ((l_iter->
prev->
e->
v1 == l_iter->
prev->
v) ^ (l_iter->
e->
v1 == l_iter->
v)) {
122 if (e_first !=
nullptr) {
123 float e1diff[3], e2diff[3];
127 if (l_first !=
nullptr) {
133 if (l_iter->
v ==
v) {
140 }
while ((l_iter = l_iter->
radial_next) != l_first);
168 if (e_first !=
nullptr) {
169 float e1diff[3], e2diff[3];
173 if (l_first !=
nullptr) {
181 if (l_iter->
v ==
v) {
191 }
while ((l_iter = l_iter->
radial_next) != l_first);
248 if (
params->face_normals) {
264 params.face_normals =
true;
285 if (
params->face_normals) {
287 for (const int i : range) {
288 BMFace *f = bmpinfo->faces[i];
289 BM_face_calc_normal(f, f->no);
295 for (const int i : range) {
296 BMVert *v = bmpinfo->verts[i];
297 bm_vert_calc_normals_impl(v);
305 params.face_normals =
true;
353 int index_face, index_loop = 0;
360 }
while ((l_curr = l_curr->
next) != l_first);
370 float split_angle_cos,
371 const bool do_sharp_edges_tag)
381 if (do_sharp_edges_tag) {
384 if (
e->l !=
nullptr) {
392 if (
e->l !=
nullptr) {
403 if (split_angle >=
float(
M_PI)) {
419 BMLoop *lfan_pivot_next = l_curr;
435 if (lfan_pivot_next == l_curr) {
464 const short (*clnors_data)[2],
465 const int cd_loop_clnors_offset,
466 const bool has_clnors,
514 if (r_lnors_spacearr) {
515 float vec_curr[3], vec_prev[3];
519 const BMVert *v_pivot = l_curr->
v;
542 const short (*clnor)[2] = clnors_data ?
543 &clnors_data[l_curr_index] :
544 static_cast<const short (*)[2]
>(
571 const BMEdge *e_org = l_curr->
e;
572 BMLoop *lfan_pivot, *lfan_pivot_next;
573 int lfan_pivot_index;
574 float lnor[3] = {0.0f, 0.0f, 0.0f};
575 float vec_curr[3], vec_next[3], vec_org[3];
578 int clnors_avg[2] = {0, 0};
579 const short (*clnor_ref)[2] =
nullptr;
580 int clnors_count = 0;
581 bool clnors_invalid =
false;
593 e_next = lfan_pivot->
e;
607 if (r_lnors_spacearr) {
608 edge_vectors->
append(vec_org);
614 if (lfan_pivot_next) {
619 e_next = (lfan_pivot->
e == e_next) ? lfan_pivot->
prev->
e : lfan_pivot->
e;
639 const BMFace *f = lfan_pivot->
f;
647 const short (*clnor)[2] = clnors_data ?
648 &clnors_data[lfan_pivot_index] :
650 lfan_pivot, cd_loop_clnors_offset));
652 clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
657 clnors_avg[0] += (*clnor)[0];
658 clnors_avg[1] += (*clnor)[1];
668 if (r_lnors_spacearr) {
671 if (e_next != e_org) {
673 edge_vectors->
append(vec_next);
687 lfan_pivot = lfan_pivot_next;
695 if (r_lnors_spacearr) {
703 edge_vectors->
clear();
706 if (clnors_invalid) {
709 clnors_avg[0] /= clnors_count;
710 clnors_avg[1] /= clnors_count;
718 clnor[0] = short(clnors_avg[0]);
719 clnor[1] = short(clnors_avg[1]);
734 if (
LIKELY(lnor_len != 0.0f)) {
752 if (r_lnors_spacearr) {
783 (
l_b->radial_next == l_a) &&
785 (l_a->
v !=
l_b->v) &&
794 const float split_angle_cos)
798 bool is_smooth =
false;
800 if (split_angle_cos != -1.0f) {
804 if (
dot >= split_angle_cos) {
817 char *hflag_p = &
e->head.hflag;
835 const float split_angle_cos)
839 bool is_smooth =
false;
841 if (split_angle_cos != -1.0f) {
845 if (
dot >= split_angle_cos) {
873 const short (*clnors_data)[2],
874 const int cd_loop_clnors_offset,
875 const bool do_rebuild,
876 const float split_angle_cos,
892 const bool has_clnors =
true;
894 int loops_of_vert_count = 0;
904 BMLoop *l_curr = e_curr_iter->
l;
905 if (l_curr ==
nullptr) {
914 if (l_curr->
v !=
v) {
924 loops_of_vert_count += 1;
927 if (index_best > index_test) {
928 index_best = index_test;
929 link_best = loops_of_vert;
931 }
while ((l_curr = l_curr->
radial_next) != e_curr_iter->
l);
934 if (
UNLIKELY(loops_of_vert ==
nullptr)) {
941 if (link_best != loops_of_vert) {
942 std::swap(link_best->
link, loops_of_vert->
link);
946 bool loops_of_vert_is_sorted =
false;
949 int loops_of_vert_handled = 0;
951 while (loops_of_vert !=
nullptr) {
953 loops_of_vert = loops_of_vert->
next;
960 cd_loop_clnors_offset,
970 BLI_assert(loops_of_vert_handled <= loops_of_vert_count);
971 if (loops_of_vert_handled == loops_of_vert_count) {
977 if (!loops_of_vert_is_sorted) {
978 if (loops_of_vert && loops_of_vert->
next) {
980 loops_of_vert_is_sorted =
true;
995 const bool do_rebuild,
996 const float split_angle_cos,
1003 const bool has_clnors =
false;
1004 const short (*clnors_data)[2] =
nullptr;
1007 const int cd_loop_clnors_offset = -1;
1014 BMLoop *l_curr = e_curr_iter->
l;
1015 if (l_curr ==
nullptr) {
1024 if (l_curr->
v !=
v) {
1028 }
while ((l_curr = l_curr->
radial_next) != e_curr_iter->
l);
1033 BMLoop *l_curr = e_curr_iter->
l;
1034 if (l_curr ==
nullptr) {
1038 if (l_curr->
v !=
v) {
1050 cd_loop_clnors_offset,
1056 }
while ((l_curr = l_curr->
radial_next) != e_curr_iter->
l);
1073 const short (*clnors_data)[2],
1074 const int cd_loop_clnors_offset,
1075 const bool do_rebuild,
1076 const float split_angle_cos)
1080 const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
1086 std::unique_ptr<blender::Vector<blender::float3, 16>> edge_vectors =
nullptr;
1097 if (!r_lnors_spacearr && has_clnors) {
1099 r_lnors_spacearr = &_lnors_spacearr;
1101 if (r_lnors_spacearr) {
1103 edge_vectors = std::make_unique<blender::Vector<blender::float3, 16>>();
1107 int index_face, index_loop = 0;
1109 BMLoop *l_curr, *l_first;
1117 }
while ((l_curr = l_curr->
next) != l_first);
1132 BMLoop *l_curr, *l_first;
1145 cd_loop_clnors_offset,
1151 }
while ((l_curr = l_curr->
next) != l_first);
1154 if (r_lnors_spacearr) {
1155 if (r_lnors_spacearr == &_lnors_spacearr) {
1185 void *__restrict chunk)
1189 if (
data->r_lnors_spacearr) {
1190 tls_data->edge_vectors = MEM_new<blender::Vector<blender::float3, 16>>(__func__);
1192 tls_data->lnors_spacearr = &tls_data->lnors_spacearr_buf;
1195 tls_data->lnors_spacearr =
nullptr;
1201 void *__restrict chunk)
1206 if (
data->r_lnors_spacearr) {
1212 void *__restrict chunk)
1217 if (
data->r_lnors_spacearr) {
1218 MEM_delete(tls_data->edge_vectors);
1226 if (
v->e ==
nullptr) {
1237 data->cd_loop_clnors_offset,
1239 data->split_angle_cos,
1241 tls_data->lnors_spacearr,
1242 tls_data->edge_vectors,
1251 if (
v->e ==
nullptr) {
1262 data->split_angle_cos,
1264 tls_data->lnors_spacearr,
1265 tls_data->edge_vectors,
1275 const short (*clnors_data)[2],
1276 const int cd_loop_clnors_offset,
1277 const bool do_rebuild,
1278 const float split_angle_cos)
1280 const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
1295 if (!r_lnors_spacearr && has_clnors) {
1297 r_lnors_spacearr = &_lnors_spacearr;
1299 if (r_lnors_spacearr) {
1324 data.r_lnos = r_lnos;
1325 data.r_lnors_spacearr = r_lnors_spacearr;
1326 data.clnors_data = clnors_data;
1327 data.cd_loop_clnors_offset = cd_loop_clnors_offset;
1328 data.do_rebuild = do_rebuild;
1329 data.split_angle_cos = split_angle_cos;
1331 BM_iter_parallel(
bm,
1338 if (r_lnors_spacearr) {
1339 if (r_lnors_spacearr == &_lnors_spacearr) {
1350 const short (*clnors_data)[2],
1351 const int cd_loop_clnors_offset,
1352 const bool do_rebuild,
1353 const float split_angle_cos)
1362 cd_loop_clnors_offset,
1373 cd_loop_clnors_offset,
1380#define LNOR_SPACE_TRIGO_THRESHOLD (1.0f - 1e-4f)
1388 const float (*new_lnors)[3])
1391 bool changed =
false;
1395 for (
int i = 0;
i <
bm->totloop;
i++) {
1403 printf(
"WARNING! Getting invalid nullptr loop space for loop %d!\n",
i);
1424 BMLoop *prev_ml =
nullptr;
1425 const float *org_nor =
nullptr;
1430 const float *
nor = new_lnors[lidx];
1450 loops = loops->
next;
1459 if (loops && org_nor) {
1462 const float *
nor = new_lnors[lidx];
1484 short (*r_clnors_data)[2],
1485 const int cd_loop_clnors_offset,
1486 const float (*new_lnors)[3])
1494 for (
int i = 0;
i <
bm->totloop;
i++) {
1498 printf(
"WARNING! Still getting invalid nullptr loop space in second loop for loop %d!\n",
1517 const float *
nor = new_lnors[lidx];
1518 short *clnor =
static_cast<short *
>(r_clnors_data ?
1519 &r_clnors_data[lidx] :
1526 int avg_nor_count = 0;
1528 short clnor_data_tmp[2], *clnor_data;
1535 const float *
nor = new_lnors[lidx];
1536 short *clnor =
static_cast<short *
>(
1537 r_clnors_data ? &r_clnors_data[lidx] :
1544 loops = loops->
next;
1548 mul_v3_fl(avg_nor, 1.0f /
float(avg_nor_count));
1550 lnors_spacearr->
lspacearr[
i], avg_nor, clnor_data_tmp);
1553 clnor_data[0] = clnor_data_tmp[0];
1554 clnor_data[1] = clnor_data_tmp[1];
1574 short (*r_clnors_data)[2],
1575 const int cd_loop_clnors_offset,
1576 float (*new_lnors)[3],
1577 const int cd_new_lnors_offset,
1599 cd_loop_clnors_offset,
1604 float (*custom_lnors)[3] = new_lnors;
1606 if (new_lnors ==
nullptr) {
1607 custom_lnors =
static_cast<float (*)[3]
>(
1619 for (
int i = 0;
i <
bm->totloop;
i++) {
1641 cd_loop_clnors_offset,
1649 bm, r_lnors_spacearr, r_clnors_data, cd_loop_clnors_offset, custom_lnors);
1651 if (custom_lnors != new_lnors) {
1676 BMLoop *l_curr, *l_first;
1687 }
while ((l_curr = l_curr->
next) != l_first);
1695 const bool use_split_normals,
1698 short (*clnors_data)[2],
1699 const int cd_loop_clnors_offset,
1700 const bool do_rebuild)
1703 if (use_split_normals) {
1710 cd_loop_clnors_offset,
1736 bm, {}, {}, {},
true, r_lnors,
bm->lnor_spacearr,
nullptr, cd_loop_clnors_offset,
false);
1740#define CLEAR_SPACEARRAY_THRESHOLD(x) ((x) / 2)
1751 if (
bm->lnor_spacearr ==
nullptr) {
1831 if (preserve_clnor) {
1839 short (*clnor)[2] =
static_cast<short (*)[2]
>(
1844 bm->lnor_spacearr->lspacearr[l_index], *clnor, oldnors[l_index]);
1854 bm, {}, {}, {},
true, r_lnors,
bm->lnor_spacearr,
nullptr, cd_loop_clnors_offset,
true);
1861 if (preserve_clnor) {
1862 short (*clnor)[2] =
static_cast<short (*)[2]
>(
1866 bm->lnor_spacearr->lspacearr[l_index], oldnors[l_index], *clnor);
1898 if (vert_free_offset != -1) {
1910 else if (edge_free_offset != -1) {
1913 else if (face_free_offset != -1) {
1925 else if (loop_free_offset != -1) {
1942 if (
bm->lnor_spacearr ==
nullptr) {
1945 if (
bm->lnor_spacearr->lspacearr ==
nullptr) {
1981 bm, {}, {}, {},
true, lnors, temp,
nullptr, cd_loop_clnors_offset,
true);
1983 for (
int i = 0;
i <
bm->totloop;
i++) {
2013 const bool do_all_loops_of_vert)
2023 if (do_all_loops_of_vert) {
2055 const bool do_all_loops_of_vert,
2066 l, loops,
bm->lnor_spacearr, totloopsel_p, do_all_loops_of_vert);
2074 const bool do_all_loops_of_vert,
2085 l, loops,
bm->lnor_spacearr, totloopsel_p, do_all_loops_of_vert);
2090 l->next, loops,
bm->lnor_spacearr, totloopsel_p, do_all_loops_of_vert);
2095 l->prev, loops,
bm->lnor_spacearr, totloopsel_p, do_all_loops_of_vert);
2104 const bool do_all_loops_of_vert,
2115 l, loops,
bm->lnor_spacearr, totloopsel_p, do_all_loops_of_vert);
2159 const bool use_sel_face_history = sel_faces && (sel_edges || sel_verts);
2166 if (use_sel_face_history) {
2177 if (ese_prev->htype ==
BM_VERT) {
2183 do_all_loops_of_vert);
2185 else if (ese_prev->htype ==
BM_EDGE) {
2191 do_all_loops_of_vert);
2197 do_all_loops_of_vert);
2205 if (totloopsel == 0) {
2232 float custom_normal[3];
2234 bm->lnor_spacearr->lspacearr[l_index], clnors_data, custom_normal);
2240 lnor_ed->
loc =
v->co;
2244 BMesh *
bm,
const bool do_all_loops_of_vert,
const char htype_override)
2267 if (htype_override != 0) {
2269 switch (htype_override) {
2301 lnors_ed_arr->
totloop = totloopsel;
2306 return lnors_ed_arr;
2310 const bool do_all_loops_of_vert)
2354 const short *clnors_data =
static_cast<const short *
>(
2359 bm->lnor_spacearr->lspacearr[l_index], clnors_data, normal);
2371 if (cd_custom_normal_offset == -1) {
2375 if (cd_normal_offset == -1) {
2379 if (
bm->lnor_spacearr ==
nullptr) {
2388 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_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
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)
void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2])
@ MLNOR_SPACEARR_BMLOOP_PTR
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
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_FLOAT_P(ele, offset)
#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)
bool BM_data_layer_free_named(BMesh *bm, CustomData *data, StringRef name)
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const StringRef name)
#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)
BMesh const char void * data
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)
static void bm_loop_normal_mark_edges_impl(BMesh *bm, BLI_bitmap *loops, const bool do_all_loops_of_vert, int *totloopsel_p)
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 int bm_loop_normal_mark_verts(BMesh *bm, BLI_bitmap *loops, const bool do_all_loops_of_vert)
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)
static int bm_loop_normal_mark_faces(BMesh *bm, BLI_bitmap *loops, const bool do_all_loops_of_vert)
BMLoopNorEditDataArray * BM_loop_normal_editdata_array_init_with_htype(BMesh *bm, const bool do_all_loops_of_vert, const char htype_override)
static int bm_loop_normal_mark_edges(BMesh *bm, BLI_bitmap *loops, const bool do_all_loops_of_vert)
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])
static void bm_lnorspace_ensure_from_free_normals(BMesh *bm)
void BM_mesh_normals_update_with_partial_ex(BMesh *, const BMPartialUpdate *bmpinfo, const BMeshNormalsUpdate_Params *params)
#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_faces_impl(BMesh *bm, BLI_bitmap *loops, const bool do_all_loops_of_vert, int *totloopsel_p)
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)
void BM_lnorspace_err(BMesh *bm)
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_loop_normal_mark_verts_impl(BMesh *bm, BLI_bitmap *loops, const bool do_all_loops_of_vert, int *totloopsel_p)
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
IndexRange index_range() const
constexpr bool is_empty() const
constexpr bool is_empty() const
void append(const T &value)
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
void * MEM_mallocN(size_t len, const char *str)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
#define LNOR_SPACE_TRIGO_THRESHOLD
static void clear(Message &msg)
float safe_acos_approx(float x)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 3 > float3
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
blender::Vector< BMFace * > faces
blender::Vector< BMVert * > verts
BMPartialUpdate_Params params
MutableSpan< float3 > vnos
MLoopNorSpace ** lspacearr
TaskParallelReduceFunc func_reduce
TaskParallelFreeFunc func_free
TaskParallelInitFunc func_init
size_t userdata_chunk_size