diff --git a/source/blender/blenkernel/BKE_paint.hh b/source/blender/blenkernel/BKE_paint.hh index add76f9f511..7dfc03bd505 100644 --- a/source/blender/blenkernel/BKE_paint.hh +++ b/source/blender/blenkernel/BKE_paint.hh @@ -323,19 +323,15 @@ struct SculptBoundaryPreviewEdge { struct SculptBoundary { /* Vertex indices of the active boundary. */ - PBVHVertRef *verts; - int verts_capacity; - int verts_num; + blender::Vector verts; /* Distance from a vertex in the boundary to initial vertex indexed by vertex index, taking into * account the length of all edges between them. Any vertex that is not in the boundary will have * a distance of 0. */ - float *distance; + blender::Array distance; /* Data for drawing the preview. */ - SculptBoundaryPreviewEdge *edges; - int edges_capacity; - int edges_num; + blender::Vector edges; /* True if the boundary loops into itself. */ bool forms_loop; @@ -360,17 +356,17 @@ struct SculptBoundary { /* Indexed by vertex index, contains the topology information needed for boundary deformations. */ - SculptBoundaryEditInfo *edit_info; + blender::Array edit_info; /* Bend Deform type. */ struct { - float (*pivot_rotation_axis)[3]; - float (*pivot_positions)[3]; + blender::Array pivot_rotation_axis; + blender::Array pivot_positions; } bend; /* Slide Deform type. */ struct { - float (*directions)[3]; + blender::Array directions; } slide; /* Twist Deform type. */ @@ -585,7 +581,7 @@ struct SculptSession : blender::NonCopyable, blender::NonMovable { std::unique_ptr pose_ik_chain_preview; /* Boundary Brush Preview */ - SculptBoundary *boundary_preview = nullptr; + std::unique_ptr boundary_preview; SculptVertexInfo vertex_info = {}; SculptFakeNeighbors fake_neighbors = {}; diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 096e4c5cdcf..e2aafe61de7 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1510,14 +1510,6 @@ SculptSession::~SculptSession() BKE_image_pool_free(this->tex_pool); } - if (this->boundary_preview) { - MEM_SAFE_FREE(this->boundary_preview->verts); - MEM_SAFE_FREE(this->boundary_preview->edges); - MEM_SAFE_FREE(this->boundary_preview->distance); - MEM_SAFE_FREE(this->boundary_preview->edit_info); - MEM_SAFE_FREE(this->boundary_preview); - } - BKE_sculptsession_free_vwpaint_data(this); MEM_SAFE_FREE(this->last_paint_canvas_key); diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 5a212db586e..e7882ba1928 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -1743,10 +1743,6 @@ static void paint_cursor_preview_boundary_data_update(PaintCursorContext *pconte * boundary data for the preview. */ BKE_sculpt_update_object_for_edit(pcontext->depsgraph, pcontext->vc.obact, false); - if (ss.boundary_preview) { - boundary::data_free(ss.boundary_preview); - } - ss.boundary_preview = boundary::data_init( *pcontext->vc.obact, pcontext->brush, ss.active_vertex, pcontext->radius); } diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 73f030f768a..5ee5d5a8aa6 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -4154,12 +4154,6 @@ void SCULPT_cache_free(blender::ed::sculpt_paint::StrokeCache *cache) MEM_SAFE_FREE(cache->layer_displacement_factor); MEM_SAFE_FREE(cache->detail_directions); - for (int i = 0; i < PAINT_SYMM_AREAS; i++) { - if (cache->boundaries[i]) { - boundary::data_free(cache->boundaries[i]); - } - } - if (cache->cloth_sim) { cloth::simulation_free(cache->cloth_sim); } diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.cc b/source/blender/editors/sculpt_paint/sculpt_boundary.cc index d53ff70af5e..c3add549ff5 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.cc +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.cc @@ -117,39 +117,14 @@ static void sculpt_boundary_index_add(SculptBoundary &boundary, const float distance, GSet *included_verts) { + boundary.verts.append(new_vertex); - boundary.verts[boundary.verts_num] = new_vertex; - - if (boundary.distance) { + if (!boundary.distance.is_empty()) { boundary.distance[new_index] = distance; } if (included_verts) { BLI_gset_add(included_verts, POINTER_FROM_INT(new_index)); } - boundary.verts_num++; - if (boundary.verts_num >= boundary.verts_capacity) { - boundary.verts_capacity += BOUNDARY_INDICES_BLOCK_SIZE; - boundary.verts = static_cast(MEM_reallocN_id( - boundary.verts, boundary.verts_capacity * sizeof(PBVHVertRef), "boundary indices")); - } -}; - -static void sculpt_boundary_preview_edge_add(SculptBoundary &boundary, - const PBVHVertRef v1, - const PBVHVertRef v2) -{ - - boundary.edges[boundary.edges_num].v1 = v1; - boundary.edges[boundary.edges_num].v2 = v2; - boundary.edges_num++; - - if (boundary.edges_num >= boundary.edges_capacity) { - boundary.edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE; - boundary.edges = static_cast( - MEM_reallocN_id(boundary.edges, - boundary.edges_capacity * sizeof(SculptBoundaryPreviewEdge), - "boundary edges")); - } }; /** @@ -217,13 +192,13 @@ static bool boundary_floodfill_cb(SculptSession &ss, } const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v), SCULPT_vertex_co_get(ss, to_v)); - const float distance_boundary_to_dst = boundary.distance ? + const float distance_boundary_to_dst = !boundary.distance.is_empty() ? boundary.distance[from_v_i] + edge_len : 0.0f; sculpt_boundary_index_add( boundary, to_v, to_v_i, distance_boundary_to_dst, data->included_verts); if (!is_duplicate) { - sculpt_boundary_preview_edge_add(boundary, from_v, to_v); + boundary.edges.append({from_v, to_v}); } return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v); } @@ -235,14 +210,10 @@ static void sculpt_boundary_indices_init(SculptSession &ss, { const int totvert = SCULPT_vertex_count_get(ss); - boundary.verts = static_cast( - MEM_malloc_arrayN(BOUNDARY_INDICES_BLOCK_SIZE, sizeof(PBVHVertRef), __func__)); if (init_boundary_distances) { - boundary.distance = static_cast(MEM_calloc_arrayN(totvert, sizeof(float), __func__)); + boundary.distance = Array(totvert, 0.0f); } - boundary.edges = static_cast( - MEM_malloc_arrayN(BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), __func__)); GSet *included_verts = BLI_gset_int_new_ex("included verts", BOUNDARY_INDICES_BLOCK_SIZE); flood_fill::FillData flood = flood_fill::init_fill(ss); @@ -275,7 +246,7 @@ static void sculpt_boundary_indices_init(SculptSession &ss, if (BLI_gset_haskey(included_verts, POINTER_FROM_INT(ni.index)) && sculpt_boundary_is_vertex_in_editable_boundary(ss, ni.vertex)) { - sculpt_boundary_preview_edge_add(boundary, fdata.last_visited_vertex, ni.vertex); + boundary.edges.append({fdata.last_visited_vertex, ni.vertex}); boundary.forms_loop = true; } } @@ -300,8 +271,7 @@ static void sculpt_boundary_edit_data_init(SculptSession &ss, const bool has_duplicates = BKE_pbvh_type(*ss.pbvh) == PBVH_GRIDS; - boundary.edit_info = static_cast( - MEM_malloc_arrayN(totvert, sizeof(SculptBoundaryEditInfo), __func__)); + boundary.edit_info = Array(totvert); for (int i = 0; i < totvert; i++) { boundary.edit_info[i].original_vertex_i = BOUNDARY_VERTEX_NONE; @@ -311,7 +281,7 @@ static void sculpt_boundary_edit_data_init(SculptSession &ss, std::queue current_iteration; std::queue next_iteration; - for (int i = 0; i < boundary.verts_num; i++) { + for (int i = 0; i < boundary.verts.size(); i++) { int index = BKE_pbvh_vertex_to_index(*ss.pbvh, boundary.verts[i]); boundary.edit_info[index].original_vertex_i = BKE_pbvh_vertex_to_index(*ss.pbvh, @@ -441,7 +411,7 @@ static void sculpt_boundary_falloff_factor_init(SculptSession &ss, continue; } - if (!boundary.distance) { + if (boundary.distance.is_empty()) { /* There are falloff modes that do not require to modify the previously calculated falloff * based on boundary distances. */ continue; @@ -481,10 +451,10 @@ static void sculpt_boundary_falloff_factor_init(SculptSession &ss, } } -SculptBoundary *data_init(Object &object, - const Brush *brush, - const PBVHVertRef initial_vertex, - const float radius) +std::unique_ptr data_init(Object &object, + const Brush *brush, + const PBVHVertRef initial_vertex, + const float radius) { SculptSession &ss = *object.sculpt; @@ -508,7 +478,8 @@ SculptBoundary *data_init(Object &object, return nullptr; } - SculptBoundary *boundary = MEM_cnew(__func__); + std::unique_ptr boundary = std::make_unique(); + *boundary = {}; const bool init_boundary_distances = brush ? brush->boundary_falloff_type != BRUSH_BOUNDARY_FALLOFF_CONSTANT : @@ -522,18 +493,6 @@ SculptBoundary *data_init(Object &object, return boundary; } -void data_free(SculptBoundary *boundary) -{ - MEM_SAFE_FREE(boundary->verts); - MEM_SAFE_FREE(boundary->edges); - MEM_SAFE_FREE(boundary->distance); - MEM_SAFE_FREE(boundary->edit_info); - MEM_SAFE_FREE(boundary->bend.pivot_positions); - MEM_SAFE_FREE(boundary->bend.pivot_rotation_axis); - MEM_SAFE_FREE(boundary->slide.directions); - MEM_SAFE_FREE(boundary); -} - /* These functions initialize the required vectors for the desired deformation using the * SculptBoundaryEditInfo. They calculate the data using the vertices that have the * max_propagation_steps value and them this data is copied to the rest of the vertices using the @@ -541,10 +500,8 @@ void data_free(SculptBoundary *boundary) static void sculpt_boundary_bend_data_init(SculptSession &ss, SculptBoundary &boundary) { const int totvert = SCULPT_vertex_count_get(ss); - boundary.bend.pivot_rotation_axis = static_cast( - MEM_calloc_arrayN(totvert, sizeof(float[3]), __func__)); - boundary.bend.pivot_positions = static_cast( - MEM_calloc_arrayN(totvert, sizeof(float[3]), __func__)); + boundary.bend.pivot_rotation_axis = Array(totvert, float3(0)); + boundary.bend.pivot_positions = Array(totvert, float3(0)); for (int i = 0; i < totvert; i++) { if (boundary.edit_info[i].propagation_steps_num != boundary.max_propagation_steps) { @@ -581,8 +538,7 @@ static void sculpt_boundary_bend_data_init(SculptSession &ss, SculptBoundary &bo static void sculpt_boundary_slide_data_init(SculptSession &ss, SculptBoundary &boundary) { const int totvert = SCULPT_vertex_count_get(ss); - boundary.slide.directions = static_cast( - MEM_calloc_arrayN(totvert, sizeof(float[3]), "slide directions")); + boundary.slide.directions = Array(totvert, float3(0)); for (int i = 0; i < totvert; i++) { if (boundary.edit_info[i].propagation_steps_num != boundary.max_propagation_steps) { @@ -608,15 +564,16 @@ static void sculpt_boundary_slide_data_init(SculptSession &ss, SculptBoundary &b static void sculpt_boundary_twist_data_init(SculptSession &ss, SculptBoundary &boundary) { zero_v3(boundary.twist.pivot_position); - float(*face_verts)[3] = static_cast( - MEM_malloc_arrayN(boundary.verts_num, sizeof(float[3]), "face verts")); - for (int i = 0; i < boundary.verts_num; i++) { + Array face_verts(boundary.verts.size()); + for (int i = 0; i < boundary.verts.size(); i++) { add_v3_v3(boundary.twist.pivot_position, SCULPT_vertex_co_get(ss, boundary.verts[i])); copy_v3_v3(face_verts[i], SCULPT_vertex_co_get(ss, boundary.verts[i])); } - mul_v3_fl(boundary.twist.pivot_position, 1.0f / boundary.verts_num); + mul_v3_fl(boundary.twist.pivot_position, 1.0f / boundary.verts.size()); if (boundary.forms_loop) { - normal_poly_v3(boundary.twist.rotation_axis, face_verts, boundary.verts_num); + normal_poly_v3(boundary.twist.rotation_axis, + reinterpret_cast(face_verts.data()), + boundary.verts.size()); } else { sub_v3_v3v3(boundary.twist.rotation_axis, @@ -624,7 +581,6 @@ static void sculpt_boundary_twist_data_init(SculptSession &ss, SculptBoundary &b SCULPT_vertex_co_get(ss, boundary.initial_vertex)); normalize_v3(boundary.twist.rotation_axis); } - MEM_freeN(face_verts); } static float sculpt_boundary_displacement_from_grab_delta_get(SculptSession &ss, @@ -1019,8 +975,8 @@ void edges_preview_draw(const uint gpuattr, } immUniformColor3fvAlpha(outline_col, outline_alpha); GPU_line_width(2.0f); - immBegin(GPU_PRIM_LINES, ss.boundary_preview->edges_num * 2); - for (int i = 0; i < ss.boundary_preview->edges_num; i++) { + immBegin(GPU_PRIM_LINES, ss.boundary_preview->edges.size() * 2); + for (int i = 0; i < ss.boundary_preview->edges.size(); i++) { immVertex3fv(gpuattr, SCULPT_vertex_co_get(ss, ss.boundary_preview->edges[i].v1)); immVertex3fv(gpuattr, SCULPT_vertex_co_get(ss, ss.boundary_preview->edges[i].v2)); } diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index efc22703c7e..42ebdb4b291 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -640,16 +640,16 @@ static Array sculpt_expand_boundary_topology_falloff_create(Object &ob, c const PBVHVertRef symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( ob, symm_it, v); - SculptBoundary *boundary = boundary::data_init(ob, nullptr, symm_vertex, FLT_MAX); + std::unique_ptr boundary = boundary::data_init( + ob, nullptr, symm_vertex, FLT_MAX); if (!boundary) { continue; } - for (int i = 0; i < boundary->verts_num; i++) { + for (int i = 0; i < boundary->verts.size(); i++) { queue.push(boundary->verts[i]); visited_verts[BKE_pbvh_vertex_to_index(*ss.pbvh, boundary->verts[i])].set(); } - boundary::data_free(boundary); } /* If there are no boundaries, return a falloff with all values set to 0. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index a29fc02781f..2e0aba88e61 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -492,7 +492,7 @@ struct StrokeCache { float3 true_initial_normal; /* Boundary brush */ - SculptBoundary *boundaries[PAINT_SYMM_AREAS]; + std::array, PAINT_SYMM_AREAS> boundaries; /* Surface Smooth Brush */ /* Stores the displacement produced by the laplacian step of HC smooth. */ @@ -1921,11 +1921,10 @@ namespace blender::ed::sculpt_paint::boundary { * Main function to get #SculptBoundary data both for brush deformation and viewport preview. * Can return NULL if there is no boundary from the given vertex using the given radius. */ -SculptBoundary *data_init(Object &object, - const Brush *brush, - PBVHVertRef initial_vertex, - float radius); -void data_free(SculptBoundary *boundary); +std::unique_ptr data_init(Object &object, + const Brush *brush, + PBVHVertRef initial_vertex, + float radius); /* Main Brush Function. */ void do_boundary_brush(const Sculpt &sd, Object &ob, blender::Span nodes);