diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index ac4f0532315..2128ee99b56 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -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 +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(ptr); +} + +/* + * Get a pointer to attribute data at vertex. + * + * Example: float *persistent_co = vertex_attr_ptr(vertex, ss->attrs.persistent_co); + */ +template +static Tptr vertex_attr_ptr(const PBVHVertRef vertex, const SculptAttribute *attr) +{ + return elem_attr_ptr(vertex, attr); +} + +/* + * Get attribute data at vertex. + * + * Example: float weight = vertex_attr_get(vertex, ss->attrs.automasking_factor); + */ +template +static T vertex_attr_get(const PBVHVertRef vertex, const SculptAttribute *attr) +{ + return *vertex_attr_ptr(vertex, attr); +} + +/* + * Set attribute data at vertex. + * + * vertex_attr_set(vertex, ss->attrs.automasking_factor, 1.0f); + */ +template +static void vertex_attr_set(const PBVHVertRef vertex, const SculptAttribute *attr, T data) +{ + *vertex_attr_ptr(vertex, attr) = data; +} + +template +static Tptr face_attr_ptr(const PBVHVertRef face, const SculptAttribute *attr) +{ + return elem_attr_ptr(face, attr); +} + +template static T face_attr_get(const PBVHFaceRef face, const SculptAttribute *attr) +{ + return *face_attr_ptr(face, attr); +} + +template +static void face_attr_set(const PBVHFaceRef face, const SculptAttribute *attr, T data) +{ + *face_attr_ptr(face, attr) = data; +} +} // namespace blender::bke::paint #endif diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index aac82868fcb..949b3a4e3e9 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -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(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(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(SCULPT_vertex_attr_get(vertex, ss->attrs.topology_island_key)); + return vertex_attr_get(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( - SCULPT_vertex_attr_get(vertex2, ss->attrs.topology_island_key)) = island_nr; + vertex_attr_set(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)) { diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index 5dd24d01728..7431e9ffc1c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -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(vertex, ss->attrs.automasking_occlusion); if (stroke_id != automasking->current_stroke_id) { - f = *(char *)SCULPT_vertex_attr_get( + f = *vertex_attr_ptr( 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( + 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(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(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(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(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(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(to_v, ss->attrs.automasking_factor, 1.0f); + vertex_attr_set(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(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(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(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(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(vertex, ss->attrs.automasking_stroke_id, ss->stroke_id); } - *(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor) = f; + vertex_attr_set(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(vertex, ss->attrs.automasking_factor, initial_value); } const int boundary_propagation_steps = brush ? diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.cc b/source/blender/editors/sculpt_paint/sculpt_brush_types.cc index 9e6ce8131ef..54c260dc037 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.cc +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.cc @@ -39,6 +39,8 @@ #include #include +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(vd.vertex, ss->attrs.persistent_disp); } else { disp_factor = &ss->cache->layer_displacement_factor[vi]; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index a61fb5c1a59..a1ad4e944e9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -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 diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index ef1a244b89d..8c05a3e3d16 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -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 #include +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(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(vertex, ss->attrs.persistent_no)); + vertex_attr_set(vertex, ss->attrs.persistent_disp, 0.0f); } return OPERATOR_FINISHED;