Refactor: Mesh: Slightly simplify tangents API
The RNA `Mesh.calc_tangents()` function used a mesh tangents API wrapper function that existed at a different abstraction level than the other functions. That wrapper was only used in this single place, so just inline its logic into the RNA code. Also give the base tangents API function a name that makes its limitations clear.
This commit is contained in:
@@ -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<int> 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<float3> vert_positions,
|
||||
OffsetIndices<int> faces,
|
||||
Span<int> corner_verts,
|
||||
Span<float3> corner_normals,
|
||||
Span<float2> uv_map,
|
||||
MutableSpan<float4> results,
|
||||
ReportList *reports);
|
||||
|
||||
/**
|
||||
* See: #BKE_editmesh_uv_tangents_calc (matching logic).
|
||||
|
||||
@@ -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<int> 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<int> faces; /* faces */
|
||||
Span<int> corner_verts; /* faces vertices */
|
||||
Span<float3> positions; /* vertices */
|
||||
Span<float2> luvs; /* texture coordinates */
|
||||
Span<float3> corner_normals; /* loops' normals */
|
||||
MutableSpan<float4> 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<int> faces,
|
||||
ReportList *reports)
|
||||
void calc_uv_tangent_tris_quads(const Span<float3> vert_positions,
|
||||
const OffsetIndices<int> faces,
|
||||
const Span<int> corner_verts,
|
||||
const Span<float3> corner_normals,
|
||||
const Span<float2> uv_map,
|
||||
MutableSpan<float4> 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<BKEMeshToTangent> 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<float2>(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<const float(*)[3]>(mesh->vert_positions().data()),
|
||||
mesh->verts_num,
|
||||
mesh->corner_verts().data(),
|
||||
r_looptangents,
|
||||
reinterpret_cast<const float(*)[3]>(mesh->corner_normals().data()),
|
||||
reinterpret_cast<const float(*)[2]>(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()
|
||||
{
|
||||
|
||||
@@ -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<float(*)[4]>(
|
||||
r_looptangents = static_cast<float4 *>(
|
||||
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<float(*)[4]>(CustomData_add_layer(
|
||||
r_looptangents = static_cast<float4 *>(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<float2>(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)
|
||||
|
||||
Reference in New Issue
Block a user