2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2006 by Nicholas Bishop
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
27 * Implements the Sculpt Mode tools
31 /** \file blender/editors/sculpt_paint/sculpt_undo.c
37 #include "MEM_guardedalloc.h"
40 #include "BLI_utildefines.h"
41 #include "BLI_string.h"
42 #include "BLI_listbase.h"
43 #include "BLI_ghash.h"
44 #include "BLI_threads.h"
46 #include "DNA_meshdata_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_mesh_types.h"
52 #include "BKE_cdderivedmesh.h"
53 #include "BKE_context.h"
54 #include "BKE_depsgraph.h"
55 #include "BKE_modifier.h"
56 #include "BKE_multires.h"
57 #include "BKE_paint.h"
60 #include "BKE_subsurf.h"
65 #include "GPU_buffers.h"
67 #include "ED_sculpt.h"
68 #include "paint_intern.h"
69 #include "sculpt_intern.h"
71 /************************** Undo *************************/
73 static void update_cb(PBVHNode *node, void *rebuild)
75 BLI_pbvh_node_mark_update(node);
76 if (*((int *)rebuild))
77 BLI_pbvh_node_mark_rebuild_draw(node);
78 BLI_pbvh_node_fully_hidden_set(node, 0);
81 static void sculpt_undo_restore_deformed(const SculptSession *ss,
82 SculptUndoNode *unode,
83 int uindex, int oindex,
87 swap_v3_v3(coord, unode->orig_co[uindex]);
88 copy_v3_v3(unode->co[uindex], ss->deform_cos[oindex]);
91 swap_v3_v3(coord, unode->co[uindex]);
95 static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNode *unode)
97 Scene *scene = CTX_data_scene(C);
98 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
99 Object *ob = CTX_data_active_object(C);
100 SculptSession *ss = ob->sculpt;
104 if (unode->maxvert) {
105 /* regular mesh restore */
107 if (ss->kb && strcmp(ss->kb->name, unode->shapeName)) {
108 /* shape key has been changed before calling undo operator */
110 Key *key = ob_get_key(ob);
111 KeyBlock *kb = key_get_named_keyblock(key, unode->shapeName);
114 ob->shapenr = BLI_findindex(&key->block, kb) + 1;
116 sculpt_update_mesh_elements(scene, sd, ob, 0);
117 WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
120 /* key has been removed -- skip this undo node */
125 index = unode->index;
130 vertCos = key_to_vertcos(ob, ss->kb);
132 for (i = 0; i < unode->totvert; i++) {
133 if (ss->modifiers_active) sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
135 if (unode->orig_co) swap_v3_v3(vertCos[index[i]], unode->orig_co[i]);
136 else swap_v3_v3(vertCos[index[i]], unode->co[i]);
140 /* propagate new coords to keyblock */
141 sculpt_vertcos_to_key(ob, ss->kb, vertCos);
143 /* pbvh uses it's own mvert array, so coords should be */
144 /* propagated to pbvh here */
145 BLI_pbvh_apply_vertCos(ss->pbvh, vertCos);
150 for (i = 0; i < unode->totvert; i++) {
151 if (ss->modifiers_active) sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
153 if (unode->orig_co) swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]);
154 else swap_v3_v3(mvert[index[i]].co, unode->co[i]);
156 mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
160 else if (unode->maxgrid && dm->getGridData) {
161 /* multires restore */
162 CCGElem **grids, *grid;
167 grids = dm->getGridData(dm);
168 gridsize = dm->getGridSize(dm);
169 dm->getGridKey(dm, &key);
172 for (j = 0; j < unode->totgrid; j++) {
173 grid = grids[unode->grids[j]];
175 for (i = 0; i < gridsize * gridsize; i++, co++)
176 swap_v3_v3(CCG_elem_offset_co(&key, grid, i), co[0]);
183 static int sculpt_undo_restore_hidden(bContext *C, DerivedMesh *dm,
184 SculptUndoNode *unode)
186 Object *ob = CTX_data_active_object(C);
187 SculptSession *ss = ob->sculpt;
190 if (unode->maxvert) {
191 MVert *mvert = ss->mvert;
193 for (i = 0; i < unode->totvert; i++) {
194 MVert *v = &mvert[unode->index[i]];
195 int uval = BLI_BITMAP_GET(unode->vert_hidden, i);
197 BLI_BITMAP_MODIFY(unode->vert_hidden, i,
204 v->flag |= ME_VERT_PBVH_UPDATE;
207 else if (unode->maxgrid && dm->getGridData) {
208 BLI_bitmap *grid_hidden = dm->getGridHidden(dm);
210 for (i = 0; i < unode->totgrid; i++) {
212 unode->grid_hidden[i],
213 grid_hidden[unode->grids[i]]);
221 static int sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNode *unode)
223 Object *ob = CTX_data_active_object(C);
224 SculptSession *ss = ob->sculpt;
229 if (unode->maxvert) {
230 /* regular mesh restore */
232 index = unode->index;
236 for (i = 0; i < unode->totvert; i++) {
237 SWAP(float, vmask[index[i]], unode->mask[i]);
238 mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
241 else if (unode->maxgrid && dm->getGridData) {
242 /* multires restore */
243 CCGElem **grids, *grid;
248 grids = dm->getGridData(dm);
249 gridsize = dm->getGridSize(dm);
250 dm->getGridKey(dm, &key);
253 for (j = 0; j < unode->totgrid; j++) {
254 grid = grids[unode->grids[j]];
256 for (i = 0; i < gridsize * gridsize; i++, mask++)
257 SWAP(float, *CCG_elem_offset_mask(&key, grid, i), *mask);
264 static void sculpt_undo_restore(bContext *C, ListBase *lb)
266 Scene *scene = CTX_data_scene(C);
267 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
268 Object *ob = CTX_data_active_object(C);
269 DerivedMesh *dm = mesh_get_derived_final(scene, ob, 0);
270 SculptSession *ss = ob->sculpt;
271 SculptUndoNode *unode;
272 MultiresModifierData *mmd;
273 int update = FALSE, rebuild = FALSE;
275 sculpt_update_mesh_elements(scene, sd, ob, 0);
277 for (unode = lb->first; unode; unode = unode->next) {
278 if (!(strcmp(unode->idname, ob->id.name) == 0))
281 /* check if undo data matches current data well enough to
283 if (unode->maxvert) {
284 if (ss->totvert != unode->maxvert)
287 else if (unode->maxgrid && dm->getGridData) {
288 if ((dm->getNumGrids(dm) != unode->maxgrid) ||
289 (dm->getGridSize(dm) != unode->gridsize))
298 switch (unode->type) {
299 case SCULPT_UNDO_COORDS:
300 if (sculpt_undo_restore_coords(C, dm, unode))
303 case SCULPT_UNDO_HIDDEN:
304 if (sculpt_undo_restore_hidden(C, dm, unode))
307 case SCULPT_UNDO_MASK:
308 if (sculpt_undo_restore_mask(C, dm, unode))
314 if (update || rebuild) {
316 /* we update all nodes still, should be more clever, but also
317 * needs to work correct when exiting/entering sculpt mode and
318 * the nodes get recreated, though in that case it could do all */
319 BLI_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
320 BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
322 if ((mmd = sculpt_multires_active(scene, ob))) {
324 multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED);
326 multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
329 tag_update = ((Mesh *)ob->data)->id.us > 1;
331 if (ss->modifiers_active) {
332 Mesh *mesh = ob->data;
333 BKE_mesh_calc_normals_tessface(mesh->mvert, mesh->totvert,
334 mesh->mface, mesh->totface, NULL);
336 free_sculptsession_deformMats(ss);
341 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
343 /* for non-PBVH drawing, need to recreate VBOs */
344 GPU_drawobject_free(ob->derivedFinal);
348 static void sculpt_undo_free(ListBase *lb)
350 SculptUndoNode *unode;
353 for (unode = lb->first; unode; unode = unode->next) {
355 MEM_freeN(unode->co);
357 MEM_freeN(unode->no);
359 MEM_freeN(unode->index);
361 MEM_freeN(unode->grids);
362 if (unode->layer_disp)
363 MEM_freeN(unode->layer_disp);
365 MEM_freeN(unode->orig_co);
366 if (unode->vert_hidden)
367 MEM_freeN(unode->vert_hidden);
368 if (unode->grid_hidden) {
369 for (i = 0; i < unode->totgrid; i++) {
370 if (unode->grid_hidden[i])
371 MEM_freeN(unode->grid_hidden[i]);
373 MEM_freeN(unode->grid_hidden);
376 MEM_freeN(unode->mask);
380 SculptUndoNode *sculpt_undo_get_node(PBVHNode *node)
382 ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
388 return BLI_findptr(lb, node, offsetof(SculptUndoNode, node));
391 static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh,
392 SculptUndoNode *unode)
394 PBVHNode *node = unode->node;
395 BLI_bitmap *grid_hidden;
396 int i, *grid_indices, totgrid;
398 grid_hidden = BLI_pbvh_grid_hidden(pbvh);
400 BLI_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid,
401 NULL, NULL, NULL, NULL);
403 unode->grid_hidden = MEM_mapallocN(sizeof(BLI_bitmap) * totgrid,
404 "unode->grid_hidden");
406 for (i = 0; i < totgrid; i++) {
407 if (grid_hidden[grid_indices[i]])
408 unode->grid_hidden[i] = MEM_dupallocN(grid_hidden[grid_indices[i]]);
410 unode->grid_hidden[i] = NULL;
414 static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
417 ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
418 SculptUndoNode *unode;
419 SculptSession *ss = ob->sculpt;
420 int totvert, allvert, totgrid, maxgrid, gridsize, *grids;
422 unode = MEM_callocN(sizeof(SculptUndoNode), "SculptUndoNode");
423 BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
427 BLI_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
428 BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
429 &maxgrid, &gridsize, NULL, NULL);
431 unode->totvert = totvert;
433 /* we will use this while sculpting, is mapalloc slow to access then? */
435 /* general TODO, fix count_alloc */
437 case SCULPT_UNDO_COORDS:
438 unode->co = MEM_mapallocN(sizeof(float) * 3 * allvert, "SculptUndoNode.co");
439 unode->no = MEM_mapallocN(sizeof(short) * 3 * allvert, "SculptUndoNode.no");
440 undo_paint_push_count_alloc(UNDO_PAINT_MESH,
443 sizeof(int)) * allvert);
445 case SCULPT_UNDO_HIDDEN:
447 sculpt_undo_alloc_and_store_hidden(ss->pbvh, unode);
449 unode->vert_hidden = BLI_BITMAP_NEW(allvert, "SculptUndoNode.vert_hidden");
452 case SCULPT_UNDO_MASK:
453 unode->mask = MEM_mapallocN(sizeof(float) * allvert, "SculptUndoNode.mask");
454 undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float) * sizeof(int)) * allvert);
458 BLI_addtail(lb, unode);
462 unode->maxgrid = maxgrid;
463 unode->totgrid = totgrid;
464 unode->gridsize = gridsize;
465 unode->grids = MEM_mapallocN(sizeof(int) * totgrid, "SculptUndoNode.grids");
469 unode->maxvert = ss->totvert;
470 unode->index = MEM_mapallocN(sizeof(int) * allvert, "SculptUndoNode.index");
473 if (ss->modifiers_active)
474 unode->orig_co = MEM_callocN(allvert * sizeof(*unode->orig_co), "undoSculpt orig_cos");
479 static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
481 SculptSession *ss = ob->sculpt;
484 BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
486 copy_v3_v3(unode->co[vd.i], vd.co);
487 if (vd.no) copy_v3_v3_short(unode->no[vd.i], vd.no);
488 else normal_float_to_short_v3(unode->no[vd.i], vd.fno);
490 if (ss->modifiers_active)
491 copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]);
493 BLI_pbvh_vertex_iter_end;
496 static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
498 PBVH *pbvh = ob->sculpt->pbvh;
499 PBVHNode *node = unode->node;
502 /* already stored during allocation */
506 int *vert_indices, allvert;
509 BLI_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
510 BLI_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
511 for (i = 0; i < allvert; i++) {
512 BLI_BITMAP_MODIFY(unode->vert_hidden, i,
513 mvert[vert_indices[i]].flag & ME_HIDE);
518 static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
520 SculptSession *ss = ob->sculpt;
523 BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL)
525 unode->mask[vd.i] = *vd.mask;
527 BLI_pbvh_vertex_iter_end;
530 SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
533 SculptSession *ss = ob->sculpt;
534 SculptUndoNode *unode;
536 /* list is manipulated by multiple threads, so we lock */
537 BLI_lock_thread(LOCK_CUSTOM1);
539 if ((unode = sculpt_undo_get_node(node))) {
540 BLI_unlock_thread(LOCK_CUSTOM1);
544 unode = sculpt_undo_alloc_node(ob, node, type);
546 BLI_unlock_thread(LOCK_CUSTOM1);
548 /* copy threaded, hopefully this is the performance critical part */
552 BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
553 NULL, NULL, NULL, NULL);
554 memcpy(unode->grids, grids, sizeof(int) * totgrid);
557 int *vert_indices, allvert;
558 BLI_pbvh_node_num_verts(ss->pbvh, node, NULL, &allvert);
559 BLI_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL);
560 memcpy(unode->index, vert_indices, sizeof(int) * unode->totvert);
564 case SCULPT_UNDO_COORDS:
565 sculpt_undo_store_coords(ob, unode);
567 case SCULPT_UNDO_HIDDEN:
568 sculpt_undo_store_hidden(ob, unode);
570 case SCULPT_UNDO_MASK:
571 sculpt_undo_store_mask(ob, unode);
575 /* store active shape key */
576 if (ss->kb) BLI_strncpy(unode->shapeName, ss->kb->name, sizeof(ss->kb->name));
577 else unode->shapeName[0] = '\0';
582 void sculpt_undo_push_begin(const char *name)
584 undo_paint_push_begin(UNDO_PAINT_MESH, name,
585 sculpt_undo_restore, sculpt_undo_free);
588 void sculpt_undo_push_end(void)
590 ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
591 SculptUndoNode *unode;
593 /* we don't need normals in the undo stack */
594 for (unode = lb->first; unode; unode = unode->next) {
596 MEM_freeN(unode->no);
600 if (unode->layer_disp) {
601 MEM_freeN(unode->layer_disp);
602 unode->layer_disp = NULL;
606 undo_paint_push_end(UNDO_PAINT_MESH);