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_undo.c')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c101
1 files changed, 63 insertions, 38 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 788d07f6e78..5d95cc80280 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -86,6 +86,7 @@ static void update_cb(PBVHNode *node, void *rebuild)
struct PartialUpdateData {
PBVH *pbvh;
bool rebuild;
+ char *modified_grids;
};
/**
@@ -94,8 +95,24 @@ struct PartialUpdateData {
static void update_cb_partial(PBVHNode *node, void *userdata)
{
struct PartialUpdateData *data = userdata;
- if (BKE_pbvh_node_vert_update_check_any(data->pbvh, node)) {
- update_cb(node, &(data->rebuild));
+ if (BKE_pbvh_type(data->pbvh) == PBVH_GRIDS) {
+ int *node_grid_indices;
+ int totgrid;
+ bool update = false;
+ BKE_pbvh_node_get_grids(data->pbvh, node, &node_grid_indices, &totgrid, NULL, NULL, NULL);
+ for (int i = 0; i < totgrid; i++) {
+ if (data->modified_grids[node_grid_indices[i]] == 1) {
+ update = true;
+ }
+ }
+ if (update) {
+ update_cb(node, &(data->rebuild));
+ }
+ }
+ else {
+ if (BKE_pbvh_node_vert_update_check_any(data->pbvh, node)) {
+ update_cb(node, &(data->rebuild));
+ }
}
}
@@ -135,7 +152,7 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt
if (unode->maxvert) {
/* regular mesh restore */
- if (ss->kb && !STREQ(ss->kb->name, unode->shapeName)) {
+ if (ss->shapekey_active && !STREQ(ss->shapekey_active->name, unode->shapeName)) {
/* shape key has been changed before calling undo operator */
Key *key = BKE_key_from_object(ob);
@@ -157,12 +174,12 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt
index = unode->index;
mvert = ss->mvert;
- if (ss->kb) {
+ if (ss->shapekey_active) {
float(*vertCos)[3];
- vertCos = BKE_keyblock_convert_to_vertcos(ob, ss->kb);
+ vertCos = BKE_keyblock_convert_to_vertcos(ob, ss->shapekey_active);
if (unode->orig_co) {
- if (ss->modifiers_active) {
+ if (ss->deform_modifiers_active) {
for (int i = 0; i < unode->totvert; i++) {
sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
}
@@ -180,36 +197,33 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt
}
/* propagate new coords to keyblock */
- sculpt_vertcos_to_key(ob, ss->kb, vertCos);
+ sculpt_vertcos_to_key(ob, ss->shapekey_active, vertCos);
/* pbvh uses it's own mvert array, so coords should be */
/* propagated to pbvh here */
- BKE_pbvh_vert_coords_apply(ss->pbvh, vertCos, ss->kb->totelem);
+ BKE_pbvh_vert_coords_apply(ss->pbvh, vertCos, ss->shapekey_active->totelem);
MEM_freeN(vertCos);
}
else {
if (unode->orig_co) {
- if (ss->modifiers_active) {
+ if (ss->deform_modifiers_active) {
for (int i = 0; i < unode->totvert; i++) {
- if (sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co)) {
- mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
- }
+ sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
+ mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
}
}
else {
for (int i = 0; i < unode->totvert; i++) {
- if (test_swap_v3_v3(mvert[index[i]].co, unode->orig_co[i])) {
- mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
- }
+ swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]);
+ mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
}
}
}
else {
for (int i = 0; i < unode->totvert; i++) {
- if (test_swap_v3_v3(mvert[index[i]].co, unode->co[i])) {
- mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
- }
+ swap_v3_v3(mvert[index[i]].co, unode->co[i]);
+ mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
}
}
}
@@ -346,9 +360,9 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C,
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
- TaskParallelSettings settings;
+ PBVHParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, (sd->flags & SCULPT_USE_OPENMP), totnode);
- BLI_task_parallel_range(
+ BKE_pbvh_parallel_range(
0, totnode, nodes, sculpt_undo_bmesh_restore_generic_task_cb, &settings);
if (nodes) {
@@ -485,7 +499,6 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
SculptUndoNode *unode;
bool update = false, rebuild = false;
bool need_mask = false;
- bool partial_update = true;
for (unode = lb->first; unode; unode = unode->next) {
/* restore pivot */
@@ -527,6 +540,9 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
return;
}
+ char *undo_modified_grids = NULL;
+ bool use_multires_undo = false;
+
for (unode = lb->first; unode; unode = unode->next) {
if (!STREQ(unode->idname, ob->id.name)) {
@@ -546,8 +562,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
continue;
}
- /* multi-res can't do partial updates since it doesn't flag edited vertices */
- partial_update = false;
+ use_multires_undo = true;
}
switch (unode->type) {
@@ -577,21 +592,29 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
}
}
+ if (use_multires_undo) {
+ int max_grid;
+ unode = lb->first;
+ max_grid = unode->maxgrid;
+ undo_modified_grids = MEM_callocN(sizeof(char) * max_grid, "undo_grids");
+ for (unode = lb->first; unode; unode = unode->next) {
+ for (int i = 0; i < unode->totgrid; i++) {
+ undo_modified_grids[unode->grids[i]] = 1;
+ }
+ }
+ }
+
if (update || rebuild) {
bool tag_update = false;
/* we update all nodes still, should be more clever, but also
* needs to work correct when exiting/entering sculpt mode and
* the nodes get recreated, though in that case it could do all */
- if (partial_update) {
- struct PartialUpdateData data = {
- .rebuild = rebuild,
- .pbvh = ss->pbvh,
- };
- BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb_partial, &data);
- }
- else {
- BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
- }
+ struct PartialUpdateData data = {
+ .rebuild = rebuild,
+ .pbvh = ss->pbvh,
+ .modified_grids = undo_modified_grids,
+ };
+ BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb_partial, &data);
BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw);
if (BKE_sculpt_multires_active(scene, ob)) {
@@ -605,7 +628,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
tag_update |= ((Mesh *)ob->data)->id.us > 1 || !BKE_sculptsession_use_pbvh_draw(ob, v3d);
- if (ss->kb || ss->modifiers_active) {
+ if (ss->shapekey_active || ss->deform_modifiers_active) {
Mesh *mesh = ob->data;
BKE_mesh_calc_normals(mesh);
@@ -620,6 +643,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase
sculpt_update_object_bounding_box(ob);
}
}
+
+ MEM_SAFE_FREE(undo_modified_grids);
}
static void sculpt_undo_free_list(ListBase *lb)
@@ -806,7 +831,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt
unode->index = MEM_mapallocN(sizeof(int) * allvert, "SculptUndoNode.index");
}
- if (ss->modifiers_active) {
+ if (ss->deform_modifiers_active) {
unode->orig_co = MEM_callocN(allvert * sizeof(*unode->orig_co), "undoSculpt orig_cos");
}
@@ -828,7 +853,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
normal_float_to_short_v3(unode->no[vd.i], vd.fno);
}
- if (ss->modifiers_active) {
+ if (ss->deform_modifiers_active) {
copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]);
}
}
@@ -1057,8 +1082,8 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType
copy_v3_v3(unode->pivot_rot, ss->pivot_rot);
/* store active shape key */
- if (ss->kb) {
- BLI_strncpy(unode->shapeName, ss->kb->name, sizeof(ss->kb->name));
+ if (ss->shapekey_active) {
+ BLI_strncpy(unode->shapeName, ss->shapekey_active->name, sizeof(ss->shapekey_active->name));
}
else {
unode->shapeName[0] = '\0';