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