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_pose.c')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c125
1 files changed, 79 insertions, 46 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index 587ce346428..09517820485 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -172,10 +172,10 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
float final_pos[3];
SculptOrigVertData orig_data;
- SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
+ 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) {
- SCULPT_orig_vert_data_update(&orig_data, &vd);
+ SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
float total_disp[3];
zero_v3(total_disp);
@@ -198,7 +198,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata,
/* Apply the vertex mask to the displacement. */
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);
mul_v3_fl(disp, mask * automask);
/* Accumulate the displacement. */
@@ -237,7 +237,7 @@ static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata,
float max = 0.0f;
/* Grow the factor. */
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) {
float vmask_f = data->prev_mask[ni.index];
max = MAX2(vmask_f, max);
}
@@ -383,7 +383,8 @@ typedef struct PoseFloodFillData {
int current_face_set;
int next_face_set;
int prev_face_set;
- int next_vertex;
+ SculptVertRef next_vertex;
+ int next_vertex_index;
bool next_face_set_found;
@@ -413,11 +414,16 @@ typedef struct PoseFloodFillData {
int target_face_set;
} PoseFloodFillData;
-static bool pose_topology_floodfill_cb(
- SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata)
+static bool pose_topology_floodfill_cb(SculptSession *ss,
+ SculptVertRef UNUSED(from_v),
+ SculptVertRef to_vref,
+ bool is_duplicate,
+ void *userdata)
{
PoseFloodFillData *data = userdata;
- const float *co = SCULPT_vertex_co_get(ss, to_v);
+ int to_v = BKE_pbvh_vertex_index_to_table(ss->pbvh, to_vref);
+
+ const float *co = SCULPT_vertex_co_get(ss, to_vref);
if (data->pose_factor) {
data->pose_factor[to_v] = 1.0f;
@@ -442,15 +448,18 @@ static bool pose_topology_floodfill_cb(
return false;
}
-static bool pose_face_sets_floodfill_cb(
- SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata)
+static bool pose_face_sets_floodfill_cb(SculptSession *ss,
+ SculptVertRef UNUSED(from_v),
+ SculptVertRef to_v,
+ bool is_duplicate,
+ void *userdata)
{
PoseFloodFillData *data = userdata;
- const int index = to_v;
+ const int index = BKE_pbvh_vertex_index_to_table(ss->pbvh, to_v);
bool visit_next = false;
- const float *co = SCULPT_vertex_co_get(ss, index);
+ const float *co = SCULPT_vertex_co_get(ss, to_v);
const bool symmetry_check = SCULPT_check_vertex_pivot_symmetry(
co, data->pose_initial_co, data->symm) &&
!is_duplicate;
@@ -464,11 +473,11 @@ static bool pose_face_sets_floodfill_cb(
if (sculpt_pose_brush_is_vertex_inside_brush_radius(
co, data->pose_initial_co, data->radius, data->symm)) {
- const int visited_face_set = SCULPT_vertex_face_set_get(ss, index);
+ const int visited_face_set = SCULPT_vertex_face_set_get(ss, to_v);
BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(visited_face_set));
}
else if (symmetry_check) {
- data->current_face_set = SCULPT_vertex_face_set_get(ss, index);
+ data->current_face_set = SCULPT_vertex_face_set_get(ss, to_v);
BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(data->current_face_set));
}
return true;
@@ -482,11 +491,11 @@ static bool pose_face_sets_floodfill_cb(
GSetIterator gs_iter;
GSET_ITER (gs_iter, data->visited_face_sets) {
const int visited_face_set = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter));
- is_vertex_valid |= SCULPT_vertex_has_face_set(ss, index, visited_face_set);
+ is_vertex_valid |= SCULPT_vertex_has_face_set(ss, to_v, visited_face_set);
}
}
else {
- is_vertex_valid = SCULPT_vertex_has_face_set(ss, index, data->current_face_set);
+ is_vertex_valid = SCULPT_vertex_has_face_set(ss, to_v, data->current_face_set);
}
if (!is_vertex_valid) {
@@ -501,11 +510,11 @@ static bool pose_face_sets_floodfill_cb(
/* Fallback origin accumulation. */
if (symmetry_check) {
- add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index));
+ add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, to_v));
data->fallback_count++;
}
- if (!symmetry_check || SCULPT_vertex_has_unique_face_set(ss, index)) {
+ if (!symmetry_check || SCULPT_vertex_has_unique_face_set(ss, to_v)) {
return visit_next;
}
@@ -514,15 +523,15 @@ static bool pose_face_sets_floodfill_cb(
bool count_as_boundary = false;
SculptVertexNeighborIter ni;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) {
- int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index);
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, to_v, ni) {
+ int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.vertex);
/* Check if we can get a valid face set for the next iteration from this neighbor. */
- if (SCULPT_vertex_has_unique_face_set(ss, ni.index) &&
+ if (SCULPT_vertex_has_unique_face_set(ss, ni.vertex) &&
!BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) {
if (!data->next_face_set_found) {
data->next_face_set = next_face_set_candidate;
- data->next_vertex = ni.index;
+ data->next_vertex = ni.vertex;
data->next_face_set_found = true;
}
count_as_boundary = true;
@@ -532,7 +541,7 @@ static bool pose_face_sets_floodfill_cb(
/* Origin accumulation. */
if (count_as_boundary) {
- add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index));
+ add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, to_v));
data->tot_co++;
}
return visit_next;
@@ -556,8 +565,6 @@ void SCULPT_pose_calc_pose_data(Sculpt *sd,
float *r_pose_origin,
float *r_pose_factor)
{
- SCULPT_vertex_random_access_ensure(ss);
-
/* Calculate the pose rotation point based on the boundaries of the brush factor. */
SculptFloodFill flood;
SCULPT_floodfill_init(ss, &flood);
@@ -608,7 +615,7 @@ static void pose_brush_init_task_cb_ex(void *__restrict userdata,
SculptVertexNeighborIter ni;
float avg = 0.0f;
int total = 0;
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) {
avg += data->pose_factor[ni.index];
total++;
}
@@ -678,12 +685,15 @@ static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd,
const float initial_location[3],
const float radius)
{
+ SCULPT_vertex_random_access_ensure(ss);
const float chain_segment_len = radius * (1.0f + br->pose_offset);
float next_chain_segment_target[3];
int totvert = SCULPT_vertex_count_get(ss);
- int nearest_vertex_index = SCULPT_nearest_vertex_get(sd, ob, initial_location, FLT_MAX, true);
+ SculptVertRef nearest_vertex = SCULPT_nearest_vertex_get(
+ sd, ob, initial_location, FLT_MAX, true);
+ int nearest_vertex_index = BKE_pbvh_vertex_index_to_table(ss->pbvh, nearest_vertex);
/* Init the buffers used to keep track of the changes in the pose factors as more segments are
* added to the IK chain. */
@@ -768,7 +778,8 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
int current_face_set = SCULPT_FACE_SET_NONE;
int prev_face_set = SCULPT_FACE_SET_NONE;
- int current_vertex = SCULPT_active_vertex_get(ss);
+ SculptVertRef current_vertex = SCULPT_active_vertex_get(ss);
+ int current_vertex_i = BKE_pbvh_vertex_index_to_table(ss->pbvh, current_vertex);
for (int s = 0; s < ik_chain->tot_segments; s++) {
@@ -797,6 +808,13 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
SCULPT_floodfill_execute(ss, &flood, pose_face_sets_floodfill_cb, &fdata);
SCULPT_floodfill_free(&flood);
+ if (!fdata.next_face_set_found) {
+ for (int i = s; i < ik_chain->tot_segments; i++) {
+ zero_v3(ik_chain->segments[i].orig);
+ }
+ break;
+ }
+
if (fdata.tot_co > 0) {
mul_v3_fl(fdata.pose_origin, 1.0f / (float)fdata.tot_co);
copy_v3_v3(ik_chain->segments[s].orig, fdata.pose_origin);
@@ -823,10 +841,15 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets(
return ik_chain;
}
-static bool pose_face_sets_fk_find_masked_floodfill_cb(
- SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
+static bool pose_face_sets_fk_find_masked_floodfill_cb(SculptSession *ss,
+ SculptVertRef from_vr,
+ SculptVertRef to_vr,
+ bool is_duplicate,
+ void *userdata)
{
PoseFloodFillData *data = userdata;
+ int from_v = BKE_pbvh_vertex_index_to_table(ss->pbvh, from_vr);
+ int to_v = BKE_pbvh_vertex_index_to_table(ss->pbvh, to_vr);
if (!is_duplicate) {
data->floodfill_it[to_v] = data->floodfill_it[from_v] + 1;
@@ -835,11 +858,11 @@ static bool pose_face_sets_fk_find_masked_floodfill_cb(
data->floodfill_it[to_v] = data->floodfill_it[from_v];
}
- const int to_face_set = SCULPT_vertex_face_set_get(ss, to_v);
+ const int to_face_set = SCULPT_vertex_face_set_get(ss, to_vr);
if (!BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(to_face_set))) {
- if (SCULPT_vertex_has_unique_face_set(ss, to_v) &&
- !SCULPT_vertex_has_unique_face_set(ss, from_v) &&
- SCULPT_vertex_has_face_set(ss, from_v, to_face_set)) {
+ if (SCULPT_vertex_has_unique_face_set(ss, to_vr) &&
+ !SCULPT_vertex_has_unique_face_set(ss, from_vr) &&
+ SCULPT_vertex_has_face_set(ss, from_vr, to_face_set)) {
BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(to_face_set));
@@ -854,14 +877,17 @@ static bool pose_face_sets_fk_find_masked_floodfill_cb(
}
}
- return SCULPT_vertex_has_face_set(ss, to_v, data->initial_face_set);
+ return SCULPT_vertex_has_face_set(ss, to_vr, data->initial_face_set);
}
-static bool pose_face_sets_fk_set_weights_floodfill_cb(
- SculptSession *ss, int UNUSED(from_v), int to_v, bool UNUSED(is_duplicate), void *userdata)
+static bool pose_face_sets_fk_set_weights_floodfill_cb(SculptSession *ss,
+ SculptVertRef UNUSED(from_v),
+ SculptVertRef to_v,
+ bool UNUSED(is_duplicate),
+ void *userdata)
{
PoseFloodFillData *data = userdata;
- data->fk_weights[to_v] = 1.0f;
+ data->fk_weights[BKE_pbvh_vertex_index_to_table(ss->pbvh, to_v)] = 1.0f;
return !SCULPT_vertex_has_face_set(ss, to_v, data->masked_face_set);
}
@@ -872,7 +898,9 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
SculptPoseIKChain *ik_chain = pose_ik_chain_new(1, totvert);
- const int active_vertex = SCULPT_active_vertex_get(ss);
+ const SculptVertRef active_vertex = SCULPT_active_vertex_get(ss);
+ const int active_vertex_i = BKE_pbvh_vertex_index_to_table(ss->pbvh, active_vertex);
+
const int active_face_set = SCULPT_active_face_set_get(ss);
SculptFloodFill flood;
@@ -880,7 +908,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
SCULPT_floodfill_add_initial(&flood, active_vertex);
PoseFloodFillData fdata;
fdata.floodfill_it = MEM_calloc_arrayN(totvert, sizeof(int), "floodfill iteration");
- fdata.floodfill_it[active_vertex] = 1;
+ fdata.floodfill_it[active_vertex_i] = 1;
fdata.initial_face_set = active_face_set;
fdata.masked_face_set = SCULPT_FACE_SET_NONE;
fdata.target_face_set = SCULPT_FACE_SET_NONE;
@@ -893,9 +921,12 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
int origin_count = 0;
float origin_acc[3] = {0.0f};
for (int i = 0; i < totvert; i++) {
- if (fdata.floodfill_it[i] != 0 && SCULPT_vertex_has_face_set(ss, i, fdata.initial_face_set) &&
- SCULPT_vertex_has_face_set(ss, i, fdata.masked_face_set)) {
- add_v3_v3(origin_acc, SCULPT_vertex_co_get(ss, i));
+ SculptVertRef vref = BKE_pbvh_table_index_to_vertex(ss->pbvh, i);
+
+ if (fdata.floodfill_it[i] != 0 &&
+ SCULPT_vertex_has_face_set(ss, vref, fdata.initial_face_set) &&
+ SCULPT_vertex_has_face_set(ss, vref, fdata.masked_face_set)) {
+ add_v3_v3(origin_acc, SCULPT_vertex_co_get(ss, vref));
origin_count++;
}
}
@@ -904,10 +935,12 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk(
float target_acc[3] = {0.0f};
if (fdata.target_face_set != fdata.masked_face_set) {
for (int i = 0; i < totvert; i++) {
+ SculptVertRef vref = BKE_pbvh_table_index_to_vertex(ss->pbvh, i);
+
if (fdata.floodfill_it[i] != 0 &&
- SCULPT_vertex_has_face_set(ss, i, fdata.initial_face_set) &&
- SCULPT_vertex_has_face_set(ss, i, fdata.target_face_set)) {
- add_v3_v3(target_acc, SCULPT_vertex_co_get(ss, i));
+ SCULPT_vertex_has_face_set(ss, vref, fdata.initial_face_set) &&
+ SCULPT_vertex_has_face_set(ss, vref, fdata.target_face_set)) {
+ add_v3_v3(target_acc, SCULPT_vertex_co_get(ss, vref));
target_count++;
}
}