78 for (
int i = 0; i < numVerts; i++) {
117 float (*r_polyNors)[3],
120 const int *origIndexFace,
121 float (*r_faceNors)[3])
143 float (*r_polyNors)[3],
146 const int *origIndexFace,
147 float (*r_faceNors)[3],
148 const bool only_face_normals)
150 float(*pnors)[3] = r_polyNors, (*fnors)[3] = r_faceNors;
153 if (only_face_normals ==
false) {
160 if ((only_face_normals ==
true) && (r_polyNors ==
NULL) && (r_faceNors ==
NULL)) {
171 if (only_face_normals ==
false) {
175 mverts,
NULL, numVerts, mloop, mpolys, numLoops, numPolys, pnors,
false);
179 const MPoly *mp = mpolys;
180 for (
int i = 0; i < numPolys; i++, mp++) {
189 const MFace *mf = mfaces;
190 for (
int i = 0; i < numFaces; i++, mf++, origIndexFace++) {
191 if (*origIndexFace < numPolys) {
196 CLOG_ERROR(&
LOG,
"tessellation face indices are incorrect. normals may look bad.");
201 if (pnors != r_polyNors) {
206 fnors = pnors =
NULL;
238 float *pnor =
data->pnors ?
data->pnors[pidx] : pnor_temp;
239 float(*lnors_weighted)[3] =
data->lnors_weighted;
241 const int nverts = mp->
totloop;
247 int i_prev = nverts - 1;
248 const float *v_prev = mverts[ml[i_prev].
v].
co;
253 for (
int i = 0; i < nverts; i++) {
254 v_curr = mverts[ml[i].
v].
co;
273 const float *prev_edge = edgevecbuf[nverts - 1];
275 for (
int i = 0; i < nverts; i++) {
277 const float *cur_edge = edgevecbuf[i];
286 prev_edge = cur_edge;
298 float *no =
data->vnors[vidx];
309 float (*r_vertnors)[3],
315 float (*r_polynors)[3],
316 const bool only_face_normals)
318 float(*pnors)[3] = r_polynors;
324 if (only_face_normals) {
339 float(*vnors)[3] = r_vertnors;
341 (
size_t)numLoops,
sizeof(*lnors_weighted), __func__);
342 bool free_vnors =
false;
350 memset(vnors, 0,
sizeof(*vnors) * (
size_t)numVerts);
358 .lnors_weighted = lnors_weighted,
369 for (
int lidx = 0; lidx < numLoops; lidx++) {
414 if (do_vert_normals || do_poly_normals) {
415 const bool do_add_poly_nors_cddata = (poly_nors ==
NULL);
416 if (do_add_poly_nors_cddata) {
431 if (do_add_poly_nors_cddata) {
467 float (*r_tri_nors)[3])
470 float(*fnors)[3] = (r_tri_nors) ?
474 if (!tnorms || !fnors) {
478 for (
int i = 0; i < looptri_num; i++) {
480 float *f_no = fnors[i];
481 const unsigned int vtri[3] = {
487 normal_tri_v3(f_no, mverts[vtri[0]].co, mverts[vtri[1]].co, mverts[vtri[2]].co);
499 for (
int i = 0; i < numVerts; i++) {
501 float *no = tnorms[i];
513 if (fnors != r_tri_nors) {
520 const char data_type)
525 if (!lnors_spacearr->
mem) {
528 mem = lnors_spacearr->
mem;
544 if (lnors_spacearr->
mem !=
NULL) {
565 #define LNOR_SPACE_TRIGO_THRESHOLD (1.0f - 1e-4f)
580 const float dtp_ref =
dot_v3v3(vec_ref, lnor);
581 const float dtp_other =
dot_v3v3(vec_other, lnor);
656 const bool is_single)
661 lnors_spacearr->
lspacearr[ml_index] = lnor_space;
662 if (bm_loop ==
NULL) {
668 lnor_space->
loops = bm_loop;
678 return (
float)val / (
float)SHRT_MAX;
684 return (
short)
floorf(val * (
float)SHRT_MAX + 0.5f);
688 const short clnor_data[2],
689 float r_custom_lnor[3])
692 if (clnor_data[0] == 0 || lnor_space->
ref_alpha == 0.0f || lnor_space->
ref_beta == 0.0f) {
708 if (betafac == 0.0f) {
722 const float custom_lnor[3],
723 short r_clnor_data[2])
727 r_clnor_data[0] = r_clnor_data[1] = 0;
734 float vec[3], cos_beta;
773 #define LOOP_SPLIT_TASK_BLOCK_SIZE 1024
818 #define INDEX_UNSET INT_MIN
819 #define INDEX_INVALID -1
821 #define IS_EDGE_SHARP(_e2l) (ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID))
824 const bool check_angle,
825 const float split_angle,
826 const bool do_sharp_edges_tag)
834 const int numEdges =
data->numEdges;
835 const int numPolys =
data->numPolys;
838 const float(*polynors)[3] =
data->polynors;
840 int(*edge_to_loops)[2] =
data->edge_to_loops;
841 int *loop_to_poly =
data->loop_to_poly;
848 const float split_angle_cos = check_angle ?
cosf(split_angle) : -1.0f;
850 for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
851 const MLoop *ml_curr;
854 const int ml_last_index = (ml_curr_index + mp->
totloop) - 1;
856 ml_curr = &mloops[ml_curr_index];
858 for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) {
859 e2l = edge_to_loops[ml_curr->
e];
861 loop_to_poly[ml_curr_index] = mp_index;
871 if ((e2l[0] | e2l[1]) == 0) {
873 e2l[0] = ml_curr_index;
878 const bool is_angle_sharp = (check_angle &&
879 dot_v3v3(polynors[loop_to_poly[e2l[0]]], polynors[mp_index]) <
888 ml_curr->
v == mloops[e2l[0]].
v || is_angle_sharp) {
894 if (do_sharp_edges_tag && is_angle_sharp) {
899 e2l[1] = ml_curr_index;
908 if (do_sharp_edges_tag) {
917 if (do_sharp_edges_tag) {
920 for (me = (
MEdge *)medges, me_index = 0; me_index < numEdges; me++, me_index++) {
937 const int UNUSED(numVerts),
938 struct MEdge *medges,
940 struct MLoop *mloops,
942 struct MPoly *mpolys,
943 const float (*polynors)[3],
945 const float split_angle)
947 if (split_angle >= (
float)
M_PI) {
953 int(*edge_to_loops)[2] =
MEM_calloc_arrayN((
size_t)numEdges,
sizeof(*edge_to_loops), __func__);
956 int *loop_to_poly =
MEM_malloc_arrayN((
size_t)numLoops,
sizeof(*loop_to_poly), __func__);
963 .edge_to_loops = edge_to_loops,
964 .loop_to_poly = loop_to_poly,
965 .polynors = polynors,
966 .numEdges = numEdges,
967 .numPolys = numPolys,
978 const int *loop_to_poly,
979 const int *e2lfan_curr,
980 const uint mv_pivot_index,
981 const MLoop **r_mlfan_curr,
982 int *r_mlfan_curr_index,
983 int *r_mlfan_vert_index,
984 int *r_mpfan_curr_index)
986 const MLoop *mlfan_next;
987 const MPoly *mpfan_next;
997 *r_mlfan_curr_index = (e2lfan_curr[0] == *r_mlfan_curr_index) ? e2lfan_curr[1] : e2lfan_curr[0];
998 *r_mpfan_curr_index = loop_to_poly[*r_mlfan_curr_index];
1003 mlfan_next = &mloops[*r_mlfan_curr_index];
1004 mpfan_next = &mpolys[*r_mpfan_curr_index];
1005 if (((*r_mlfan_curr)->v == mlfan_next->
v && (*r_mlfan_curr)->v == mv_pivot_index) ||
1006 ((*r_mlfan_curr)->v != mlfan_next->
v && (*r_mlfan_curr)->v != mv_pivot_index)) {
1008 *r_mlfan_vert_index = *r_mlfan_curr_index;
1009 if (--(*r_mlfan_curr_index) < mpfan_next->
loopstart) {
1015 if (++(*r_mlfan_curr_index) >= mpfan_next->
loopstart + mpfan_next->
totloop) {
1016 *r_mlfan_curr_index = mpfan_next->
loopstart;
1018 *r_mlfan_vert_index = *r_mlfan_curr_index;
1020 *r_mlfan_curr = &mloops[*r_mlfan_curr_index];
1027 const short(*clnors_data)[2] = common_data->
clnors_data;
1037 const int ml_curr_index =
data->ml_curr_index;
1039 const int ml_prev_index =
data->ml_prev_index;
1040 const int *e2l_prev =
data->e2l_prev;
1042 const int mp_index =
data->mp_index;
1050 printf(
"BASIC: handling loop %d / edge %d / vert %d / poly %d\n",
1058 if (lnors_spacearr) {
1059 float vec_curr[3], vec_prev[3];
1061 const unsigned int mv_pivot_index = ml_curr->
v;
1062 const MVert *mv_pivot = &mverts[mv_pivot_index];
1063 const MEdge *me_curr = &medges[ml_curr->
e];
1064 const MVert *mv_2 = (me_curr->
v1 == mv_pivot_index) ? &mverts[me_curr->
v2] :
1065 &mverts[me_curr->
v1];
1066 const MEdge *me_prev = &medges[ml_prev->
e];
1067 const MVert *mv_3 = (me_prev->v1 == mv_pivot_index) ? &mverts[me_prev->v2] :
1068 &mverts[me_prev->v1];
1090 short(*clnors_data)[2] = common_data->
clnors_data;
1106 const int ml_curr_index =
data->ml_curr_index;
1107 const int ml_prev_index =
data->ml_prev_index;
1108 const int mp_index =
data->mp_index;
1109 const int *e2l_prev =
data->e2l_prev;
1120 const unsigned int 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};
1131 int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
1134 int clnors_avg[2] = {0, 0};
1135 short(*clnor_ref)[2] =
NULL;
1137 bool clnors_invalid =
false;
1144 e2lfan_curr = e2l_prev;
1145 mlfan_curr = ml_prev;
1146 mlfan_curr_index = ml_prev_index;
1147 mlfan_vert_index = ml_curr_index;
1148 mpfan_curr_index = mp_index;
1156 const MVert *mv_2 = (me_org->
v1 == mv_pivot_index) ? &mverts[me_org->
v2] : &mverts[me_org->
v1];
1162 if (lnors_spacearr) {
1170 const MEdge *me_curr = &medges[mlfan_curr->
e];
1177 const MVert *mv_2 = (me_curr->
v1 == mv_pivot_index) ? &mverts[me_curr->
v2] :
1178 &mverts[me_curr->
v1];
1195 short(*clnor)[2] = &clnors_data[mlfan_vert_index];
1197 clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
1202 clnors_avg[0] += (*clnor)[0];
1203 clnors_avg[1] += (*clnor)[1];
1213 if (lnors_spacearr) {
1216 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_nbr;
1266 clnors_avg[1] /= clnors_nbr;
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;
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 unsigned int mv_pivot_index = ml_curr->
v;
1365 const int *e2lfan_curr;
1366 const MLoop *mlfan_curr;
1368 int mlfan_curr_index, mlfan_vert_index, mpfan_curr_index;
1370 e2lfan_curr = e2l_prev;
1376 mlfan_curr = ml_prev;
1377 mlfan_curr_index = ml_prev_index;
1378 mlfan_vert_index = ml_curr_index;
1379 mpfan_curr_index = mp_curr_index;
1400 e2lfan_curr = edge_to_loops[mlfan_curr->
e];
1408 if (mlfan_vert_index == ml_curr_index) {
1431 const int numLoops = common_data->
numLoops;
1432 const int numPolys = common_data->
numPolys;
1437 const MLoop *ml_curr;
1438 const MLoop *ml_prev;
1456 if (lnors_spacearr) {
1464 for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
1468 ml_prev_index = ml_last_index;
1470 ml_curr = &mloops[ml_curr_index];
1471 ml_prev = &mloops[ml_prev_index];
1472 lnors = &loopnors[ml_curr_index];
1474 for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++, lnors++) {
1475 const int *e2l_curr = edge_to_loops[ml_curr->
e];
1476 const int *e2l_prev = edge_to_loops[ml_prev->
e];
1479 printf(
"Checking loop %d / edge %u / vert %u (sharp edge: %d, skiploop: %d)...",
1517 if (data_idx == 0) {
1521 data = &data_buff[data_idx];
1530 data->ml_curr = ml_curr;
1531 data->ml_prev = ml_prev;
1532 data->ml_curr_index = ml_curr_index;
1534 data->ml_prev_index = ml_prev_index;
1537 data->mp_index = mp_index;
1538 if (lnors_spacearr) {
1555 data->ml_curr = ml_curr;
1556 data->ml_prev = ml_prev;
1557 data->ml_curr_index = ml_curr_index;
1558 data->ml_prev_index = ml_prev_index;
1559 data->e2l_prev = e2l_prev;
1560 data->mp_index = mp_index;
1561 if (lnors_spacearr) {
1579 ml_prev_index = ml_curr_index;
1585 if (
pool && data_idx) {
1605 const int UNUSED(numVerts),
1609 float (*r_loopnors)[3],
1612 const float (*polynors)[3],
1614 const bool use_split_normals,
1615 const float split_angle,
1617 short (*clnors_data)[2],
1618 int *r_loop_to_poly)
1622 BLI_assert(use_split_normals || !(r_lnors_spacearr));
1624 if (!use_split_normals) {
1634 for (mp_index = 0; mp_index < numPolys; mp_index++) {
1635 MPoly *mp = &mpolys[mp_index];
1637 const int ml_index_end = ml_index + mp->
totloop;
1640 for (; ml_index < ml_index_end; ml_index++) {
1641 if (r_loop_to_poly) {
1642 r_loop_to_poly[ml_index] = mp_index;
1645 copy_v3_v3(r_loopnors[ml_index], polynors[mp_index]);
1669 int(*edge_to_loops)[2] =
MEM_calloc_arrayN((
size_t)numEdges,
sizeof(*edge_to_loops), __func__);
1672 int *loop_to_poly = r_loop_to_poly ?
1677 const bool check_angle = (split_angle < (
float)
M_PI) && (clnors_data ==
NULL);
1685 if (!r_lnors_spacearr && clnors_data) {
1687 r_lnors_spacearr = &_lnors_spacearr;
1689 if (r_lnors_spacearr) {
1696 .loopnors = r_loopnors,
1697 .clnors_data = clnors_data,
1702 .edge_to_loops = edge_to_loops,
1703 .loop_to_poly = loop_to_poly,
1704 .polynors = polynors,
1705 .numEdges = numEdges,
1706 .numLoops = numLoops,
1707 .numPolys = numPolys,
1728 if (!r_loop_to_poly) {
1732 if (r_lnors_spacearr) {
1733 if (r_lnors_spacearr == &_lnors_spacearr) {
1744 #undef INDEX_INVALID
1745 #undef IS_EDGE_SHARP
1761 float (*r_custom_loopnors)[3],
1764 const float (*polynors)[3],
1766 short (*r_clnors_data)[2],
1767 const bool use_vertices)
1782 const bool use_split_normals =
true;
1806 for (
int i = 0; i < numVerts; i++) {
1813 for (
int i = 0; i < numLoops; i++) {
1829 if (!use_vertices) {
1830 for (
int i = 0; i < numLoops; i++) {
1838 printf(
"WARNING! Getting invalid NULL loop space for loop %d!\n", i);
1860 const float *org_nor =
NULL;
1864 MLoop *ml = &mloops[lidx];
1865 const int nidx = lidx;
1866 float *
nor = r_custom_loopnors[nidx];
1877 const MPoly *mp = &mpolys[loop_to_poly[lidx]];
1886 loops = loops->
next;
1895 if (loops && org_nor) {
1897 MLoop *ml = &mloops[lidx];
1898 const int nidx = lidx;
1899 float *
nor = r_custom_loopnors[nidx];
1902 const MPoly *mp = &mpolys[loop_to_poly[lidx]];
1935 for (
int i = 0; i < numLoops; i++) {
1939 printf(
"WARNING! Still getting invalid NULL loop space in second loop for loop %d!\n", i);
1952 const int nidx = use_vertices ? (int)mloops[i].
v : i;
1953 float *
nor = r_custom_loopnors[nidx];
1961 short clnor_data_tmp[2], *clnor_data;
1966 const int nidx = use_vertices ? (int)mloops[lidx].
v : lidx;
1967 float *
nor = r_custom_loopnors[nidx];
1973 loops = loops->
next;
1977 mul_v3_fl(avg_nor, 1.0f / (
float)nbr_nors);
1981 clnor_data[0] = clnor_data_tmp[0];
1982 clnor_data[1] = clnor_data_tmp[1];
1999 float (*r_custom_loopnors)[3],
2002 const float (*polynors)[3],
2004 short (*r_clnors_data)[2])
2021 float (*r_custom_vertnors)[3],
2028 const float (*polynors)[3],
2030 short (*r_clnors_data)[2])
2052 if (clnors !=
NULL) {
2053 memset(clnors, 0,
sizeof(*clnors) * (
size_t)numloops);
2060 bool free_polynors =
false;
2061 if (polynors ==
NULL) {
2072 free_polynors =
true;
2088 if (free_polynors) {
2124 const MLoop *mloops,
2126 const float (*clnors)[3],
2127 float (*r_vert_clnors)[3])
2129 int *vert_loops_nbr =
MEM_calloc_arrayN((
size_t)numVerts,
sizeof(*vert_loops_nbr), __func__);
2131 copy_vn_fl((
float *)r_vert_clnors, 3 * numVerts, 0.0f);
2135 for (i = 0, ml = mloops; i < numLoops; i++, ml++) {
2136 const unsigned int v = ml->
v;
2139 vert_loops_nbr[
v]++;
2142 for (i = 0; i < numVerts; i++) {
2143 mul_v3_fl(r_vert_clnors[i], 1.0f / (
float)vert_loops_nbr[i]);
2149 #undef LNOR_SPACE_TRIGO_THRESHOLD
2165 const MLoop *loopstart,
2169 const int nverts = mpoly->
totloop;
2170 const float *v_prev = mvert[loopstart[nverts - 1].
v].
co;
2171 const float *v_curr;
2176 for (
int i = 0; i < nverts; i++) {
2177 v_curr = mvert[loopstart[i].
v].
co;
2188 const MLoop *loopstart,
2189 const MVert *mvarray,
2195 else if (mpoly->
totloop == 3) {
2197 r_no, mvarray[loopstart[0].
v].co, mvarray[loopstart[1].
v].co, mvarray[loopstart[2].
v].co);
2199 else if (mpoly->
totloop == 4) {
2201 mvarray[loopstart[0].
v].co,
2202 mvarray[loopstart[1].
v].co,
2203 mvarray[loopstart[2].
v].co,
2204 mvarray[loopstart[3].
v].co);
2214 const MLoop *loopstart,
2215 const float (*vertex_coords)[3],
2218 const int nverts = mpoly->
totloop;
2219 const float *v_prev = vertex_coords[loopstart[nverts - 1].
v];
2220 const float *v_curr;
2225 for (
int i = 0; i < nverts; i++) {
2226 v_curr = vertex_coords[loopstart[i].v];
2237 const MLoop *loopstart,
2238 const float (*vertex_coords)[3],
2244 else if (mpoly->
totloop == 3) {
2246 vertex_coords[loopstart[0].
v],
2247 vertex_coords[loopstart[1].
v],
2248 vertex_coords[loopstart[2].
v]);
2250 else if (mpoly->
totloop == 4) {
2252 vertex_coords[loopstart[0].
v],
2253 vertex_coords[loopstart[1].
v],
2254 vertex_coords[loopstart[2].
v],
2255 vertex_coords[loopstart[3].
v]);
2265 const MLoop *loopstart,
2273 for (
int i = 0; i < mpoly->
totloop; i++) {
2279 const MLoop *loopstart,
2280 const MVert *mvarray,
2285 mvarray[loopstart[0].
v].co,
2286 mvarray[loopstart[1].
v].co,
2287 mvarray[loopstart[2].
v].co);
2289 else if (mpoly->
totloop == 4) {
2291 mvarray[loopstart[0].
v].co,
2292 mvarray[loopstart[1].
v].co,
2293 mvarray[loopstart[2].
v].co,
2294 mvarray[loopstart[3].
v].co);
2306 mvarray[loopstart[0].
v].co, mvarray[loopstart[1].
v].co, mvarray[loopstart[2].
v].co);
2309 const MLoop *l_iter = loopstart;
2313 for (
int i = 0; i < mpoly->
totloop; i++, l_iter++) {
2331 float total_area = 0;
2333 for (mp = mpoly; i--; mp++) {
2349 for (i = 0; i < mpoly->
totloop; i++, l_iter++) {
2350 copy_v2_v2(vertexcos[i], uv_array[l_iter].uv);
2377 const MLoop *loopstart,
2378 const MVert *mvarray,
2381 const float *v_pivot, *v_step1;
2382 float total_volume = 0.0f;
2386 v_pivot = mvarray[loopstart[0].
v].co;
2387 v_step1 = mvarray[loopstart[1].
v].co;
2389 for (
int i = 2; i < mpoly->
totloop; i++) {
2390 const float *v_step2 = mvarray[loopstart[i].
v].co;
2395 total_volume += tetra_volume;
2403 for (
uint j = 0; j < 3; j++) {
2404 r_cent[j] += tetra_volume * (v_pivot[j] + v_step1[j] + v_step2[j]);
2410 return total_volume;
2419 const MLoop *loopstart,
2420 const MVert *mvarray,
2421 const float reference_center[3],
2425 float v_pivot[3], v_step1[3];
2426 float total_volume = 0.0f;
2428 sub_v3_v3v3(v_pivot, mvarray[loopstart[0].
v].co, reference_center);
2429 sub_v3_v3v3(v_step1, mvarray[loopstart[1].
v].co, reference_center);
2430 for (
int i = 2; i < mpoly->
totloop; i++) {
2432 sub_v3_v3v3(v_step2, mvarray[loopstart[i].
v].co, reference_center);
2434 total_volume += tetra_volume;
2435 for (
uint j = 0; j < 3; j++) {
2436 r_cent[j] += tetra_volume * (v_pivot[j] + v_step1[j] + v_step2[j]);
2440 return total_volume;
2450 const MLoop *loopstart,
2451 const MVert *mvarray,
2454 float total_area = 0.0f;
2455 float v1[3],
v2[3], v3[3],
normal[3], tri_cent[3];
2462 for (
int i = 2; i < mpoly->
totloop; i++) {
2466 total_area += tri_area;
2480 const MLoop *loopstart,
2481 const MVert *mvarray,
2487 int i_this = mpoly->
totloop - 1;
2490 sub_v3_v3v3(nor_prev, mvarray[loopstart[i_this - 1].
v].co, mvarray[loopstart[i_this].
v].co);
2493 while (i_next < mpoly->totloop) {
2494 sub_v3_v3v3(nor_next, mvarray[loopstart[i_this].
v].co, mvarray[loopstart[i_next].
v].co);
2507 const MLoop *ml, *ml_next;
2511 ml = &ml_next[i - 1];
2547 for (mvert = me->
mvert; i--; mvert++) {
2569 for (mpoly = me->
mpoly; i--; mpoly++) {
2571 for (
int j = mpoly->
loopstart; j < loopend; j++) {
2600 float total_area = 0.0f;
2606 for (mpoly = me->
mpoly; i--; mpoly++) {
2611 total_area += poly_area;
2635 float total_volume = 0.0f;
2645 for (mpoly = me->
mpoly; i--; mpoly++) {
2651 total_volume += poly_volume;
2654 if (total_volume != 0.0f) {
2658 mul_v3_fl(r_cent, 0.25f / total_volume);
2664 return init_cent_result;
2686 if (looptri_num == 0) {
2690 float totweight = 0.0f;
2693 for (i = 0, lt = looptri; i < looptri_num; i++, lt++) {
2696 const MVert *v3 = &mverts[mloop[lt->
tri[2]].
v];
2705 if (totweight == 0.0f) {
2709 mul_v3_fl(r_center, 1.0f / (3.0f * totweight));
2721 const int mverts_num,
2723 const int looptri_num,
2740 if (looptri_num == 0) {
2750 for (i = 0, lt = looptri; i < looptri_num; i++, lt++) {
2753 const MVert *v3 = &mverts[mloop[lt->
tri[2]].
v];
2773 *r_volume =
fabsf(totvol);
2779 if (totvol != 0.0f) {
2780 mul_v3_fl(r_center, (1.0f / 3.0f) / totvol);
2798 unsigned int lindex[4],
2800 const int UNUSED(polyindex),
2807 const bool hasOrigSpace,
2817 for (i = 0; i < numUV; i++) {
2820 for (j = 0; j < mf_len; j++) {
2826 for (i = 0; i < numCol; i++) {
2829 for (j = 0; j < mf_len; j++) {
2838 for (j = 0; j < mf_len; j++) {
2848 for (j = 0; j < mf_len; j++) {
2857 for (j = 0; j < mf_len; j++) {
2875 const int *polyindices,
2876 unsigned int (*loopindices)[4],
2877 const int num_faces)
2892 unsigned int(*lidx)[4];
2894 for (i = 0; i < numUV; i++) {
2898 for (findex = 0, pidx = polyindices, lidx = loopindices; findex < num_faces;
2899 pidx++, lidx++, findex++, texface++) {
2900 for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) {
2906 for (i = 0; i < numCol; i++) {
2910 for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, mcol++) {
2911 for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) {
2921 for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, mcol++) {
2922 for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) {
2932 for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, of++) {
2933 for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) {
2939 if (hasLoopNormal) {
2943 for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, fnors++) {
2944 for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) {
2950 if (hasLoopTangent) {
2955 for (findex = 0, pidx = polyindices, lidx = loopindices; findex < num_faces;
2956 pidx++, lidx++, findex++) {
2957 int nverts = (mface ? mface[findex].
v4 : (*lidx)[3]) ? 4 : 3;
2958 for (j = nverts; j--;) {
2959 copy_v4_v4(ftangents[findex * 4 + j], ltangents[(*lidx)[j]]);
2968 const int *polyindices,
2969 unsigned int (*loopindices)[4],
2970 const int num_faces,
2971 const char *layer_name)
2984 unsigned int(*lidx)[4];
3002 for (findex = 0, pidx = polyindices, lidx = loopindices; findex < num_faces;
3003 pidx++, lidx++, findex++) {
3004 int nverts = (mface ? mface[findex].
v4 : (*lidx)[3]) ? 4 : 3;
3005 for (j = nverts; j--;) {
3006 copy_v4_v4(ftangents[findex * 4 + j], ltangents[(*lidx)[j]]);
3028 const bool do_face_nor_copy)
3033 #define USE_TESSFACE_SPEEDUP
3034 #define USE_TESSFACE_QUADS
3037 #define TESSFACE_IS_QUAD 1
3045 int *mface_to_poly_map;
3046 unsigned int(*lindices)[4];
3047 int poly_index, mface_index;
3056 mface_to_poly_map =
MEM_malloc_arrayN((
size_t)looptri_num,
sizeof(*mface_to_poly_map), __func__);
3062 for (poly_index = 0; poly_index < totpoly; poly_index++, mp++) {
3063 const unsigned int mp_loopstart = (
unsigned int)mp->
loopstart;
3064 const unsigned int mp_totloop = (
unsigned int)mp->
totloop;
3065 unsigned int l1, l2, l3, l4;
3067 if (mp_totloop < 3) {
3071 #ifdef USE_TESSFACE_SPEEDUP
3073 # define ML_TO_MF(i1, i2, i3) \
3074 mface_to_poly_map[mface_index] = poly_index; \
3075 mf = &mface[mface_index]; \
3076 lidx = lindices[mface_index]; \
3078 l1 = mp_loopstart + i1; \
3079 l2 = mp_loopstart + i2; \
3080 l3 = mp_loopstart + i3; \
3081 mf->v1 = mloop[l1].v; \
3082 mf->v2 = mloop[l2].v; \
3083 mf->v3 = mloop[l3].v; \
3089 mf->mat_nr = mp->mat_nr; \
3090 mf->flag = mp->flag; \
3095 # define ML_TO_MF_QUAD() \
3096 mface_to_poly_map[mface_index] = poly_index; \
3097 mf = &mface[mface_index]; \
3098 lidx = lindices[mface_index]; \
3100 l1 = mp_loopstart + 0; \
3101 l2 = mp_loopstart + 1; \
3102 l3 = mp_loopstart + 2; \
3103 l4 = mp_loopstart + 3; \
3104 mf->v1 = mloop[l1].v; \
3105 mf->v2 = mloop[l2].v; \
3106 mf->v3 = mloop[l3].v; \
3107 mf->v4 = mloop[l4].v; \
3112 mf->mat_nr = mp->mat_nr; \
3113 mf->flag = mp->flag; \
3114 mf->edcode = TESSFACE_IS_QUAD; \
3117 else if (mp_totloop == 3) {
3121 else if (mp_totloop == 4) {
3122 # ifdef USE_TESSFACE_QUADS
3134 const float *co_curr, *co_prev;
3138 float axis_mat[3][3];
3139 float(*projverts)[2];
3140 unsigned int(*tris)[3];
3142 const unsigned int totfilltri = mp_totloop - 2;
3154 ml = mloop + mp_loopstart;
3155 co_prev = mvert[ml[mp_totloop - 1].
v].
co;
3156 for (j = 0; j < mp_totloop; j++, ml++) {
3157 co_curr = mvert[ml->
v].
co;
3168 ml = mloop + mp_loopstart;
3169 for (j = 0; j < mp_totloop; j++, ml++) {
3176 for (j = 0; j < totfilltri; j++) {
3177 unsigned int *tri = tris[j];
3178 lidx = lindices[mface_index];
3180 mface_to_poly_map[mface_index] = poly_index;
3181 mf = &mface[mface_index];
3184 l1 = mp_loopstart + tri[0];
3185 l2 = mp_loopstart + tri[1];
3186 l3 = mp_loopstart + tri[2];
3188 mf->
v1 = mloop[l1].
v;
3189 mf->
v2 = mloop[l2].
v;
3190 mf->
v3 = mloop[l3].
v;
3215 totface = mface_index;
3220 if (
LIKELY(looptri_num != totface)) {
3221 mface =
MEM_reallocN(mface,
sizeof(*mface) * (
size_t)totface);
3223 sizeof(*mface_to_poly_map) * (
size_t)totface);
3233 if (do_face_nor_copy) {
3239 for (mface_index = 0; mface_index < totface; mface_index++) {
3240 copy_v3_v3(fnors[mface_index], pnors[mface_to_poly_map[mface_index]]);
3260 #ifdef USE_TESSFACE_QUADS
3262 for (mface_index = 0; mface_index < totface; mface_index++, mf++) {
3274 #undef USE_TESSFACE_SPEEDUP
3275 #undef USE_TESSFACE_QUADS
3278 #undef ML_TO_MF_QUAD
3294 #define USE_TESSFACE_SPEEDUP
3300 int poly_index, mlooptri_index;
3305 for (poly_index = 0; poly_index < totpoly; poly_index++, mp++) {
3306 const unsigned int mp_loopstart = (
unsigned int)mp->
loopstart;
3307 const unsigned int mp_totloop = (
unsigned int)mp->
totloop;
3308 unsigned int l1, l2, l3;
3309 if (mp_totloop < 3) {
3313 #ifdef USE_TESSFACE_SPEEDUP
3315 # define ML_TO_MLT(i1, i2, i3) \
3317 mlt = &mlooptri[mlooptri_index]; \
3318 l1 = mp_loopstart + i1; \
3319 l2 = mp_loopstart + i2; \
3320 l3 = mp_loopstart + i3; \
3321 ARRAY_SET_ITEMS(mlt->tri, l1, l2, l3); \
3322 mlt->poly = (unsigned int)poly_index; \
3326 else if (mp_totloop == 3) {
3330 else if (mp_totloop == 4) {
3339 mvert[mloop[mlt_a->
tri[1]].v].
co,
3340 mvert[mloop[mlt_a->
tri[2]].v].
co,
3341 mvert[mloop[mlt_b->
tri[2]].v].
co))) {
3343 mlt_a->
tri[2] = mlt_b->
tri[2];
3344 mlt_b->
tri[0] = mlt_a->
tri[1];
3349 const float *co_curr, *co_prev;
3353 float axis_mat[3][3];
3354 float(*projverts)[2];
3355 unsigned int(*tris)[3];
3357 const unsigned int totfilltri = mp_totloop - 2;
3369 ml = mloop + mp_loopstart;
3370 co_prev = mvert[ml[mp_totloop - 1].
v].
co;
3371 for (j = 0; j < mp_totloop; j++, ml++) {
3372 co_curr = mvert[ml->
v].
co;
3383 ml = mloop + mp_loopstart;
3384 for (j = 0; j < mp_totloop; j++, ml++) {
3391 for (j = 0; j < totfilltri; j++) {
3392 unsigned int *tri = tris[j];
3394 mlt = &mlooptri[mlooptri_index];
3397 l1 = mp_loopstart + tri[0];
3398 l2 = mp_loopstart + tri[1];
3399 l3 = mp_loopstart + tri[2];
3402 mlt->
poly = (
unsigned int)poly_index;
3419 #undef USE_TESSFACE_SPEEDUP
3433 MFace *mf = mface + findex;
3435 for (
int i = 0; i < numTex; i++) {
3452 for (
int i = 0; i < numCol; i++) {
3471 const int max = mf->
v4 ? 4 : 3;
3473 for (
int i = 0; i <
max; i++, lnors++, tlnors++) {
3482 int tot = mf->
v4 ? 4 : 3;
3500 const int side = (int)
sqrtf((
float)(fd->
totdisp / corners));
3501 const int side_sq = side * side;
3503 for (
int i = 0; i < tot; i++, disps += side_sq, ld++) {
3513 memcpy(ld->
disps, disps, (
size_t)side_sq *
sizeof(
float[3]));
3516 memset(ld->
disps, 0, (
size_t)side_sq *
sizeof(
float[3]));
3598 int i, j, totloop, totpoly, *polyindex;
3601 #define ME_FGON (1 << 3)
3607 totpoly = totface_i;
3616 for (i = 0; i < totface_i; i++, mf++) {
3617 totloop += mf->
v4 ? 4 : 3;
3636 for (i = 0; i < totedge_i; i++, me++) {
3650 for (i = 0; i < totface_i; i++, mf++, mp++) {
3658 #define ML(v1, v2) \
3661 ml->e = POINTER_AS_UINT(BLI_edgehash_lookup(eh, mf->v1, mf->v2)); \
3692 *r_totpoly = totpoly;
3693 *r_totloop = totloop;
3714 for (
int x = 0;
x < sides;
x++) {
3717 for (
int y = 0;
y <
x;
y++) {
3718 co_a = co[
y * sides +
x];
3719 co_b = co[
x * sides +
y];
3722 SWAP(
float, co_a[0], co_a[1]);
3723 SWAP(
float, co_b[0], co_b[1]);
3725 if (use_loop_mdisp_flip) {
3731 co_a = co[
x * sides +
x];
3733 SWAP(
float, co_a[0], co_a[1]);
3735 if (use_loop_mdisp_flip) {
3754 const bool use_loop_mdisp_flip)
3757 int loopend = loopstart + mpoly->
totloop - 1;
3761 for (
int i = loopstart; i <= loopend; i++) {
3771 unsigned int prev_edge_index = mloop[loopstart].
e;
3772 mloop[loopstart].
e = mloop[loopend].
e;
3774 for (loopstart++; loopend > loopstart; loopstart++, loopend--) {
3775 mloop[loopend].
e = mloop[loopend - 1].
e;
3776 SWAP(
unsigned int, mloop[loopstart].
e, prev_edge_index);
3778 if (!loops_in_ldata) {
3779 SWAP(
MLoop, mloop[loopstart], mloop[loopend]);
3782 swap_v3_v3(lnors[loopstart], lnors[loopend]);
3787 if (loopstart == loopend) {
3788 mloop[loopstart].
e = prev_edge_index;
3809 for (mp = mpoly, i = 0; i < totpoly; mp++, i++) {
3829 for (i = 0; i < totedge; i++) {
3838 for (i = 0; i < totpoly; i++) {
3839 MPoly *p = &mpoly[i];
3841 for (j = 0; j < p->
totloop; j++) {
3857 const int UNUSED(totedge),
3862 for (
const MPoly *mp = mpoly; i--; mp++) {
3865 int j = mp->totloop;
3866 for (ml = &mloop[mp->loopstart]; j--; ml++) {
3874 for (
const MPoly *mp = mpoly; i--; mp++) {
3875 if ((mp->flag &
ME_HIDE) == 0) {
3877 int j = mp->totloop;
3878 for (ml = &mloop[mp->loopstart]; j--; ml++) {
3907 for (
mv = mvert; i--;
mv++) {
3912 for (med = medge; i--; med++) {
3917 for (mp = mpoly; i--; mp++) {
3924 for (ml = &mloop[mp->
loopstart]; j--; ml++) {
3938 const int UNUSED(totvert),
3950 for (med = medge; i--; med++) {
3963 for (mp = mpoly; i--; mp++) {
3969 for (ml = &mloop[mp->
loopstart]; j--; ml++) {
4012 const float (*vert_cos_src)[3],
4013 const float (*vert_cos_dst)[3],
4015 const float (*vert_cos_org)[3],
4016 float (*vert_cos_new)[3])
4021 int *vert_accum =
MEM_calloc_arrayN((
size_t)totvert,
sizeof(*vert_accum), __func__);
4023 memset(vert_cos_new,
'\0',
sizeof(*vert_cos_new) * (
size_t)totvert);
4025 for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
4028 for (
int j = 0; j < mp->
totloop; j++) {
4029 unsigned int v_prev = loopstart[(mp->
totloop + (j - 1)) % mp->
totloop].
v;
4030 unsigned int v_curr = loopstart[j].
v;
4031 unsigned int v_next = loopstart[(j + 1) % mp->
totloop].
v;
4036 vert_cos_dst[v_curr],
4037 vert_cos_org[v_prev],
4038 vert_cos_org[v_curr],
4039 vert_cos_org[v_next],
4040 vert_cos_src[v_prev],
4041 vert_cos_src[v_curr],
4042 vert_cos_src[v_next]);
4045 vert_accum[v_curr] += 1;
4049 for (i = 0; i < totvert; i++) {
4050 if (vert_accum[i]) {
4051 mul_v3_fl(vert_cos_new[i], 1.0f / (
float)vert_accum[i]);
4054 copy_v3_v3(vert_cos_new[i], vert_cos_org[i]);
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
void CustomData_swap(struct CustomData *data, const int index_a, const int index_b)
void CustomData_free(struct CustomData *data, int totelem)
int CustomData_number_of_layers(const struct CustomData *data, int type)
bool CustomData_has_layer(const struct CustomData *data, int type)
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
bool CustomData_is_referenced_layer(struct CustomData *data, int type)
void * CustomData_get_n(const struct CustomData *data, int type, int index, int n)
void CustomData_bmesh_do_versions_update_active_layers(struct CustomData *fdata, struct CustomData *ldata)
void CustomData_external_add(struct CustomData *data, struct ID *id, int type, int totelem, const char *filename)
void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *ldata, int totloop)
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
void * CustomData_get_layer(const struct CustomData *data, int type)
bool CustomData_external_test(struct CustomData *data, int type)
void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *ldata, int total)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
void CustomData_external_read(struct CustomData *data, struct ID *id, CustomDataMask mask, int totelem)
void * CustomData_get(const struct CustomData *data, int index, int type)
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
int test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr)
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd)
bool BKE_mesh_minmax(const struct Mesh *me, float r_min[3], float r_max[3])
int multires_mdisp_corners(struct MDisps *s)
#define BLI_array_alloca(arr, realsize)
#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)
#define BLI_BITMAP_NEW(_tot, _alloc_string)
void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits)
#define BLI_BITMAP_SET(_bitmap, _index, _set)
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP free_value)
EdgeHash * BLI_edgehash_new_ex(const char *info, const unsigned int nentries_reserve)
bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val)
void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val)
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)
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
float area_poly_v3(const float verts[][3], unsigned int nr)
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])
void transform_point_by_tri_v3(float pt_tar[3], float const pt_src[3], const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3], const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3])
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3])
float volume_tri_tetrahedron_signed_v3_6x(const float v1[3], const float v2[3], const float v3[3])
bool is_quad_flip_v3_first_third_fast(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3])
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
float area_poly_v2(const float verts[][2], unsigned int nr)
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
void mid_v3_v3v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
void copy_vn_fl(float *array_tar, const int size, const float val)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
MINLINE bool compare_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT
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 normal_short_to_float_v3(float r[3], const short n[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
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
bool is_finite_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
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])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void swap_v3_v3(float a[3], float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
void BLI_memarena_free(struct MemArena *ma) 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 BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
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_polyfill_calc_arena(const float(*coords)[2], const unsigned int coords_tot, const int coords_sign, unsigned int(*r_tris)[3], struct MemArena *arena)
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)
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
void * BLI_task_pool_user_data(TaskPool *pool)
void BLI_task_pool_work_and_wait(TaskPool *pool)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
TaskPool * BLI_task_pool_create(void *userdata, TaskPriority priority)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
#define UNUSED_FUNCTION(x)
#define INIT_MINMAX(min, max)
#define ARRAY_SET_ITEMS(...)
#define POINTER_FROM_INT(i)
#define UNUSED_VARS_NDEBUG(...)
#define POINTER_AS_INT(i)
#define POINTER_FROM_UINT(i)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define MESH_MLOOPCOL_FROM_MCOL(_mloopcol, _mcol)
#define MESH_MLOOPCOL_TO_MCOL(_mloopcol, _mcol)
Object is a sort of wrapper for general info.
NSNotificationCenter * center
_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 y
_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 v1
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
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...
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
static CCL_NAMESPACE_BEGIN const double alpha
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)
void *(* MEM_mallocN)(size_t len, const char *str)
static void mesh_normals_loop_custom_set(const MVert *mverts, const int numVerts, MEdge *medges, const int numEdges, MLoop *mloops, float(*r_custom_loopnors)[3], const int numLoops, MPoly *mpolys, const float(*polynors)[3], const int numPolys, short(*r_clnors_data)[2], const bool use_vertices)
static void mesh_calc_normals_poly_finalize_cb(void *__restrict userdata, const int vidx, const TaskParallelTLS *__restrict UNUSED(tls))
void BKE_mesh_recalc_looptri(const MLoop *mloop, const MPoly *mpoly, const MVert *mvert, int totloop, int totpoly, MLoopTri *mlooptri)
bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3])
void BKE_mesh_normals_loop_split(const MVert *mverts, const int UNUSED(numVerts), MEdge *medges, const int numEdges, MLoop *mloops, float(*r_loopnors)[3], const int numLoops, MPoly *mpolys, const float(*polynors)[3], const int numPolys, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], int *r_loop_to_poly)
static void mesh_calc_ngon_normal(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvert, float normal[3])
MLoopNorSpace * BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
void BKE_mesh_ensure_normals(Mesh *mesh)
static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, const float reference_center[3], float r_cent[3])
static void mesh_calc_ngon_normal_coords(const MPoly *mpoly, const MLoop *loopstart, const float(*vertex_coords)[3], float r_normal[3])
void BKE_mesh_polygon_flip_ex(MPoly *mpoly, MLoop *mloop, CustomData *ldata, float(*lnors)[3], MDisps *mdisp, const bool use_loop_mdisp_flip)
void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData *ldata, CustomData *pdata, int totedge_i, int totface_i, int totloop_i, int totpoly_i, MEdge *medge, MFace *mface, int *r_totloop, int *r_totpoly, MLoop **r_mloop, MPoly **r_mpoly)
void BKE_mesh_polygons_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly)
static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, MFace *mface, int totloop, int findex, int loopstart, int numTex, int numCol)
static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
void BKE_mesh_calc_normals_mapping(MVert *mverts, int numVerts, const MLoop *mloop, const MPoly *mpolys, int numLoops, int numPolys, float(*r_polyNors)[3], const MFace *mfaces, int numFaces, const int *origIndexFace, float(*r_faceNors)[3])
void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh)
void BKE_mesh_calc_poly_normal(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, float r_no[3])
bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
void BKE_lnor_space_define(MLoopNorSpace *lnor_space, const float lnor[3], float vec_ref[3], float vec_other[3], BLI_Stack *edge_vectors)
void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts, const MLoop *mloop, const MPoly *mpolys, int numLoops, int numPolys, float(*r_polyNors)[3], const MFace *mfaces, int numFaces, const int *origIndexFace, float(*r_faceNors)[3], const bool only_face_normals)
bool BKE_mesh_center_bounds(const Mesh *me, float r_cent[3])
static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common_data)
struct LoopSplitTaskData LoopSplitTaskData
void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data, BLI_Stack *edge_vectors)
#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])
float BKE_mesh_calc_area(const Mesh *me)
static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data)
void BKE_mesh_normals_loop_custom_set(const MVert *mverts, 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])
#define ML_TO_MLT(i1, i2, i3)
void BKE_mesh_calc_poly_angles(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, float angles[])
void BKE_mesh_calc_normals_poly(MVert *mverts, float(*r_vertnors)[3], int numVerts, const MLoop *mloop, const MPoly *mpolys, int numLoops, int numPolys, float(*r_polynors)[3], const bool only_face_normals)
void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops, const char data_type)
void BKE_mesh_flush_hidden_from_polys(Mesh *me)
void BKE_mesh_loops_to_mface_corners(CustomData *fdata, CustomData *ldata, CustomData *UNUSED(pdata), unsigned int lindex[4], int findex, const int UNUSED(polyindex), const int mf_len, const int numUV, const int numCol, const bool hasPCol, const bool hasOrigSpace, const bool hasLNor)
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])
float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray)
struct MeshCalcNormalsData MeshCalcNormalsData
void BKE_mesh_flush_select_from_polys_ex(MVert *mvert, const int totvert, const MLoop *mloop, MEdge *medge, const int totedge, const MPoly *mpoly, const int totpoly)
void BKE_mesh_calc_poly_center(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, float r_cent[3])
#define LNOR_SPACE_TRIGO_THRESHOLD
void BKE_mesh_poly_edgebitmap_insert(unsigned int *edge_bitmap, const MPoly *mp, const MLoop *mloop)
void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata)
void BKE_mesh_calc_relative_deform(const MPoly *mpoly, const int totpoly, const MLoop *mloop, const int totvert, const float(*vert_cos_src)[3], const float(*vert_cos_dst)[3], const float(*vert_cos_org)[3], float(*vert_cos_new)[3])
void BKE_mesh_calc_poly_normal_coords(const MPoly *mpoly, const MLoop *loopstart, const float(*vertex_coords)[3], float r_no[3])
bool BKE_mesh_center_median(const Mesh *me, float r_cent[3])
void BKE_mesh_normals_loop_custom_from_vertices_set(const MVert *mverts, float(*r_custom_vertnors)[3], const int numVerts, MEdge *medges, const int numEdges, MLoop *mloops, const int numLoops, MPoly *mpolys, const float(*polynors)[3], const int numPolys, short(*r_clnors_data)[2])
static bool loop_split_generator_check_cyclic_smooth_fan(const MLoop *mloops, const MPoly *mpolys, const int(*edge_to_loops)[2], const int *loop_to_poly, const int *e2l_prev, BLI_bitmap *skip_loops, const MLoop *ml_curr, const MLoop *ml_prev, const int ml_curr_index, const int ml_prev_index, const int mp_curr_index)
static float UNUSED_FUNCTION() mesh_calc_poly_volume_centroid(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, float r_cent[3])
void BKE_mesh_flush_hidden_from_verts(Mesh *me)
void BKE_mesh_calc_normals(Mesh *mesh)
void BKE_mesh_flush_select_from_verts(Mesh *me)
#define ML_TO_MF(i1, i2, i3)
int BKE_mesh_tessface_calc_ex(CustomData *fdata, CustomData *ldata, CustomData *pdata, MVert *mvert, int totface, int totloop, int totpoly, const bool do_face_nor_copy)
void BKE_mesh_poly_edgehash_insert(EdgeHash *ehash, const MPoly *mp, const MLoop *mloop)
void BKE_mesh_flush_hidden_from_polys_ex(MVert *mvert, const MLoop *mloop, MEdge *medge, const int UNUSED(totedge), const MPoly *mpoly, const int totpoly)
static void mesh_calc_normals_poly_prepare_cb(void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls))
float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array)
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_calc_volume(const MVert *mverts, const int mverts_num, const MLoopTri *looptri, const int looptri_num, const MLoop *mloop, float *r_volume, float r_center[3])
void BKE_mesh_calc_normals_mapping_simple(struct Mesh *mesh)
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_set_custom_normals(Mesh *mesh, float(*r_custom_loopnors)[3])
static bool mesh_calc_center_centroid_ex(const MVert *mverts, int UNUSED(mverts_num), const MLoopTri *looptri, int looptri_num, const MLoop *mloop, float r_center[3])
static void mesh_calc_normals_poly_cb(void *__restrict userdata, const int pidx, const TaskParallelTLS *__restrict UNUSED(tls))
void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3])
static float mesh_calc_poly_area_centroid(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray, float r_cent[3])
void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh)
void BKE_mesh_ensure_normals_for_display(Mesh *mesh)
void BKE_mesh_flush_hidden_from_verts_ex(const MVert *mvert, const MLoop *mloop, MEdge *medge, const int totedge, MPoly *mpoly, const int totpoly)
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)
bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
static void loop_split_worker(TaskPool *__restrict pool, void *taskdata)
void BKE_mesh_flush_select_from_verts_ex(const MVert *mvert, const int UNUSED(totvert), const MLoop *mloop, MEdge *medge, const int totedge, MPoly *mpoly, const int totpoly)
MINLINE float unit_short_to_float(const short val)
static void mesh_calc_ngon_center(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvert, float cent[3])
void BKE_mesh_set_custom_normals_from_vertices(Mesh *mesh, float(*r_custom_vertnors)[3])
static void mesh_calc_normals_vert_fallback(MVert *mverts, int numVerts)
void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, MFace *mface, const int *polyindices, unsigned int(*loopindices)[4], const int num_faces)
void BKE_mesh_flush_select_from_polys(Mesh *me)
static void mesh_set_custom_normals(Mesh *mesh, float(*r_custom_nors)[3], const bool use_vertices)
void BKE_mesh_tangent_loops_to_tessdata(CustomData *fdata, CustomData *ldata, MFace *mface, const int *polyindices, unsigned int(*loopindices)[4], const int num_faces, const char *layer_name)
#define IS_EDGE_SHARP(_e2l)
struct LoopSplitTaskDataCommon LoopSplitTaskDataCommon
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])
static void area(int d1, int d2, int e1, int e2, float weights[2])
CustomDataExternal * external
const float(* vertexCos)[3]
const float(* polynors)[3]
MLoopNorSpaceArray * lnors_spacearr
MLoopNorSpace * lnor_space
struct LinkNode * loops_pool
MLoopNorSpace ** lspacearr
float(* lnors_weighted)[3]
struct EditMeshData * edit_data
struct BMEditMesh * edit_mesh
struct CustomData pdata ldata
struct CustomData vdata edata fdata
ccl_device_inline float beta(float x, float y)