Cleanup: Use spans and float3 to store sculpt and PBVH vert positions
Also store the allocated deformed positions in a separate array in PBVH, so there isn't one pointer that _sometimes_ has ownership of its data. Pull Request: https://projects.blender.org/blender/blender/pulls/109981
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include "BLI_compiler_compat.h"
|
||||
#ifdef __cplusplus
|
||||
# include "BLI_array.hh"
|
||||
# include "BLI_math_vector_types.hh"
|
||||
# include "BLI_offset_indices.hh"
|
||||
#endif
|
||||
#include "BLI_utildefines.h"
|
||||
@@ -594,7 +595,7 @@ typedef struct SculptSession {
|
||||
struct Depsgraph *depsgraph;
|
||||
|
||||
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
|
||||
float (*vert_positions)[3];
|
||||
blender::MutableSpan<blender::float3> vert_positions;
|
||||
blender::OffsetIndices<int> polys;
|
||||
blender::Span<int> corner_verts;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_offset_indices.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
@@ -498,8 +499,8 @@ struct PBVHVertexIter {
|
||||
int gridsize;
|
||||
|
||||
/* mesh */
|
||||
float (*vert_positions)[3];
|
||||
float (*vert_normals)[3];
|
||||
blender::MutableSpan<blender::float3> vert_positions;
|
||||
blender::MutableSpan<blender::float3> vert_normals;
|
||||
const bool *hide_vert;
|
||||
int totvert;
|
||||
const int *vert_indices;
|
||||
@@ -558,7 +559,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
else if (vi.vert_positions) { \
|
||||
else if (!vi.vert_positions.is_empty()) { \
|
||||
vi.visible = !(vi.hide_vert && vi.hide_vert[vi.vert_indices[vi.gx]]); \
|
||||
if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \
|
||||
continue; \
|
||||
|
||||
@@ -1737,7 +1737,7 @@ static void sculpt_update_object(
|
||||
|
||||
/* These are assigned to the base mesh in Multires. This is needed because Face Sets operators
|
||||
* and tools use the Face Sets data from the base mesh when Multires is active. */
|
||||
ss->vert_positions = BKE_mesh_vert_positions_for_write(me);
|
||||
ss->vert_positions = me->vert_positions_for_write();
|
||||
ss->polys = me->polys();
|
||||
ss->corner_verts = me->corner_verts();
|
||||
}
|
||||
@@ -1745,7 +1745,7 @@ static void sculpt_update_object(
|
||||
ss->totvert = me->totvert;
|
||||
ss->totpoly = me->totpoly;
|
||||
ss->totfaces = me->totpoly;
|
||||
ss->vert_positions = BKE_mesh_vert_positions_for_write(me);
|
||||
ss->vert_positions = me->vert_positions_for_write();
|
||||
ss->polys = me->polys();
|
||||
ss->corner_verts = me->corner_verts();
|
||||
ss->multires.active = false;
|
||||
|
||||
@@ -699,7 +699,6 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node)
|
||||
memset((void *)args, 0, sizeof(*args));
|
||||
|
||||
args->pbvh_type = pbvh->header.type;
|
||||
args->mesh_verts_num = pbvh->totvert;
|
||||
args->mesh_grids_num = pbvh->totgrid;
|
||||
args->node = node;
|
||||
|
||||
@@ -857,7 +856,7 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh)
|
||||
if (!pbvh->deformed) {
|
||||
/* Deformed positions not matching the original mesh are owned directly by the PBVH, and are
|
||||
* set separately by #BKE_pbvh_vert_coords_apply. */
|
||||
pbvh->vert_positions = BKE_mesh_vert_positions_for_write(mesh);
|
||||
pbvh->vert_positions = mesh->vert_positions_for_write();
|
||||
}
|
||||
|
||||
pbvh->hide_poly = static_cast<bool *>(CustomData_get_layer_named_for_write(
|
||||
@@ -869,7 +868,7 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh)
|
||||
mesh->vert_normals();
|
||||
mesh->poly_normals();
|
||||
|
||||
pbvh->vert_normals = BKE_mesh_vert_normals_for_write(mesh);
|
||||
pbvh->vert_normals = mesh->runtime->vert_normals;
|
||||
pbvh->poly_normals = mesh->runtime->poly_normals;
|
||||
|
||||
pbvh->vdata = &mesh->vdata;
|
||||
@@ -1095,14 +1094,6 @@ void BKE_pbvh_free(PBVH *pbvh)
|
||||
}
|
||||
}
|
||||
|
||||
if (pbvh->deformed) {
|
||||
if (pbvh->vert_positions) {
|
||||
/* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
|
||||
|
||||
MEM_freeN((void *)pbvh->vert_positions);
|
||||
}
|
||||
}
|
||||
|
||||
if (pbvh->looptri) {
|
||||
MEM_freeN((void *)pbvh->looptri);
|
||||
}
|
||||
@@ -1119,7 +1110,7 @@ void BKE_pbvh_free(PBVH *pbvh)
|
||||
|
||||
pbvh_pixels_free(pbvh);
|
||||
|
||||
MEM_freeN(pbvh);
|
||||
MEM_delete(pbvh);
|
||||
}
|
||||
|
||||
static void pbvh_iter_begin(PBVHIter *iter,
|
||||
@@ -1387,8 +1378,7 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const Span<float3> positions(reinterpret_cast<const float3 *>(pbvh->vert_positions),
|
||||
pbvh->totvert);
|
||||
const Span<float3> positions = pbvh->vert_positions;
|
||||
const OffsetIndices polys = pbvh->polys;
|
||||
const Span<int> corner_verts(pbvh->corner_verts, pbvh->mesh->totloop);
|
||||
|
||||
@@ -1407,7 +1397,7 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes)
|
||||
return;
|
||||
}
|
||||
|
||||
MutableSpan<float3> vert_normals(reinterpret_cast<float3 *>(pbvh->vert_normals), pbvh->totvert);
|
||||
MutableSpan<float3> vert_normals = pbvh->vert_normals;
|
||||
MutableSpan<float3> poly_normals = pbvh->poly_normals;
|
||||
|
||||
VectorSet<int> verts_to_update;
|
||||
@@ -2470,7 +2460,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
|
||||
int *r_active_face_index,
|
||||
float *r_face_normal)
|
||||
{
|
||||
const float(*positions)[3] = pbvh->vert_positions;
|
||||
const Span<float3> positions = pbvh->vert_positions;
|
||||
const int *corner_verts = pbvh->corner_verts;
|
||||
const int *looptris = node->prim_indices;
|
||||
int looptris_num = node->totprim;
|
||||
@@ -2819,7 +2809,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
|
||||
float *depth,
|
||||
float *dist_sq)
|
||||
{
|
||||
const float(*positions)[3] = pbvh->vert_positions;
|
||||
const Span<float3> positions = pbvh->vert_positions;
|
||||
const int *corner_verts = pbvh->corner_verts;
|
||||
const int *looptris = node->prim_indices;
|
||||
int i, looptris_num = node->totprim;
|
||||
@@ -3182,10 +3172,10 @@ float (*BKE_pbvh_vert_coords_alloc(PBVH *pbvh))[3]
|
||||
{
|
||||
float(*vertCos)[3] = nullptr;
|
||||
|
||||
if (pbvh->vert_positions) {
|
||||
if (!pbvh->vert_positions.is_empty()) {
|
||||
vertCos = static_cast<float(*)[3]>(
|
||||
MEM_malloc_arrayN(pbvh->totvert, sizeof(float[3]), __func__));
|
||||
memcpy(vertCos, pbvh->vert_positions, sizeof(float[3]) * pbvh->totvert);
|
||||
memcpy(vertCos, pbvh->vert_positions.data(), sizeof(float[3]) * pbvh->totvert);
|
||||
}
|
||||
|
||||
return vertCos;
|
||||
@@ -3199,12 +3189,13 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int
|
||||
}
|
||||
|
||||
if (!pbvh->deformed) {
|
||||
if (pbvh->vert_positions) {
|
||||
if (!pbvh->vert_positions.is_empty()) {
|
||||
/* if pbvh is not already deformed, verts/faces points to the */
|
||||
/* original data and applying new coords to this arrays would lead to */
|
||||
/* unneeded deformation -- duplicate verts/faces to avoid this */
|
||||
pbvh->vert_positions_deformed = blender::Array<float3>(pbvh->vert_positions.as_span());
|
||||
pbvh->vert_positions = pbvh->vert_positions_deformed;
|
||||
|
||||
pbvh->vert_positions = static_cast<float(*)[3]>(MEM_dupallocN(pbvh->vert_positions));
|
||||
/* No need to dupalloc pbvh->looptri, this one is 'totally owned' by pbvh,
|
||||
* it's never some mesh data. */
|
||||
|
||||
@@ -3212,8 +3203,8 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int
|
||||
}
|
||||
}
|
||||
|
||||
if (pbvh->vert_positions) {
|
||||
float(*positions)[3] = pbvh->vert_positions;
|
||||
if (!pbvh->vert_positions.is_empty()) {
|
||||
MutableSpan<float3> positions = pbvh->vert_positions;
|
||||
/* copy new verts coords */
|
||||
for (int a = 0; a < pbvh->totvert; a++) {
|
||||
/* no need for float comparison here (memory is exactly equal or not) */
|
||||
@@ -3301,7 +3292,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
|
||||
vi->grid = nullptr;
|
||||
vi->no = nullptr;
|
||||
vi->fno = nullptr;
|
||||
vi->vert_positions = nullptr;
|
||||
vi->vert_positions = {};
|
||||
vi->vertex.i = 0LL;
|
||||
|
||||
BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, &gridsize, &grids);
|
||||
@@ -3322,7 +3313,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m
|
||||
}
|
||||
vi->vert_indices = vert_indices;
|
||||
vi->vert_positions = pbvh->vert_positions;
|
||||
vi->is_mesh = pbvh->vert_positions != nullptr;
|
||||
vi->is_mesh = !pbvh->vert_positions.is_empty();
|
||||
|
||||
if (pbvh->header.type == PBVH_BMESH) {
|
||||
BLI_gsetIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
|
||||
@@ -3402,13 +3393,13 @@ void BKE_pbvh_parallel_range_settings(TaskParallelSettings *settings,
|
||||
float (*BKE_pbvh_get_vert_positions(const PBVH *pbvh))[3]
|
||||
{
|
||||
BLI_assert(pbvh->header.type == PBVH_FACES);
|
||||
return pbvh->vert_positions;
|
||||
return reinterpret_cast<float(*)[3]>(pbvh->vert_positions.data());
|
||||
}
|
||||
|
||||
const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3]
|
||||
{
|
||||
BLI_assert(pbvh->header.type == PBVH_FACES);
|
||||
return pbvh->vert_normals;
|
||||
return reinterpret_cast<const float(*)[3]>(pbvh->vert_normals.data());
|
||||
}
|
||||
|
||||
const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh)
|
||||
|
||||
@@ -157,10 +157,12 @@ struct PBVH {
|
||||
Mesh *mesh;
|
||||
|
||||
/* NOTE: Normals are not `const` because they can be updated for drawing by sculpt code. */
|
||||
float (*vert_normals)[3];
|
||||
blender::MutableSpan<blender::float3> vert_normals;
|
||||
blender::MutableSpan<blender::float3> poly_normals;
|
||||
bool *hide_vert;
|
||||
float (*vert_positions)[3];
|
||||
blender::MutableSpan<blender::float3> vert_positions;
|
||||
/** Local vertex positions owned by the PVBH when not sculpting base mesh positions directly. */
|
||||
blender::Array<blender::float3> vert_positions_deformed;
|
||||
blender::OffsetIndices<int> polys;
|
||||
bool *hide_poly;
|
||||
/** Only valid for polygon meshes. */
|
||||
|
||||
@@ -670,11 +670,10 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
|
||||
const AttributeAccessor attributes = mesh->attributes();
|
||||
const VArraySpan uv_map = *attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
|
||||
|
||||
uv_islands::MeshData mesh_data(
|
||||
{pbvh->looptri, pbvh->totprim},
|
||||
{pbvh->corner_verts, mesh->totloop},
|
||||
uv_map,
|
||||
{static_cast<blender::float3 *>(static_cast<void *>(pbvh->vert_positions)), pbvh->totvert});
|
||||
uv_islands::MeshData mesh_data({pbvh->looptri, pbvh->totprim},
|
||||
{pbvh->corner_verts, mesh->totloop},
|
||||
uv_map,
|
||||
pbvh->vert_positions);
|
||||
uv_islands::UVIslands islands(mesh_data);
|
||||
|
||||
uv_islands::UVIslandsMask uv_masks;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
/* Needed for BKE_ccg.h. */
|
||||
#include "BLI_assert.h"
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_offset_indices.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
@@ -34,13 +35,13 @@ struct PBVH_GPU_Args {
|
||||
|
||||
BMesh *bm;
|
||||
const Mesh *me;
|
||||
const float (*vert_positions)[3];
|
||||
blender::MutableSpan<blender::float3> vert_positions;
|
||||
blender::OffsetIndices<int> polys;
|
||||
blender::Span<int> corner_verts;
|
||||
blender::Span<int> corner_edges;
|
||||
int mesh_verts_num, mesh_faces_num, mesh_grids_num;
|
||||
int mesh_faces_num, mesh_grids_num;
|
||||
CustomData *vdata, *ldata, *pdata;
|
||||
const float (*vert_normals)[3];
|
||||
blender::Span<blender::float3> vert_normals;
|
||||
|
||||
const char *active_color;
|
||||
const char *render_color;
|
||||
|
||||
@@ -345,8 +345,7 @@ struct PBVHBatches {
|
||||
flat = sharp_faces && sharp_faces[poly_i];
|
||||
if (flat) {
|
||||
const float3 fno = blender::bke::mesh::poly_normal_calc(
|
||||
{reinterpret_cast<const float3 *>(args->vert_positions), args->mesh_verts_num},
|
||||
args->corner_verts.slice(args->polys[poly_i]));
|
||||
args->vert_positions, args->corner_verts.slice(args->polys[poly_i]));
|
||||
normal_float_to_short_v3(no, fno);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1542,7 +1542,7 @@ static void project_line_gesture_apply_task_cb(void *__restrict userdata,
|
||||
continue;
|
||||
}
|
||||
add_v3_v3(vd.co, disp);
|
||||
if (vd.vert_positions) {
|
||||
if (vd.is_mesh) {
|
||||
BKE_pbvh_vert_tag_update_normal(sgcontext->ss->pbvh, vd.vertex);
|
||||
}
|
||||
any_updated = true;
|
||||
|
||||
@@ -3262,7 +3262,7 @@ static void do_vpaint_brush_smear(bContext *C,
|
||||
const int v_index = has_grids ? ss->corner_verts[vd.grid_indices[vd.g]] :
|
||||
vd.vert_indices[vd.i];
|
||||
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
|
||||
const float3 &mv_curr = &ss->vert_positions[v_index];
|
||||
const float3 &mv_curr = ss->vert_positions[v_index];
|
||||
|
||||
/* if the vertex is selected for painting. */
|
||||
if (use_vert_sel && !select_vert[v_index]) {
|
||||
|
||||
@@ -321,7 +321,7 @@ float (*SCULPT_mesh_deformed_positions_get(SculptSession *ss))[3]
|
||||
if (ss->shapekey_active || ss->deform_modifiers_active) {
|
||||
return BKE_pbvh_get_vert_positions(ss->pbvh);
|
||||
}
|
||||
return ss->vert_positions;
|
||||
return reinterpret_cast<float(*)[3]>(ss->vert_positions.data());
|
||||
case PBVH_BMESH:
|
||||
case PBVH_GRIDS:
|
||||
return nullptr;
|
||||
|
||||
@@ -417,7 +417,7 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt
|
||||
|
||||
/* No need for float comparison here (memory is exactly equal or not). */
|
||||
index = unode->index;
|
||||
float(*positions)[3] = ss->vert_positions;
|
||||
blender::MutableSpan<blender::float3> positions = ss->vert_positions;
|
||||
|
||||
if (ss->shapekey_active) {
|
||||
float(*vertCos)[3];
|
||||
|
||||
@@ -245,7 +245,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
||||
sculpt_session->multires.level = mmd->sculptlvl;
|
||||
sculpt_session->totvert = mesh->totvert;
|
||||
sculpt_session->totpoly = mesh->totpoly;
|
||||
sculpt_session->vert_positions = nullptr;
|
||||
sculpt_session->vert_positions = {};
|
||||
sculpt_session->polys = {};
|
||||
sculpt_session->corner_verts = {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user