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_math.h"
34 #include "BLI_task.h"
35 #include "BLI_utildefines.h"
36 
37 #include "BKE_customdata.h"
38 #include "BKE_mesh.h"
39 #include "BKE_mesh_runtime.h"
40 #include "BKE_mesh_tangent.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 */
get_num_faces(const SMikkTSpaceContext * pContext)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 
get_num_verts_of_face(const SMikkTSpaceContext * pContext,const int face_idx)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 
get_position(const SMikkTSpaceContext * pContext,float r_co[3],const int face_idx,const int vert_idx)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 
get_texture_coordinate(const SMikkTSpaceContext * pContext,float r_uv[2],const int face_idx,const int vert_idx)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 
get_normal(const SMikkTSpaceContext * pContext,float r_no[3],const int face_idx,const int vert_idx)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 
set_tspace(const SMikkTSpaceContext * pContext,const float fv_tangent[3],const float face_sign,const int face_idx,const int vert_idx)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.
120  * tangent vector + sign of bi-tangent one, which combined with
121  * split normals can be used to recreate the full tangent space.
122  * Note: * The mesh should be made of only tris and quads!
123  */
BKE_mesh_calc_loop_tangent_single_ex(const MVert * mverts,const int UNUSED (numVerts),const MLoop * mloops,float (* r_looptangent)[4],float (* loopnors)[3],const MLoopUV * loopuvs,const int UNUSED (numLoops),const MPoly * mpolys,const int numPolys,ReportList * reports)124 void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts,
125                                           const int UNUSED(numVerts),
126                                           const MLoop *mloops,
127                                           float (*r_looptangent)[4],
128                                           float (*loopnors)[3],
129                                           const MLoopUV *loopuvs,
130                                           const int UNUSED(numLoops),
131                                           const MPoly *mpolys,
132                                           const int numPolys,
133                                           ReportList *reports)
134 {
135   BKEMeshToTangent mesh_to_tangent = {NULL};
136   SMikkTSpaceContext s_context = {NULL};
137   SMikkTSpaceInterface s_interface = {NULL};
138 
139   const MPoly *mp;
140   int mp_index;
141 
142   /* First check we do have a tris/quads only mesh. */
143   for (mp = mpolys, mp_index = 0; mp_index < numPolys; mp++, mp_index++) {
144     if (mp->totloop > 4) {
145       BKE_report(
146           reports, RPT_ERROR, "Tangent space can only be computed for tris/quads, aborting");
147       return;
148     }
149   }
150 
151   /* Compute Mikktspace's tangent normals. */
152   mesh_to_tangent.mpolys = mpolys;
153   mesh_to_tangent.mloops = mloops;
154   mesh_to_tangent.mverts = mverts;
155   mesh_to_tangent.luvs = loopuvs;
156   mesh_to_tangent.lnors = loopnors;
157   mesh_to_tangent.tangents = r_looptangent;
158   mesh_to_tangent.num_polys = numPolys;
159 
160   s_context.m_pUserData = &mesh_to_tangent;
161   s_context.m_pInterface = &s_interface;
162   s_interface.m_getNumFaces = get_num_faces;
163   s_interface.m_getNumVerticesOfFace = get_num_verts_of_face;
164   s_interface.m_getPosition = get_position;
165   s_interface.m_getTexCoord = get_texture_coordinate;
166   s_interface.m_getNormal = get_normal;
167   s_interface.m_setTSpaceBasic = set_tspace;
168 
169   /* 0 if failed */
170   if (genTangSpaceDefault(&s_context) == false) {
171     BKE_report(reports, RPT_ERROR, "Mikktspace failed to generate tangents for this mesh!");
172   }
173 }
174 
175 /**
176  * Wrapper around BKE_mesh_calc_loop_tangent_single_ex, which takes care of most boiling code.
177  * \note
178  * - There must be a valid loop's CD_NORMALS available.
179  * - The mesh should be made of only tris and quads!
180  */
BKE_mesh_calc_loop_tangent_single(Mesh * mesh,const char * uvmap,float (* r_looptangents)[4],ReportList * reports)181 void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
182                                        const char *uvmap,
183                                        float (*r_looptangents)[4],
184                                        ReportList *reports)
185 {
186   MLoopUV *loopuvs;
187   float(*loopnors)[3];
188 
189   /* Check we have valid texture coordinates first! */
190   if (uvmap) {
191     loopuvs = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvmap);
192   }
193   else {
194     loopuvs = CustomData_get_layer(&mesh->ldata, CD_MLOOPUV);
195   }
196   if (!loopuvs) {
197     BKE_reportf(reports,
198                 RPT_ERROR,
199                 "Tangent space computation needs an UVMap, \"%s\" not found, aborting",
200                 uvmap);
201     return;
202   }
203 
204   loopnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
205   if (!loopnors) {
206     BKE_report(
207         reports, RPT_ERROR, "Tangent space computation needs loop normals, none found, aborting");
208     return;
209   }
210 
211   BKE_mesh_calc_loop_tangent_single_ex(mesh->mvert,
212                                        mesh->totvert,
213                                        mesh->mloop,
214                                        r_looptangents,
215                                        loopnors,
216                                        loopuvs,
217                                        mesh->totloop,
218                                        mesh->mpoly,
219                                        mesh->totpoly,
220                                        reports);
221 }
222 
223 /** \} */
224 
225 /* -------------------------------------------------------------------- */
226 /** \name Mesh Tangent Calculations (All Layers)
227  * \{ */
228 
229 /* Necessary complexity to handle looptri's as quads for correct tangents */
230 #define USE_LOOPTRI_DETECT_QUADS
231 
232 typedef struct {
233   const float (*precomputedFaceNormals)[3];
234   const float (*precomputedLoopNormals)[3];
235   const MLoopTri *looptri;
236   MLoopUV *mloopuv;   /* texture coordinates */
237   const MPoly *mpoly; /* indices */
238   const MLoop *mloop; /* indices */
239   const MVert *mvert; /* vertices & normals */
240   const float (*orco)[3];
241   float (*tangent)[4]; /* destination */
242   int numTessFaces;
243 
244 #ifdef USE_LOOPTRI_DETECT_QUADS
245   /* map from 'fake' face index to looptri,
246    * quads will point to the first looptri of the quad */
247   const int *face_as_quad_map;
248   int num_face_as_quad_map;
249 #endif
250 
251 } SGLSLMeshToTangent;
252 
253 /* interface */
dm_ts_GetNumFaces(const SMikkTSpaceContext * pContext)254 static int dm_ts_GetNumFaces(const SMikkTSpaceContext *pContext)
255 {
256   SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
257 
258 #ifdef USE_LOOPTRI_DETECT_QUADS
259   return pMesh->num_face_as_quad_map;
260 #else
261   return pMesh->numTessFaces;
262 #endif
263 }
264 
dm_ts_GetNumVertsOfFace(const SMikkTSpaceContext * pContext,const int face_num)265 static int dm_ts_GetNumVertsOfFace(const SMikkTSpaceContext *pContext, const int face_num)
266 {
267 #ifdef USE_LOOPTRI_DETECT_QUADS
268   SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
269   if (pMesh->face_as_quad_map) {
270     const MLoopTri *lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
271     const MPoly *mp = &pMesh->mpoly[lt->poly];
272     if (mp->totloop == 4) {
273       return 4;
274     }
275   }
276   return 3;
277 #else
278   UNUSED_VARS(pContext, face_num);
279   return 3;
280 #endif
281 }
282 
dm_ts_GetPosition(const SMikkTSpaceContext * pContext,float r_co[3],const int face_num,const int vert_index)283 static void dm_ts_GetPosition(const SMikkTSpaceContext *pContext,
284                               float r_co[3],
285                               const int face_num,
286                               const int vert_index)
287 {
288   // assert(vert_index >= 0 && vert_index < 4);
289   SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
290   const MLoopTri *lt;
291   uint loop_index;
292   const float *co;
293 
294 #ifdef USE_LOOPTRI_DETECT_QUADS
295   if (pMesh->face_as_quad_map) {
296     lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
297     const MPoly *mp = &pMesh->mpoly[lt->poly];
298     if (mp->totloop == 4) {
299       loop_index = (uint)(mp->loopstart + vert_index);
300       goto finally;
301     }
302     /* fall through to regular triangle */
303   }
304   else {
305     lt = &pMesh->looptri[face_num];
306   }
307 #else
308   lt = &pMesh->looptri[face_num];
309 #endif
310   loop_index = lt->tri[vert_index];
311 
312 finally:
313   co = pMesh->mvert[pMesh->mloop[loop_index].v].co;
314   copy_v3_v3(r_co, co);
315 }
316 
dm_ts_GetTextureCoordinate(const SMikkTSpaceContext * pContext,float r_uv[2],const int face_num,const int vert_index)317 static void dm_ts_GetTextureCoordinate(const SMikkTSpaceContext *pContext,
318                                        float r_uv[2],
319                                        const int face_num,
320                                        const int vert_index)
321 {
322   // assert(vert_index >= 0 && vert_index < 4);
323   SGLSLMeshToTangent *pMesh = pContext->m_pUserData;
324   const MLoopTri *lt;
325   uint loop_index;
326 
327 #ifdef USE_LOOPTRI_DETECT_QUADS
328   if (pMesh->face_as_quad_map) {
329     lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
330     const MPoly *mp = &pMesh->mpoly[lt->poly];
331     if (mp->totloop == 4) {
332       loop_index = (uint)(mp->loopstart + vert_index);
333       goto finally;
334     }
335     /* fall through to regular triangle */
336   }
337   else {
338     lt = &pMesh->looptri[face_num];
339   }
340 #else
341   lt = &pMesh->looptri[face_num];
342 #endif
343   loop_index = lt->tri[vert_index];
344 
345 finally:
346   if (pMesh->mloopuv != NULL) {
347     const float *uv = pMesh->mloopuv[loop_index].uv;
348     copy_v2_v2(r_uv, uv);
349   }
350   else {
351     const float *orco = pMesh->orco[pMesh->mloop[loop_index].v];
352     map_to_sphere(&r_uv[0], &r_uv[1], orco[0], orco[1], orco[2]);
353   }
354 }
355 
dm_ts_GetNormal(const SMikkTSpaceContext * pContext,float r_no[3],const int face_num,const int vert_index)356 static void dm_ts_GetNormal(const SMikkTSpaceContext *pContext,
357                             float r_no[3],
358                             const int face_num,
359                             const int vert_index)
360 {
361   // assert(vert_index >= 0 && vert_index < 4);
362   SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *)pContext->m_pUserData;
363   const MLoopTri *lt;
364   uint loop_index;
365 
366 #ifdef USE_LOOPTRI_DETECT_QUADS
367   if (pMesh->face_as_quad_map) {
368     lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
369     const MPoly *mp = &pMesh->mpoly[lt->poly];
370     if (mp->totloop == 4) {
371       loop_index = (uint)(mp->loopstart + vert_index);
372       goto finally;
373     }
374     /* fall through to regular triangle */
375   }
376   else {
377     lt = &pMesh->looptri[face_num];
378   }
379 #else
380   lt = &pMesh->looptri[face_num];
381 #endif
382   loop_index = lt->tri[vert_index];
383 
384 finally:
385   if (pMesh->precomputedLoopNormals) {
386     copy_v3_v3(r_no, pMesh->precomputedLoopNormals[loop_index]);
387   }
388   else if ((pMesh->mpoly[lt->poly].flag & ME_SMOOTH) == 0) { /* flat */
389     if (pMesh->precomputedFaceNormals) {
390       copy_v3_v3(r_no, pMesh->precomputedFaceNormals[lt->poly]);
391     }
392     else {
393 #ifdef USE_LOOPTRI_DETECT_QUADS
394       const MPoly *mp = &pMesh->mpoly[lt->poly];
395       if (mp->totloop == 4) {
396         normal_quad_v3(r_no,
397                        pMesh->mvert[pMesh->mloop[mp->loopstart + 0].v].co,
398                        pMesh->mvert[pMesh->mloop[mp->loopstart + 1].v].co,
399                        pMesh->mvert[pMesh->mloop[mp->loopstart + 2].v].co,
400                        pMesh->mvert[pMesh->mloop[mp->loopstart + 3].v].co);
401       }
402       else
403 #endif
404       {
405         normal_tri_v3(r_no,
406                       pMesh->mvert[pMesh->mloop[lt->tri[0]].v].co,
407                       pMesh->mvert[pMesh->mloop[lt->tri[1]].v].co,
408                       pMesh->mvert[pMesh->mloop[lt->tri[2]].v].co);
409       }
410     }
411   }
412   else {
413     const short *no = pMesh->mvert[pMesh->mloop[loop_index].v].no;
414     normal_short_to_float_v3(r_no, no);
415   }
416 }
417 
dm_ts_SetTSpace(const SMikkTSpaceContext * pContext,const float fvTangent[3],const float fSign,const int face_num,const int vert_index)418 static void dm_ts_SetTSpace(const SMikkTSpaceContext *pContext,
419                             const float fvTangent[3],
420                             const float fSign,
421                             const int face_num,
422                             const int vert_index)
423 {
424   // assert(vert_index >= 0 && vert_index < 4);
425   SGLSLMeshToTangent *pMesh = (SGLSLMeshToTangent *)pContext->m_pUserData;
426   const MLoopTri *lt;
427   uint loop_index;
428 
429 #ifdef USE_LOOPTRI_DETECT_QUADS
430   if (pMesh->face_as_quad_map) {
431     lt = &pMesh->looptri[pMesh->face_as_quad_map[face_num]];
432     const MPoly *mp = &pMesh->mpoly[lt->poly];
433     if (mp->totloop == 4) {
434       loop_index = (uint)(mp->loopstart + vert_index);
435       goto finally;
436     }
437     /* fall through to regular triangle */
438   }
439   else {
440     lt = &pMesh->looptri[face_num];
441   }
442 #else
443   lt = &pMesh->looptri[face_num];
444 #endif
445   loop_index = lt->tri[vert_index];
446 
447   float *pRes;
448 
449 finally:
450   pRes = pMesh->tangent[loop_index];
451   copy_v3_v3(pRes, fvTangent);
452   pRes[3] = fSign;
453 }
454 
DM_calc_loop_tangents_thread(TaskPool * __restrict UNUSED (pool),void * taskdata)455 static void DM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), void *taskdata)
456 {
457   struct SGLSLMeshToTangent *mesh2tangent = taskdata;
458   /* new computation method */
459   {
460     SMikkTSpaceContext sContext = {NULL};
461     SMikkTSpaceInterface sInterface = {NULL};
462 
463     sContext.m_pUserData = mesh2tangent;
464     sContext.m_pInterface = &sInterface;
465     sInterface.m_getNumFaces = dm_ts_GetNumFaces;
466     sInterface.m_getNumVerticesOfFace = dm_ts_GetNumVertsOfFace;
467     sInterface.m_getPosition = dm_ts_GetPosition;
468     sInterface.m_getTexCoord = dm_ts_GetTextureCoordinate;
469     sInterface.m_getNormal = dm_ts_GetNormal;
470     sInterface.m_setTSpaceBasic = dm_ts_SetTSpace;
471 
472     /* 0 if failed */
473     genTangSpaceDefault(&sContext);
474   }
475 }
476 
BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData * uv_data,CustomData * tan_data,int numLoopData,const char * layer_name)477 void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data,
478                                                   CustomData *tan_data,
479                                                   int numLoopData,
480                                                   const char *layer_name)
481 {
482   if (CustomData_get_named_layer_index(tan_data, CD_TANGENT, layer_name) == -1 &&
483       CustomData_get_named_layer_index(uv_data, CD_MLOOPUV, layer_name) != -1) {
484     CustomData_add_layer_named(tan_data, CD_TANGENT, CD_CALLOC, NULL, numLoopData, layer_name);
485   }
486 }
487 
488 /**
489  * Here we get some useful information such as active uv layer name and
490  * 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  */
BKE_mesh_calc_loop_tangent_step_0(const CustomData * loopData,bool calc_active_tangent,const char (* tangent_names)[MAX_NAME],int tangent_names_count,bool * rcalc_act,bool * rcalc_ren,int * ract_uv_n,int * rren_uv_n,char * ract_uv_name,char * rren_uv_name,short * rtangent_mask)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  */
BKE_mesh_calc_loop_tangent_ex(const MVert * mvert,const MPoly * mpoly,const uint mpoly_len,const MLoop * mloop,const MLoopTri * looptri,const uint looptri_len,CustomData * loopdata,bool calc_active_tangent,const char (* tangent_names)[MAX_NAME],int tangent_names_len,const float (* poly_normals)[3],const float (* loop_normals)[3],const float (* vert_orco)[3],CustomData * loopdata_out,const uint loopdata_out_len,short * tangent_mask_curr_p)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       TaskPool *task_pool = BLI_task_pool_create(NULL, TASK_PRIORITY_LOW);
660 
661       tangent_mask_curr = 0;
662       /* Calculate tangent layers */
663       SGLSLMeshToTangent data_array[MAX_MTFACE];
664       const int tangent_layer_num = CustomData_number_of_layers(loopdata_out, CD_TANGENT);
665       for (int n = 0; n < tangent_layer_num; n++) {
666         int index = CustomData_get_layer_index_n(loopdata_out, CD_TANGENT, n);
667         BLI_assert(n < MAX_MTFACE);
668         SGLSLMeshToTangent *mesh2tangent = &data_array[n];
669         mesh2tangent->numTessFaces = (int)looptri_len;
670 #ifdef USE_LOOPTRI_DETECT_QUADS
671         mesh2tangent->face_as_quad_map = face_as_quad_map;
672         mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
673 #endif
674         mesh2tangent->mvert = mvert;
675         mesh2tangent->mpoly = mpoly;
676         mesh2tangent->mloop = mloop;
677         mesh2tangent->looptri = looptri;
678         /* Note, we assume we do have tessellated loop normals at this point
679          * (in case it is object-enabled), have to check this is valid. */
680         mesh2tangent->precomputedLoopNormals = loop_normals;
681         mesh2tangent->precomputedFaceNormals = poly_normals;
682 
683         mesh2tangent->orco = NULL;
684         mesh2tangent->mloopuv = CustomData_get_layer_named(
685             loopdata, CD_MLOOPUV, loopdata_out->layers[index].name);
686 
687         /* Fill the resulting tangent_mask */
688         if (!mesh2tangent->mloopuv) {
689           mesh2tangent->orco = vert_orco;
690           if (!mesh2tangent->orco) {
691             continue;
692           }
693 
694           tangent_mask_curr |= DM_TANGENT_MASK_ORCO;
695         }
696         else {
697           int uv_ind = CustomData_get_named_layer_index(
698               loopdata, CD_MLOOPUV, loopdata_out->layers[index].name);
699           int uv_start = CustomData_get_layer_index(loopdata, CD_MLOOPUV);
700           BLI_assert(uv_ind != -1 && uv_start != -1);
701           BLI_assert(uv_ind - uv_start < MAX_MTFACE);
702           tangent_mask_curr |= (short)(1 << (uv_ind - uv_start));
703         }
704 
705         mesh2tangent->tangent = loopdata_out->layers[index].data;
706         BLI_task_pool_push(task_pool, DM_calc_loop_tangents_thread, mesh2tangent, false, NULL);
707       }
708 
709       BLI_assert(tangent_mask_curr == tangent_mask);
710       BLI_task_pool_work_and_wait(task_pool);
711       BLI_task_pool_free(task_pool);
712     }
713     else {
714       tangent_mask_curr = tangent_mask;
715     }
716 #ifdef USE_LOOPTRI_DETECT_QUADS
717     if (face_as_quad_map) {
718       MEM_freeN(face_as_quad_map);
719     }
720 #  undef USE_LOOPTRI_DETECT_QUADS
721 
722 #endif
723 
724     *tangent_mask_curr_p = tangent_mask_curr;
725 
726     /* Update active layer index */
727     int act_uv_index = (act_uv_n != -1) ?
728                            CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, act_uv_n) :
729                            -1;
730     if (act_uv_index != -1) {
731       int tan_index = CustomData_get_named_layer_index(
732           loopdata, CD_TANGENT, loopdata->layers[act_uv_index].name);
733       CustomData_set_layer_active_index(loopdata, CD_TANGENT, tan_index);
734     } /* else tangent has been built from orco */
735 
736     /* Update render layer index */
737     int ren_uv_index = (ren_uv_n != -1) ?
738                            CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, ren_uv_n) :
739                            -1;
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 
BKE_mesh_calc_loop_tangents(Mesh * me_eval,bool calc_active_tangent,const char (* tangent_names)[MAX_NAME],int tangent_names_len)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 /** \} */
777