60 #define FLT_EQ_NONAN(_fa, _fb) (*((const uint32_t *)&_fa) == *((const uint32_t *)&_fb))
62 float virtual_lock =
r[0];
71 virtual_lock = test_lock;
196 float (*r_poly_normals)[3])
202 BLI_assert((r_poly_normals !=
nullptr) || (mpoly_len == 0));
208 data.pnors = r_poly_normals;
243 float *pnor =
data->pnors ?
data->pnors[pidx] : pnor_temp;
245 const int i_end = mp->
totloop - 1;
252 const float *v_curr = mverts[ml[i_end].
v].
co;
253 for (
int i_next = 0; i_next <= i_end; i_next++) {
254 const float *v_next = mverts[ml[i_next].
v].
co;
266 float edvec_prev[3], edvec_next[3], edvec_end[3];
267 const float *v_curr = mverts[ml[i_end].
v].
co;
268 sub_v3_v3v3(edvec_prev, mverts[ml[i_end - 1].
v].co, v_curr);
272 for (
int i_next = 0, i_curr = i_end; i_next <= i_end; i_curr = i_next++) {
273 const float *v_next = mverts[ml[i_next].
v].
co;
276 if (i_next != i_end) {
286 const float vnor_add[3] = {pnor[0] * fac, pnor[1] * fac, pnor[2] * fac};
301 float *no =
data->vnors[vidx];
312 const int UNUSED(mloop_len),
315 float (*r_poly_normals)[3],
316 float (*r_vert_normals)[3])
322 memset(r_vert_normals, 0,
sizeof(*r_vert_normals) * (
size_t)mvert_len);
328 data.pnors = r_poly_normals;
329 data.vnors = r_vert_normals;
365 float(*vert_normals)[3];
366 float(*poly_normals)[3];
411 float(*poly_normals)[3];
470 float (*r_tri_nors)[3])
473 float(*fnors)[3] = (r_tri_nors) ? r_tri_nors :
475 (
size_t)looptri_num,
sizeof(*fnors),
"meshnormals");
477 if (!tnorms || !fnors) {
481 for (
int i = 0; i < looptri_num; i++) {
483 float *f_no = fnors[i];
484 const uint vtri[3] = {
490 normal_tri_v3(f_no, mverts[vtri[0]].co, mverts[vtri[1]].co, mverts[vtri[2]].co);
502 for (
int i = 0; i < numVerts; i++) {
504 float *no = tnorms[i];
514 if (fnors != r_tri_nors) {
521 const char data_type)
526 if (!lnors_spacearr->
mem) {
529 mem = lnors_spacearr->
mem;
533 mem,
sizeof(
LinkNode) * (size_t)numLoops);
544 *lnors_spacearr_tls = *lnors_spacearr;
556 lnors_spacearr_tls->
mem =
nullptr;
565 if (lnors_spacearr->
mem !=
nullptr) {
576 lnors_spacearr->
mem =
nullptr;
586 #define LNOR_SPACE_TRIGO_THRESHOLD (1.0f - 1e-4f)
596 const float dtp_ref =
dot_v3v3(vec_ref, lnor);
597 const float dtp_other =
dot_v3v3(vec_other, lnor);
664 const bool is_single)
669 lnors_spacearr->
lspacearr[ml_index] = lnor_space;
670 if (bm_loop ==
nullptr) {
686 return (
float)val / (
float)SHRT_MAX;
692 return (
short)
floorf(val * (
float)SHRT_MAX + 0.5f);
696 const short clnor_data[2],
697 float r_custom_lnor[3])
700 if (clnor_data[0] == 0 || lnor_space->
ref_alpha == 0.0f || lnor_space->
ref_beta == 0.0f) {
710 const float alpha = (alphafac > 0.0f ? lnor_space->
ref_alpha : pi2 - lnor_space->
ref_alpha) *
716 if (betafac == 0.0f) {
720 const float sinalpha =
sinf(alpha);
730 const float custom_lnor[3],
731 short r_clnor_data[2])
736 r_clnor_data[0] = r_clnor_data[1] = 0;
743 float vec[3], cos_beta;
782 #define LOOP_SPLIT_TASK_BLOCK_SIZE 1024
828 #define INDEX_UNSET INT_MIN
829 #define INDEX_INVALID -1
831 #define IS_EDGE_SHARP(_e2l) (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))
834 const bool check_angle,
835 const float split_angle,
836 const bool do_sharp_edges_tag)
843 const int numEdges =
data->numEdges;
844 const int numPolys =
data->numPolys;
847 const float(*polynors)[3] =
data->polynors;
849 int(*edge_to_loops)[2] =
data->edge_to_loops;
850 int *loop_to_poly =
data->loop_to_poly;
857 const float split_angle_cos = check_angle ?
cosf(split_angle) : -1.0f;
859 for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
860 const MLoop *ml_curr;
863 const int ml_last_index = (ml_curr_index + mp->
totloop) - 1;
865 ml_curr = &mloops[ml_curr_index];
867 for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) {
868 e2l = edge_to_loops[ml_curr->
e];
870 loop_to_poly[ml_curr_index] = mp_index;
880 if ((e2l[0] | e2l[1]) == 0) {
882 e2l[0] = ml_curr_index;
887 const bool is_angle_sharp = (check_angle &&
888 dot_v3v3(polynors[loop_to_poly[e2l[0]]], polynors[mp_index]) <
897 ml_curr->
v == mloops[e2l[0]].
v || is_angle_sharp) {
903 if (do_sharp_edges_tag && is_angle_sharp) {
908 e2l[1] = ml_curr_index;
917 if (do_sharp_edges_tag) {
926 if (do_sharp_edges_tag) {
929 for (me = (
MEdge *)medges, me_index = 0; me_index < numEdges; me++, me_index++) {
940 const int UNUSED(numVerts),
941 struct MEdge *medges,
943 struct MLoop *mloops,
945 struct MPoly *mpolys,
946 const float (*polynors)[3],
948 const float split_angle)
950 if (split_angle >= (
float)
M_PI) {
957 (
size_t)numEdges,
sizeof(*edge_to_loops), __func__);
960 int *loop_to_poly = (
int *)
MEM_malloc_arrayN((
size_t)numLoops,
sizeof(*loop_to_poly), __func__);
963 common_data.
mverts = mverts;
964 common_data.
medges = medges;
965 common_data.
mloops = mloops;
966 common_data.
mpolys = mpolys;
981 const int *loop_to_poly,
982 const int *e2lfan_curr,
983 const uint mv_pivot_index,
984 const MLoop **r_mlfan_curr,
985 int *r_mlfan_curr_index,
986 int *r_mlfan_vert_index,
987 int *r_mpfan_curr_index)
989 const MLoop *mlfan_next;
990 const MPoly *mpfan_next;
999 *r_mlfan_curr_index = (e2lfan_curr[0] == *r_mlfan_curr_index) ? e2lfan_curr[1] : e2lfan_curr[0];
1000 *r_mpfan_curr_index = loop_to_poly[*r_mlfan_curr_index];
1005 mlfan_next = &mloops[*r_mlfan_curr_index];
1006 mpfan_next = &mpolys[*r_mpfan_curr_index];
1007 if (((*r_mlfan_curr)->v == mlfan_next->
v && (*r_mlfan_curr)->v == mv_pivot_index) ||
1008 ((*r_mlfan_curr)->v != mlfan_next->
v && (*r_mlfan_curr)->v != mv_pivot_index)) {
1010 *r_mlfan_vert_index = *r_mlfan_curr_index;
1011 if (--(*r_mlfan_curr_index) < mpfan_next->
loopstart) {
1017 if (++(*r_mlfan_curr_index) >= mpfan_next->
loopstart + mpfan_next->
totloop) {
1018 *r_mlfan_curr_index = mpfan_next->
loopstart;
1020 *r_mlfan_vert_index = *r_mlfan_curr_index;
1022 *r_mlfan_curr = &mloops[*r_mlfan_curr_index];
1029 const short(*clnors_data)[2] = common_data->
clnors_data;
1039 const int ml_curr_index =
data->ml_curr_index;
1041 const int ml_prev_index =
data->ml_prev_index;
1042 const int *e2l_prev =
data->e2l_prev;
1044 const int mp_index =
data->mp_index;
1052 printf(
"BASIC: handling loop %d / edge %d / vert %d / poly %d\n",
1060 if (lnors_spacearr) {
1061 float vec_curr[3], vec_prev[3];
1063 const uint mv_pivot_index = ml_curr->
v;
1064 const MVert *mv_pivot = &mverts[mv_pivot_index];
1065 const MEdge *me_curr = &medges[ml_curr->
e];
1066 const MVert *mv_2 = (me_curr->
v1 == mv_pivot_index) ? &mverts[me_curr->
v2] :
1067 &mverts[me_curr->
v1];
1068 const MEdge *me_prev = &medges[ml_prev->
e];
1069 const MVert *mv_3 = (me_prev->v1 == mv_pivot_index) ? &mverts[me_prev->v2] :
1070 &mverts[me_prev->v1];
1091 short(*clnors_data)[2] = common_data->
clnors_data;
1107 const int ml_curr_index =
data->ml_curr_index;
1108 const int ml_prev_index =
data->ml_prev_index;
1109 const int mp_index =
data->mp_index;
1110 const int *e2l_prev =
data->e2l_prev;
1120 const uint mv_pivot_index = ml_curr->
v;
1121 const MVert *mv_pivot = &mverts[mv_pivot_index];
1124 const MEdge *me_org = &medges[ml_curr->
e];
1126 const int *e2lfan_curr;
1127 float vec_curr[3], vec_prev[3], vec_org[3];
1128 const MLoop *mlfan_curr;
1129 float lnor[3] = {0.0f, 0.0f, 0.0f};
1132 int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
1135 int clnors_avg[2] = {0, 0};
1136 short(*clnor_ref)[2] =
nullptr;
1137 int clnors_count = 0;
1138 bool clnors_invalid =
false;
1145 e2lfan_curr = e2l_prev;
1146 mlfan_curr = ml_prev;
1147 mlfan_curr_index = ml_prev_index;
1148 mlfan_vert_index = ml_curr_index;
1149 mpfan_curr_index = mp_index;
1157 const MVert *mv_2 = (me_org->
v1 == mv_pivot_index) ? &mverts[me_org->
v2] : &mverts[me_org->
v1];
1163 if (lnors_spacearr) {
1171 const MEdge *me_curr = &medges[mlfan_curr->
e];
1178 const MVert *mv_2 = (me_curr->
v1 == mv_pivot_index) ? &mverts[me_curr->
v2] :
1179 &mverts[me_curr->
v1];
1196 short(*clnor)[2] = &clnors_data[mlfan_vert_index];
1198 clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
1203 clnors_avg[0] += (*clnor)[0];
1204 clnors_avg[1] += (*clnor)[1];
1214 if (lnors_spacearr) {
1217 if (me_curr != me_org) {
1243 e2lfan_curr = edge_to_loops[mlfan_curr->
e];
1252 if (lnors_spacearr) {
1255 copy_v3_v3(lnor, loopnors[mlfan_vert_index]);
1262 if (clnors_invalid) {
1265 clnors_avg[0] /= clnors_count;
1266 clnors_avg[1] /= clnors_count;
1269 printf(
"Invalid clnors in this fan!\n");
1273 clnor[0] = (short)clnors_avg[0];
1274 clnor[1] = (short)clnors_avg[1];
1286 if (
LIKELY(lnor_len != 0.0f)) {
1304 if (
data->e2l_prev) {
1306 data->edge_vectors = edge_vectors;
1331 if (
data->ml_curr ==
nullptr) {
1353 const MPoly *mpolys,
1354 const int (*edge_to_loops)[2],
1355 const int *loop_to_poly,
1356 const int *e2l_prev,
1358 const MLoop *ml_curr,
1359 const MLoop *ml_prev,
1360 const int ml_curr_index,
1361 const int ml_prev_index,
1362 const int mp_curr_index)
1364 const uint mv_pivot_index = ml_curr->
v;
1365 const int *e2lfan_curr;
1366 const MLoop *mlfan_curr;
1369 int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
1371 e2lfan_curr = e2l_prev;
1377 mlfan_curr = ml_prev;
1378 mlfan_curr_index = ml_prev_index;
1379 mlfan_vert_index = ml_curr_index;
1380 mpfan_curr_index = mp_curr_index;
1401 e2lfan_curr = edge_to_loops[mlfan_curr->
e];
1409 if (mlfan_vert_index == ml_curr_index) {
1432 const int numLoops = common_data->
numLoops;
1433 const int numPolys = common_data->
numPolys;
1438 const MLoop *ml_curr;
1439 const MLoop *ml_prev;
1457 if (lnors_spacearr) {
1465 for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
1469 ml_prev_index = ml_last_index;
1471 ml_curr = &mloops[ml_curr_index];
1472 ml_prev = &mloops[ml_prev_index];
1473 lnors = &loopnors[ml_curr_index];
1475 for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++, lnors++) {
1476 const int *e2l_curr = edge_to_loops[ml_curr->
e];
1477 const int *e2l_prev = edge_to_loops[ml_prev->
e];
1480 printf(
"Checking loop %d / edge %u / vert %u (sharp edge: %d, skiploop: %d)",
1518 if (data_idx == 0) {
1522 data = &data_buff[data_idx];
1531 data->ml_curr = ml_curr;
1532 data->ml_prev = ml_prev;
1533 data->ml_curr_index = ml_curr_index;
1535 data->ml_prev_index = ml_prev_index;
1536 data->e2l_prev =
nullptr;
1538 data->mp_index = mp_index;
1539 if (lnors_spacearr) {
1556 data->ml_curr = ml_curr;
1557 data->ml_prev = ml_prev;
1558 data->ml_curr_index = ml_curr_index;
1559 data->ml_prev_index = ml_prev_index;
1560 data->e2l_prev = e2l_prev;
1561 data->mp_index = mp_index;
1562 if (lnors_spacearr) {
1580 ml_prev_index = ml_curr_index;
1586 if (
pool && data_idx) {
1601 const float (*vert_normals)[3],
1602 const int UNUSED(numVerts),
1606 float (*r_loopnors)[3],
1609 const float (*polynors)[3],
1611 const bool use_split_normals,
1612 const float split_angle,
1614 short (*clnors_data)[2],
1615 int *r_loop_to_poly)
1619 BLI_assert(use_split_normals || !(r_lnors_spacearr));
1621 if (!use_split_normals) {
1630 for (mp_index = 0; mp_index < numPolys; mp_index++) {
1631 MPoly *mp = &mpolys[mp_index];
1633 const int ml_index_end = ml_index + mp->
totloop;
1636 for (; ml_index < ml_index_end; ml_index++) {
1637 if (r_loop_to_poly) {
1638 r_loop_to_poly[ml_index] = mp_index;
1641 copy_v3_v3(r_loopnors[ml_index], polynors[mp_index]);
1644 copy_v3_v3(r_loopnors[ml_index], vert_normals[mloops[ml_index].
v]);
1666 (
size_t)numEdges,
sizeof(*edge_to_loops), __func__);
1669 int *loop_to_poly = r_loop_to_poly ? r_loop_to_poly :
1671 (
size_t)numLoops,
sizeof(*loop_to_poly), __func__);
1674 const bool check_angle = (split_angle < (
float)
M_PI) && (clnors_data ==
nullptr);
1682 if (!r_lnors_spacearr && clnors_data) {
1684 r_lnors_spacearr = &_lnors_spacearr;
1686 if (r_lnors_spacearr) {
1695 common_data.
mverts = mverts;
1696 common_data.
medges = medges;
1697 common_data.
mloops = mloops;
1698 common_data.
mpolys = mpolys;
1725 if (!r_loop_to_poly) {
1729 if (r_lnors_spacearr) {
1730 if (r_lnors_spacearr == &_lnors_spacearr) {
1741 #undef INDEX_INVALID
1742 #undef IS_EDGE_SHARP
1754 const float (*vert_normals)[3],
1759 float (*r_custom_loopnors)[3],
1762 const float (*polynors)[3],
1764 short (*r_clnors_data)[2],
1765 const bool use_vertices)
1776 int *loop_to_poly = (
int *)
MEM_malloc_arrayN((
size_t)numLoops,
sizeof(int), __func__);
1779 const bool use_split_normals =
true;
1804 for (
int i = 0; i < numVerts; i++) {
1806 copy_v3_v3(r_custom_loopnors[i], vert_normals[i]);
1811 for (
int i = 0; i < numLoops; i++) {
1826 if (!use_vertices) {
1827 for (
int i = 0; i < numLoops; i++) {
1834 printf(
"WARNING! Getting invalid nullptr loop space for loop %d!\n", i);
1855 MLoop *prev_ml =
nullptr;
1856 const float *org_nor =
nullptr;
1860 MLoop *ml = &mloops[lidx];
1861 const int nidx = lidx;
1862 float *
nor = r_custom_loopnors[nidx];
1872 const MPoly *mp = &mpolys[loop_to_poly[lidx]];
1881 loops = loops->
next;
1890 if (loops && org_nor) {
1892 MLoop *ml = &mloops[lidx];
1893 const int nidx = lidx;
1894 float *
nor = r_custom_loopnors[nidx];
1897 const MPoly *mp = &mpolys[loop_to_poly[lidx]];
1931 for (
int i = 0; i < numLoops; i++) {
1935 printf(
"WARNING! Still getting invalid nullptr loop space in second loop for loop %d!\n",
1948 const int nidx = use_vertices ? (int)mloops[i].
v : i;
1949 float *
nor = r_custom_loopnors[nidx];
1955 int avg_nor_count = 0;
1957 short clnor_data_tmp[2], *clnor_data;
1962 const int nidx = use_vertices ? (int)mloops[lidx].
v : lidx;
1963 float *
nor = r_custom_loopnors[nidx];
1969 loops = loops->
next;
1973 mul_v3_fl(avg_nor, 1.0f / (
float)avg_nor_count);
1977 clnor_data[0] = clnor_data_tmp[0];
1978 clnor_data[1] = clnor_data_tmp[1];
1991 const float (*vert_normals)[3],
1996 float (*r_custom_loopnors)[3],
1999 const float (*polynors)[3],
2001 short (*r_clnors_data)[2])
2019 const float (*vert_normals)[3],
2020 float (*r_custom_vertnors)[3],
2027 const float (*polynors)[3],
2029 short (*r_clnors_data)[2])
2052 if (clnors !=
nullptr) {
2053 memset(clnors, 0,
sizeof(*clnors) * (
size_t)numloops);
2086 const MLoop *mloops,
2088 const float (*clnors)[3],
2089 float (*r_vert_clnors)[3])
2092 (
size_t)numVerts,
sizeof(*vert_loops_count), __func__);
2094 copy_vn_fl((
float *)r_vert_clnors, 3 * numVerts, 0.0f);
2098 for (i = 0, ml = mloops; i < numLoops; i++, ml++) {
2102 vert_loops_count[
v]++;
2105 for (i = 0; i < numVerts; i++) {
2106 mul_v3_fl(r_vert_clnors[i], 1.0f / (
float)vert_loops_count[i]);
2112 #undef LNOR_SPACE_TRIGO_THRESHOLD
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, struct EditMeshData *emd)
void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, struct EditMeshData *emd)
@ MLNOR_SPACEARR_LOOP_INDEX
@ MLNOR_SPACEARR_BMLOOP_PTR
void BKE_mesh_calc_poly_normal(const struct MPoly *mpoly, const struct MLoop *loopstart, const struct MVert *mvarray, float r_no[3])
#define BLI_BITMAP_NEW(_num, _alloc_string)
#define BLI_BITMAP_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
#define BLI_BITMAP_DISABLE(_bitmap, _index)
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits)
#define BLI_BITMAP_SET(_bitmap, _index, _set)
void BLI_linklist_prepend_nlink(LinkNode **listp, void *ptr, LinkNode *nlink) ATTR_NONNULL(1
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)
MINLINE float saacos(float fac)
MINLINE float saacosf(float f)
void accumulate_vertex_normals_tri_v3(float n1[3], float n2[3], float n3[3], const float f_no[3], const float co1[3], const float co2[3], const float co3[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
MINLINE bool compare_v3v3(const float a[3], const float b[3], float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
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 bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
void copy_vn_fl(float *array_tar, int size, float val)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src) ATTR_NONNULL(1
#define BLI_MEMARENA_STD_BUFSIZE
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void * BLI_stack_peek(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_stack_push(BLI_Stack *stack, const void *src) ATTR_NONNULL()
bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_stack_clear(BLI_Stack *stack) ATTR_NONNULL()
void BLI_stack_free(BLI_Stack *stack) ATTR_NONNULL()
void BLI_stack_discard(BLI_Stack *stack) ATTR_NONNULL()
#define BLI_stack_new(esize, descr)
void * BLI_task_pool_user_data(TaskPool *pool)
void BLI_task_pool_work_and_wait(TaskPool *pool)
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
pthread_mutex_t ThreadMutex
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
Read Guarded memory(de)allocation.
Platform independent time functions.
Utility defines for timing/benchmarks.
#define TIMEIT_START_AVERAGED(var)
#define TIMEIT_END_AVERAGED(var)
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE float atomic_cas_float(float *v, float old, float _new)
#define _ATOMIC_LIKELY(x)
ATTR_WARN_UNUSED_RESULT const BMVert * v
IconTextureDrawCall normal
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
size_t(* MEM_allocN_len)(const void *vmemh)
MLoopNorSpace * BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
float(* BKE_mesh_vertex_normals_for_write(Mesh *mesh))[3]
static void mesh_calc_normals_poly_and_vertex_finalize_fn(void *__restrict userdata, const int vidx, const TaskParallelTLS *__restrict UNUSED(tls))
static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
static void mesh_calc_normals_poly_and_vertex_accum_fn(void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls))
void BKE_lnor_space_define(MLoopNorSpace *lnor_space, const float lnor[3], float vec_ref[3], float vec_other[3], BLI_Stack *edge_vectors)
static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common_data)
void BKE_mesh_clear_derived_normals(Mesh *mesh)
static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data, BLI_Stack *edge_vectors)
#define FLT_EQ_NONAN(_fa, _fb)
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])
#define LOOP_SPLIT_TASK_BLOCK_SIZE
MINLINE short unit_float_to_short(const float val)
void BKE_mesh_calc_normals_looptri(MVert *mverts, int numVerts, const MLoop *mloop, const MLoopTri *looptri, int looptri_num, float(*r_tri_nors)[3])
static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops, const char data_type)
void BKE_mesh_vertex_normals_clear_dirty(Mesh *mesh)
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])
static void add_v3_v3_atomic(float r[3], const float a[3])
void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
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])
void BKE_mesh_poly_normals_clear_dirty(Mesh *mesh)
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])
bool BKE_mesh_poly_normals_are_dirty(const Mesh *mesh)
#define LNOR_SPACE_TRIGO_THRESHOLD
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)
bool BKE_mesh_vertex_normals_are_dirty(const Mesh *mesh)
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)
void BKE_mesh_assert_normals_dirty_or_calculated(const Mesh *mesh)
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)
void BKE_mesh_calc_normals(Mesh *mesh)
static void mesh_edges_sharp_tag(LoopSplitTaskDataCommon *data, const bool check_angle, const float split_angle, const bool do_sharp_edges_tag)
void BKE_mesh_normals_tag_dirty(Mesh *mesh)
const float(* BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
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)
void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
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])
void BKE_mesh_set_custom_normals(Mesh *mesh, float(*r_custom_loopnors)[3])
static void mesh_calc_normals_poly_fn(void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls))
float(* BKE_mesh_poly_normals_for_write(Mesh *mesh))[3]
void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3])
void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpaceArray *lnors_spacearr_tls)
const float(* BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
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)
static void loop_split_worker(TaskPool *__restrict pool, void *taskdata)
MINLINE float unit_short_to_float(const short val)
void BKE_lnor_spacearr_tls_init(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpaceArray *lnors_spacearr_tls)
void BKE_mesh_set_custom_normals_from_vertices(Mesh *mesh, float(*r_custom_vertnors)[3])
static void mesh_set_custom_normals(Mesh *mesh, float(*r_custom_nors)[3], const bool use_vertices)
#define IS_EDGE_SHARP(_e2l)
void BKE_lnor_space_add_loop(MLoopNorSpaceArray *lnors_spacearr, MLoopNorSpace *lnor_space, const int ml_index, void *bm_loop, const bool is_single)
void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2])
void isolate_task(const Function &function)
const float(* vertexCos)[3]
const float(* polynors)[3]
const float(* vert_normals)[3]
MLoopNorSpaceArray * lnors_spacearr
MLoopNorSpace * lnor_space
struct LinkNode * loops_pool
MLoopNorSpace ** lspacearr
struct EditMeshData * edit_data
struct BMEditMesh * edit_mesh
ccl_device_inline float beta(float x, float y)