Do not lock key whn undoing to another shapekey while sculpting
[blender-staging.git] / source / blender / editors / sculpt_paint / sculpt_undo.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software  Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2006 by Nicholas Bishop
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  * Implements the Sculpt Mode tools
30  *
31  */
32
33 /** \file blender/editors/sculpt_paint/sculpt_undo.c
34  *  \ingroup edsculpt
35  */
36
37
38 #include "MEM_guardedalloc.h"
39
40 #include "BLI_math.h"
41 #include "BLI_utildefines.h"
42 #include "BLI_ghash.h"
43 #include "BLI_threads.h"
44
45 #include "DNA_meshdata_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_scene_types.h"
48 #include "DNA_mesh_types.h"
49
50 #include "BKE_cdderivedmesh.h"
51 #include "BKE_context.h"
52 #include "BKE_depsgraph.h"
53 #include "BKE_modifier.h"
54 #include "BKE_multires.h"
55 #include "BKE_paint.h"
56 #include "BKE_key.h"
57 #include "BKE_mesh.h"
58
59 #include "WM_api.h"
60 #include "WM_types.h"
61
62 #include "GPU_buffers.h"
63
64 #include "ED_sculpt.h"
65 #include "paint_intern.h"
66 #include "sculpt_intern.h"
67
68 /************************** Undo *************************/
69
70 static void update_cb(PBVHNode *node, void *unused)
71 {
72         (void)unused;
73         BLI_pbvh_node_mark_update(node);
74 }
75
76 static void sculpt_restore_deformed(SculptSession *ss, SculptUndoNode *unode, int uindex, int oindex, float coord[3])
77 {
78         if(unode->orig_co) {
79                 swap_v3_v3(coord, unode->orig_co[uindex]);
80                 copy_v3_v3(unode->co[uindex], ss->deform_cos[oindex]);
81         } else swap_v3_v3(coord, unode->co[uindex]);
82 }
83
84 static void sculpt_undo_restore(bContext *C, ListBase *lb)
85 {
86         Scene *scene = CTX_data_scene(C);
87         Object *ob = CTX_data_active_object(C);
88         DerivedMesh *dm = mesh_get_derived_final(scene, ob, 0);
89         SculptSession *ss = ob->sculpt;
90         SculptUndoNode *unode;
91         MVert *mvert;
92         MultiresModifierData *mmd;
93         int *index;
94         int i, j, update= 0;
95
96         sculpt_update_mesh_elements(scene, ob, 0);
97
98         for(unode=lb->first; unode; unode=unode->next) {
99                 if(!(strcmp(unode->idname, ob->id.name)==0))
100                         continue;
101
102                 if(unode->maxvert) {
103                         /* regular mesh restore */
104                         if(ss->totvert != unode->maxvert)
105                                 continue;
106
107                         if (ss->kb && strcmp(ss->kb->name, unode->shapeName)) {
108                                 /* shape key has been changed before calling undo operator */
109
110                                 Key *key= ob_get_key(ob);
111                                 KeyBlock *kb= key_get_named_keyblock(key, unode->shapeName);
112
113                                 if (kb) {
114                                         ob->shapenr= BLI_findindex(&key->block, kb) + 1;
115
116                                         sculpt_update_mesh_elements(scene, ob, 0);
117                                         WM_event_add_notifier(C, NC_OBJECT|ND_DATA, ob);
118                                 } else {
119                                         /* key has been removed -- skip this undo node */
120                                         continue;
121                                 }
122                         }
123
124                         index= unode->index;
125                         mvert= ss->mvert;
126
127                         if (ss->kb) {
128                                 float (*vertCos)[3];
129                                 vertCos= key_to_vertcos(ob, ss->kb);
130
131                                 for(i=0; i<unode->totvert; i++) {
132                                         if(ss->modifiers_active) sculpt_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
133                                         else {
134                                                 if(unode->orig_co) swap_v3_v3(vertCos[index[i]], unode->orig_co[i]);
135                                                 else swap_v3_v3(vertCos[index[i]], unode->co[i]);
136                                         }
137                                 }
138
139                                 /* propagate new coords to keyblock */
140                                 sculpt_vertcos_to_key(ob, ss->kb, vertCos);
141
142                                 /* pbvh uses it's own mvert array, so coords should be */
143                                 /* propagated to pbvh here */
144                                 BLI_pbvh_apply_vertCos(ss->pbvh, vertCos);
145
146                                 MEM_freeN(vertCos);
147                         } else {
148                                 for(i=0; i<unode->totvert; i++) {
149                                         if(ss->modifiers_active) sculpt_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
150                                         else {
151                                                 if(unode->orig_co) swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]);
152                                                 else swap_v3_v3(mvert[index[i]].co, unode->co[i]);
153                                         }
154                                         mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
155                                 }
156                         }
157                 }
158                 else if(unode->maxgrid && dm->getGridData) {
159                         /* multires restore */
160                         DMGridData **grids, *grid;
161                         float (*co)[3];
162                         int gridsize;
163
164                         if(dm->getNumGrids(dm) != unode->maxgrid)
165                                 continue;
166                         if(dm->getGridSize(dm) != unode->gridsize)
167                                 continue;
168
169                         grids= dm->getGridData(dm);
170                         gridsize= dm->getGridSize(dm);
171
172                         co = unode->co;
173                         for(j=0; j<unode->totgrid; j++) {
174                                 grid= grids[unode->grids[j]];
175
176                                 for(i=0; i<gridsize*gridsize; i++, co++)
177                                         swap_v3_v3(grid[i].co, co[0]);
178                         }
179                 }
180
181                 update= 1;
182         }
183
184         if(update) {
185                 int tag_update= 0;
186                 /* we update all nodes still, should be more clever, but also
187                    needs to work correct when exiting/entering sculpt mode and
188                    the nodes get recreated, though in that case it could do all */
189                 BLI_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, NULL);
190                 BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw, NULL);
191
192                 if((mmd=sculpt_multires_active(scene, ob)))
193                         multires_mark_as_modified(ob);
194
195                 tag_update= ((Mesh*)ob->data)->id.us > 1;
196
197                 if(ss->modifiers_active) {
198                         Mesh *me= ob->data;
199                         mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
200
201                         sculpt_free_deformMats(ss);
202                         tag_update|= 1;
203                 }
204
205                 if(tag_update)
206                         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
207
208                 /* for non-PBVH drawing, need to recreate VBOs */
209                 GPU_drawobject_free(ob->derivedFinal);
210         }
211 }
212
213 static void sculpt_undo_free(ListBase *lb)
214 {
215         SculptUndoNode *unode;
216
217         for(unode=lb->first; unode; unode=unode->next) {
218                 if(unode->co)
219                         MEM_freeN(unode->co);
220                 if(unode->no)
221                         MEM_freeN(unode->no);
222                 if(unode->index)
223                         MEM_freeN(unode->index);
224                 if(unode->grids)
225                         MEM_freeN(unode->grids);
226                 if(unode->layer_disp)
227                         MEM_freeN(unode->layer_disp);
228                 if(unode->orig_co)
229                         MEM_freeN(unode->orig_co);
230         }
231 }
232
233 SculptUndoNode *sculpt_undo_get_node(PBVHNode *node)
234 {
235         ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
236         SculptUndoNode *unode;
237
238         if(!lb)
239                 return NULL;
240
241         for(unode=lb->first; unode; unode=unode->next)
242                 if(unode->node == node)
243                         return unode;
244
245         return NULL;
246 }
247
248 SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node)
249 {
250         ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
251         SculptSession *ss = ob->sculpt;
252         SculptUndoNode *unode;
253         int totvert, allvert, totgrid, maxgrid, gridsize, *grids;
254
255         /* list is manipulated by multiple threads, so we lock */
256         BLI_lock_thread(LOCK_CUSTOM1);
257
258         if((unode= sculpt_undo_get_node(node))) {
259                 BLI_unlock_thread(LOCK_CUSTOM1);
260                 return unode;
261         }
262
263         unode= MEM_callocN(sizeof(SculptUndoNode), "SculptUndoNode");
264         strcpy(unode->idname, ob->id.name);
265         unode->node= node;
266
267         BLI_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
268         BLI_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
269                 &maxgrid, &gridsize, NULL, NULL);
270
271         unode->totvert= totvert;
272         /* we will use this while sculpting, is mapalloc slow to access then? */
273         unode->co= MEM_mapallocN(sizeof(float)*3*allvert, "SculptUndoNode.co");
274         unode->no= MEM_mapallocN(sizeof(short)*3*allvert, "SculptUndoNode.no");
275         undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float)*3 + sizeof(short)*3 + sizeof(int))*allvert);
276         BLI_addtail(lb, unode);
277
278         if(maxgrid) {
279                 /* multires */
280                 unode->maxgrid= maxgrid;
281                 unode->totgrid= totgrid;
282                 unode->gridsize= gridsize;
283                 unode->grids= MEM_mapallocN(sizeof(int)*totgrid, "SculptUndoNode.grids");
284         }
285         else {
286                 /* regular mesh */
287                 unode->maxvert= ss->totvert;
288                 unode->index= MEM_mapallocN(sizeof(int)*allvert, "SculptUndoNode.index");
289         }
290
291         if(ss->modifiers_active)
292                 unode->orig_co= MEM_callocN(allvert*sizeof(*unode->orig_co), "undoSculpt orig_cos");
293
294         BLI_unlock_thread(LOCK_CUSTOM1);
295
296         /* copy threaded, hopefully this is the performance critical part */
297         {
298                 PBVHVertexIter vd;
299
300                 BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL) {
301                         copy_v3_v3(unode->co[vd.i], vd.co);
302                         if(vd.no) VECCOPY(unode->no[vd.i], vd.no)
303                         else normal_float_to_short_v3(unode->no[vd.i], vd.fno);
304                         if(vd.vert_indices) unode->index[vd.i]= vd.vert_indices[vd.i];
305
306                         if(ss->modifiers_active)
307                                 copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]);
308                 }
309                 BLI_pbvh_vertex_iter_end;
310         }
311
312         if(unode->grids)
313                 memcpy(unode->grids, grids, sizeof(int)*totgrid);
314
315         /* store active shape key */
316         if(ss->kb) BLI_strncpy(unode->shapeName, ss->kb->name, sizeof(ss->kb->name));
317         else unode->shapeName[0]= '\0';
318
319         return unode;
320 }
321
322 void sculpt_undo_push_begin(const char *name)
323 {
324         undo_paint_push_begin(UNDO_PAINT_MESH, name,
325                 sculpt_undo_restore, sculpt_undo_free);
326 }
327
328 void sculpt_undo_push_end(void)
329 {
330         ListBase *lb= undo_paint_push_get_list(UNDO_PAINT_MESH);
331         SculptUndoNode *unode;
332
333         /* we don't need normals in the undo stack */
334         for(unode=lb->first; unode; unode=unode->next) {
335                 if(unode->no) {
336                         MEM_freeN(unode->no);
337                         unode->no= NULL;
338                 }
339
340                 if(unode->layer_disp) {
341                         MEM_freeN(unode->layer_disp);
342                         unode->layer_disp= NULL;
343                 }
344         }
345
346         undo_paint_push_end(UNDO_PAINT_MESH);
347 }