54 const uint loop_idx =
uint(faces[face_num].start()) + vert_num;
60 const float *uv =
luvs[
uint(faces[face_num].start()) + vert_num];
71 float *p_res =
tangents[
uint(faces[face_num].start()) + vert_num];
72 copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
86 const int *corner_verts,
87 float (*r_looptangent)[4],
88 const float (*corner_normals)[3],
89 const float (*loop_uvs)[2],
91 const OffsetIndices<int> faces,
98 mesh_to_tangent.
positions = vert_positions;
99 mesh_to_tangent.
luvs = loop_uvs;
101 mesh_to_tangent.
tangents = r_looptangent;
107 for (
const int64_t i : faces.index_range()) {
108 if (faces[i].
size() > 4) {
110 reports,
RPT_ERROR,
"Tangent space can only be computed for tris/quads, aborting");
120 float (*r_looptangents)[4],
130 const VArraySpan uv_map = *attributes.lookup<
float2>(uvmap, AttrDomain::Corner);
134 "Tangent space computation needs a UV Map, \"%s\" not found, aborting",
140 reinterpret_cast<const float(*)[3]
>(mesh->vert_positions().data()),
142 mesh->corner_verts().data(),
144 reinterpret_cast<const float(*)[3]
>(mesh->corner_normals().data()),
145 reinterpret_cast<const float(*)[2]
>(uv_map.
data()),
158#define USE_TRI_DETECT_QUADS
163#ifdef USE_TRI_DETECT_QUADS
172#ifdef USE_TRI_DETECT_QUADS
175 if (faces[face_index].
size() == 4) {
188#ifdef USE_TRI_DETECT_QUADS
192 if (faces[face_index].
size() == 4) {
193 return uint(faces[face_index][vert_num]);
208# pragma GCC diagnostic push
209# pragma GCC diagnostic ignored "-Warray-bounds"
212 return uint(tri[
int(vert_num)]);
215# pragma GCC diagnostic pop
223 uint loop_index =
GetLoop(face_num, vert_num, tri, face_index);
231 uint loop_index =
GetLoop(face_num, vert_num, tri, face_index);
246 uint loop_index =
GetLoop(face_num, vert_num, tri, face_index);
254#ifdef USE_TRI_DETECT_QUADS
257 if (face.size() == 4) {
281 uint loop_index =
GetLoop(face_num, vert_num, tri, face_index);
283 copy_v4_fl4(tangent[loop_index], T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
300#ifdef USE_TRI_DETECT_QUADS
319 const char *layer_name)
329 bool calc_active_tangent,
331 int tangent_names_count,
338 short *rtangent_mask)
344 if (*ract_uv_n != -1) {
352 if (*rren_uv_n != -1) {
360 for (
int i = 0; i < tangent_names_count; i++) {
361 if (tangent_names[i][0] == 0) {
362 calc_active_tangent =
true;
365 if (calc_active_tangent) {
368 for (
int i = 0; i < tangent_names_count; i++) {
369 if (
STREQ(ract_uv_name, tangent_names[i])) {
372 if (
STREQ(rren_uv_name, tangent_names[i])) {
380 for (
int n = 0; n < uv_layer_num; n++) {
383 for (
int i = 0; i < tangent_names_count; i++) {
384 if (tangent_names[i][0] &&
STREQ(tangent_names[i], name)) {
389 if (!add && ((*rcalc_act && ract_uv_name[0] &&
STREQ(ract_uv_name, name)) ||
390 (*rcalc_ren && rren_uv_name[0] &&
STREQ(rren_uv_name, name))))
395 *rtangent_mask |= short(1 << n);
399 if (uv_layer_num == 0) {
405 const OffsetIndices<int> faces,
406 const int *corner_verts,
407 const int3 *corner_tris,
408 const int *corner_tri_faces,
409 const uint corner_tris_len,
413 bool calc_active_tangent,
415 int tangent_names_len,
422 const uint loopdata_out_len,
423 short *tangent_mask_curr_p)
427 bool calc_act =
false;
428 bool calc_ren =
false;
431 short tangent_mask = 0;
432 short tangent_mask_curr = *tangent_mask_curr_p;
445 if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
448 for (
int i = 0; i < tangent_names_len; i++) {
449 if (tangent_names[i][0]) {
451 loopdata, loopdata_out,
int(loopdata_out_len), tangent_names[i]);
460 if (calc_act && act_uv_name[0]) {
462 loopdata, loopdata_out,
int(loopdata_out_len), act_uv_name);
464 if (calc_ren && ren_uv_name[0]) {
466 loopdata, loopdata_out,
int(loopdata_out_len), ren_uv_name);
469#ifdef USE_TRI_DETECT_QUADS
470 int num_face_as_quad_map;
471 int *face_as_quad_map =
nullptr;
474 if (corner_tris_len !=
uint(faces.size())) {
478 face_as_quad_map =
static_cast<int *
>(
MEM_mallocN(
sizeof(
int) * corner_tris_len, __func__));
480 for (k = 0, j = 0; j <
int(corner_tris_len); k++, j++) {
481 face_as_quad_map[k] = j;
483 if (faces[corner_tri_faces[j]].
size() == 4) {
487 num_face_as_quad_map = k;
490 num_face_as_quad_map =
int(corner_tris_len);
495 if (corner_tris_len != 0) {
498 tangent_mask_curr = 0;
502 for (
int n = 0; n < tangent_layer_num; n++) {
507#ifdef USE_TRI_DETECT_QUADS
511 mesh2tangent->
positions = vert_positions;
516 mesh2tangent->
tri_faces = corner_tri_faces;
523 mesh2tangent->
orco = {};
529 mesh2tangent->
orco = vert_orco;
530 if (mesh2tangent->
orco.is_empty()) {
542 tangent_mask_curr |= short(1 << (uv_ind - uv_start));
545 mesh2tangent->
tangent =
static_cast<float(*)[4]
>(loopdata_out->
layers[index].
data);
549 BLI_assert(tangent_mask_curr == tangent_mask);
554 tangent_mask_curr = tangent_mask;
556#ifdef USE_TRI_DETECT_QUADS
557 if (face_as_quad_map) {
560# undef USE_TRI_DETECT_QUADS
564 *tangent_mask_curr_p = tangent_mask_curr;
569 if (tan_index != -1) {
577 if (tan_index != -1) {
585 bool calc_active_tangent,
587 int tangent_names_len)
592 const Span<int3> corner_tris = mesh_eval->corner_tris();
594 const VArraySpan sharp_face = *attributes.lookup<
bool>(
"sharp_face", AttrDomain::Face);
597 short tangent_mask = 0;
600 mesh_eval->corner_verts().data(),
602 mesh_eval->corner_tri_faces().data(),
609 mesh_eval->vert_normals(),
610 mesh_eval->face_normals(),
611 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)
#define MAX_CUSTOMDATA_LAYER_NAME
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr const T * data() const
constexpr int64_t size() const
constexpr bool is_empty() const
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
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)
void BKE_mesh_calc_loop_tangent_ex(const Span< float3 > vert_positions, const OffsetIndices< int > faces, const int *corner_verts, const int3 *corner_tris, const int *corner_tri_faces, const uint corner_tris_len, 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)
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)
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)