Cleanup: remove redundant BKE/BLI/BIF headers
[blender.git] / source / blender / blenkernel / intern / mesh_tangent.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/blenkernel/intern/mesh_tangent.c
27  *  \ingroup bke
28  *
29  * Functions to evaluate mesh tangents.
30  */
31
32 #include <limits.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "DNA_mesh_types.h"
37 #include "DNA_meshdata_types.h"
38
39 #include "BLI_utildefines.h"
40 #include "BLI_math.h"
41 #include "BLI_task.h"
42
43 #include "BKE_customdata.h"
44 #include "BKE_mesh.h"
45 #include "BKE_mesh_tangent.h"
46 #include "BKE_mesh_runtime.h"
47 #include "BKE_report.h"
48
49 #include "BLI_strict_flags.h"
50
51 #include "atomic_ops.h"
52 #include "mikktspace.h"
53
54
55 /* -------------------------------------------------------------------- */
56
57 /** \name Mesh Tangent Calculations (Single Layer)
58  * \{ */
59
60 /* Tangent space utils. */
61
62 /* User data. */
63 typedef struct {
64         const MPoly *mpolys;   /* faces */
65         const MLoop *mloops;   /* faces's vertices */
66         const MVert *mverts;   /* vertices */
67         const MLoopUV *luvs;   /* texture coordinates */
68         float (*lnors)[3];     /* loops' normals */
69         float (*tangents)[4];  /* output tangents */
70         int num_polys;         /* number of polygons */
71 } BKEMeshToTangent;
72
73 /* Mikktspace's API */
74 static int get_num_faces(const SMikkTSpaceContext *pContext)
75 {
76         BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
77         return p_mesh->num_polys;
78 }
79
80 static int get_num_verts_of_face(const SMikkTSpaceContext *pContext, const int face_idx)
81 {
82         BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
83         return p_mesh->mpolys[face_idx].totloop;
84 }
85
86 static void get_position(const SMikkTSpaceContext *pContext, float r_co[3], const int face_idx, const int vert_idx)
87 {
88         BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
89         const int loop_idx = p_mesh->mpolys[face_idx].loopstart + vert_idx;
90         copy_v3_v3(r_co, p_mesh->mverts[p_mesh->mloops[loop_idx].v].co);
91 }
92
93 static void get_texture_coordinate(
94         const SMikkTSpaceContext *pContext, float r_uv[2], const int face_idx,
95         const int vert_idx)
96 {
97         BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
98         copy_v2_v2(r_uv, p_mesh->luvs[p_mesh->mpolys[face_idx].loopstart + vert_idx].uv);
99 }
100
101 static void get_normal(const SMikkTSpaceContext *pContext, float r_no[3], const int face_idx, const int vert_idx)
102 {
103         BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
104         copy_v3_v3(r_no, p_mesh->lnors[p_mesh->mpolys[face_idx].loopstart + vert_idx]);
105 }
106
107 static void set_tspace(
108         const SMikkTSpaceContext *pContext, const float fv_tangent[3], const float face_sign,
109         const int face_idx, const int vert_idx)
110 {
111         BKEMeshToTangent *p_mesh = (BKEMeshToTangent *)pContext->m_pUserData;
112         float *p_res = p_mesh->tangents[p_mesh->mpolys[face_idx].loopstart + vert_idx];
113         copy_v3_v3(p_res, fv_tangent);
114         p_res[3] = face_sign;
115 }
116
117 /**
118  * Compute simplified tangent space normals, i.e. tangent vector + sign of bi-tangent one, which combined with
119  * split normals can be used to recreate the full tangent space.
120  * Note: * The mesh should be made of only tris and quads!
121  */
122 void BKE_mesh_calc_loop_tangent_single_ex(
123         const MVert *mverts, const int UNUSED(numVerts), const MLoop *mloops,
124         float (*r_looptangent)[4], float (*loopnors)[3], const MLoopUV *loopuvs,
125         const int UNUSED(numLoops), const MPoly *mpolys, const int numPolys,
126         ReportList *reports)
127 {
128         BKEMeshToTangent mesh_to_tangent = {NULL};
129         SMikkTSpaceContext s_context = {NULL};
130         SMikkTSpaceInterface s_interface = {NULL};
131
132         const MPoly *mp;
133         int mp_index;
134
135         /* First check we do have a tris/quads only mesh. */
136         for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
137                 if (mp->totloop > 4) {
138                         BKE_report(reports, RPT_ERROR, "Tangent space can only be computed for tris/quads, aborting");
139                         return;
140                 }
141         }
142
143         /* Compute Mikktspace's tangent normals. */
144         mesh_to_tangent.mpolys = mpolys;
145         mesh_to_tangent.mloops = mloops;
146         mesh_to_tangent.mverts = mverts;
147         mesh_to_tangent.luvs = loopuvs;
148         mesh_to_tangent.lnors = loopnors;
149         mesh_to_tangent.tangents = r_looptangent;
150         mesh_to_tangent.num_polys = numPolys;
151
152         s_context.m_pUserData = &mesh_to_tangent;
153         s_context.m_pInterface = &s_interface;
154         s_interface.m_getNumFaces = get_num_faces;
155         s_interface.m_getNumVerticesOfFace = get_num_verts_of_face;
156         s_interface.m_getPosition = get_position;
157         s_interface.m_getTexCoord = get_texture_coordinate;
158         s_interface.m_getNormal = get_normal;
159         s_interface.m_setTSpaceBasic = set_tspace;
160
161         /* 0 if failed */
162         if (genTangSpaceDefault(&s_context) == false) {
163                 BKE_report(reports, RPT_ERROR, "Mikktspace failed to generate tangents for this mesh!");
164         }
165 }
166
167 /**
168  * Wrapper around BKE_mesh_calc_loop_tangent_single_ex, which takes care of most boiling code.
169  * \note
170  * - There must be a valid loop's CD_NORMALS available.
171  * - The mesh should be made of only tris and quads!
172  */
173 void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, const char *uvmap, float (*r_looptangents)[4], ReportList *reports)
174 {
175         MLoopUV *loopuvs;
176         float (*loopnors)[3];
177
178         /* Check we have valid texture coordinates first! */
179         if (uvmap) {
180                 loopuvs = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvmap);
181         }
182         else {
183                 loopuvs = CustomData_get_layer(&mesh->ldata, CD_MLOOPUV);
184         }
185         if (!loopuvs) {
186                 BKE_reportf(reports, RPT_ERROR, "Tangent space computation needs an UVMap, \"%s\" not found, aborting", uvmap);
187                 return;
188         }
189
190         loopnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
191         if (!loopnors) {
192                 BKE_report(reports, RPT_ERROR, "Tangent space computation needs loop normals, none found, aborting");
193                 return;
194         }
195
196         BKE_mesh_calc_loop_tangent_single_ex(
197                 mesh->mvert, mesh->totvert, mesh->mloop, r_looptangents,
198                 loopnors, loopuvs, mesh->totloop, mesh->mpoly, mesh->totpoly, reports);
199 }
200
201 /** \} */
202
203
204 /* -------------------------------------------------------------------- */
205
206 /** \name Mesh Tangent Calculations (All Layers)
207  * \{ */
208
209
210 /* Necessary complexity to handle looptri's as quads for correct tangents */
211 #define USE_LOOPTRI_DETECT_QUADS
212
213 typedef struct {
214         const float (*precomputedFaceNormals)[3];
215         const float (*precomputedLoopNormals)[3];
216         const MLoopTri *looptri;
217         MLoopUV *mloopuv;   /* texture coordinates */
218         const MPoly *mpoly;       /* indices */
219         const MLoop *mloop;       /* indices */
220         const MVert *mvert;       /* vertices & normals */
221         const float (*orco)[3];
222         float (*tangent)[4];    /* destination */
223         int numTessFaces;
224
225 #ifdef USE_LOOPTRI_DETECT_QUADS
226         /* map from 'fake' face index to looptri,
227          * quads will point to the first looptri of the quad */
228         const int    *face_as_quad_map;
229         int       num_face_as_quad_map;
230 #endif
231
232 } SGLSLMeshToTangent;
233
234 /* interface */
235 static int dm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
236 {
237         SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
238
239 #ifdef USE_LOOPTRI_DETECT_QUADS
240         return pMesh->num_face_as_quad_map;
241 #else
242         return pMesh->numTessFaces;
243 #endif
244 }
245
246 static int dm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
247 {
248 #ifdef USE_LOOPTRI_DETECT_QUADS
249         SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
250         if (pMesh->face_as_quad_map) {
251                 const MLoopTri *lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
252                 const MPoly *mp = &pMesh->mpoly[lt->poly];
253                 if (mp->totloop == 4) {
254                         return 4;
255                 }
256         }
257         return 3;
258 #else
259         UNUSED_VARS(pContext, face_num);
260         return 3;
261 #endif
262 }
263
264 static void dm_ts_GetPosition(
265         const SMikkTSpaceContext *pContext, float r_co[3],
266         const int face_num, const int vert_index)
267 {
268         //assert(vert_index >= 0 && vert_index < 4);
269         SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
270         const MLoopTri *lt;
271         uint loop_index;
272         const float *co;
273
274 #ifdef USE_LOOPTRI_DETECT_QUADS
275         if (pMesh->face_as_quad_map) {
276                 lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
277                 const MPoly *mp = &pMesh->mpoly[lt->poly];
278                 if (mp->totloop == 4) {
279                         loop_index = (uint)(mp->loopstart + vert_index);
280                         goto finally;
281                 }
282                 /* fall through to regular triangle */
283         }
284         else {
285                 lt = &pMesh->looptri[face_num];
286         }
287 #else
288         lt = &pMesh->looptri[face_num];
289 #endif
290         loop_index = lt->tri[vert_index];
291
292 finally:
293         co = pMesh->mvert[pMesh->mloop[loop_index].v].co;
294         copy_v3_v3(r_co, co);
295 }
296
297 static void dm_ts_GetTextureCoordinate(
298         const SMikkTSpaceContext *pContext, float r_uv[2],
299         const int face_num, const int vert_index)
300 {
301         //assert(vert_index >= 0 && vert_index < 4);
302         SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
303         const MLoopTri *lt;
304         uint loop_index;
305
306 #ifdef USE_LOOPTRI_DETECT_QUADS
307         if (pMesh->face_as_quad_map) {
308                 lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
309                 const MPoly *mp = &pMesh->mpoly[lt->poly];
310                 if (mp->totloop == 4) {
311                         loop_index = (uint)(mp->loopstart + vert_index);
312                         goto finally;
313                 }
314                 /* fall through to regular triangle */
315         }
316         else {
317                 lt = &pMesh->looptri[face_num];
318         }
319 #else
320         lt = &pMesh->looptri[face_num];
321 #endif
322         loop_index = lt->tri[vert_index];
323
324 finally:
325         if (pMesh->mloopuv != NULL) {
326                 const float *uv = pMesh->mloopuv[loop_index].uv;
327                 copy_v2_v2(r_uv, uv);
328         }
329         else {
330                 const float *orco = pMesh->orco[pMesh->mloop[loop_index].v];
331                 map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
332         }
333 }
334
335 static void dm_ts_GetNormal(
336         const SMikkTSpaceContext *pContext, float r_no[3],
337         const int face_num, const int vert_index)
338 {
339         //assert(vert_index >= 0 && vert_index < 4);
340         SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
341         const MLoopTri *lt;
342         uint loop_index;
343
344 #ifdef USE_LOOPTRI_DETECT_QUADS
345         if (pMesh->face_as_quad_map) {
346                 lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
347                 const MPoly *mp = &pMesh->mpoly[lt->poly];
348                 if (mp->totloop == 4) {
349                         loop_index = (uint)(mp->loopstart + vert_index);
350                         goto finally;
351                 }
352                 /* fall through to regular triangle */
353         }
354         else {
355                 lt = &pMesh->looptri[face_num];
356         }
357 #else
358         lt = &pMesh->looptri[face_num];
359 #endif
360         loop_index = lt->tri[vert_index];
361
362 finally:
363         if (pMesh->precomputedLoopNormals) {
364                 copy_v3_v3(r_no, pMesh->precomputedLoopNormals[loop_index]);
365         }
366         else if ((pMesh->mpoly[lt->poly].flag & ME_SMOOTH) == 0) {  /* flat */
367                 if (pMesh->precomputedFaceNormals) {
368                         copy_v3_v3(r_no, pMesh->precomputedFaceNormals[lt->poly]);
369                 }
370                 else {
371 #ifdef USE_LOOPTRI_DETECT_QUADS
372                         const MPoly *mp = &pMesh->mpoly[lt->poly];
373                         if (mp->totloop == 4) {
374                                 normal_quad_v3(
375                                         r_no,
376                                         pMesh->mvert[pMesh->mloop[mp->loopstart + 0].v].co,
377                                         pMesh->mvert[pMesh->mloop[mp->loopstart + 1].v].co,
378                                         pMesh->mvert[pMesh->mloop[mp->loopstart + 2].v].co,
379                                         pMesh->mvert[pMesh->mloop[mp->loopstart + 3].v].co);
380                         }
381                         else
382 #endif
383                         {
384                                 normal_tri_v3(
385                                         r_no,
386                                         pMesh->mvert[pMesh->mloop[lt->tri[0]].v].co,
387                                         pMesh->mvert[pMesh->mloop[lt->tri[1]].v].co,
388                                         pMesh->mvert[pMesh->mloop[lt->tri[2]].v].co);
389                         }
390                 }
391         }
392         else {
393                 const short *no = pMesh->mvert[pMesh->mloop[loop_index].v].no;
394                 normal_short_to_float_v3(r_no, no);
395         }
396 }
397
398 static void dm_ts_SetTSpace(
399         const SMikkTSpaceContext *pContext, const float fvTangent[3], const float fSign,
400         const int face_num, const int vert_index)
401 {
402         //assert(vert_index >= 0 && vert_index < 4);
403         SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData;
404         const MLoopTri *lt;
405         uint loop_index;
406
407 #ifdef USE_LOOPTRI_DETECT_QUADS
408         if (pMesh->face_as_quad_map) {
409                 lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
410                 const MPoly *mp = &pMesh->mpoly[lt->poly];
411                 if (mp->totloop == 4) {
412                         loop_index = (uint)(mp->loopstart + vert_index);
413                         goto finally;
414                 }
415                 /* fall through to regular triangle */
416         }
417         else {
418                 lt = &pMesh->looptri[face_num];
419         }
420 #else
421         lt = &pMesh->looptri[face_num];
422 #endif
423         loop_index = lt->tri[vert_index];
424
425         float *pRes;
426
427 finally:
428         pRes = pMesh->tangent[loop_index];
429         copy_v3_v3(pRes, fvTangent);
430         pRes[3] = fSign;
431 }
432
433 static void DM_calc_loop_tangents_thread(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid))
434 {
435         struct SGLSLMeshToTangent *mesh2tangent = taskdata;
436         /* new computation method */
437         {
438                 SMikkTSpaceContext sContext = {NULL};
439                 SMikkTSpaceInterface sInterface = {NULL};
440
441                 sContext.m_pUserData = mesh2tangent;
442                 sContext.m_pInterface = &sInterface;
443                 sInterface.m_getNumFaces = dm_ts_GetNumFaces;
444                 sInterface.m_getNumVerticesOfFace = dm_ts_GetNumVertsOfFace;
445                 sInterface.m_getPosition = dm_ts_GetPosition;
446                 sInterface.m_getTexCoord = dm_ts_GetTextureCoordinate;
447                 sInterface.m_getNormal = dm_ts_GetNormal;
448                 sInterface.m_setTSpaceBasic = dm_ts_SetTSpace;
449
450                 /* 0 if failed */
451                 genTangSpaceDefault(&sContext);
452         }
453 }
454
455 void BKE_mesh_add_loop_tangent_named_layer_for_uv(
456         CustomData *uv_data, CustomData *tan_data, int numLoopData,
457         const char *layer_name)
458 {
459         if (CustomData_get_named_layer_index(tan_data, CD_TANGENT, layer_name) == -1 &&
460             CustomData_get_named_layer_index(uv_data, CD_MLOOPUV, layer_name) != -1)
461         {
462                 CustomData_add_layer_named(
463                         tan_data, CD_TANGENT, CD_CALLOC, NULL,
464                         numLoopData, layer_name);
465         }
466 }
467
468 /**
469  * Here we get some useful information such as active uv layer name and search if it is already in tangent_names.
470  * Also, we calculate tangent_mask that works as a descriptor of tangents state.
471  * If tangent_mask has changed, then recalculate tangents.
472  */
473 void BKE_mesh_calc_loop_tangent_step_0(
474         const CustomData *loopData, bool calc_active_tangent,
475         const char (*tangent_names)[MAX_NAME], int tangent_names_count,
476         bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
477         char *ract_uv_name, char *rren_uv_name, short *rtangent_mask)
478 {
479         /* Active uv in viewport */
480         int layer_index = CustomData_get_layer_index(loopData, CD_MLOOPUV);
481         *ract_uv_n = CustomData_get_active_layer(loopData, CD_MLOOPUV);
482         ract_uv_name[0] = 0;
483         if (*ract_uv_n != -1) {
484                 strcpy(ract_uv_name, loopData->layers[*ract_uv_n + layer_index].name);
485         }
486
487         /* Active tangent in render */
488         *rren_uv_n = CustomData_get_render_layer(loopData, CD_MLOOPUV);
489         rren_uv_name[0] = 0;
490         if (*rren_uv_n != -1) {
491                 strcpy(rren_uv_name, loopData->layers[*rren_uv_n + layer_index].name);
492         }
493
494         /* If active tangent not in tangent_names we take it into account */
495         *rcalc_act = false;
496         *rcalc_ren = false;
497         for (int i = 0; i < tangent_names_count; i++) {
498                 if (tangent_names[i][0] == 0) {
499                         calc_active_tangent = true;
500                 }
501         }
502         if (calc_active_tangent) {
503                 *rcalc_act = true;
504                 *rcalc_ren = true;
505                 for (int i = 0; i < tangent_names_count; i++) {
506                         if (STREQ(ract_uv_name, tangent_names[i]))
507                                 *rcalc_act = false;
508                         if (STREQ(rren_uv_name, tangent_names[i]))
509                                 *rcalc_ren = false;
510                 }
511         }
512         *rtangent_mask = 0;
513
514         const int uv_layer_num = CustomData_number_of_layers(loopData, CD_MLOOPUV);
515         for (int n = 0; n < uv_layer_num; n++) {
516                 const char *name = CustomData_get_layer_name(loopData, CD_MLOOPUV, n);
517                 bool add = false;
518                 for (int i = 0; i < tangent_names_count; i++) {
519                         if (tangent_names[i][0] && STREQ(tangent_names[i], name)) {
520                                 add = true;
521                                 break;
522                         }
523                 }
524                 if (!add && ((*rcalc_act && ract_uv_name[0] && STREQ(ract_uv_name, name)) ||
525                              (*rcalc_ren && rren_uv_name[0] && STREQ(rren_uv_name, name))))
526                 {
527                         add = true;
528                 }
529                 if (add)
530                         *rtangent_mask |= (short)(1 << n);
531         }
532
533         if (uv_layer_num == 0)
534                 *rtangent_mask |= DM_TANGENT_MASK_ORCO;
535 }
536
537 /**
538  * See: #BKE_editmesh_loop_tangent_calc (matching logic).
539  */
540 void BKE_mesh_calc_loop_tangent_ex(
541         const MVert *mvert,
542         const MPoly *mpoly, const uint mpoly_len,
543         const MLoop *mloop,
544         const MLoopTri *looptri,
545         const uint looptri_len,
546
547         CustomData *loopdata,
548         bool calc_active_tangent,
549         const char (*tangent_names)[MAX_NAME], int tangent_names_len,
550         const float (*poly_normals)[3],
551         const float (*loop_normals)[3],
552         const float (*vert_orco)[3],
553         /* result */
554         CustomData *loopdata_out,
555         const uint  loopdata_out_len,
556         short *tangent_mask_curr_p)
557 {
558         int act_uv_n = -1;
559         int ren_uv_n = -1;
560         bool calc_act = false;
561         bool calc_ren = false;
562         char act_uv_name[MAX_NAME];
563         char ren_uv_name[MAX_NAME];
564         short tangent_mask = 0;
565         short tangent_mask_curr = *tangent_mask_curr_p;
566
567         BKE_mesh_calc_loop_tangent_step_0(
568                 loopdata, calc_active_tangent, tangent_names, tangent_names_len,
569                 &calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask);
570         if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
571                 /* Check we have all the needed layers */
572                 /* Allocate needed tangent layers */
573                 for (int i = 0; i < tangent_names_len; i++)
574                         if (tangent_names[i][0])
575                                 BKE_mesh_add_loop_tangent_named_layer_for_uv(loopdata, loopdata_out, (int)loopdata_out_len, tangent_names[i]);
576                 if ((tangent_mask & DM_TANGENT_MASK_ORCO) && CustomData_get_named_layer_index(loopdata, CD_TANGENT, "") == -1)
577                             CustomData_add_layer_named(loopdata_out, CD_TANGENT, CD_CALLOC, NULL, (int)loopdata_out_len, "");
578                 if (calc_act && act_uv_name[0])
579                         BKE_mesh_add_loop_tangent_named_layer_for_uv(loopdata, loopdata_out, (int)loopdata_out_len, act_uv_name);
580                 if (calc_ren && ren_uv_name[0])
581                         BKE_mesh_add_loop_tangent_named_layer_for_uv(loopdata, loopdata_out, (int)loopdata_out_len, ren_uv_name);
582
583 #ifdef USE_LOOPTRI_DETECT_QUADS
584                 int num_face_as_quad_map;
585                 int *face_as_quad_map = NULL;
586
587                 /* map faces to quads */
588                 if (looptri_len != mpoly_len) {
589                         /* over alloc, since we dont know how many ngon or quads we have */
590
591                         /* map fake face index to looptri */
592                         face_as_quad_map = MEM_mallocN(sizeof(int) * looptri_len, __func__);
593                         int k, j;
594                         for (k = 0, j = 0; j < (int)looptri_len; k++, j++) {
595                                 face_as_quad_map[k] = j;
596                                 /* step over all quads */
597                                 if (mpoly[looptri[j].poly].totloop == 4) {
598                                         j++;  /* skips the nest looptri */
599                                 }
600                         }
601                         num_face_as_quad_map = k;
602                 }
603                 else {
604                         num_face_as_quad_map = (int)looptri_len;
605                 }
606 #endif
607
608                 /* Calculation */
609                 if (looptri_len != 0) {
610                         TaskScheduler *scheduler = BLI_task_scheduler_get();
611                         TaskPool *task_pool;
612                         task_pool = BLI_task_pool_create(scheduler, NULL);
613
614                         tangent_mask_curr = 0;
615                         /* Calculate tangent layers */
616                         SGLSLMeshToTangent data_array[MAX_MTFACE];
617                         const int tangent_layer_num = CustomData_number_of_layers(loopdata_out, CD_TANGENT);
618                         for (int n = 0; n < tangent_layer_num; n++) {
619                                 int index = CustomData_get_layer_index_n(loopdata_out, CD_TANGENT, n);
620                                 BLI_assert(n < MAX_MTFACE);
621                                 SGLSLMeshToTangent *mesh2tangent = &data_array[n];
622                                 mesh2tangent->numTessFaces = (int)looptri_len;
623 #ifdef USE_LOOPTRI_DETECT_QUADS
624                                 mesh2tangent->face_as_quad_map = face_as_quad_map;
625                                 mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
626 #endif
627                                 mesh2tangent->mvert = mvert;
628                                 mesh2tangent->mpoly = mpoly;
629                                 mesh2tangent->mloop = mloop;
630                                 mesh2tangent->looptri = looptri;
631                                 /* Note, we assume we do have tessellated loop normals at this point (in case it is object-enabled),
632                                  * have to check this is valid...
633                                  */
634                                 mesh2tangent->precomputedLoopNormals = loop_normals;
635                                 mesh2tangent->precomputedFaceNormals = poly_normals;
636
637                                 mesh2tangent->orco = NULL;
638                                 mesh2tangent->mloopuv = CustomData_get_layer_named(loopdata, CD_MLOOPUV, loopdata_out->layers[index].name);
639
640                                 /* Fill the resulting tangent_mask */
641                                 if (!mesh2tangent->mloopuv) {
642                                     mesh2tangent->orco = vert_orco;
643                                     if (!mesh2tangent->orco)
644                                             continue;
645
646                                     tangent_mask_curr |= DM_TANGENT_MASK_ORCO;
647                                 }
648                                 else {
649                                     int uv_ind = CustomData_get_named_layer_index(loopdata, CD_MLOOPUV, loopdata_out->layers[index].name);
650                                     int uv_start = CustomData_get_layer_index(loopdata, CD_MLOOPUV);
651                                     BLI_assert(uv_ind != -1 && uv_start != -1);
652                                     BLI_assert(uv_ind - uv_start < MAX_MTFACE);
653                                     tangent_mask_curr |= (short)(1 << (uv_ind - uv_start));
654                                 }
655
656                                 mesh2tangent->tangent = loopdata_out->layers[index].data;
657                                 BLI_task_pool_push(task_pool, DM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW);
658                         }
659
660                         BLI_assert(tangent_mask_curr == tangent_mask);
661                         BLI_task_pool_work_and_wait(task_pool);
662                         BLI_task_pool_free(task_pool);
663                 }
664                 else {
665                         tangent_mask_curr = tangent_mask;
666                 }
667 #ifdef USE_LOOPTRI_DETECT_QUADS
668                 if (face_as_quad_map) {
669                         MEM_freeN(face_as_quad_map);
670                 }
671 #undef USE_LOOPTRI_DETECT_QUADS
672
673 #endif
674
675                 *tangent_mask_curr_p = tangent_mask_curr;
676
677                 /* Update active layer index */
678                 int act_uv_index = CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, act_uv_n);
679                 if (act_uv_index != -1) {
680                     int tan_index = CustomData_get_named_layer_index(loopdata, CD_TANGENT, loopdata->layers[act_uv_index].name);
681                     CustomData_set_layer_active_index(loopdata, CD_TANGENT, tan_index);
682                 }/* else tangent has been built from orco */
683
684                 /* Update render layer index */
685                 int ren_uv_index = CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, ren_uv_n);
686                 if (ren_uv_index != -1) {
687                     int tan_index = CustomData_get_named_layer_index(loopdata, CD_TANGENT, loopdata->layers[ren_uv_index].name);
688                     CustomData_set_layer_render_index(loopdata, CD_TANGENT, tan_index);
689                 }/* else tangent has been built from orco */
690         }
691 }
692
693 void BKE_mesh_calc_loop_tangents(
694         Mesh *me_eval, bool calc_active_tangent,
695         const char (*tangent_names)[MAX_NAME], int tangent_names_len)
696 {
697         BKE_mesh_runtime_looptri_ensure(me_eval);
698
699         /* TODO(campbell): store in Mesh.runtime to avoid recalculation. */
700         short tangent_mask = 0;
701         BKE_mesh_calc_loop_tangent_ex(
702                 me_eval->mvert,
703                 me_eval->mpoly, (uint)me_eval->totpoly,
704                 me_eval->mloop,
705                 me_eval->runtime.looptris.array, (uint)me_eval->runtime.looptris.len,
706                 &me_eval->ldata,
707                 calc_active_tangent,
708                 tangent_names, tangent_names_len,
709                 CustomData_get_layer(&me_eval->pdata, CD_NORMAL),
710                 CustomData_get_layer(&me_eval->ldata, CD_NORMAL),
711                 CustomData_get_layer(&me_eval->vdata, CD_ORCO),  /* may be NULL */
712                 /* result */
713                 &me_eval->ldata, (uint)me_eval->totloop,
714                 &tangent_mask);
715 }
716
717 /** \} */