diff --git a/source/blender/blenkernel/BKE_mesh_tangent.hh b/source/blender/blenkernel/BKE_mesh_tangent.hh index a13c627f42c..a2fe059f03d 100644 --- a/source/blender/blenkernel/BKE_mesh_tangent.hh +++ b/source/blender/blenkernel/BKE_mesh_tangent.hh @@ -14,6 +14,8 @@ struct ReportList; struct Mesh; +namespace blender::bke::mesh { + /** * Compute simplified tangent space normals, i.e. * tangent vector + sign of bi-tangent one, which combined with @@ -21,28 +23,13 @@ struct Mesh; * * \note The mesh should be made of only triangles and quads! */ -void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], - int numVerts, - const int *corner_verts, - float (*r_looptangent)[4], - const float (*corner_normals)[3], - const float (*loop_uvs)[2], - int numLoops, - blender::OffsetIndices faces, - ReportList *reports); - -/** - * Wrapper around BKE_mesh_calc_loop_tangent_single_ex, which takes care of most boilerplate code. - * \note - * - There must be a valid loop's CD_NORMALS available. - * - The mesh should be made of only triangles and quads! - */ -void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, - const char *uvmap, - float (*r_looptangents)[4], - ReportList *reports); - -namespace blender::bke::mesh { +void calc_uv_tangent_tris_quads(Span vert_positions, + OffsetIndices faces, + Span corner_verts, + Span corner_normals, + Span uv_map, + MutableSpan results, + ReportList *reports); /** * See: #BKE_editmesh_uv_tangents_calc (matching logic). diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index 822dd88f657..ed28b2f315e 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -12,10 +12,8 @@ #include "BLI_math_geom.h" #include "BLI_math_vector.h" +#include "BLI_task.hh" -#include "BKE_attribute.hh" -#include "BKE_customdata.hh" -#include "BKE_mesh.hh" #include "BKE_mesh_tangent.hh" #include "BKE_report.hh" @@ -23,23 +21,16 @@ #include "BLI_strict_flags.h" /* IWYU pragma: keep. Keep last. */ -using blender::Array; -using blender::float2; -using blender::float3; -using blender::float4; -using blender::int3; -using blender::OffsetIndices; -using blender::Span; -using blender::StringRef; - /* -------------------------------------------------------------------- */ /** \name Mesh Tangent Calculations (Single Layer) * \{ */ +namespace blender::bke::mesh { + struct BKEMeshToTangent { uint GetNumFaces() { - return uint(num_faces); + return uint(faces.size()); } uint GetNumVerticesOfFace(const uint face_num) @@ -75,34 +66,29 @@ struct BKEMeshToTangent { return true; } - OffsetIndices faces; /* faces */ - const int *corner_verts; /* faces vertices */ - const float (*positions)[3]; /* vertices */ - const float (*luvs)[2]; /* texture coordinates */ - const float (*corner_normals)[3]; /* loops' normals */ - float (*tangents)[4]; /* output tangents */ - int num_faces; /* number of polygons */ + OffsetIndices faces; /* faces */ + Span corner_verts; /* faces vertices */ + Span positions; /* vertices */ + Span luvs; /* texture coordinates */ + Span corner_normals; /* loops' normals */ + MutableSpan tangents; /* output tangents */ }; -void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], - const int /*numVerts*/, - const int *corner_verts, - float (*r_looptangent)[4], - const float (*corner_normals)[3], - const float (*loop_uvs)[2], - const int /*numLoops*/, - const OffsetIndices faces, - ReportList *reports) +void calc_uv_tangent_tris_quads(const Span vert_positions, + const OffsetIndices faces, + const Span corner_verts, + const Span corner_normals, + const Span uv_map, + MutableSpan results, + ReportList *reports) { - /* Compute Mikktspace's tangent normals. */ BKEMeshToTangent mesh_to_tangent; mesh_to_tangent.faces = faces; mesh_to_tangent.corner_verts = corner_verts; mesh_to_tangent.positions = vert_positions; - mesh_to_tangent.luvs = loop_uvs; + mesh_to_tangent.luvs = uv_map; mesh_to_tangent.corner_normals = corner_normals; - mesh_to_tangent.tangents = r_looptangent; - mesh_to_tangent.num_faces = int(faces.size()); + mesh_to_tangent.tangents = results; mikk::Mikktspace mikk(mesh_to_tangent); @@ -118,39 +104,6 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], mikk.genTangSpace(); } -void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, - const char *uvmap, - float (*r_looptangents)[4], - ReportList *reports) -{ - using namespace blender; - using namespace blender::bke; - if (!uvmap) { - uvmap = CustomData_get_active_layer_name(&mesh->corner_data, CD_PROP_FLOAT2); - } - - const AttributeAccessor attributes = mesh->attributes(); - const VArraySpan uv_map = *attributes.lookup(uvmap, AttrDomain::Corner); - if (uv_map.is_empty()) { - BKE_reportf(reports, - RPT_ERROR, - "Tangent space computation needs a UV Map, \"%s\" not found, aborting", - uvmap); - return; - } - - BKE_mesh_calc_loop_tangent_single_ex( - reinterpret_cast(mesh->vert_positions().data()), - mesh->verts_num, - mesh->corner_verts().data(), - r_looptangents, - reinterpret_cast(mesh->corner_normals().data()), - reinterpret_cast(uv_map.data()), - mesh->corners_num, - mesh->faces(), - reports); -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -160,8 +113,6 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, /* Necessary complexity to handle corner_tris as quads for correct tangents. */ #define USE_TRI_DETECT_QUADS -namespace blender::bke::mesh { - struct SGLSLMeshToTangent { uint GetNumFaces() { diff --git a/source/blender/makesrna/intern/rna_mesh_api.cc b/source/blender/makesrna/intern/rna_mesh_api.cc index 7f173854b01..dccf570dc73 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.cc +++ b/source/blender/makesrna/intern/rna_mesh_api.cc @@ -58,20 +58,40 @@ static void rna_Mesh_sharp_from_angle_set(Mesh *mesh, const float angle) static void rna_Mesh_calc_tangents(Mesh *mesh, ReportList *reports, const char *uvmap) { - float(*r_looptangents)[4]; - + using namespace blender; + float4 *r_looptangents; if (CustomData_has_layer(&mesh->corner_data, CD_MLOOPTANGENT)) { - r_looptangents = static_cast( + r_looptangents = static_cast( CustomData_get_layer_for_write(&mesh->corner_data, CD_MLOOPTANGENT, mesh->corners_num)); - memset(r_looptangents, 0, sizeof(float[4]) * mesh->corners_num); + memset(r_looptangents, 0, sizeof(float4) * mesh->corners_num); } else { - r_looptangents = static_cast(CustomData_add_layer( + r_looptangents = static_cast(CustomData_add_layer( &mesh->corner_data, CD_MLOOPTANGENT, CD_SET_DEFAULT, mesh->corners_num)); CustomData_set_layer_flag(&mesh->corner_data, CD_MLOOPTANGENT, CD_FLAG_TEMPORARY); } - BKE_mesh_calc_loop_tangent_single(mesh, uvmap, r_looptangents, reports); + if (!uvmap) { + uvmap = CustomData_get_active_layer_name(&mesh->corner_data, CD_PROP_FLOAT2); + } + + const bke::AttributeAccessor attributes = mesh->attributes(); + const VArraySpan uv_map = *attributes.lookup(uvmap, bke::AttrDomain::Corner); + if (uv_map.is_empty()) { + BKE_reportf(reports, + RPT_ERROR, + "Tangent space computation needs a UV Map, \"%s\" not found, aborting", + uvmap); + return; + } + + bke::mesh::calc_uv_tangent_tris_quads(mesh->vert_positions(), + mesh->faces(), + mesh->corner_verts(), + mesh->corner_normals(), + uv_map, + {r_looptangents, mesh->corners_num}, + reports); } static void rna_Mesh_free_tangents(Mesh *mesh)