52 const uint loop_idx =
uint(
faces[face_num].start()) + vert_num;
58 const float *uv =
luvs[
uint(
faces[face_num].start()) + vert_num];
84 const int *corner_verts,
85 float (*r_looptangent)[4],
86 const float (*corner_normals)[3],
87 const float (*loop_uvs)[2],
89 const OffsetIndices<int>
faces,
96 mesh_to_tangent.
positions = vert_positions;
97 mesh_to_tangent.
luvs = loop_uvs;
99 mesh_to_tangent.
tangents = r_looptangent;
108 reports,
RPT_ERROR,
"Tangent space can only be computed for tris/quads, aborting");
118 float (*r_looptangents)[4],
132 "Tangent space computation needs a UV Map, \"%s\" not found, aborting",
138 reinterpret_cast<const float(*)[3]
>(
mesh->vert_positions().data()),
140 mesh->corner_verts().data(),
142 reinterpret_cast<const float(*)[3]
>(
mesh->corner_normals().data()),
143 reinterpret_cast<const float(*)[2]
>(uv_map.
data()),
156#define USE_TRI_DETECT_QUADS
161#ifdef USE_TRI_DETECT_QUADS
170#ifdef USE_TRI_DETECT_QUADS
186#ifdef USE_TRI_DETECT_QUADS
191 return uint(
faces[face_index][vert_num]);
206# pragma GCC diagnostic push
207# pragma GCC diagnostic ignored "-Warray-bounds"
210 return uint(tri[
int(vert_num)]);
213# pragma GCC diagnostic pop
221 uint loop_index =
GetLoop(face_num, vert_num, tri, face_index);
229 uint loop_index =
GetLoop(face_num, vert_num, tri, face_index);
244 uint loop_index =
GetLoop(face_num, vert_num, tri, face_index);
252#ifdef USE_TRI_DETECT_QUADS
255 if (face.
size() == 4) {
279 uint loop_index =
GetLoop(face_num, vert_num, tri, face_index);
298#ifdef USE_TRI_DETECT_QUADS
317 const char *layer_name)
327 bool calc_active_tangent,
329 int tangent_names_count,
336 short *rtangent_mask)
342 if (*ract_uv_n != -1) {
350 if (*rren_uv_n != -1) {
358 for (
int i = 0;
i < tangent_names_count;
i++) {
359 if (tangent_names[
i][0] == 0) {
360 calc_active_tangent =
true;
363 if (calc_active_tangent) {
366 for (
int i = 0;
i < tangent_names_count;
i++) {
367 if (
STREQ(ract_uv_name, tangent_names[
i])) {
370 if (
STREQ(rren_uv_name, tangent_names[
i])) {
378 for (
int n = 0; n < uv_layer_num; n++) {
381 for (
int i = 0;
i < tangent_names_count;
i++) {
382 if (tangent_names[
i][0] &&
STREQ(tangent_names[
i], name)) {
387 if (!
add && ((*rcalc_act && ract_uv_name[0] &&
STREQ(ract_uv_name, name)) ||
388 (*rcalc_ren && rren_uv_name[0] &&
STREQ(rren_uv_name, name))))
393 *rtangent_mask |= short(1 << n);
397 if (uv_layer_num == 0) {
409 bool calc_active_tangent,
411 int tangent_names_len,
418 const uint loopdata_out_len,
419 short *tangent_mask_curr_p)
423 bool calc_act =
false;
424 bool calc_ren =
false;
427 short tangent_mask = 0;
428 short tangent_mask_curr = *tangent_mask_curr_p;
441 if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
444 for (
int i = 0;
i < tangent_names_len;
i++) {
445 if (tangent_names[
i][0]) {
447 loopdata, loopdata_out,
int(loopdata_out_len), tangent_names[
i]);
456 if (calc_act && act_uv_name[0]) {
458 loopdata, loopdata_out,
int(loopdata_out_len), act_uv_name);
460 if (calc_ren && ren_uv_name[0]) {
462 loopdata, loopdata_out,
int(loopdata_out_len), ren_uv_name);
465#ifdef USE_TRI_DETECT_QUADS
466 int num_face_as_quad_map;
467 int *face_as_quad_map =
nullptr;
470 if (corner_tris.
size() !=
faces.size()) {
476 for (k = 0, j = 0; j < int(corner_tris.
size()); k++, j++) {
477 face_as_quad_map[k] = j;
479 if (
faces[corner_tri_faces[j]].
size() == 4) {
483 num_face_as_quad_map = k;
486 num_face_as_quad_map = int(corner_tris.
size());
491 if (corner_tris.
size() != 0) {
494 tangent_mask_curr = 0;
498 for (
int n = 0; n < tangent_layer_num; n++) {
503#ifdef USE_TRI_DETECT_QUADS
507 mesh2tangent->
positions = vert_positions;
519 mesh2tangent->
orco = {};
525 mesh2tangent->
orco = vert_orco;
526 if (mesh2tangent->
orco.is_empty()) {
538 tangent_mask_curr |= short(1 << (uv_ind - uv_start));
541 mesh2tangent->
tangent =
static_cast<float(*)[4]
>(loopdata_out->
layers[index].
data);
545 BLI_assert(tangent_mask_curr == tangent_mask);
550 tangent_mask_curr = tangent_mask;
552#ifdef USE_TRI_DETECT_QUADS
553 if (face_as_quad_map) {
556# undef USE_TRI_DETECT_QUADS
560 *tangent_mask_curr_p = tangent_mask_curr;
565 if (tan_index != -1) {
573 if (tan_index != -1) {
581 bool calc_active_tangent,
583 int tangent_names_len)
588 const Span<int3> corner_tris = mesh_eval->corner_tris();
593 short tangent_mask = 0;
596 mesh_eval->corner_verts(),
598 mesh_eval->corner_tri_faces(),
604 mesh_eval->vert_normals(),
605 mesh_eval->face_normals(),
606 mesh_eval->corner_normals(),
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n)
void CustomData_set_layer_render_index(CustomData *data, eCustomDataType type, int n)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
const char * CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type)
void CustomData_set_layer_active_index(CustomData *data, eCustomDataType type, int n)
const char * CustomData_get_render_layer_name(const CustomData *data, eCustomDataType type)
int CustomData_get_active_layer(const CustomData *data, eCustomDataType type)
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
int CustomData_get_render_layer(const CustomData *data, eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
#define DM_TANGENT_MASK_ORCO
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
bool map_to_sphere(float *r_u, float *r_v, float x, float y, float z)
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
void BLI_task_pool_work_and_wait(TaskPool *pool)
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t size() const
constexpr const T * data() const
constexpr int64_t size() const
constexpr bool is_empty() const
GAttributeReader lookup(const StringRef attribute_id) const
#define MAX_CUSTOMDATA_LAYER_NAME
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void BKE_mesh_calc_loop_tangent_ex(const Span< float3 > vert_positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int3 > corner_tris, const Span< int > corner_tri_faces, const Span< bool > sharp_faces, const CustomData *loopdata, bool calc_active_tangent, const char(*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len, const Span< float3 > vert_normals, const Span< float3 > face_normals, const Span< float3 > corner_normals, const Span< float3 > vert_orco, CustomData *loopdata_out, const uint loopdata_out_len, short *tangent_mask_curr_p)
void BKE_mesh_calc_loop_tangents(Mesh *mesh_eval, bool calc_active_tangent, const char(*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len)
void BKE_mesh_add_loop_tangent_named_layer_for_uv(const CustomData *uv_data, CustomData *tan_data, int numLoopData, const char *layer_name)
void BKE_mesh_calc_loop_tangent_single_ex(const float(*vert_positions)[3], const int, const int *corner_verts, float(*r_looptangent)[4], const float(*corner_normals)[3], const float(*loop_uvs)[2], const int, const OffsetIndices< int > faces, ReportList *reports)
static void DM_calc_loop_tangents_thread(TaskPool *__restrict, void *taskdata)
void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData, bool calc_active_tangent, const char(*tangent_names)[MAX_CUSTOMDATA_LAYER_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)
void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, const char *uvmap, float(*r_looptangents)[4], ReportList *reports)
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
mikk::float3 GetNormal(const uint face_num, const uint vert_num)
mikk::float3 GetPosition(const uint face_num, const uint vert_num)
void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation)
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
const float(* corner_normals)[3]
OffsetIndices< int > faces
const float(* positions)[3]
uint GetNumVerticesOfFace(const uint face_num)
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
uint GetNumVerticesOfFace(const uint face_num)
uint GetLoop(const uint face_num, const uint vert_num, int3 &tri, int &face_index)
OffsetIndices< int > faces
Span< float3 > face_normals
Span< float3 > vert_normals
void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation)
const int * face_as_quad_map
mikk::float3 GetNormal(const uint face_num, const uint vert_num)
Span< float3 > corner_normals
mikk::float3 GetPosition(const uint face_num, const uint vert_num)