1
1

Sculpt: cleanup sculpt attribute API

* `BKE_sculpt_vertex_attr_get` (and it's alias `SCULPT_vertex_attr_get`)
  is now `blender::bke::paint::vertex_attr_ptr`.  Same for the face
  versions of those functions.  The SCULPT_XXX aliases are removed.
* Removed code duplication; `[vertex/face]_attr_ptr` now just calls
  a generic template (`elem_attr_ptr`).
* Added `[vertex/face]_attr_get` and `[vertex/face]_attr_set` functions
  to get/set attribute data without pointer wrangling.
* Given the unwieldly length of `blender::bke::paint::` it's recommended
  to do a `using blender::bke::paint;` at the top of sculpt files.

Example: `float w = vertex_attr_get<float>(vertex,
ss->attrs.automasking_factor);`
This commit is contained in:
2023-04-13 12:12:56 -07:00
parent 97c05aa288
commit fbf091750c
6 changed files with 116 additions and 76 deletions

View File

@@ -799,48 +799,6 @@ void BKE_sculpt_attribute_destroy_temporary_all(struct Object *ob);
/* Destroy attributes that were marked as stroke only in SculptAttributeParams. */
void BKE_sculpt_attributes_destroy_temporary_stroke(struct Object *ob);
BLI_INLINE void *BKE_sculpt_vertex_attr_get(const PBVHVertRef vertex, const SculptAttribute *attr)
{
if (attr->data) {
char *p = (char *)attr->data;
int idx = (int)vertex.i;
if (attr->data_for_bmesh) {
BMElem *v = (BMElem *)vertex.i;
idx = v->head.index;
}
return p + attr->elem_size * (int)idx;
}
else {
BMElem *v = (BMElem *)vertex.i;
return BM_ELEM_CD_GET_VOID_P(v, attr->bmesh_cd_offset);
}
return NULL;
}
BLI_INLINE void *BKE_sculpt_face_attr_get(const PBVHFaceRef vertex, const SculptAttribute *attr)
{
if (attr->data) {
char *p = (char *)attr->data;
int idx = (int)vertex.i;
if (attr->data_for_bmesh) {
BMElem *v = (BMElem *)vertex.i;
idx = v->head.index;
}
return p + attr->elem_size * (int)idx;
}
else {
BMElem *v = (BMElem *)vertex.i;
return BM_ELEM_CD_GET_VOID_P(v, attr->bmesh_cd_offset);
}
return NULL;
}
/**
* Create new color layer on object if it doesn't have one and if experimental feature set has
* sculpt vertex color enabled. Returns truth if new layer has been added, false otherwise.
@@ -943,4 +901,84 @@ struct CurveMapping *BKE_sculpt_default_cavity_curve(void);
#ifdef __cplusplus
}
namespace blender::bke::paint {
/* Base implementation for vertex_attr_*** and face_attr_*** methods.
* Returns a pointer to the attribute data (as defined by attr) for elem.
*/
template<typename Tptr, typename ElemRef = PBVHVertRef>
static Tptr elem_attr_ptr(const ElemRef elem, const SculptAttribute *attr)
{
void *ptr = nullptr;
if (attr->data) {
char *p = (char *)attr->data;
int idx = (int)elem.i;
if (attr->data_for_bmesh) {
BMElem *e = (BMElem *)elem.i;
idx = e->head.index;
}
ptr = p + attr->elem_size * (int)idx;
}
else {
BMElem *v = (BMElem *)elem.i;
ptr = BM_ELEM_CD_GET_VOID_P(v, attr->bmesh_cd_offset);
}
return static_cast<Tptr>(ptr);
}
/*
* Get a pointer to attribute data at vertex.
*
* Example: float *persistent_co = vertex_attr_ptr<float*>(vertex, ss->attrs.persistent_co);
*/
template<typename Tptr>
static Tptr vertex_attr_ptr(const PBVHVertRef vertex, const SculptAttribute *attr)
{
return elem_attr_ptr<Tptr, PBVHVertRef>(vertex, attr);
}
/*
* Get attribute data at vertex.
*
* Example: float weight = vertex_attr_get<float>(vertex, ss->attrs.automasking_factor);
*/
template<typename T>
static T vertex_attr_get(const PBVHVertRef vertex, const SculptAttribute *attr)
{
return *vertex_attr_ptr<T *>(vertex, attr);
}
/*
* Set attribute data at vertex.
*
* vertex_attr_set<float>(vertex, ss->attrs.automasking_factor, 1.0f);
*/
template<typename T>
static void vertex_attr_set(const PBVHVertRef vertex, const SculptAttribute *attr, T data)
{
*vertex_attr_ptr<T *>(vertex, attr) = data;
}
template<typename Tptr>
static Tptr face_attr_ptr(const PBVHVertRef face, const SculptAttribute *attr)
{
return elem_attr_ptr<Tptr, PBVHFaceRef>(face, attr);
}
template<typename T> static T face_attr_get(const PBVHFaceRef face, const SculptAttribute *attr)
{
return *face_attr_ptr<T *>(face, attr);
}
template<typename T>
static void face_attr_set(const PBVHFaceRef face, const SculptAttribute *attr, T data)
{
*face_attr_ptr<T *>(face, attr) = data;
}
} // namespace blender::bke::paint
#endif

View File

@@ -81,6 +81,8 @@ using blender::MutableSpan;
using blender::Set;
using blender::Vector;
using namespace blender::bke::paint;
static float sculpt_calc_radius(ViewContext *vc,
const Brush *brush,
const Scene *scene,
@@ -209,7 +211,7 @@ void SCULPT_vertex_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3]
const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, PBVHVertRef vertex)
{
if (ss->attrs.persistent_co) {
return (const float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_co);
return vertex_attr_ptr<const float *>(vertex, ss->attrs.persistent_co);
}
return SCULPT_vertex_co_get(ss, vertex);
@@ -257,7 +259,7 @@ void SCULPT_vertex_limit_surface_get(SculptSession *ss, PBVHVertRef vertex, floa
void SCULPT_vertex_persistent_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3])
{
if (ss->attrs.persistent_no) {
copy_v3_v3(no, (float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_no));
copy_v3_v3(no, vertex_attr_ptr<float *>(vertex, ss->attrs.persistent_no));
return;
}
SCULPT_vertex_normal_get(ss, vertex, no);
@@ -6385,7 +6387,7 @@ void SCULPT_face_set_set(SculptSession *ss, PBVHFaceRef face, int fset)
int SCULPT_vertex_island_get(SculptSession *ss, PBVHVertRef vertex)
{
if (ss->attrs.topology_island_key) {
return *static_cast<uint8_t *>(SCULPT_vertex_attr_get(vertex, ss->attrs.topology_island_key));
return vertex_attr_get<uint8_t>(vertex, ss->attrs.topology_island_key);
}
return -1;
@@ -6432,8 +6434,7 @@ void SCULPT_topology_islands_ensure(Object *ob)
PBVHVertRef vertex2 = stack.pop_last();
SculptVertexNeighborIter ni;
*static_cast<uint8_t *>(
SCULPT_vertex_attr_get(vertex2, ss->attrs.topology_island_key)) = island_nr;
vertex_attr_set<uint8_t>(vertex2, ss->attrs.topology_island_key, island_nr);
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex2, ni) {
if (visit.add(ni.vertex) && SCULPT_vertex_any_face_visible_get(ss, ni.vertex)) {

View File

@@ -56,6 +56,7 @@ using blender::float3;
using blender::IndexRange;
using blender::Set;
using blender::Vector;
using namespace blender::bke::paint;
AutomaskingCache *SCULPT_automasking_active_cache_get(SculptSession *ss)
{
@@ -264,10 +265,10 @@ static float automasking_view_occlusion_factor(AutomaskingCache *automasking,
uchar stroke_id,
AutomaskingNodeData * /*automask_data*/)
{
char f = *(char *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_occlusion);
char f = vertex_attr_get<char>(vertex, ss->attrs.automasking_occlusion);
if (stroke_id != automasking->current_stroke_id) {
f = *(char *)SCULPT_vertex_attr_get(
f = *vertex_attr_ptr<char *>(
vertex,
ss->attrs.automasking_occlusion) = SCULPT_vertex_is_occluded(ss, vertex, true) ? 2 : 1;
}
@@ -282,8 +283,8 @@ static float automasking_factor_end(SculptSession *ss,
float value)
{
if (ss->attrs.automasking_stroke_id) {
*(uchar *)SCULPT_vertex_attr_get(
vertex, ss->attrs.automasking_stroke_id) = automasking->current_stroke_id;
vertex_attr_set<uchar>(
vertex, ss->attrs.automasking_stroke_id, automasking->current_stroke_id);
}
return value;
@@ -443,7 +444,7 @@ static void sculpt_calc_blurred_cavity(SculptSession *ss,
factor_sum = sculpt_cavity_calc_factor(automasking, factor_sum);
*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_cavity) = factor_sum;
vertex_attr_set<float>(vertex, ss->attrs.automasking_cavity, factor_sum);
}
int SCULPT_automasking_settings_hash(Object *ob, AutomaskingCache *automasking)
@@ -497,13 +498,13 @@ static float sculpt_automasking_cavity_factor(AutomaskingCache *automasking,
SculptSession *ss,
PBVHVertRef vertex)
{
uchar stroke_id = *(uchar *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_stroke_id);
uchar stroke_id = vertex_attr_get<uchar>(vertex, ss->attrs.automasking_stroke_id);
if (stroke_id != automasking->current_stroke_id) {
sculpt_calc_blurred_cavity(ss, automasking, automasking->settings.cavity_blur_steps, vertex);
}
float factor = *(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_cavity);
float factor = vertex_attr_get<float>(vertex, ss->attrs.automasking_cavity);
bool inverted = automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_INVERTED;
if ((automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_ALL) &&
@@ -538,7 +539,7 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking,
* automasking information can't be computed in real time per vertex and needs to be
* initialized for the whole mesh when the stroke starts. */
if (ss->attrs.automasking_factor) {
float factor = *(float *)SCULPT_vertex_attr_get(vert, ss->attrs.automasking_factor);
float factor = vertex_attr_get<float>(vert, ss->attrs.automasking_factor);
if (automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_ALL) {
factor *= sculpt_automasking_cavity_factor(automasking, ss, vert);
@@ -548,7 +549,7 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking,
}
uchar stroke_id = ss->attrs.automasking_stroke_id ?
*(uchar *)SCULPT_vertex_attr_get(vert, ss->attrs.automasking_stroke_id) :
vertex_attr_get<uchar>(vert, ss->attrs.automasking_stroke_id) :
-1;
bool do_occlusion = (automasking->settings.flags &
@@ -620,8 +621,8 @@ static bool automask_floodfill_cb(
{
AutomaskFloodFillData *data = (AutomaskFloodFillData *)userdata;
*(float *)SCULPT_vertex_attr_get(to_v, ss->attrs.automasking_factor) = 1.0f;
*(float *)SCULPT_vertex_attr_get(from_v, ss->attrs.automasking_factor) = 1.0f;
vertex_attr_set<float>(to_v, ss->attrs.automasking_factor, 1.0f);
vertex_attr_set<float>(from_v, ss->attrs.automasking_factor, 1.0f);
return (!data->use_radius ||
SCULPT_is_vertex_inside_brush_radius_symm(
SCULPT_vertex_co_get(ss, to_v), data->location, data->radius, data->symm));
@@ -641,7 +642,7 @@ static void SCULPT_topology_automasking_init(Sculpt *sd, Object *ob)
for (int i : IndexRange(totvert)) {
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
(*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor)) = 0.0f;
vertex_attr_set<float>(vertex, ss->attrs.automasking_factor, 0.0f);
}
/* Flood fill automask to connected vertices. Limited to vertices inside
@@ -682,7 +683,7 @@ static void sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob)
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
if (!SCULPT_vertex_has_face_set(ss, vertex, active_face_set)) {
*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor) = 0.0f;
vertex_attr_set<float>(vertex, ss->attrs.automasking_factor, 0.0f);
}
}
}
@@ -747,8 +748,8 @@ static void SCULPT_boundary_automasking_init(Object *ob,
const float p = 1.0f - (float(edge_distance[i]) / float(propagation_steps));
const float edge_boundary_automask = pow2f(p);
*(float *)SCULPT_vertex_attr_get(
vertex, ss->attrs.automasking_factor) *= (1.0f - edge_boundary_automask);
*vertex_attr_ptr<float *>(vertex,
ss->attrs.automasking_factor) *= (1.0f - edge_boundary_automask);
}
MEM_SAFE_FREE(edge_distance);
@@ -793,7 +794,7 @@ static void sculpt_normal_occlusion_automasking_fill(AutomaskingCache *automaski
for (int i = 0; i < totvert; i++) {
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
float f = *(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor);
float f = vertex_attr_get<float>(vertex, ss->attrs.automasking_factor);
if (int(mode) & BRUSH_AUTOMASKING_VIEW_NORMAL) {
if (int(mode) & BRUSH_AUTOMASKING_VIEW_OCCLUSION) {
@@ -804,10 +805,10 @@ static void sculpt_normal_occlusion_automasking_fill(AutomaskingCache *automaski
}
if (ss->attrs.automasking_stroke_id) {
*(uchar *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_stroke_id) = ss->stroke_id;
vertex_attr_set<uchar>(vertex, ss->attrs.automasking_stroke_id, ss->stroke_id);
}
*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor) = f;
vertex_attr_set<float>(vertex, ss->attrs.automasking_factor, f);
}
}
@@ -926,7 +927,7 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object
for (int i : IndexRange(totvert)) {
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
(*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor)) = initial_value;
vertex_attr_set<float>(vertex, ss->attrs.automasking_factor, initial_value);
}
const int boundary_propagation_steps = brush ?

View File

@@ -39,6 +39,8 @@
#include <cstdlib>
#include <cstring>
using namespace blender::bke::paint;
/* -------------------------------------------------------------------- */
/** \name SculptProjectVector
*
@@ -1543,7 +1545,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
const int vi = vd.index;
float *disp_factor;
if (use_persistent_base) {
disp_factor = (float *)SCULPT_vertex_attr_get(vd.vertex, ss->attrs.persistent_disp);
disp_factor = vertex_attr_ptr<float *>(vd.vertex, ss->attrs.persistent_disp);
}
else {
disp_factor = &ss->cache->layer_displacement_factor[vi];

View File

@@ -1910,8 +1910,3 @@ void SCULPT_topology_islands_invalidate(SculptSession *ss);
int SCULPT_vertex_island_get(SculptSession *ss, PBVHVertRef vertex);
/** \} */
/* Make SCULPT_ alias to a few blenkernel sculpt methods. */
#define SCULPT_vertex_attr_get BKE_sculpt_vertex_attr_get
#define SCULPT_face_attr_get BKE_sculpt_face_attr_get

View File

@@ -13,6 +13,7 @@
#include "BLI_math.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
#include "BLI_math_vector_types.hh"
#include "BLT_translation.h"
@@ -71,6 +72,9 @@
#include <cstdlib>
#include <cstring>
using namespace blender::bke::paint;
using blender::float3;
/* Reset the copy of the mesh that is being sculpted on (currently just for the layer brush). */
static int sculpt_set_persistent_base_exec(bContext *C, wmOperator * /*op*/)
@@ -101,11 +105,10 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator * /*op*/)
for (int i = 0; i < totvert; i++) {
PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
copy_v3_v3((float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_co),
SCULPT_vertex_co_get(ss, vertex));
vertex_attr_set<float3>(vertex, ss->attrs.persistent_co, SCULPT_vertex_co_get(ss, vertex));
SCULPT_vertex_normal_get(
ss, vertex, (float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_no));
(*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_disp)) = 0.0f;
ss, vertex, vertex_attr_ptr<float *>(vertex, ss->attrs.persistent_no));
vertex_attr_set<float>(vertex, ss->attrs.persistent_disp, 0.0f);
}
return OPERATOR_FINISHED;