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:
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user