Cleanup: Use std::queue instead of GSQueue in sculpt code

This improves type safety, simplifies memory management,
and is a step towards removing the GSQueue container.
This commit is contained in:
Hans Goudey
2023-12-26 08:08:29 -05:00
parent fcbb94ed1e
commit dca81dc3df
7 changed files with 40 additions and 55 deletions

View File

@@ -19,7 +19,6 @@
#include "BLI_blenlib.h"
#include "BLI_dial_2d.h"
#include "BLI_ghash.h"
#include "BLI_gsqueue.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_set.hh"
@@ -1013,18 +1012,17 @@ void init_fill(SculptSession *ss, SculptFloodFill *flood)
int vertex_count = SCULPT_vertex_count_get(ss);
SCULPT_vertex_random_access_ensure(ss);
flood->queue = BLI_gsqueue_new(sizeof(intptr_t));
flood->visited_verts = BLI_BITMAP_NEW(vertex_count, "visited verts");
}
void add_initial(SculptFloodFill *flood, PBVHVertRef vertex)
{
BLI_gsqueue_push(flood->queue, &vertex);
flood->queue.push(vertex);
}
void add_and_skip_initial(SculptFloodFill *flood, PBVHVertRef vertex)
{
BLI_gsqueue_push(flood->queue, &vertex);
flood->queue.push(vertex);
BLI_BITMAP_ENABLE(flood->visited_verts, vertex.i);
}
@@ -1094,10 +1092,10 @@ void execute(SculptSession *ss,
void *userdata),
void *userdata)
{
while (!BLI_gsqueue_is_empty(flood->queue)) {
PBVHVertRef from_v;
while (!flood->queue.empty()) {
PBVHVertRef from_v = flood->queue.front();
flood->queue.pop();
BLI_gsqueue_pop(flood->queue, &from_v);
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
const PBVHVertRef to_v = ni.vertex;
@@ -1114,7 +1112,7 @@ void execute(SculptSession *ss,
BLI_BITMAP_ENABLE(flood->visited_verts, BKE_pbvh_vertex_to_index(ss->pbvh, to_v));
if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
BLI_gsqueue_push(flood->queue, &to_v);
flood->queue.push(to_v);
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
@@ -1124,8 +1122,6 @@ void execute(SculptSession *ss,
void free_fill(SculptFloodFill *flood)
{
MEM_SAFE_FREE(flood->visited_verts);
BLI_gsqueue_free(flood->queue);
flood->queue = nullptr;
}
} // namespace blender::ed::sculpt_paint::flood_fill

View File

@@ -308,8 +308,8 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
boundary->edit_info[i].propagation_steps_num = BOUNDARY_STEPS_NONE;
}
GSQueue *current_iteration = BLI_gsqueue_new(sizeof(PBVHVertRef));
GSQueue *next_iteration = BLI_gsqueue_new(sizeof(PBVHVertRef));
std::queue<PBVHVertRef> current_iteration;
std::queue<PBVHVertRef> next_iteration;
/* Initialized the first iteration with the vertices already in the boundary. This is propagation
* step 0. */
@@ -334,7 +334,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
}
BLI_gsqueue_push(current_iteration, &boundary->verts[i]);
current_iteration.push(boundary->verts[i]);
}
int propagation_steps_num = 0;
@@ -343,14 +343,14 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
while (true) {
/* Stop adding steps to edit info. This happens when a steps is further away from the boundary
* than the brush radius or when the entire mesh was already processed. */
if (accum_distance > radius || BLI_gsqueue_is_empty(current_iteration)) {
if (accum_distance > radius || current_iteration.empty()) {
boundary->max_propagation_steps = propagation_steps_num;
break;
}
while (!BLI_gsqueue_is_empty(current_iteration)) {
PBVHVertRef from_v;
BLI_gsqueue_pop(current_iteration, &from_v);
while (!current_iteration.empty()) {
PBVHVertRef from_v = current_iteration.front();
current_iteration.pop();
int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
@@ -375,7 +375,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
boundary->edit_info[ni.index].propagation_steps_num =
boundary->edit_info[from_v_i].propagation_steps_num + 1;
BLI_gsqueue_push(next_iteration, &ni.vertex);
next_iteration.push(ni.vertex);
/* When copying the data to the neighbor for the next iteration, it has to be copied to
* all its duplicates too. This is because it is not possible to know if the updated
@@ -410,19 +410,16 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
}
/* Copy the new vertices to the queue to be processed in the next iteration. */
while (!BLI_gsqueue_is_empty(next_iteration)) {
PBVHVertRef next_v;
BLI_gsqueue_pop(next_iteration, &next_v);
BLI_gsqueue_push(current_iteration, &next_v);
while (!next_iteration.empty()) {
PBVHVertRef next_v = next_iteration.front();
next_iteration.pop();
current_iteration.push(next_v);
}
propagation_steps_num++;
}
MEM_SAFE_FREE(visited_verts);
BLI_gsqueue_free(current_iteration);
BLI_gsqueue_free(next_iteration);
}
/* This functions assigns a falloff factor to each one of the SculptBoundaryEditInfo structs based

View File

@@ -10,7 +10,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
#include "BLI_gsqueue.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"

View File

@@ -8,7 +8,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_gsqueue.h"
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
#include "BLI_task.h"

View File

@@ -637,7 +637,7 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P
const int totvert = SCULPT_vertex_count_get(ss);
float *dists = static_cast<float *>(MEM_calloc_arrayN(totvert, sizeof(float), __func__));
BitVector<> visited_verts(totvert);
GSQueue *queue = BLI_gsqueue_new(sizeof(PBVHVertRef));
std::queue<PBVHVertRef> queue;
/* Search and initialize a boundary per symmetry pass, then mark those vertices as visited. */
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
@@ -655,22 +655,22 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P
}
for (int i = 0; i < boundary->verts_num; i++) {
BLI_gsqueue_push(queue, &boundary->verts[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. */
if (BLI_gsqueue_is_empty(queue)) {
if (queue.empty()) {
return dists;
}
/* Propagate the values from the boundaries to the rest of the mesh. */
while (!BLI_gsqueue_is_empty(queue)) {
PBVHVertRef v_next;
while (!queue.empty()) {
PBVHVertRef v_next = queue.front();
queue.pop();
BLI_gsqueue_pop(queue, &v_next);
int v_next_i = BKE_pbvh_vertex_to_index(ss->pbvh, v_next);
SculptVertexNeighborIter ni;
@@ -680,12 +680,11 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P
}
dists[ni.index] = dists[v_next_i] + 1.0f;
visited_verts[ni.index].set();
BLI_gsqueue_push(queue, &ni.vertex);
queue.push(ni.vertex);
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
BLI_gsqueue_free(queue);
return dists;
}
@@ -709,7 +708,7 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR
/* Search and mask as visited the initial vertices using the enabled symmetry passes. */
BitVector<> visited_verts(totvert);
GSQueue *queue = BLI_gsqueue_new(sizeof(PBVHVertRef));
std::queue<PBVHVertRef> queue;
const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
for (char symm_it = 0; symm_it <= symm; symm_it++) {
if (!SCULPT_is_symmetry_iteration_valid(symm_it, symm)) {
@@ -720,18 +719,18 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR
ob, symm_it, v);
int symm_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, symm_vertex);
BLI_gsqueue_push(queue, &symm_vertex);
queue.push(symm_vertex);
visited_verts[symm_vertex_i].set();
}
if (BLI_gsqueue_is_empty(queue)) {
if (queue.empty()) {
return dists;
}
/* Propagate the falloff increasing the value by 1 each time a new vertex is visited. */
while (!BLI_gsqueue_is_empty(queue)) {
PBVHVertRef v_next;
BLI_gsqueue_pop(queue, &v_next);
while (!queue.empty()) {
PBVHVertRef v_next = queue.front();
queue.pop();
int v_next_i = BKE_pbvh_vertex_to_index(ss->pbvh, v_next);
@@ -743,12 +742,11 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR
}
dists[neighbor_v.i] = dists[v_next_i] + 1.0f;
visited_verts[neighbor_v.i].set();
BLI_gsqueue_push(queue, &neighbor_v);
queue.push(neighbor_v);
}
}
}
BLI_gsqueue_free(queue);
return dists;
}

View File

@@ -9,6 +9,7 @@
#pragma once
#include <memory>
#include <queue>
#include "DNA_brush_types.h"
#include "DNA_key_types.h"
@@ -26,7 +27,6 @@
#include "BLI_compiler_attrs.h"
#include "BLI_compiler_compat.h"
#include "BLI_generic_array.hh"
#include "BLI_gsqueue.h"
#include "BLI_implicit_sharing.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
@@ -134,7 +134,7 @@ struct SculptOrigFaceData {
/* Flood Fill. */
struct SculptFloodFill {
GSQueue *queue;
std::queue<PBVHVertRef> queue;
BLI_bitmap *visited_verts;
};

View File

@@ -10,7 +10,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
#include "BLI_gsqueue.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_vector.hh"
#include "BLI_task.h"
@@ -595,14 +594,13 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
ss->preview_vert_list = MEM_cnew_array<PBVHVertRef>(max_preview_verts, __func__);
}
GSQueue *non_visited_verts = BLI_gsqueue_new(sizeof(PBVHVertRef));
PBVHVertRef active_v = SCULPT_active_vertex_get(ss);
BLI_gsqueue_push(non_visited_verts, &active_v);
std::queue<PBVHVertRef> non_visited_verts;
non_visited_verts.push(SCULPT_active_vertex_get(ss));
while (!BLI_gsqueue_is_empty(non_visited_verts)) {
PBVHVertRef from_v;
while (!non_visited_verts.empty()) {
PBVHVertRef from_v = non_visited_verts.front();
non_visited_verts.pop();
BLI_gsqueue_pop(non_visited_verts, &from_v);
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
if (totpoints + (ni.size * 2) < max_preview_verts) {
@@ -618,15 +616,13 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
BLI_BITMAP_ENABLE(visited_verts, 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(non_visited_verts, &to_v);
non_visited_verts.push(to_v);
}
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
BLI_gsqueue_free(non_visited_verts);
MEM_freeN(visited_verts);
ss->preview_vert_count = totpoints;