Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_boundary.c')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c355
1 files changed, 203 insertions, 152 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index 44e2dfae480..355f260ae11 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -7,13 +7,11 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_math.h"
#include "BLI_task.h"
#include "DNA_brush_types.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -21,20 +19,13 @@
#include "BKE_ccg.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
-#include "BKE_mesh.h"
-#include "BKE_multires.h"
-#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
-#include "BKE_scene.h"
#include "paint_intern.h"
#include "sculpt_intern.h"
#include "GPU_immediate.h"
-#include "GPU_immediate_util.h"
-#include "GPU_matrix.h"
#include "GPU_state.h"
#include "bmesh.h"
@@ -46,32 +37,38 @@
#define BOUNDARY_STEPS_NONE -1
typedef struct BoundaryInitialVertexFloodFillData {
- int initial_vertex;
+ PBVHVertRef initial_vertex;
+ int initial_vertex_i;
int boundary_initial_vertex_steps;
- int boundary_initial_vertex;
+ PBVHVertRef boundary_initial_vertex;
+ int boundary_initial_vertex_i;
int *floodfill_steps;
float radius_sq;
} BoundaryInitialVertexFloodFillData;
static bool boundary_initial_vertex_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)
{
BoundaryInitialVertexFloodFillData *data = 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);
+
if (!SCULPT_vertex_visible_get(ss, to_v)) {
return false;
}
if (!is_duplicate) {
- data->floodfill_steps[to_v] = data->floodfill_steps[from_v] + 1;
+ data->floodfill_steps[to_v_i] = data->floodfill_steps[from_v_i] + 1;
}
else {
- data->floodfill_steps[to_v] = data->floodfill_steps[from_v];
+ data->floodfill_steps[to_v_i] = data->floodfill_steps[from_v_i];
}
if (SCULPT_vertex_is_boundary(ss, to_v)) {
- if (data->floodfill_steps[to_v] < data->boundary_initial_vertex_steps) {
- data->boundary_initial_vertex_steps = data->floodfill_steps[to_v];
+ if (data->floodfill_steps[to_v_i] < data->boundary_initial_vertex_steps) {
+ data->boundary_initial_vertex_steps = data->floodfill_steps[to_v_i];
+ data->boundary_initial_vertex_i = to_v_i;
data->boundary_initial_vertex = to_v;
}
}
@@ -83,9 +80,9 @@ static bool boundary_initial_vertex_floodfill_cb(
/* From a vertex index anywhere in the mesh, returns the closest vertex in a mesh boundary inside
* the given radius, if it exists. */
-static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss,
- const int initial_vertex,
- const float radius)
+static PBVHVertRef sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss,
+ const PBVHVertRef initial_vertex,
+ const float radius)
{
if (SCULPT_vertex_is_boundary(ss, initial_vertex)) {
@@ -98,7 +95,7 @@ static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss,
BoundaryInitialVertexFloodFillData fdata = {
.initial_vertex = initial_vertex,
- .boundary_initial_vertex = BOUNDARY_VERTEX_NONE,
+ .boundary_initial_vertex = {BOUNDARY_VERTEX_NONE},
.boundary_initial_vertex_steps = INT_MAX,
.radius_sq = radius * radius,
};
@@ -119,34 +116,38 @@ static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss,
static int BOUNDARY_INDICES_BLOCK_SIZE = 300;
static void sculpt_boundary_index_add(SculptBoundary *boundary,
+ const PBVHVertRef new_vertex,
const int new_index,
const float distance,
- GSet *included_vertices)
+ GSet *included_verts)
{
- boundary->vertices[boundary->num_vertices] = new_index;
+ boundary->verts[boundary->verts_num] = new_vertex;
+
if (boundary->distance) {
boundary->distance[new_index] = distance;
}
- if (included_vertices) {
- BLI_gset_add(included_vertices, POINTER_FROM_INT(new_index));
+ if (included_verts) {
+ BLI_gset_add(included_verts, POINTER_FROM_INT(new_index));
}
- boundary->num_vertices++;
- if (boundary->num_vertices >= boundary->vertices_capacity) {
- boundary->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
- boundary->vertices = MEM_reallocN_id(
- boundary->vertices, boundary->vertices_capacity * sizeof(int), "boundary indices");
+ boundary->verts_num++;
+ if (boundary->verts_num >= boundary->verts_capacity) {
+ boundary->verts_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
+ boundary->verts = MEM_reallocN_id(
+ boundary->verts, boundary->verts_capacity * sizeof(PBVHVertRef), "boundary indices");
}
};
-static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, const int v1, const int v2)
+static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary,
+ const PBVHVertRef v1,
+ const PBVHVertRef v2)
{
- boundary->edges[boundary->num_edges].v1 = v1;
- boundary->edges[boundary->num_edges].v2 = v2;
- boundary->num_edges++;
+ boundary->edges[boundary->edges_num].v1 = v1;
+ boundary->edges[boundary->edges_num].v2 = v2;
+ boundary->edges_num++;
- if (boundary->num_edges >= boundary->edges_capacity) {
+ if (boundary->edges_num >= boundary->edges_capacity) {
boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
boundary->edges = MEM_reallocN_id(boundary->edges,
boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge),
@@ -159,7 +160,7 @@ static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, const int
* as well as to check if the initial vertex is valid.
*/
static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss,
- const int initial_vertex)
+ const PBVHVertRef initial_vertex)
{
if (!SCULPT_vertex_visible_get(ss, initial_vertex)) {
@@ -170,9 +171,9 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss,
int boundary_vertex_count = 0;
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, initial_vertex, ni) {
- if (SCULPT_vertex_visible_get(ss, ni.index)) {
+ if (SCULPT_vertex_visible_get(ss, ni.vertex)) {
neighbor_count++;
- if (SCULPT_vertex_is_boundary(ss, ni.index)) {
+ if (SCULPT_vertex_is_boundary(ss, ni.vertex)) {
boundary_vertex_count++;
}
}
@@ -199,16 +200,19 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss,
typedef struct BoundaryFloodFillData {
SculptBoundary *boundary;
- GSet *included_vertices;
+ GSet *included_verts;
EdgeSet *preview_edges;
- int last_visited_vertex;
+ PBVHVertRef last_visited_vertex;
} BoundaryFloodFillData;
static bool boundary_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);
+
BoundaryFloodFillData *data = userdata;
SculptBoundary *boundary = data->boundary;
if (!SCULPT_vertex_is_boundary(ss, to_v)) {
@@ -217,9 +221,10 @@ static bool boundary_floodfill_cb(
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 ?
- boundary->distance[from_v] + edge_len :
+ boundary->distance[from_v_i] + edge_len :
0.0f;
- sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
+ 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);
}
@@ -229,32 +234,38 @@ static bool boundary_floodfill_cb(
static void sculpt_boundary_indices_init(SculptSession *ss,
SculptBoundary *boundary,
const bool init_boundary_distances,
- const int initial_boundary_index)
+ const PBVHVertRef initial_boundary_vertex)
{
const int totvert = SCULPT_vertex_count_get(ss);
- boundary->vertices = MEM_malloc_arrayN(
- BOUNDARY_INDICES_BLOCK_SIZE, sizeof(int), "boundary indices");
+ boundary->verts = MEM_malloc_arrayN(
+ BOUNDARY_INDICES_BLOCK_SIZE, sizeof(PBVHVertRef), "boundary indices");
+
if (init_boundary_distances) {
boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances");
}
boundary->edges = MEM_malloc_arrayN(
BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), "boundary edges");
- GSet *included_vertices = BLI_gset_int_new_ex("included vertices", BOUNDARY_INDICES_BLOCK_SIZE);
+ GSet *included_verts = BLI_gset_int_new_ex("included verts", BOUNDARY_INDICES_BLOCK_SIZE);
SculptFloodFill flood;
SCULPT_floodfill_init(ss, &flood);
- boundary->initial_vertex = initial_boundary_index;
+ int initial_boundary_index = BKE_pbvh_vertex_to_index(ss->pbvh, initial_boundary_vertex);
+
+ boundary->initial_vertex = initial_boundary_vertex;
+ boundary->initial_vertex_i = initial_boundary_index;
+
copy_v3_v3(boundary->initial_vertex_position,
SCULPT_vertex_co_get(ss, boundary->initial_vertex));
- sculpt_boundary_index_add(boundary, initial_boundary_index, 0.0f, included_vertices);
- SCULPT_floodfill_add_initial(&flood, initial_boundary_index);
+ sculpt_boundary_index_add(
+ boundary, initial_boundary_vertex, initial_boundary_index, 0.0f, included_verts);
+ SCULPT_floodfill_add_initial(&flood, boundary->initial_vertex);
BoundaryFloodFillData fdata = {
.boundary = boundary,
- .included_vertices = included_vertices,
- .last_visited_vertex = BOUNDARY_VERTEX_NONE,
+ .included_verts = included_verts,
+ .last_visited_vertex = {BOUNDARY_VERTEX_NONE},
};
@@ -262,20 +273,20 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
SCULPT_floodfill_free(&flood);
/* Check if the boundary loops into itself and add the extra preview edge to close the loop. */
- if (fdata.last_visited_vertex != BOUNDARY_VERTEX_NONE &&
+ if (fdata.last_visited_vertex.i != BOUNDARY_VERTEX_NONE &&
sculpt_boundary_is_vertex_in_editable_boundary(ss, fdata.last_visited_vertex)) {
SculptVertexNeighborIter ni;
SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, fdata.last_visited_vertex, ni) {
- if (BLI_gset_haskey(included_vertices, POINTER_FROM_INT(ni.index)) &&
- sculpt_boundary_is_vertex_in_editable_boundary(ss, ni.index)) {
- sculpt_boundary_preview_edge_add(boundary, fdata.last_visited_vertex, ni.index);
+ 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->forms_loop = true;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
}
- BLI_gset_free(included_vertices, NULL);
+ BLI_gset_free(included_verts, NULL);
}
/**
@@ -286,7 +297,7 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
*/
static void sculpt_boundary_edit_data_init(SculptSession *ss,
SculptBoundary *boundary,
- const int initial_vertex,
+ const PBVHVertRef initial_vertex,
const float radius)
{
const int totvert = SCULPT_vertex_count_get(ss);
@@ -297,72 +308,78 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info");
for (int i = 0; i < totvert; i++) {
- boundary->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE;
- boundary->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE;
+ boundary->edit_info[i].original_vertex_i = BOUNDARY_VERTEX_NONE;
+ boundary->edit_info[i].propagation_steps_num = BOUNDARY_STEPS_NONE;
}
- GSQueue *current_iteration = BLI_gsqueue_new(sizeof(int));
- GSQueue *next_iteration = BLI_gsqueue_new(sizeof(int));
+ GSQueue *current_iteration = BLI_gsqueue_new(sizeof(PBVHVertRef));
+ GSQueue *next_iteration = BLI_gsqueue_new(sizeof(PBVHVertRef));
/* Initialized the first iteration with the vertices already in the boundary. This is propagation
* step 0. */
- BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_vertices");
- for (int i = 0; i < boundary->num_vertices; i++) {
- boundary->edit_info[boundary->vertices[i]].original_vertex = boundary->vertices[i];
- boundary->edit_info[boundary->vertices[i]].num_propagation_steps = 0;
+ BLI_bitmap *visited_verts = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_verts");
+ for (int i = 0; i < boundary->verts_num; 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,
+ boundary->verts[i]);
+ boundary->edit_info[index].propagation_steps_num = 0;
/* This ensures that all duplicate vertices in the boundary have the same original_vertex
* index, so the deformation for them will be the same. */
if (has_duplicates) {
SculptVertexNeighborIter ni_duplis;
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, boundary->vertices[i], ni_duplis) {
+ SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, boundary->verts[i], ni_duplis) {
if (ni_duplis.is_duplicate) {
- boundary->edit_info[ni_duplis.index].original_vertex = boundary->vertices[i];
+ boundary->edit_info[ni_duplis.index].original_vertex_i = BKE_pbvh_vertex_to_index(
+ ss->pbvh, boundary->verts[i]);
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
}
- BLI_gsqueue_push(current_iteration, &boundary->vertices[i]);
+ BLI_gsqueue_push(current_iteration, &boundary->verts[i]);
}
- int num_propagation_steps = 0;
+ int propagation_steps_num = 0;
float accum_distance = 0.0f;
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)) {
- boundary->max_propagation_steps = num_propagation_steps;
+ boundary->max_propagation_steps = propagation_steps_num;
break;
}
while (!BLI_gsqueue_is_empty(current_iteration)) {
- int from_v;
+ PBVHVertRef from_v;
BLI_gsqueue_pop(current_iteration, &from_v);
+ int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v);
+
SculptVertexNeighborIter ni;
SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
- const bool is_visible = SCULPT_vertex_visible_get(ss, ni.index);
+ const bool is_visible = SCULPT_vertex_visible_get(ss, ni.vertex);
if (!is_visible ||
- boundary->edit_info[ni.index].num_propagation_steps != BOUNDARY_STEPS_NONE) {
+ boundary->edit_info[ni.index].propagation_steps_num != BOUNDARY_STEPS_NONE) {
continue;
}
- boundary->edit_info[ni.index].original_vertex =
- boundary->edit_info[from_v].original_vertex;
+ boundary->edit_info[ni.index].original_vertex_i =
+ boundary->edit_info[from_v_i].original_vertex_i;
- BLI_BITMAP_ENABLE(visited_vertices, ni.index);
+ BLI_BITMAP_ENABLE(visited_verts, ni.index);
if (ni.is_duplicate) {
/* Grids duplicates handling. */
- boundary->edit_info[ni.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps;
+ boundary->edit_info[ni.index].propagation_steps_num =
+ boundary->edit_info[from_v_i].propagation_steps_num;
}
else {
- boundary->edit_info[ni.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps + 1;
+ boundary->edit_info[ni.index].propagation_steps_num =
+ boundary->edit_info[from_v_i].propagation_steps_num + 1;
- BLI_gsqueue_push(next_iteration, &ni.index);
+ BLI_gsqueue_push(next_iteration, &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
@@ -370,12 +387,12 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
* copy the data in the from_v neighbor iterator. */
if (has_duplicates) {
SculptVertexNeighborIter ni_duplis;
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
+ SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.vertex, ni_duplis) {
if (ni_duplis.is_duplicate) {
- boundary->edit_info[ni_duplis.index].original_vertex =
- boundary->edit_info[from_v].original_vertex;
- boundary->edit_info[ni_duplis.index].num_propagation_steps =
- boundary->edit_info[from_v].num_propagation_steps + 1;
+ boundary->edit_info[ni_duplis.index].original_vertex_i =
+ boundary->edit_info[from_v_i].original_vertex_i;
+ boundary->edit_info[ni_duplis.index].propagation_steps_num =
+ boundary->edit_info[from_v_i].propagation_steps_num + 1;
}
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
@@ -383,11 +400,12 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
/* Check the distance using the vertex that was propagated from the initial vertex that
* was used to initialize the boundary. */
- if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
- boundary->pivot_vertex = ni.index;
- copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
+ if (boundary->edit_info[from_v_i].original_vertex_i ==
+ BKE_pbvh_vertex_to_index(ss->pbvh, initial_vertex)) {
+ boundary->pivot_vertex = ni.vertex;
+ copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.vertex));
accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
- SCULPT_vertex_co_get(ss, ni.index));
+ SCULPT_vertex_co_get(ss, ni.vertex));
}
}
}
@@ -396,15 +414,15 @@ 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)) {
- int next_v;
+ PBVHVertRef next_v;
BLI_gsqueue_pop(next_iteration, &next_v);
BLI_gsqueue_push(current_iteration, &next_v);
}
- num_propagation_steps++;
+ propagation_steps_num++;
}
- MEM_SAFE_FREE(visited_vertices);
+ MEM_SAFE_FREE(visited_verts);
BLI_gsqueue_free(current_iteration);
BLI_gsqueue_free(next_iteration);
@@ -422,12 +440,13 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
BKE_curvemapping_init(brush->curve);
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != -1) {
+ if (boundary->edit_info[i].propagation_steps_num != -1) {
boundary->edit_info[i].strength_factor = BKE_brush_curve_strength(
- brush, boundary->edit_info[i].num_propagation_steps, boundary->max_propagation_steps);
+ brush, boundary->edit_info[i].propagation_steps_num, boundary->max_propagation_steps);
}
- if (boundary->edit_info[i].original_vertex == boundary->initial_vertex) {
+ if (boundary->edit_info[i].original_vertex_i ==
+ BKE_pbvh_vertex_to_index(ss->pbvh, boundary->initial_vertex)) {
/* All vertices that are propagated from the original vertex won't be affected by the
* boundary falloff, so there is no need to calculate anything else. */
continue;
@@ -439,7 +458,7 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
continue;
}
- const float boundary_distance = boundary->distance[boundary->edit_info[i].original_vertex];
+ const float boundary_distance = boundary->distance[boundary->edit_info[i].original_vertex_i];
float falloff_distance = 0.0f;
float direction = 1.0f;
@@ -473,22 +492,22 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
SculptBoundary *SCULPT_boundary_data_init(Object *object,
Brush *brush,
- const int initial_vertex,
+ const PBVHVertRef initial_vertex,
const float radius)
{
SculptSession *ss = object->sculpt;
- if (initial_vertex == BOUNDARY_VERTEX_NONE) {
+ if (initial_vertex.i == PBVH_REF_NONE) {
return NULL;
}
SCULPT_vertex_random_access_ensure(ss);
SCULPT_boundary_info_ensure(object);
- const int boundary_initial_vertex = sculpt_boundary_get_closest_boundary_vertex(
+ const PBVHVertRef boundary_initial_vertex = sculpt_boundary_get_closest_boundary_vertex(
ss, initial_vertex, radius);
- if (boundary_initial_vertex == BOUNDARY_VERTEX_NONE) {
+ if (boundary_initial_vertex.i == BOUNDARY_VERTEX_NONE) {
return NULL;
}
@@ -514,7 +533,7 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object,
void SCULPT_boundary_data_free(SculptBoundary *boundary)
{
- MEM_SAFE_FREE(boundary->vertices);
+ MEM_SAFE_FREE(boundary->verts);
MEM_SAFE_FREE(boundary->edges);
MEM_SAFE_FREE(boundary->distance);
MEM_SAFE_FREE(boundary->edit_info);
@@ -536,30 +555,35 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
boundary->bend.pivot_positions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "pivot positions");
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
+ if (boundary->edit_info[i].propagation_steps_num != boundary->max_propagation_steps) {
continue;
}
+
+ PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
+
float dir[3];
float normal[3];
- SCULPT_vertex_normal_get(ss, i, normal);
- sub_v3_v3v3(dir,
- SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
- SCULPT_vertex_co_get(ss, i));
+ SCULPT_vertex_normal_get(ss, vertex, normal);
+ sub_v3_v3v3(
+ dir,
+ SCULPT_vertex_co_get(
+ ss, BKE_pbvh_index_to_vertex(ss->pbvh, boundary->edit_info[i].original_vertex_i)),
+ SCULPT_vertex_co_get(ss, vertex));
cross_v3_v3v3(
- boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
- normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
- copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, i));
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex_i], dir, normal);
+ normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex_i]);
+ copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex_i],
+ SCULPT_vertex_co_get(ss, vertex));
}
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ if (boundary->edit_info[i].propagation_steps_num == BOUNDARY_STEPS_NONE) {
continue;
}
copy_v3_v3(boundary->bend.pivot_positions[i],
- boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
+ boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex_i]);
copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
- boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
+ boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex_i]);
}
}
@@ -569,36 +593,37 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b
boundary->slide.directions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "slide directions");
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
+ if (boundary->edit_info[i].propagation_steps_num != boundary->max_propagation_steps) {
continue;
}
- sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
- SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
- SCULPT_vertex_co_get(ss, i));
- normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
+ sub_v3_v3v3(
+ boundary->slide.directions[boundary->edit_info[i].original_vertex_i],
+ SCULPT_vertex_co_get(
+ ss, BKE_pbvh_index_to_vertex(ss->pbvh, boundary->edit_info[i].original_vertex_i)),
+ SCULPT_vertex_co_get(ss, BKE_pbvh_index_to_vertex(ss->pbvh, i)));
+ normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex_i]);
}
for (int i = 0; i < totvert; i++) {
- if (boundary->edit_info[i].num_propagation_steps == BOUNDARY_STEPS_NONE) {
+ if (boundary->edit_info[i].propagation_steps_num == BOUNDARY_STEPS_NONE) {
continue;
}
copy_v3_v3(boundary->slide.directions[i],
- boundary->slide.directions[boundary->edit_info[i].original_vertex]);
+ boundary->slide.directions[boundary->edit_info[i].original_vertex_i]);
}
}
static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *boundary)
{
zero_v3(boundary->twist.pivot_position);
- float(*poly_verts)[3] = MEM_malloc_arrayN(
- boundary->num_vertices, sizeof(float[3]), "poly verts");
- for (int i = 0; i < boundary->num_vertices; i++) {
- add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->vertices[i]));
- copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->vertices[i]));
+ float(*poly_verts)[3] = MEM_malloc_arrayN(boundary->verts_num, sizeof(float[3]), "poly verts");
+ for (int i = 0; i < boundary->verts_num; i++) {
+ add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->verts[i]));
+ copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->verts[i]));
}
- mul_v3_fl(boundary->twist.pivot_position, 1.0f / boundary->num_vertices);
+ mul_v3_fl(boundary->twist.pivot_position, 1.0f / boundary->verts_num);
if (boundary->forms_loop) {
- normal_poly_v3(boundary->twist.rotation_axis, poly_verts, boundary->num_vertices);
+ normal_poly_v3(boundary->twist.rotation_axis, poly_verts, boundary->verts_num);
}
else {
sub_v3_v3v3(boundary->twist.rotation_axis,
@@ -647,12 +672,16 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
angle_factor = floorf(angle_factor * 10) / 10.0f;
}
const float angle = angle_factor * M_PI;
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -660,7 +689,8 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float t_orig_co[3];
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
@@ -671,7 +701,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
if (vd.mvert) {
- BKE_pbvh_vert_mark_update(ss->pbvh, vd.index);
+ BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
}
}
BKE_pbvh_vertex_iter_end;
@@ -695,12 +725,16 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -708,7 +742,8 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
@@ -717,7 +752,7 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
strength);
if (vd.mvert) {
- BKE_pbvh_vert_mark_update(ss->pbvh, vd.index);
+ BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
}
}
BKE_pbvh_vertex_iter_end;
@@ -739,14 +774,18 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -754,7 +793,8 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
@@ -763,7 +803,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
strength);
if (vd.mvert) {
- BKE_pbvh_vert_mark_update(ss->pbvh, vd.index);
+ BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
}
}
BKE_pbvh_vertex_iter_end;
@@ -785,12 +825,16 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -798,7 +842,8 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
madd_v3_v3v3fl(target_co,
orig_data.co,
@@ -806,7 +851,7 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
if (vd.mvert) {
- BKE_pbvh_vert_mark_update(ss->pbvh, vd.index);
+ BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
}
}
BKE_pbvh_vertex_iter_end;
@@ -828,6 +873,9 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
PBVHVertexIter vd;
SculptOrigVertData orig_data;
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
+ AutomaskingNodeData automask_data;
+ SCULPT_automasking_node_begin(
+ data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]);
const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
float angle_factor = disp / ss->cache->radius;
@@ -838,10 +886,11 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
const float angle = angle_factor * M_PI;
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
+ SCULPT_automasking_node_update(ss, &automask_data, &vd);
SCULPT_orig_vert_data_update(&orig_data, &vd);
if (!SCULPT_check_vertex_pivot_symmetry(
orig_data.co, boundary->initial_vertex_position, symm)) {
@@ -849,7 +898,8 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
}
const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
- const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+ const float automask = SCULPT_automasking_factor_get(
+ ss->cache->automasking, ss, vd.vertex, &automask_data);
float t_orig_co[3];
float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
@@ -860,7 +910,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
add_v3_v3(target_co, boundary->twist.pivot_position);
if (vd.mvert) {
- BKE_pbvh_vert_mark_update(ss->pbvh, vd.index);
+ BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
}
}
BKE_pbvh_vertex_iter_end;
@@ -884,7 +934,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
- if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+ if (boundary->edit_info[vd.index].propagation_steps_num == -1) {
continue;
}
@@ -896,11 +946,11 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
float coord_accum[3] = {0.0f, 0.0f, 0.0f};
int total_neighbors = 0;
- const int current_propagation_steps = boundary->edit_info[vd.index].num_propagation_steps;
+ const int current_propagation_steps = boundary->edit_info[vd.index].propagation_steps_num;
SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
- if (current_propagation_steps == boundary->edit_info[ni.index].num_propagation_steps) {
- add_v3_v3(coord_accum, SCULPT_vertex_co_get(ss, ni.index));
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) {
+ if (current_propagation_steps == boundary->edit_info[ni.index].propagation_steps_num) {
+ add_v3_v3(coord_accum, SCULPT_vertex_co_get(ss, ni.vertex));
total_neighbors++;
}
}
@@ -919,7 +969,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
target_co, vd.co, disp, boundary->edit_info[vd.index].strength_factor * mask * strength);
if (vd.mvert) {
- BKE_pbvh_vert_mark_update(ss->pbvh, vd.index);
+ BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
}
}
BKE_pbvh_vertex_iter_end;
@@ -933,7 +983,8 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
const int symm_area = ss->cache->mirror_symmetry_pass;
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- int initial_vertex;
+ PBVHVertRef initial_vertex;
+
if (ss->cache->mirror_symmetry_pass == 0) {
initial_vertex = SCULPT_active_vertex_get(ss);
}
@@ -1017,8 +1068,8 @@ void SCULPT_boundary_edges_preview_draw(const uint gpuattr,
}
immUniformColor3fvAlpha(outline_col, outline_alpha);
GPU_line_width(2.0f);
- immBegin(GPU_PRIM_LINES, ss->boundary_preview->num_edges * 2);
- for (int i = 0; i < ss->boundary_preview->num_edges; i++) {
+ immBegin(GPU_PRIM_LINES, ss->boundary_preview->edges_num * 2);
+ for (int i = 0; i < ss->boundary_preview->edges_num; 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));
}