diff options
author | Joseph Eagar <joeedh@gmail.com> | 2022-07-30 05:01:32 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2022-07-30 05:03:51 +0300 |
commit | d7cfb6ac71e4225a654487ab134c89051dad03ed (patch) | |
tree | 28aeec264ad7dac127e8a5542cb3147a1e88c34e /source/blender/editors/sculpt_paint/sculpt_ops.c | |
parent | 27a16abe81a63c4ac72c218bef19b1a85d2eec4b (diff) |
Sculpt: Opaque vertex type for sculpt
This is a port of sculpt-dev's `SculptVertRef` refactor
(note that `SculptVertRef was renamed to PBVHVertRef`)
to master. `PBVHVertRef` is a structure that abstracts
the concept of a vertex in the sculpt code; it's simply
an `intptr_t` wrapped in a struct.
For `PBVH_FACES` and `PBVH_GRIDS` this struct stores a
vertex index, but for `BMesh` it stores a direct pointer
to a BMVert. The intptr_t is wrapped in a struct to prevent
the accidental usage of it as an index.
There are many reasons to do this:
* Right now `BMesh` verts are not logical sculpt verts;
to use the sculpt API they must first be converted to indices.
This requires a lot of indirect lookups into tables, leading to performance
loss. It has also led to greater code complexity and duplication.
* Having an abstract vertex type makes it feasible to have one unified
temporary attribute API for all three PBVH modes, which in turn
made it rather trivial to port sculpt brushes to DynTopo in
sculpt-dev (e.g. the layer brush, draw sharp, the smooth brushes,
the paint brushes, etc). This attribute API will be in a future patch.
* We need to do this anyway for the eventual move to C++.
Differential Revision: https://developer.blender.org/D14272
Reviewed By: Brecht Van Lommel
Ref D14272
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_ops.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_ops.c | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c index f16763be735..3279d54e6f1 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.c +++ b/source/blender/editors/sculpt_paint/sculpt_ops.c @@ -129,8 +129,10 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op)) "layer persistent base"); for (int i = 0; i < totvert; i++) { - copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i)); - SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, vertex)); + SCULPT_vertex_normal_get(ss, vertex, ss->persistent_base[i].no); ss->persistent_base[i].disp = 0.0f; } @@ -543,7 +545,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Object *ob = CTX_data_active_object(C); - ss->preview_vert_index_count = 0; + ss->preview_vert_count = 0; int totpoints = 0; /* This function is called from the cursor drawing code, so the PBVH may not be build yet. */ @@ -573,29 +575,32 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float /* Assuming an average of 6 edges per vertex in a triangulated mesh. */ const int max_preview_vertices = SCULPT_vertex_count_get(ss) * 3 * 2; - if (ss->preview_vert_index_list == NULL) { - ss->preview_vert_index_list = MEM_callocN(max_preview_vertices * sizeof(int), "preview lines"); + if (ss->preview_vert_list == NULL) { + ss->preview_vert_list = MEM_callocN(max_preview_vertices * sizeof(PBVHVertRef), + "preview lines"); } - GSQueue *not_visited_vertices = BLI_gsqueue_new(sizeof(int)); - int active_v = SCULPT_active_vertex_get(ss); + GSQueue *not_visited_vertices = BLI_gsqueue_new(sizeof(PBVHVertRef)); + PBVHVertRef active_v = SCULPT_active_vertex_get(ss); BLI_gsqueue_push(not_visited_vertices, &active_v); while (!BLI_gsqueue_is_empty(not_visited_vertices)) { - int from_v; + PBVHVertRef from_v; + BLI_gsqueue_pop(not_visited_vertices, &from_v); SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) { if (totpoints + (ni.size * 2) < max_preview_vertices) { - int to_v = ni.index; - ss->preview_vert_index_list[totpoints] = from_v; + PBVHVertRef to_v = ni.vertex; + int to_v_i = ni.index; + ss->preview_vert_list[totpoints] = from_v; totpoints++; - ss->preview_vert_index_list[totpoints] = to_v; + ss->preview_vert_list[totpoints] = to_v; totpoints++; - if (BLI_BITMAP_TEST(visited_vertices, to_v)) { + if (BLI_BITMAP_TEST(visited_vertices, to_v_i)) { continue; } - BLI_BITMAP_ENABLE(visited_vertices, to_v); + BLI_BITMAP_ENABLE(visited_vertices, to_v_i); const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v); if (len_squared_v3v3(brush_co, co) < radius * radius) { BLI_gsqueue_push(not_visited_vertices, &to_v); @@ -609,7 +614,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float MEM_freeN(visited_vertices); - ss->preview_vert_index_count = totpoints; + ss->preview_vert_count = totpoints; } static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op)) @@ -764,7 +769,7 @@ static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent Object *ob = CTX_data_active_object(C); Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; - int active_vertex = SCULPT_active_vertex_get(ss); + PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss); float active_vertex_color[4]; if (!SCULPT_handles_colors_report(ss, op->reports)) { @@ -883,7 +888,7 @@ static void do_mask_by_color_contiguous_update_nodes_cb( } update_node = true; if (vd.mvert) { - BKE_pbvh_vert_mark_update(ss->pbvh, vd.index); + BKE_pbvh_vert_mark_update(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -893,8 +898,11 @@ static void do_mask_by_color_contiguous_update_nodes_cb( } static bool sculpt_mask_by_color_contiguous_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + MaskByColorContiguousFloodFillData *data = userdata; float current_color[4]; @@ -902,10 +910,10 @@ static bool sculpt_mask_by_color_contiguous_floodfill_cb( float new_vertex_mask = sculpt_mask_by_color_delta_get( current_color, data->initial_color, data->threshold, data->invert); - data->new_mask[to_v] = new_vertex_mask; + data->new_mask[to_v_i] = new_vertex_mask; if (is_duplicate) { - data->new_mask[to_v] = data->new_mask[from_v]; + data->new_mask[to_v_i] = data->new_mask[from_v_i]; } float len = len_v3v3(current_color, data->initial_color); @@ -914,7 +922,7 @@ static bool sculpt_mask_by_color_contiguous_floodfill_cb( } static void sculpt_mask_by_color_contiguous(Object *object, - const int vertex, + const PBVHVertRef vertex, const float threshold, const bool invert, const bool preserve_mask) @@ -991,7 +999,7 @@ static void do_mask_by_color_task_cb(void *__restrict userdata, PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { float col[4]; - SCULPT_vertex_color_get(ss, vd.index, col); + SCULPT_vertex_color_get(ss, vd.vertex, col); const float current_mask = *vd.mask; const float new_mask = sculpt_mask_by_color_delta_get(active_color, col, threshold, invert); @@ -1002,7 +1010,7 @@ static void do_mask_by_color_task_cb(void *__restrict userdata, } update_node = true; if (vd.mvert) { - BKE_pbvh_vert_mark_update(ss->pbvh, vd.index); + BKE_pbvh_vert_mark_update(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1012,7 +1020,7 @@ static void do_mask_by_color_task_cb(void *__restrict userdata, } static void sculpt_mask_by_color_full_mesh(Object *object, - const int vertex, + const PBVHVertRef vertex, const float threshold, const bool invert, const bool preserve_mask) @@ -1067,7 +1075,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven SCULPT_undo_push_begin(ob, "Mask by color"); BKE_sculpt_color_layer_create_if_needed(ob); - const int active_vertex = SCULPT_active_vertex_get(ss); + const PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss); const float threshold = RNA_float_get(op->ptr, "threshold"); const bool invert = RNA_boolean_get(op->ptr, "invert"); const bool preserve_mask = RNA_boolean_get(op->ptr, "preserve_previous_mask"); |