Cleanup: Use C++ types for various mesh array arguments

Also remove duplicated code for creating an array of BMesh positions
This commit is contained in:
Hans Goudey
2024-05-10 18:23:13 -04:00
committed by Hans Goudey
parent e916cd5d69
commit da32aeb455
9 changed files with 202 additions and 208 deletions
@@ -8,6 +8,9 @@
* \ingroup bke
*/
#include "BLI_math_vector_types.hh"
#include "BLI_span.hh"
#include "DNA_customdata_types.h"
struct BMEditMesh;
@@ -23,9 +26,9 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
const float (*face_normals)[3],
const float (*corner_normals)[3],
const float (*vert_orco)[3],
blender::Span<blender::float3> face_normals,
blender::Span<blender::float3> corner_normals,
blender::Span<blender::float3> vert_orco,
CustomData *dm_loopdata_out,
uint dm_loopdata_out_len,
short *tangent_mask_curr_p);
+5 -1
View File
@@ -7,6 +7,7 @@
* \ingroup bke
*/
#include "BLI_array.hh"
#include "BLI_compiler_attrs.h"
#include "BLI_compiler_compat.h"
#include "BLI_utildefines.h"
@@ -138,7 +139,10 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *
bool BKE_mesh_attribute_required(const char *name);
float (*BKE_mesh_orco_verts_get(const Object *ob))[3];
blender::Array<blender::float3> BKE_mesh_orco_verts_get(const Object *ob);
void BKE_mesh_orco_verts_transform(Mesh *mesh,
blender::MutableSpan<blender::float3> orco,
bool invert);
void BKE_mesh_orco_verts_transform(Mesh *mesh, float (*orco)[3], int totvert, bool invert);
/**
@@ -9,6 +9,7 @@
#include "DNA_customdata_types.h"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_sys_types.h"
@@ -45,7 +46,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
/**
* See: #BKE_editmesh_loop_tangent_calc (matching logic).
*/
void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
void BKE_mesh_calc_loop_tangent_ex(blender::Span<blender::float3> vert_positions,
blender::OffsetIndices<int> faces,
const int *corner_verts,
const blender::int3 *corner_tris,
@@ -57,10 +58,10 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
const float (*vert_normals)[3],
const float (*face_normals)[3],
const float (*corner_normals)[3],
const float (*vert_orco)[3],
blender::Span<blender::float3> vert_normals,
blender::Span<blender::float3> face_normals,
blender::Span<blender::float3> corner_normals,
blender::Span<blender::float3> vert_orco,
/* result */
CustomData *loopdata_out,
uint loopdata_out_len,
+27 -51
View File
@@ -69,6 +69,7 @@
# include "DNA_userdef_types.h"
#endif
using blender::Array;
using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
@@ -316,40 +317,22 @@ void DM_interp_vert_data(const DerivedMesh *source,
&source->vertData, &dest->vertData, src_indices, weights, nullptr, count, dest_index);
}
static float (*get_editbmesh_orco_verts(const BMEditMesh *em))[3]
{
BMIter iter;
BMVert *eve;
float(*orco)[3];
int i;
/* these may not really be the orco's, but it's only for preview.
* could be solver better once, but isn't simple */
orco = (float(*)[3])MEM_malloc_arrayN(em->bm->totvert, sizeof(float[3]), "BMEditMesh Orco");
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
copy_v3_v3(orco[i], eve->co);
}
return orco;
}
/* orco custom data layer */
static float (*get_orco_coords(const Object *ob, const BMEditMesh *em, int layer, int *free))[3]
static Span<float3> get_orco_coords(const Object *ob,
const BMEditMesh *em,
eCustomDataType layer_type,
Array<float3> &storage)
{
*free = 0;
if (layer == CD_ORCO) {
/* get original coordinates */
*free = 1;
if (layer_type == CD_ORCO) {
if (em) {
return get_editbmesh_orco_verts(em);
storage = BM_mesh_vert_coords_alloc(em->bm);
return storage;
}
return BKE_mesh_orco_verts_get(ob);
storage = BKE_mesh_orco_verts_get(ob);
return storage;
}
if (layer == CD_CLOTH_ORCO) {
if (layer_type == CD_CLOTH_ORCO) {
/* apply shape key for cloth, this should really be solved
* by a more flexible customdata system, but not simple */
if (!em) {
@@ -360,23 +343,23 @@ static float (*get_orco_coords(const Object *ob, const BMEditMesh *em, int layer
BKE_key_from_object(const_cast<Object *>(ob)), clmd->sim_parms->shapekey_rest);
if (kb && kb->data) {
return (float(*)[3])kb->data;
return {static_cast<const float3 *>(kb->data), kb->totelem};
}
}
}
return nullptr;
return {};
}
return nullptr;
return {};
}
static Mesh *create_orco_mesh(const Object *ob, const Mesh *mesh, const BMEditMesh *em, int layer)
static Mesh *create_orco_mesh(const Object *ob,
const Mesh *mesh,
const BMEditMesh *em,
eCustomDataType layer)
{
Mesh *orco_mesh;
float(*orco)[3];
int free;
if (em) {
orco_mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, nullptr, mesh);
BKE_mesh_ensure_default_orig_index_customdata(orco_mesh);
@@ -385,15 +368,12 @@ static Mesh *create_orco_mesh(const Object *ob, const Mesh *mesh, const BMEditMe
orco_mesh = BKE_mesh_copy_for_eval(mesh);
}
orco = get_orco_coords(ob, em, layer, &free);
Array<float3> storage;
const Span<float3> orco = get_orco_coords(ob, em, layer, storage);
if (orco) {
orco_mesh->vert_positions_for_write().copy_from(
{reinterpret_cast<const float3 *>(orco), orco_mesh->verts_num});
if (!orco.is_empty()) {
orco_mesh->vert_positions_for_write().copy_from(orco);
orco_mesh->tag_positions_changed();
if (free) {
MEM_freeN(orco);
}
}
return orco_mesh;
@@ -430,21 +410,17 @@ static void add_orco_mesh(Object *ob,
else {
/* TODO(sybren): totvert should potentially change here, as ob->data
* or em may have a different number of vertices than dm. */
int free = 0;
float(*orco)[3] = get_orco_coords(ob, em, layer, &free);
if (orco) {
Array<float3> storage;
const Span<float3> orco = get_orco_coords(ob, em, layer, storage);
if (!orco.is_empty()) {
layer_orco = orco_coord_layer_ensure(mesh, layer);
layer_orco.copy_from(Span<float3>(reinterpret_cast<float3 *>(orco), totvert));
}
if (free) {
MEM_freeN(orco);
layer_orco.copy_from(orco);
}
}
if (!layer_orco.is_empty()) {
if (layer == CD_ORCO) {
BKE_mesh_orco_verts_transform(
(Mesh *)ob->data, reinterpret_cast<float(*)[3]>(layer_orco.data()), totvert, false);
BKE_mesh_orco_verts_transform((Mesh *)ob->data, layer_orco, false);
}
}
}
@@ -24,6 +24,9 @@
/* interface */
#include "mikktspace.hh"
using blender::float3;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Tangent Space Calculation
* \{ */
@@ -105,12 +108,12 @@ struct SGLSLEditMeshToTangent {
mikk::float3 GetNormal(const uint face_num, const uint vert_index)
{
const BMLoop *l = GetLoop(face_num, vert_index);
if (precomputedLoopNormals) {
return mikk::float3(precomputedLoopNormals[BM_elem_index_get(l)]);
if (!corner_normals.is_empty()) {
return mikk::float3(corner_normals[BM_elem_index_get(l)]);
}
if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH) == 0) { /* flat */
if (precomputedFaceNormals) {
return mikk::float3(precomputedFaceNormals[BM_elem_index_get(l->f)]);
if (!face_normals.is_empty()) {
return mikk::float3(face_normals[BM_elem_index_get(l->f)]);
}
return mikk::float3(l->f->no);
}
@@ -127,11 +130,11 @@ struct SGLSLEditMeshToTangent {
copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
}
const float (*precomputedFaceNormals)[3];
const float (*precomputedLoopNormals)[3];
blender::Span<std::array<BMLoop *, 3>> looptris;
Span<float3> face_normals;
Span<float3> corner_normals;
Span<std::array<BMLoop *, 3>> looptris;
int cd_loop_uv_offset; /* texture coordinates */
const float (*orco)[3];
Span<float3> orco;
float (*tangent)[4]; /* destination */
int numTessFaces;
@@ -155,9 +158,9 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
const float (*face_normals)[3],
const float (*corner_normals)[3],
const float (*vert_orco)[3],
const Span<float3> face_normals,
const Span<float3> corner_normals,
const Span<float3> vert_orco,
/* result */
CustomData *loopdata_out,
const uint loopdata_out_len,
@@ -253,17 +256,17 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
mesh2tangent->face_as_quad_map = face_as_quad_map;
mesh2tangent->num_face_as_quad_map = num_face_as_quad_map;
#endif
mesh2tangent->precomputedFaceNormals = face_normals;
mesh2tangent->face_normals = face_normals;
/* NOTE: we assume we do have tessellated loop normals at this point
* (in case it is object-enabled), have to check this is valid. */
mesh2tangent->precomputedLoopNormals = corner_normals;
mesh2tangent->corner_normals = corner_normals;
mesh2tangent->cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, n);
/* needed for indexing loop-tangents */
int htype_index = BM_LOOP;
if (mesh2tangent->cd_loop_uv_offset == -1) {
mesh2tangent->orco = vert_orco;
if (!mesh2tangent->orco) {
if (mesh2tangent->orco.is_empty()) {
continue;
}
/* needed for orco lookups */
@@ -279,7 +282,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
BLI_assert(uv_ind - uv_start < MAX_MTFACE);
tangent_mask_curr |= 1 << (uv_ind - uv_start);
}
if (mesh2tangent->precomputedFaceNormals) {
if (!mesh2tangent->face_normals.is_empty()) {
/* needed for face normal lookups */
htype_index |= BM_FACE;
}
+20 -18
View File
@@ -989,25 +989,20 @@ void BKE_mesh_texspace_get_reference(Mesh *mesh,
}
}
float (*BKE_mesh_orco_verts_get(const Object *ob))[3]
blender::Array<float3> BKE_mesh_orco_verts_get(const Object *ob)
{
const Mesh *mesh = static_cast<const Mesh *>(ob->data);
const Mesh *tme = mesh->texcomesh ? mesh->texcomesh : mesh;
/* Get appropriate vertex coordinates */
float(*vcos)[3] = (float(*)[3])MEM_calloc_arrayN(mesh->verts_num, sizeof(*vcos), "orco mesh");
blender::Array<float3> result(mesh->verts_num);
const Span<float3> positions = tme->vert_positions();
result.as_mutable_span().take_front(positions.size()).copy_from(positions);
result.as_mutable_span().drop_front(positions.size()).fill(float3(0));
int totvert = min_ii(tme->verts_num, mesh->verts_num);
for (int a = 0; a < totvert; a++) {
copy_v3_v3(vcos[a], positions[a]);
}
return vcos;
return result;
}
void BKE_mesh_orco_verts_transform(Mesh *mesh, float (*orco)[3], int totvert, const bool invert)
void BKE_mesh_orco_verts_transform(Mesh *mesh, MutableSpan<float3> orco, const bool invert)
{
float texspace_location[3], texspace_size[3];
@@ -1015,14 +1010,14 @@ void BKE_mesh_orco_verts_transform(Mesh *mesh, float (*orco)[3], int totvert, co
mesh->texcomesh ? mesh->texcomesh : mesh, texspace_location, texspace_size);
if (invert) {
for (int a = 0; a < totvert; a++) {
float *co = orco[a];
for (const int a : orco.index_range()) {
float3 &co = orco[a];
madd_v3_v3v3v3(co, texspace_location, co, texspace_size);
}
}
else {
for (int a = 0; a < totvert; a++) {
float *co = orco[a];
for (const int a : orco.index_range()) {
float3 &co = orco[a];
co[0] = (co[0] - texspace_location[0]) / texspace_size[0];
co[1] = (co[1] - texspace_location[1]) / texspace_size[1];
co[2] = (co[2] - texspace_location[2]) / texspace_size[2];
@@ -1030,6 +1025,11 @@ void BKE_mesh_orco_verts_transform(Mesh *mesh, float (*orco)[3], int totvert, co
}
}
void BKE_mesh_orco_verts_transform(Mesh *mesh, float (*orco)[3], int totvert, bool invert)
{
BKE_mesh_orco_verts_transform(mesh, {reinterpret_cast<float3 *>(orco), totvert}, invert);
}
void BKE_mesh_orco_ensure(Object *ob, Mesh *mesh)
{
if (CustomData_has_layer(&mesh->vert_data, CD_ORCO)) {
@@ -1037,9 +1037,11 @@ void BKE_mesh_orco_ensure(Object *ob, Mesh *mesh)
}
/* Orcos are stored in normalized 0..1 range by convention. */
float(*orcodata)[3] = BKE_mesh_orco_verts_get(ob);
BKE_mesh_orco_verts_transform(mesh, orcodata, mesh->verts_num, false);
CustomData_add_layer_with_data(&mesh->vert_data, CD_ORCO, orcodata, mesh->verts_num, nullptr);
blender::Array<float3> orcodata = BKE_mesh_orco_verts_get(ob);
BKE_mesh_orco_verts_transform(mesh, orcodata, false);
float3 *data = static_cast<float3 *>(
CustomData_add_layer(&mesh->vert_data, CD_ORCO, CD_CONSTRUCT, mesh->verts_num));
MutableSpan(data, mesh->verts_num).copy_from(orcodata);
}
Mesh *BKE_mesh_from_object(Object *ob)
@@ -29,6 +29,10 @@
#include "BLI_strict_flags.h" /* Keep last. */
using blender::float2;
using blender::float3;
using blender::int3;
using blender::OffsetIndices;
using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Mesh Tangent Calculations (Single Layer)
@@ -68,13 +72,13 @@ struct BKEMeshToTangent {
copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
}
blender::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 */
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 */
};
void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3],
@@ -84,7 +88,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3],
const float (*corner_normals)[3],
const float (*loop_uvs)[2],
const int /*numLoops*/,
const blender::OffsetIndices<int> faces,
const OffsetIndices<int> faces,
ReportList *reports)
{
/* Compute Mikktspace's tangent normals. */
@@ -179,7 +183,7 @@ struct SGLSLMeshToTangent {
#endif
}
uint GetLoop(const uint face_num, const uint vert_num, blender::int3 &tri, int &face_index)
uint GetLoop(const uint face_num, const uint vert_num, int3 &tri, int &face_index)
{
#ifdef USE_TRI_DETECT_QUADS
if (face_as_quad_map) {
@@ -202,7 +206,7 @@ struct SGLSLMeshToTangent {
mikk::float3 GetPosition(const uint face_num, const uint vert_num)
{
blender::int3 tri;
int3 tri;
int face_index;
uint loop_index = GetLoop(face_num, vert_num, tri, face_index);
return mikk::float3(positions[corner_verts[loop_index]]);
@@ -210,7 +214,7 @@ struct SGLSLMeshToTangent {
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
{
blender::int3 tri;
int3 tri;
int face_index;
uint loop_index = GetLoop(face_num, vert_num, tri, face_index);
if (mloopuv != nullptr) {
@@ -225,15 +229,15 @@ struct SGLSLMeshToTangent {
mikk::float3 GetNormal(const uint face_num, const uint vert_num)
{
blender::int3 tri;
int3 tri;
int face_index;
uint loop_index = GetLoop(face_num, vert_num, tri, face_index);
if (precomputedLoopNormals) {
return mikk::float3(precomputedLoopNormals[loop_index]);
if (!corner_normals.is_empty()) {
return mikk::float3(corner_normals[loop_index]);
}
if (!sharp_faces.is_empty() && sharp_faces[face_index]) { /* flat */
if (precomputedFaceNormals) {
return mikk::float3(precomputedFaceNormals[face_index]);
if (!face_normals.is_empty()) {
return mikk::float3(face_normals[face_index]);
}
#ifdef USE_TRI_DETECT_QUADS
const blender::IndexRange face = faces[face_index];
@@ -260,25 +264,25 @@ struct SGLSLMeshToTangent {
void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation)
{
blender::int3 tri;
int3 tri;
int face_index;
uint loop_index = GetLoop(face_num, vert_num, tri, face_index);
copy_v4_fl4(tangent[loop_index], T.x, T.y, T.z, orientation ? 1.0f : -1.0f);
}
const float (*precomputedFaceNormals)[3];
const float (*precomputedLoopNormals)[3];
const blender::int3 *corner_tris;
Span<float3> face_normals;
Span<float3> corner_normals;
const int3 *corner_tris;
const int *tri_faces;
const float2 *mloopuv; /* texture coordinates */
blender::OffsetIndices<int> faces;
const int *corner_verts; /* indices */
const float (*positions)[3]; /* vertex coordinates */
const float (*vert_normals)[3];
const float (*orco)[3];
OffsetIndices<int> faces;
const int *corner_verts; /* indices */
Span<float3> positions; /* vertex coordinates */
Span<float3> vert_normals;
Span<float3> orco;
float (*tangent)[4]; /* destination */
blender::Span<bool> sharp_faces;
Span<bool> sharp_faces;
int numTessFaces;
#ifdef USE_TRI_DETECT_QUADS
@@ -385,22 +389,22 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
}
}
void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const blender::OffsetIndices<int> faces,
void BKE_mesh_calc_loop_tangent_ex(const Span<float3> vert_positions,
const OffsetIndices<int> faces,
const int *corner_verts,
const blender::int3 *corner_tris,
const int3 *corner_tris,
const int *corner_tri_faces,
const uint corner_tris_len,
const blender::Span<bool> sharp_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 float (*vert_normals)[3],
const float (*face_normals)[3],
const float (*corner_normals)[3],
const float (*vert_orco)[3],
const Span<float3> vert_normals,
const Span<float3> face_normals,
const Span<float3> corner_normals,
const Span<float3> vert_orco,
/* result */
CustomData *loopdata_out,
const uint loopdata_out_len,
@@ -501,17 +505,17 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
mesh2tangent->sharp_faces = sharp_faces;
/* NOTE: we assume we do have tessellated loop normals at this point
* (in case it is object-enabled), have to check this is valid. */
mesh2tangent->precomputedLoopNormals = corner_normals;
mesh2tangent->precomputedFaceNormals = face_normals;
mesh2tangent->corner_normals = corner_normals;
mesh2tangent->face_normals = face_normals;
mesh2tangent->orco = nullptr;
mesh2tangent->orco = {};
mesh2tangent->mloopuv = static_cast<const float2 *>(CustomData_get_layer_named(
loopdata, CD_PROP_FLOAT2, loopdata_out->layers[index].name));
/* Fill the resulting tangent_mask */
if (!mesh2tangent->mloopuv) {
mesh2tangent->orco = vert_orco;
if (!mesh2tangent->orco) {
if (mesh2tangent->orco.is_empty()) {
continue;
}
@@ -573,31 +577,32 @@ void BKE_mesh_calc_loop_tangents(Mesh *mesh_eval,
/* TODO(@ideasman42): store in Mesh.runtime to avoid recalculation. */
using namespace blender;
using namespace blender::bke;
const blender::Span<int3> corner_tris = mesh_eval->corner_tris();
const Span<int3> corner_tris = mesh_eval->corner_tris();
const bke::AttributeAccessor attributes = mesh_eval->attributes();
const VArraySpan sharp_face = *attributes.lookup<bool>("sharp_face", AttrDomain::Face);
const float3 *orco = static_cast<const float3 *>(
CustomData_get_layer(&mesh_eval->vert_data, CD_ORCO));
short tangent_mask = 0;
BKE_mesh_calc_loop_tangent_ex(
reinterpret_cast<const float(*)[3]>(mesh_eval->vert_positions().data()),
mesh_eval->faces(),
mesh_eval->corner_verts().data(),
corner_tris.data(),
mesh_eval->corner_tri_faces().data(),
uint(corner_tris.size()),
sharp_face,
&mesh_eval->corner_data,
calc_active_tangent,
tangent_names,
tangent_names_len,
reinterpret_cast<const float(*)[3]>(mesh_eval->vert_normals().data()),
reinterpret_cast<const float(*)[3]>(mesh_eval->face_normals().data()),
reinterpret_cast<const float(*)[3]>(mesh_eval->corner_normals().data()),
/* may be nullptr */
static_cast<const float(*)[3]>(CustomData_get_layer(&mesh_eval->vert_data, CD_ORCO)),
/* result */
&mesh_eval->corner_data,
uint(mesh_eval->corners_num),
&tangent_mask);
BKE_mesh_calc_loop_tangent_ex(mesh_eval->vert_positions(),
mesh_eval->faces(),
mesh_eval->corner_verts().data(),
corner_tris.data(),
mesh_eval->corner_tri_faces().data(),
uint(corner_tris.size()),
sharp_face,
&mesh_eval->corner_data,
calc_active_tangent,
tangent_names,
tangent_names_len,
mesh_eval->vert_normals(),
mesh_eval->face_normals(),
mesh_eval->corner_normals(),
/* may be nullptr */
orco ? Span(orco, mesh_eval->verts_num) : Span<float3>(),
/* result */
&mesh_eval->corner_data,
uint(mesh_eval->corners_num),
&tangent_mask);
}
/** \} */
@@ -43,8 +43,9 @@ static void extract_tan_init_common(const MeshRenderData &mr,
const CustomData *cd_vdata = (mr.extract_type == MR_EXTRACT_BMESH) ? &mr.bm->vdata :
&mr.mesh->vert_data;
uint32_t tan_layers = cache.cd_used.tan;
const float(*orco)[3] = (const float(*)[3])CustomData_get_layer(cd_vdata, CD_ORCO);
float(*orco_allocated)[3] = nullptr;
const float3 *orco_ptr = static_cast<const float3 *>(CustomData_get_layer(cd_vdata, CD_ORCO));
Span<float3> orco = orco_ptr ? Span(orco_ptr, mr.verts_num) : Span<float3>();
Array<float3> orco_allocated;
bool use_orco_tan = cache.cd_used.tan_orco != 0;
int tan_len = 0;
@@ -81,9 +82,9 @@ static void extract_tan_init_common(const MeshRenderData &mr,
STRNCPY(r_tangent_names[tan_len++], layer_name);
}
}
if (use_orco_tan && orco == nullptr) {
if (use_orco_tan && orco.is_empty()) {
/* If `orco` is not available compute it ourselves */
orco_allocated = (float(*)[3])MEM_mallocN(sizeof(*orco) * mr.verts_num, __func__);
orco_allocated.reinitialize(mr.verts_num);
if (mr.extract_type == MR_EXTRACT_BMESH) {
BMesh *bm = mr.bm;
@@ -100,8 +101,7 @@ static void extract_tan_init_common(const MeshRenderData &mr,
}
}
/* TODO: This is not thread-safe. Draw extraction should not modify the mesh. */
BKE_mesh_orco_verts_transform(
const_cast<Mesh *>(mr.mesh), orco_allocated, mr.verts_num, false);
BKE_mesh_orco_verts_transform(const_cast<Mesh *>(mr.mesh), orco_allocated, false);
orco = orco_allocated;
}
@@ -115,15 +115,15 @@ static void extract_tan_init_common(const MeshRenderData &mr,
calc_active_tangent,
r_tangent_names,
tan_len,
reinterpret_cast<const float(*)[3]>(mr.face_normals.data()),
reinterpret_cast<const float(*)[3]>(mr.corner_normals.data()),
mr.face_normals,
mr.corner_normals,
orco,
r_loop_data,
mr.corners_num,
&tangent_mask);
}
else {
BKE_mesh_calc_loop_tangent_ex(reinterpret_cast<const float(*)[3]>(mr.vert_positions.data()),
BKE_mesh_calc_loop_tangent_ex(mr.vert_positions,
mr.faces,
mr.corner_verts.data(),
corner_tris.data(),
@@ -134,9 +134,9 @@ static void extract_tan_init_common(const MeshRenderData &mr,
calc_active_tangent,
r_tangent_names,
tan_len,
reinterpret_cast<const float(*)[3]>(mr.vert_normals.data()),
reinterpret_cast<const float(*)[3]>(mr.face_normals.data()),
reinterpret_cast<const float(*)[3]>(mr.corner_normals.data()),
mr.vert_normals,
mr.face_normals,
mr.corner_normals,
orco,
r_loop_data,
mr.corner_verts.size(),
@@ -154,8 +154,6 @@ static void extract_tan_init_common(const MeshRenderData &mr,
GPU_vertformat_alias_add(format, "at");
}
MEM_SAFE_FREE(orco_allocated);
int v_len = mr.corners_num;
if (format->attr_len == 0) {
GPU_vertformat_attr_add(format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+43 -41
View File
@@ -477,6 +477,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
MFreeBakeData freeBakeData,
MultiresBakeResult *result)
{
using namespace blender;
DerivedMesh *dm = bkr->lores_dm;
const int lvl = bkr->lvl;
if (dm->getNumPolys(dm) == 0) {
@@ -485,8 +486,8 @@ static void do_multires_bake(MultiresBakeRender *bkr,
MultiresBakeQueue queue;
const blender::Span<blender::float2> uv_map(
reinterpret_cast<const blender::float2 *>(dm->getLoopDataArray(dm, CD_PROP_FLOAT2)),
const Span<float2> uv_map(
reinterpret_cast<const float2 *>(dm->getLoopDataArray(dm, CD_PROP_FLOAT2)),
dm->getNumLoops(dm));
float *pvtangent = nullptr;
@@ -499,22 +500,22 @@ static void do_multires_bake(MultiresBakeRender *bkr,
Mesh *temp_mesh = BKE_mesh_new_nomain(
dm->getNumVerts(dm), dm->getNumEdges(dm), dm->getNumPolys(dm), dm->getNumLoops(dm));
temp_mesh->vert_positions_for_write().copy_from(
{reinterpret_cast<const blender::float3 *>(dm->getVertArray(dm)), temp_mesh->verts_num});
{reinterpret_cast<const float3 *>(dm->getVertArray(dm)), temp_mesh->verts_num});
temp_mesh->edges_for_write().copy_from(
{reinterpret_cast<const blender::int2 *>(dm->getEdgeArray(dm)), temp_mesh->edges_num});
{reinterpret_cast<const int2 *>(dm->getEdgeArray(dm)), temp_mesh->edges_num});
temp_mesh->face_offsets_for_write().copy_from({dm->getPolyArray(dm), temp_mesh->faces_num + 1});
temp_mesh->corner_verts_for_write().copy_from(
{dm->getCornerVertArray(dm), temp_mesh->corners_num});
temp_mesh->corner_edges_for_write().copy_from(
{dm->getCornerEdgeArray(dm), temp_mesh->corners_num});
const blender::Span<blender::float3> positions = temp_mesh->vert_positions();
const blender::OffsetIndices faces = temp_mesh->faces();
const blender::Span<int> corner_verts = temp_mesh->corner_verts();
const blender::Span<blender::float3> vert_normals = temp_mesh->vert_normals();
const blender::Span<blender::float3> face_normals = temp_mesh->face_normals();
const blender::Span<blender::int3> corner_tris = temp_mesh->corner_tris();
const blender::Span<int> tri_faces = temp_mesh->corner_tri_faces();
const Span<float3> positions = temp_mesh->vert_positions();
const OffsetIndices faces = temp_mesh->faces();
const Span<int> corner_verts = temp_mesh->corner_verts();
const Span<float3> vert_normals = temp_mesh->vert_normals();
const Span<float3> face_normals = temp_mesh->face_normals();
const Span<int3> corner_tris = temp_mesh->corner_tris();
const Span<int> tri_faces = temp_mesh->corner_tri_faces();
if (require_tangent) {
if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) {
@@ -526,41 +527,42 @@ static void do_multires_bake(MultiresBakeRender *bkr,
/* Copy sharp faces and edges, for corner normals domain and tangents
* to be computed correctly. */
if (sharp_edges) {
blender::bke::MutableAttributeAccessor attributes = temp_mesh->attributes_for_write();
bke::MutableAttributeAccessor attributes = temp_mesh->attributes_for_write();
attributes.add<bool>("sharp_edge",
blender::bke::AttrDomain::Edge,
blender::bke::AttributeInitVArray(blender::VArray<bool>::ForSpan(
blender::Span<bool>(sharp_edges, temp_mesh->edges_num))));
bke::AttrDomain::Edge,
bke::AttributeInitVArray(VArray<bool>::ForSpan(
Span<bool>(sharp_edges, temp_mesh->edges_num))));
}
if (sharp_faces) {
blender::bke::MutableAttributeAccessor attributes = temp_mesh->attributes_for_write();
bke::MutableAttributeAccessor attributes = temp_mesh->attributes_for_write();
attributes.add<bool>("sharp_face",
blender::bke::AttrDomain::Face,
blender::bke::AttributeInitVArray(blender::VArray<bool>::ForSpan(
blender::Span<bool>(sharp_faces, temp_mesh->faces_num))));
bke::AttrDomain::Face,
bke::AttributeInitVArray(VArray<bool>::ForSpan(
Span<bool>(sharp_faces, temp_mesh->faces_num))));
}
const blender::Span<blender::float3> corner_normals = temp_mesh->corner_normals();
BKE_mesh_calc_loop_tangent_ex(
reinterpret_cast<const float(*)[3]>(positions.data()),
faces,
dm->getCornerVertArray(dm),
corner_tris.data(),
tri_faces.data(),
corner_tris.size(),
sharp_faces ? blender::Span(sharp_faces, faces.size()) : blender::Span<bool>(),
&dm->loopData,
true,
nullptr,
0,
reinterpret_cast<const float(*)[3]>(vert_normals.data()),
reinterpret_cast<const float(*)[3]>(face_normals.data()),
reinterpret_cast<const float(*)[3]>(corner_normals.data()),
(const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* May be nullptr. */
/* result */
&dm->loopData,
dm->getNumLoops(dm),
&dm->tangent_mask);
const float3 *orco = static_cast<const float3 *>(dm->getVertDataArray(dm, CD_ORCO));
const Span<float3> corner_normals = temp_mesh->corner_normals();
BKE_mesh_calc_loop_tangent_ex(positions,
faces,
dm->getCornerVertArray(dm),
corner_tris.data(),
tri_faces.data(),
corner_tris.size(),
sharp_faces ? Span(sharp_faces, faces.size()) : Span<bool>(),
&dm->loopData,
true,
nullptr,
0,
vert_normals,
face_normals,
corner_normals,
orco ? Span(orco, positions.size()) : Span<float3>(),
/* result */
&dm->loopData,
dm->getNumLoops(dm),
&dm->tangent_mask);
}
pvtangent = static_cast<float *>(DM_get_loop_data_layer(dm, CD_TANGENT));
@@ -575,7 +577,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
BLI_threadpool_init(&threads, do_multires_bake_thread, tot_thread);
}
blender::Array<MultiresBakeThread> handles(tot_thread);
Array<MultiresBakeThread> handles(tot_thread);
init_ccgdm_arrays(bkr->hires_dm);