Blender  V2.93
sculpt_undo.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2006 by Nicholas Bishop
17  * All rights reserved.
18  * Implements the Sculpt Mode tools
19  */
20 
25 #include <stddef.h>
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "BLI_ghash.h"
30 #include "BLI_listbase.h"
31 #include "BLI_math.h"
32 #include "BLI_string.h"
33 #include "BLI_task.h"
34 #include "BLI_threads.h"
35 #include "BLI_utildefines.h"
36 
37 #include "DNA_mesh_types.h"
38 #include "DNA_meshdata_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_screen_types.h"
42 
43 #include "BKE_ccg.h"
44 #include "BKE_context.h"
45 #include "BKE_customdata.h"
46 #include "BKE_global.h"
47 #include "BKE_key.h"
48 #include "BKE_main.h"
49 #include "BKE_mesh.h"
50 #include "BKE_multires.h"
51 #include "BKE_object.h"
52 #include "BKE_paint.h"
53 #include "BKE_scene.h"
54 #include "BKE_subdiv_ccg.h"
55 #include "BKE_subsurf.h"
56 #include "BKE_undo_system.h"
57 
58 /* TODO(sergey): Ideally should be no direct call to such low level things. */
59 #include "BKE_subdiv_eval.h"
60 
61 #include "DEG_depsgraph.h"
62 
63 #include "WM_api.h"
64 #include "WM_types.h"
65 
66 #include "ED_object.h"
67 #include "ED_sculpt.h"
68 #include "ED_undo.h"
69 
70 #include "bmesh.h"
71 #include "sculpt_intern.h"
72 
73 /* Implementation of undo system for objects in sculpt mode.
74  *
75  * Each undo step in sculpt mode consists of list of nodes, each node contains:
76  * - Node type
77  * - Data for this type.
78  *
79  * Node type used for undo depends on specific operation and active sculpt mode
80  * ("regular" or dynamic topology).
81  *
82  * Regular sculpt brushes will use COORDS, HIDDEN or MASK nodes. These nodes are
83  * created for every BVH node which is affected by the brush. The undo push for
84  * the node happens BEFORE modifications. This makes the operation undo to work
85  * in the following way: for every node in the undo step swap happens between
86  * node in the undo stack and the corresponding value in the BVH. This is how
87  * redo is possible after undo.
88  *
89  * The COORDS, HIDDEN or MASK type of nodes contains arrays of the corresponding
90  * values.
91  *
92  * Operations like Symmetrize are using GEOMETRY type of nodes which pushes the
93  * entire state of the mesh to the undo stack. This node contains all CustomData
94  * layers.
95  *
96  * The tricky aspect of this undo node type is that it stores mesh before and
97  * after modification. This allows the undo system to both undo and redo the
98  * symmetrize operation within the pre-modified-push of other node type
99  * behavior, but it uses more memory that it seems it should be.
100  *
101  * The dynamic topology undo nodes are handled somewhat separately from all
102  * other ones and the idea there is to store log of operations: which vertices
103  * and faces have been added or removed.
104  *
105  * Begin of dynamic topology sculpting mode have own node type. It contains an
106  * entire copy of mesh since just enabling the dynamic topology mode already
107  * does modifications on it.
108  *
109  * End of dynamic topology and symmetrize in this mode are handled in a special
110  * manner as well. */
111 
112 typedef struct UndoSculpt {
114 
115  size_t undo_size;
117 
118 static UndoSculpt *sculpt_undo_get_nodes(void);
119 
120 static void update_cb(PBVHNode *node, void *rebuild)
121 {
124  if (*((bool *)rebuild)) {
126  }
128 }
129 
132  bool rebuild;
134 };
135 
139 static void update_cb_partial(PBVHNode *node, void *userdata)
140 {
141  struct PartialUpdateData *data = userdata;
142  if (BKE_pbvh_type(data->pbvh) == PBVH_GRIDS) {
143  int *node_grid_indices;
144  int totgrid;
145  bool update = false;
146  BKE_pbvh_node_get_grids(data->pbvh, node, &node_grid_indices, &totgrid, NULL, NULL, NULL);
147  for (int i = 0; i < totgrid; i++) {
148  if (data->modified_grids[node_grid_indices[i]] == 1) {
149  update = true;
150  }
151  }
152  if (update) {
153  update_cb(node, &(data->rebuild));
154  }
155  }
156  else {
158  update_cb(node, &(data->rebuild));
159  }
160  }
161 }
162 
163 static bool test_swap_v3_v3(float a[3], float b[3])
164 {
165  /* No need for float comparison here (memory is exactly equal or not). */
166  if (memcmp(a, b, sizeof(float[3])) != 0) {
167  swap_v3_v3(a, b);
168  return true;
169  }
170  return false;
171 }
172 
174  const SculptSession *ss, SculptUndoNode *unode, int uindex, int oindex, float coord[3])
175 {
176  if (test_swap_v3_v3(coord, unode->orig_co[uindex])) {
177  copy_v3_v3(unode->co[uindex], ss->deform_cos[oindex]);
178  return true;
179  }
180  return false;
181 }
182 
184 {
185  ViewLayer *view_layer = CTX_data_view_layer(C);
186  Object *ob = OBACT(view_layer);
187  SculptSession *ss = ob->sculpt;
188  SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
189  MVert *mvert;
190  int *index;
191 
192  if (unode->maxvert) {
193  /* Regular mesh restore. */
194 
195  if (ss->shapekey_active && !STREQ(ss->shapekey_active->name, unode->shapeName)) {
196  /* Shape key has been changed before calling undo operator. */
197 
198  Key *key = BKE_key_from_object(ob);
199  KeyBlock *kb = key ? BKE_keyblock_find_name(key, unode->shapeName) : NULL;
200 
201  if (kb) {
202  ob->shapenr = BLI_findindex(&key->block, kb) + 1;
203 
204  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
206  }
207  else {
208  /* Key has been removed -- skip this undo node. */
209  return false;
210  }
211  }
212 
213  /* No need for float comparison here (memory is exactly equal or not). */
214  index = unode->index;
215  mvert = ss->mvert;
216 
217  if (ss->shapekey_active) {
218  float(*vertCos)[3];
220 
221  if (unode->orig_co) {
222  if (ss->deform_modifiers_active) {
223  for (int i = 0; i < unode->totvert; i++) {
224  sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
225  }
226  }
227  else {
228  for (int i = 0; i < unode->totvert; i++) {
229  swap_v3_v3(vertCos[index[i]], unode->orig_co[i]);
230  }
231  }
232  }
233  else {
234  for (int i = 0; i < unode->totvert; i++) {
235  swap_v3_v3(vertCos[index[i]], unode->co[i]);
236  }
237  }
238 
239  /* Propagate new coords to keyblock. */
240  SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
241 
242  /* PBVH uses its own mvert array, so coords should be */
243  /* propagated to PBVH here. */
245 
246  MEM_freeN(vertCos);
247  }
248  else {
249  if (unode->orig_co) {
250  if (ss->deform_modifiers_active) {
251  for (int i = 0; i < unode->totvert; i++) {
252  sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
253  mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
254  }
255  }
256  else {
257  for (int i = 0; i < unode->totvert; i++) {
258  swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]);
259  mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
260  }
261  }
262  }
263  else {
264  for (int i = 0; i < unode->totvert; i++) {
265  swap_v3_v3(mvert[index[i]].co, unode->co[i]);
266  mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
267  }
268  }
269  }
270  }
271  else if (unode->maxgrid && subdiv_ccg != NULL) {
272  /* Multires restore. */
273  CCGElem **grids, *grid;
274  CCGKey key;
275  float(*co)[3];
276  int gridsize;
277 
278  grids = subdiv_ccg->grids;
279  gridsize = subdiv_ccg->grid_size;
280  BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
281 
282  co = unode->co;
283  for (int j = 0; j < unode->totgrid; j++) {
284  grid = grids[unode->grids[j]];
285 
286  for (int i = 0; i < gridsize * gridsize; i++, co++) {
287  swap_v3_v3(CCG_elem_offset_co(&key, grid, i), co[0]);
288  }
289  }
290  }
291 
292  return true;
293 }
294 
296 {
297  ViewLayer *view_layer = CTX_data_view_layer(C);
298  Object *ob = OBACT(view_layer);
299  SculptSession *ss = ob->sculpt;
300  SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
301 
302  if (unode->maxvert) {
303  MVert *mvert = ss->mvert;
304 
305  for (int i = 0; i < unode->totvert; i++) {
306  MVert *v = &mvert[unode->index[i]];
307  if ((BLI_BITMAP_TEST(unode->vert_hidden, i) != 0) != ((v->flag & ME_HIDE) != 0)) {
308  BLI_BITMAP_FLIP(unode->vert_hidden, i);
309  v->flag ^= ME_HIDE;
310  v->flag |= ME_VERT_PBVH_UPDATE;
311  }
312  }
313  }
314  else if (unode->maxgrid && subdiv_ccg != NULL) {
315  BLI_bitmap **grid_hidden = subdiv_ccg->grid_hidden;
316 
317  for (int i = 0; i < unode->totgrid; i++) {
318  SWAP(BLI_bitmap *, unode->grid_hidden[i], grid_hidden[unode->grids[i]]);
319  }
320  }
321 
322  return true;
323 }
324 
326 {
327  ViewLayer *view_layer = CTX_data_view_layer(C);
328  Object *ob = OBACT(view_layer);
329  SculptSession *ss = ob->sculpt;
330 
331  if (unode->maxvert) {
332  /* regular mesh restore */
333  int *index = unode->index;
334  MVert *mvert = ss->mvert;
335  MPropCol *vcol = ss->vcol;
336 
337  for (int i = 0; i < unode->totvert; i++) {
338  copy_v4_v4(vcol[index[i]].color, unode->col[i]);
339  mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
340  }
341  }
342  return true;
343 }
344 
346 {
347  ViewLayer *view_layer = CTX_data_view_layer(C);
348  Object *ob = OBACT(view_layer);
349  SculptSession *ss = ob->sculpt;
350  SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
351  MVert *mvert;
352  float *vmask;
353  int *index;
354 
355  if (unode->maxvert) {
356  /* Regular mesh restore. */
357 
358  index = unode->index;
359  mvert = ss->mvert;
360  vmask = ss->vmask;
361 
362  for (int i = 0; i < unode->totvert; i++) {
363  if (vmask[index[i]] != unode->mask[i]) {
364  SWAP(float, vmask[index[i]], unode->mask[i]);
365  mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
366  }
367  }
368  }
369  else if (unode->maxgrid && subdiv_ccg != NULL) {
370  /* Multires restore. */
371  CCGElem **grids, *grid;
372  CCGKey key;
373  float *mask;
374  int gridsize;
375 
376  grids = subdiv_ccg->grids;
377  gridsize = subdiv_ccg->grid_size;
378  BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
379 
380  mask = unode->mask;
381  for (int j = 0; j < unode->totgrid; j++) {
382  grid = grids[unode->grids[j]];
383 
384  for (int i = 0; i < gridsize * gridsize; i++, mask++) {
385  SWAP(float, *CCG_elem_offset_mask(&key, grid, i), *mask);
386  }
387  }
388  }
389 
390  return true;
391 }
392 
394 {
395  ViewLayer *view_layer = CTX_data_view_layer(C);
396  Object *ob = OBACT(view_layer);
398  int *face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
399  for (int i = 0; i < me->totpoly; i++) {
400  face_sets[i] = unode->face_sets[i];
401  }
402  return false;
403 }
404 
406  void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
407 {
408  PBVHNode **nodes = userdata;
409 
410  BKE_pbvh_node_mark_redraw(nodes[n]);
411 }
412 
414 {
415  if (unode->applied) {
416  BM_log_undo(ss->bm, ss->bm_log);
417  unode->applied = false;
418  }
419  else {
420  BM_log_redo(ss->bm, ss->bm_log);
421  unode->applied = true;
422  }
423 
424  if (unode->type == SCULPT_UNDO_MASK) {
425  int totnode;
426  PBVHNode **nodes;
427 
428  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
429 
430  TaskParallelSettings settings;
431  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
433  0, totnode, nodes, sculpt_undo_bmesh_restore_generic_task_cb, &settings);
434 
435  if (nodes) {
436  MEM_freeN(nodes);
437  }
438  }
439  else {
440  SCULPT_pbvh_clear(ob);
441  }
442 }
443 
444 /* Create empty sculpt BMesh and enable logging. */
446 {
447  SculptSession *ss = ob->sculpt;
448  Mesh *me = ob->data;
449 
450  SCULPT_pbvh_clear(ob);
451 
452  /* Create empty BMesh and enable logging. */
454  &((struct BMeshCreateParams){
455  .use_toolflags = false,
456  }));
460 
461  /* Restore the BMLog using saved entries. */
463 }
464 
466  SculptUndoNode *unode,
467  Object *ob,
468  SculptSession *ss)
469 {
470  if (unode->applied) {
472  unode->applied = false;
473  }
474  else {
475  sculpt_undo_bmesh_enable(ob, unode);
476 
477  /* Restore the mesh from the first log entry. */
478  BM_log_redo(ss->bm, ss->bm_log);
479 
480  unode->applied = true;
481  }
482 }
483 
485  SculptUndoNode *unode,
486  Object *ob,
487  SculptSession *ss)
488 {
489  if (unode->applied) {
490  sculpt_undo_bmesh_enable(ob, unode);
491 
492  /* Restore the mesh from the last log entry. */
493  BM_log_undo(ss->bm, ss->bm_log);
494 
495  unode->applied = false;
496  }
497  else {
498  /* Disable dynamic topology sculpting. */
500  unode->applied = true;
501  }
502 }
503 
505 {
506  Mesh *mesh = object->data;
507 
508  BLI_assert(!geometry->is_initialized);
509  geometry->is_initialized = true;
510 
515 
516  geometry->totvert = mesh->totvert;
517  geometry->totedge = mesh->totedge;
518  geometry->totloop = mesh->totloop;
519  geometry->totpoly = mesh->totpoly;
520 }
521 
523 {
524  Mesh *mesh = object->data;
525 
526  BLI_assert(geometry->is_initialized);
527 
528  CustomData_free(&mesh->vdata, mesh->totvert);
529  CustomData_free(&mesh->edata, mesh->totedge);
532  CustomData_free(&mesh->pdata, mesh->totpoly);
533 
534  mesh->totvert = geometry->totvert;
535  mesh->totedge = geometry->totedge;
536  mesh->totloop = geometry->totloop;
537  mesh->totpoly = geometry->totpoly;
538  mesh->totface = 0;
539 
541  &geometry->vdata, &mesh->vdata, CD_MASK_MESH.vmask, CD_DUPLICATE, geometry->totvert);
543  &geometry->edata, &mesh->edata, CD_MASK_MESH.emask, CD_DUPLICATE, geometry->totedge);
545  &geometry->ldata, &mesh->ldata, CD_MASK_MESH.lmask, CD_DUPLICATE, geometry->totloop);
547  &geometry->pdata, &mesh->pdata, CD_MASK_MESH.pmask, CD_DUPLICATE, geometry->totpoly);
548 
550 }
551 
553 {
554  if (geometry->totvert) {
555  CustomData_free(&geometry->vdata, geometry->totvert);
556  }
557  if (geometry->totedge) {
558  CustomData_free(&geometry->edata, geometry->totedge);
559  }
560  if (geometry->totloop) {
561  CustomData_free(&geometry->ldata, geometry->totloop);
562  }
563  if (geometry->totpoly) {
564  CustomData_free(&geometry->pdata, geometry->totpoly);
565  }
566 }
567 
569 {
570  if (unode->geometry_clear_pbvh) {
571  SCULPT_pbvh_clear(object);
572  }
573 
574  if (unode->applied) {
576  unode->applied = false;
577  }
578  else {
580  unode->applied = true;
581  }
582 }
583 
584 /* Handle all dynamic-topology updates
585  *
586  * Returns true if this was a dynamic-topology undo step, otherwise
587  * returns false to indicate the non-dyntopo code should run. */
589  SculptUndoNode *unode,
590  Object *ob,
591  SculptSession *ss)
592 {
593  switch (unode->type) {
595  sculpt_undo_bmesh_restore_begin(C, unode, ob, ss);
596  return true;
597 
599  sculpt_undo_bmesh_restore_end(C, unode, ob, ss);
600  return true;
601  default:
602  if (ss->bm_log) {
603  sculpt_undo_bmesh_restore_generic(unode, ob, ss);
604  return true;
605  }
606  break;
607  }
608 
609  return false;
610 }
611 
612 /* Geometry updates (such as Apply Base, for example) will re-evaluate the object and refine its
613  * Subdiv descriptor. Upon undo it is required that mesh, grids, and subdiv all stay consistent
614  * with each other. This means that when geometry coordinate changes the undo should refine the
615  * subdiv to the new coarse mesh coordinates. Tricky part is: this needs to happen without using
616  * dependency graph tag: tagging object for geometry update will either loose sculpted data from
617  * the sculpt grids, or will wrongly "commit" them to the CD_MDISPS.
618  *
619  * So what we do instead is do minimum object evaluation to get base mesh coordinates for the
620  * multires modifier input. While this is expensive, it is less expensive than dependency graph
621  * evaluation and is only happening when geometry coordinates changes on undo.
622  *
623  * Note that the dependency graph is ensured to be evaluated prior to the undo step is decoded,
624  * so if the object's modifier stack references other object it is all fine. */
626  SculptSession *ss,
627  Object *object,
628  struct Subdiv *subdiv)
629 {
631  depsgraph, object, ss->multires.modifier, NULL);
632 
633  BKE_subdiv_eval_refine_from_mesh(subdiv, object->data, deformed_verts);
634 
635  MEM_freeN(deformed_verts);
636 }
637 
639 {
641  ViewLayer *view_layer = CTX_data_view_layer(C);
642  View3D *v3d = CTX_wm_view3d(C);
643  Object *ob = OBACT(view_layer);
644  SculptSession *ss = ob->sculpt;
645  SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
646  SculptUndoNode *unode;
647  bool update = false, rebuild = false, update_mask = false, update_visibility = false;
648  bool need_mask = false;
649  bool need_refine_subdiv = false;
650 
651  for (unode = lb->first; unode; unode = unode->next) {
652  /* Restore pivot. */
653  copy_v3_v3(ss->pivot_pos, unode->pivot_pos);
654  copy_v3_v3(ss->pivot_rot, unode->pivot_rot);
655  if (STREQ(unode->idname, ob->id.name)) {
656  if (unode->type == SCULPT_UNDO_MASK) {
657  /* Is possible that we can't do the mask undo (below)
658  * because of the vertex count. */
659  need_mask = true;
660  break;
661  }
662  }
663  }
664 
666 
667  if (lb->first) {
668  unode = lb->first;
669  if (unode->type == SCULPT_UNDO_FACE_SETS) {
671 
672  rebuild = true;
674 
675  BKE_sculpt_update_object_for_edit(depsgraph, ob, true, need_mask, false);
676 
678 
680 
681  if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
683  }
684 
686  if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) {
688  }
689 
690  unode->applied = true;
691  return;
692  }
693  }
694 
695  if (lb->first != NULL) {
696  /* Only do early object update for edits if first node needs this.
697  * Undo steps like geometry does not need object to be updated before they run and will
698  * ensure object is updated after the node is handled. */
699  const SculptUndoNode *first_unode = (const SculptUndoNode *)lb->first;
700  if (first_unode->type != SCULPT_UNDO_GEOMETRY) {
701  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask, false);
702  }
703 
704  if (sculpt_undo_bmesh_restore(C, lb->first, ob, ss)) {
705  return;
706  }
707  }
708 
709  char *undo_modified_grids = NULL;
710  bool use_multires_undo = false;
711 
712  for (unode = lb->first; unode; unode = unode->next) {
713 
714  if (!STREQ(unode->idname, ob->id.name)) {
715  continue;
716  }
717 
718  /* Check if undo data matches current data well enough to
719  * continue. */
720  if (unode->maxvert) {
721  if (ss->totvert != unode->maxvert) {
722  continue;
723  }
724  }
725  else if (unode->maxgrid && subdiv_ccg != NULL) {
726  if ((subdiv_ccg->num_grids != unode->maxgrid) ||
727  (subdiv_ccg->grid_size != unode->gridsize)) {
728  continue;
729  }
730 
731  use_multires_undo = true;
732  }
733 
734  switch (unode->type) {
735  case SCULPT_UNDO_COORDS:
736  if (sculpt_undo_restore_coords(C, depsgraph, unode)) {
737  update = true;
738  }
739  break;
740  case SCULPT_UNDO_HIDDEN:
741  if (sculpt_undo_restore_hidden(C, unode)) {
742  rebuild = true;
743  update_visibility = true;
744  }
745  break;
746  case SCULPT_UNDO_MASK:
747  if (sculpt_undo_restore_mask(C, unode)) {
748  update = true;
749  update_mask = true;
750  }
751  break;
753  break;
754  case SCULPT_UNDO_COLOR:
755  if (sculpt_undo_restore_color(C, unode)) {
756  update = true;
757  }
758  break;
759 
761  need_refine_subdiv = true;
762  sculpt_undo_geometry_restore(unode, ob);
763  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask, false);
764  break;
765 
769  BLI_assert(!"Dynamic topology should've already been handled");
770  break;
771  }
772  }
773 
774  if (use_multires_undo) {
775  for (unode = lb->first; unode; unode = unode->next) {
776  if (!STREQ(unode->idname, ob->id.name)) {
777  continue;
778  }
779  if (unode->maxgrid == 0) {
780  continue;
781  }
782 
783  if (undo_modified_grids == NULL) {
784  undo_modified_grids = MEM_callocN(sizeof(char) * unode->maxgrid, "undo_grids");
785  }
786 
787  for (int i = 0; i < unode->totgrid; i++) {
788  undo_modified_grids[unode->grids[i]] = 1;
789  }
790  }
791  }
792 
793  if (subdiv_ccg != NULL && need_refine_subdiv) {
794  sculpt_undo_refine_subdiv(depsgraph, ss, ob, subdiv_ccg->subdiv);
795  }
796 
797  if (update || rebuild) {
798  bool tag_update = false;
799  /* We update all nodes still, should be more clever, but also
800  * needs to work correct when exiting/entering sculpt mode and
801  * the nodes get recreated, though in that case it could do all. */
802  struct PartialUpdateData data = {
803  .rebuild = rebuild,
804  .pbvh = ss->pbvh,
805  .modified_grids = undo_modified_grids,
806  };
809 
810  if (update_mask) {
812  }
813 
814  if (update_visibility) {
817  }
818 
820  if (rebuild) {
822  }
823  else {
825  }
826  }
827 
828  tag_update |= ID_REAL_USERS(ob->data) > 1 || !BKE_sculptsession_use_pbvh_draw(ob, v3d) ||
830 
831  if (tag_update) {
832  Mesh *mesh = ob->data;
834 
836  }
837 
838  if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && update_visibility) {
839  Mesh *mesh = ob->data;
841  }
842 
843  if (tag_update) {
845  }
846  else {
848  }
849  }
850 
851  MEM_SAFE_FREE(undo_modified_grids);
852 }
853 
855 {
856  SculptUndoNode *unode = lb->first;
857  while (unode != NULL) {
858  SculptUndoNode *unode_next = unode->next;
859  if (unode->co) {
860  MEM_freeN(unode->co);
861  }
862  if (unode->no) {
863  MEM_freeN(unode->no);
864  }
865  if (unode->index) {
866  MEM_freeN(unode->index);
867  }
868  if (unode->grids) {
869  MEM_freeN(unode->grids);
870  }
871  if (unode->orig_co) {
872  MEM_freeN(unode->orig_co);
873  }
874  if (unode->vert_hidden) {
875  MEM_freeN(unode->vert_hidden);
876  }
877  if (unode->grid_hidden) {
878  for (int i = 0; i < unode->totgrid; i++) {
879  if (unode->grid_hidden[i]) {
880  MEM_freeN(unode->grid_hidden[i]);
881  }
882  }
883  MEM_freeN(unode->grid_hidden);
884  }
885  if (unode->mask) {
886  MEM_freeN(unode->mask);
887  }
888 
889  if (unode->bm_entry) {
890  BM_log_entry_drop(unode->bm_entry);
891  }
892 
896 
897  if (unode->face_sets) {
898  MEM_freeN(unode->face_sets);
899  }
900 
901  MEM_freeN(unode);
902 
903  unode = unode_next;
904  }
905 }
906 
907 /* Most likely we don't need this. */
908 #if 0
909 static bool sculpt_undo_cleanup(bContext *C, ListBase *lb)
910 {
912  ViewLayer *view_layer = CTX_data_view_layer(C);
913  Object *ob = OBACT(view_layer);
914  SculptUndoNode *unode;
915 
916  unode = lb->first;
917 
918  if (unode && !STREQ(unode->idname, ob->id.name)) {
919  if (unode->bm_entry) {
921  }
922 
923  return true;
924  }
925 
926  return false;
927 }
928 #endif
929 
931 {
932  UndoSculpt *usculpt = sculpt_undo_get_nodes();
933 
934  if (usculpt == NULL) {
935  return NULL;
936  }
937 
938  return BLI_findptr(&usculpt->nodes, node, offsetof(SculptUndoNode, node));
939 }
940 
942 {
943  UndoSculpt *usculpt = sculpt_undo_get_nodes();
944 
945  if (usculpt == NULL) {
946  return NULL;
947  }
948 
949  return usculpt->nodes.first;
950 }
951 
953 {
954  PBVHNode *node = unode->node;
955  BLI_bitmap **grid_hidden = BKE_pbvh_grid_hidden(pbvh);
956 
957  int *grid_indices, totgrid;
958  BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, NULL);
959 
960  size_t alloc_size = sizeof(*unode->grid_hidden) * (size_t)totgrid;
961  unode->grid_hidden = MEM_callocN(alloc_size, "unode->grid_hidden");
962 
963  for (int i = 0; i < totgrid; i++) {
964  if (grid_hidden[grid_indices[i]]) {
965  unode->grid_hidden[i] = MEM_dupallocN(grid_hidden[grid_indices[i]]);
966  alloc_size += MEM_allocN_len(unode->grid_hidden[i]);
967  }
968  else {
969  unode->grid_hidden[i] = NULL;
970  }
971  }
972 
973  return alloc_size;
974 }
975 
976 /* Allocate node and initialize its default fields specific for the given undo type.
977  * Will also add the node to the list in the undo step. */
979 {
980  const size_t alloc_size = sizeof(SculptUndoNode);
981  SculptUndoNode *unode = MEM_callocN(alloc_size, "SculptUndoNode");
982  BLI_strncpy(unode->idname, object->id.name, sizeof(unode->idname));
983  unode->type = type;
984 
985  UndoSculpt *usculpt = sculpt_undo_get_nodes();
986  BLI_addtail(&usculpt->nodes, unode);
987  usculpt->undo_size += alloc_size;
988 
989  return unode;
990 }
991 
992 /* Will return first existing undo node of the given type.
993  * If such node does not exist will allocate node of this type, register it in the undo step and
994  * return it. */
996 {
997  UndoSculpt *usculpt = sculpt_undo_get_nodes();
998 
999  LISTBASE_FOREACH (SculptUndoNode *, unode, &usculpt->nodes) {
1000  if (unode->type == type) {
1001  return unode;
1002  }
1003  }
1004 
1005  return sculpt_undo_alloc_node_type(object, type);
1006 }
1007 
1009 {
1010  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1011  SculptSession *ss = ob->sculpt;
1012  int totvert = 0;
1013  int allvert = 0;
1014  int totgrid = 0;
1015  int maxgrid = 0;
1016  int gridsize = 0;
1017  int *grids = NULL;
1018 
1020  unode->node = node;
1021 
1022  if (node) {
1023  BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
1024  BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid, &maxgrid, &gridsize, NULL);
1025 
1026  unode->totvert = totvert;
1027  }
1028 
1029  switch (type) {
1030  case SCULPT_UNDO_COORDS: {
1031  size_t alloc_size = sizeof(*unode->co) * (size_t)allvert;
1032  unode->co = MEM_callocN(alloc_size, "SculptUndoNode.co");
1033  usculpt->undo_size += alloc_size;
1034 
1035  /* FIXME: Should explain why this is allocated here, to be freed in
1036  * `SCULPT_undo_push_end_ex()`? */
1037  alloc_size = sizeof(*unode->no) * (size_t)allvert;
1038  unode->no = MEM_callocN(alloc_size, "SculptUndoNode.no");
1039  usculpt->undo_size += alloc_size;
1040  break;
1041  }
1042  case SCULPT_UNDO_HIDDEN: {
1043  if (maxgrid) {
1044  usculpt->undo_size += sculpt_undo_alloc_and_store_hidden(ss->pbvh, unode);
1045  }
1046  else {
1047  unode->vert_hidden = BLI_BITMAP_NEW(allvert, "SculptUndoNode.vert_hidden");
1048  usculpt->undo_size += BLI_BITMAP_SIZE(allvert);
1049  }
1050 
1051  break;
1052  }
1053  case SCULPT_UNDO_MASK: {
1054  const size_t alloc_size = sizeof(*unode->mask) * (size_t)allvert;
1055  unode->mask = MEM_callocN(alloc_size, "SculptUndoNode.mask");
1056  usculpt->undo_size += alloc_size;
1057  break;
1058  }
1059  case SCULPT_UNDO_COLOR: {
1060  const size_t alloc_size = sizeof(*unode->col) * (size_t)allvert;
1061  unode->col = MEM_callocN(alloc_size, "SculptUndoNode.col");
1062  usculpt->undo_size += alloc_size;
1063  break;
1064  }
1068  BLI_assert(!"Dynamic topology should've already been handled");
1069  case SCULPT_UNDO_GEOMETRY:
1070  case SCULPT_UNDO_FACE_SETS:
1071  break;
1072  }
1073 
1074  if (maxgrid) {
1075  /* Multires. */
1076  unode->maxgrid = maxgrid;
1077  unode->totgrid = totgrid;
1078  unode->gridsize = gridsize;
1079 
1080  const size_t alloc_size = sizeof(*unode->grids) * (size_t)totgrid;
1081  unode->grids = MEM_callocN(alloc_size, "SculptUndoNode.grids");
1082  usculpt->undo_size += alloc_size;
1083  }
1084  else {
1085  /* Regular mesh. */
1086  unode->maxvert = ss->totvert;
1087 
1088  const size_t alloc_size = sizeof(*unode->index) * (size_t)allvert;
1089  unode->index = MEM_callocN(alloc_size, "SculptUndoNode.index");
1090  usculpt->undo_size += alloc_size;
1091  }
1092 
1093  if (ss->deform_modifiers_active) {
1094  const size_t alloc_size = sizeof(*unode->orig_co) * (size_t)allvert;
1095  unode->orig_co = MEM_callocN(alloc_size, "undoSculpt orig_cos");
1096  usculpt->undo_size += alloc_size;
1097  }
1098 
1099  return unode;
1100 }
1101 
1103 {
1104  SculptSession *ss = ob->sculpt;
1105  PBVHVertexIter vd;
1106 
1107  BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) {
1108  copy_v3_v3(unode->co[vd.i], vd.co);
1109  if (vd.no) {
1110  copy_v3_v3_short(unode->no[vd.i], vd.no);
1111  }
1112  else {
1113  normal_float_to_short_v3(unode->no[vd.i], vd.fno);
1114  }
1115 
1116  if (ss->deform_modifiers_active) {
1117  copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]);
1118  }
1119  }
1121 }
1122 
1124 {
1125  PBVH *pbvh = ob->sculpt->pbvh;
1126  PBVHNode *node = unode->node;
1127 
1128  if (unode->grids) {
1129  /* Already stored during allocation. */
1130  }
1131  else {
1132  MVert *mvert;
1133  const int *vert_indices;
1134  int allvert;
1135 
1136  BKE_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
1137  BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
1138  for (int i = 0; i < allvert; i++) {
1139  BLI_BITMAP_SET(unode->vert_hidden, i, mvert[vert_indices[i]].flag & ME_HIDE);
1140  }
1141  }
1142 }
1143 
1145 {
1146  SculptSession *ss = ob->sculpt;
1147  PBVHVertexIter vd;
1148 
1149  BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) {
1150  unode->mask[vd.i] = *vd.mask;
1151  }
1153 }
1154 
1156 {
1157  SculptSession *ss = ob->sculpt;
1158  PBVHVertexIter vd;
1159 
1160  BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) {
1161  copy_v4_v4(unode->col[vd.i], vd.col);
1162  }
1164 }
1165 
1167 {
1168  if (!unode->geometry_original.is_initialized) {
1169  return &unode->geometry_original;
1170  }
1171 
1173 
1174  return &unode->geometry_modified;
1175 }
1176 
1178 {
1180  unode->applied = false;
1181  unode->geometry_clear_pbvh = true;
1182 
1184  sculpt_undo_geometry_store_data(geometry, object);
1185 
1186  return unode;
1187 }
1188 
1190 {
1191  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1192  SculptUndoNode *unode = usculpt->nodes.first;
1193 
1194  unode = MEM_callocN(sizeof(*unode), __func__);
1195 
1196  BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
1197  unode->type = type;
1198  unode->applied = true;
1199 
1201 
1202  unode->face_sets = MEM_callocN(me->totpoly * sizeof(int), "sculpt face sets");
1203 
1204  int *face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
1205  for (int i = 0; i < me->totpoly; i++) {
1206  unode->face_sets[i] = face_sets[i];
1207  }
1208 
1209  BLI_addtail(&usculpt->nodes, unode);
1210 
1211  return unode;
1212 }
1213 
1215 {
1216  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1217  SculptSession *ss = ob->sculpt;
1218  PBVHVertexIter vd;
1219 
1220  SculptUndoNode *unode = usculpt->nodes.first;
1221 
1222  if (unode == NULL) {
1223  unode = MEM_callocN(sizeof(*unode), __func__);
1224 
1225  BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
1226  unode->type = type;
1227  unode->applied = true;
1228 
1229  if (type == SCULPT_UNDO_DYNTOPO_END) {
1230  unode->bm_entry = BM_log_entry_add(ss->bm_log);
1232  }
1233  else if (type == SCULPT_UNDO_DYNTOPO_BEGIN) {
1234  /* Store a copy of the mesh's current vertices, loops, and
1235  * polys. A full copy like this is needed because entering
1236  * dynamic-topology immediately does topological edits
1237  * (converting polys to triangles) that the BMLog can't
1238  * fully restore from. */
1239  SculptUndoNodeGeometry *geometry = &unode->geometry_bmesh_enter;
1240  sculpt_undo_geometry_store_data(geometry, ob);
1241 
1242  unode->bm_entry = BM_log_entry_add(ss->bm_log);
1243  BM_log_all_added(ss->bm, ss->bm_log);
1244  }
1245  else {
1246  unode->bm_entry = BM_log_entry_add(ss->bm_log);
1247  }
1248 
1249  BLI_addtail(&usculpt->nodes, unode);
1250  }
1251 
1252  if (node) {
1253  switch (type) {
1254  case SCULPT_UNDO_COORDS:
1255  case SCULPT_UNDO_MASK:
1256  /* Before any vertex values get modified, ensure their
1257  * original positions are logged. */
1260  }
1262  break;
1263 
1264  case SCULPT_UNDO_HIDDEN: {
1265  GSetIterator gs_iter;
1269  }
1271 
1272  GSET_ITER (gs_iter, faces) {
1273  BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1274  BM_log_face_modified(ss->bm_log, f);
1275  }
1276  break;
1277  }
1278 
1282  case SCULPT_UNDO_GEOMETRY:
1283  case SCULPT_UNDO_FACE_SETS:
1284  case SCULPT_UNDO_COLOR:
1285  break;
1286  }
1287  }
1288 
1289  return unode;
1290 }
1291 
1293 {
1294  SculptSession *ss = ob->sculpt;
1295  SculptUndoNode *unode;
1296 
1297  /* List is manipulated by multiple threads, so we lock. */
1299 
1300  ss->needs_flush_to_id = 1;
1301 
1303  /* Dynamic topology stores only one undo node per stroke,
1304  * regardless of the number of PBVH nodes modified. */
1305  unode = sculpt_undo_bmesh_push(ob, node, type);
1307  return unode;
1308  }
1309  if (type == SCULPT_UNDO_GEOMETRY) {
1310  unode = sculpt_undo_geometry_push(ob, type);
1312  return unode;
1313  }
1314  if (type == SCULPT_UNDO_FACE_SETS) {
1315  unode = sculpt_undo_face_sets_push(ob, type);
1317  return unode;
1318  }
1319  if ((unode = SCULPT_undo_get_node(node))) {
1321  return unode;
1322  }
1323 
1324  unode = sculpt_undo_alloc_node(ob, node, type);
1325 
1326  /* NOTE: If this ever becomes a bottleneck, make a lock inside of the node.
1327  * so we release global lock sooner, but keep data locked for until it is
1328  * fully initialized.
1329  */
1330 
1331  if (unode->grids) {
1332  int totgrid, *grids;
1333  BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid, NULL, NULL, NULL);
1334  memcpy(unode->grids, grids, sizeof(int) * totgrid);
1335  }
1336  else {
1337  const int *vert_indices;
1338  int allvert;
1339  BKE_pbvh_node_num_verts(ss->pbvh, node, NULL, &allvert);
1340  BKE_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL);
1341  memcpy(unode->index, vert_indices, sizeof(int) * unode->totvert);
1342  }
1343 
1344  switch (type) {
1345  case SCULPT_UNDO_COORDS:
1346  sculpt_undo_store_coords(ob, unode);
1347  break;
1348  case SCULPT_UNDO_HIDDEN:
1349  sculpt_undo_store_hidden(ob, unode);
1350  break;
1351  case SCULPT_UNDO_MASK:
1352  sculpt_undo_store_mask(ob, unode);
1353  break;
1354  case SCULPT_UNDO_COLOR:
1355  sculpt_undo_store_color(ob, unode);
1356  break;
1360  BLI_assert(!"Dynamic topology should've already been handled");
1361  case SCULPT_UNDO_GEOMETRY:
1362  case SCULPT_UNDO_FACE_SETS:
1363  break;
1364  }
1365 
1366  /* Store sculpt pivot. */
1367  copy_v3_v3(unode->pivot_pos, ss->pivot_pos);
1368  copy_v3_v3(unode->pivot_rot, ss->pivot_rot);
1369 
1370  /* Store active shape key. */
1371  if (ss->shapekey_active) {
1372  BLI_strncpy(unode->shapeName, ss->shapekey_active->name, sizeof(ss->shapekey_active->name));
1373  }
1374  else {
1375  unode->shapeName[0] = '\0';
1376  }
1377 
1379 
1380  return unode;
1381 }
1382 
1383 void SCULPT_undo_push_begin(Object *ob, const char *name)
1384 {
1385  UndoStack *ustack = ED_undo_stack_get();
1386 
1387  if (ob != NULL) {
1388  /* If possible, we need to tag the object and its geometry data as 'changed in the future' in
1389  * the previous undo step if it's a memfile one. */
1392  }
1393 
1394  /* Special case, we never read from this. */
1395  bContext *C = NULL;
1396 
1398 }
1399 
1401 {
1402  SCULPT_undo_push_end_ex(false);
1403 }
1404 
1405 void SCULPT_undo_push_end_ex(const bool use_nested_undo)
1406 {
1407  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1408  SculptUndoNode *unode;
1409 
1410  /* We don't need normals in the undo stack. */
1411  for (unode = usculpt->nodes.first; unode; unode = unode->next) {
1412  if (unode->no) {
1413  usculpt->undo_size -= MEM_allocN_len(unode->no);
1414  MEM_freeN(unode->no);
1415  unode->no = NULL;
1416  }
1417  }
1418 
1419  /* We could remove this and enforce all callers run in an operator using 'OPTYPE_UNDO'. */
1420  wmWindowManager *wm = G_MAIN->wm.first;
1421  if (wm->op_undo_depth == 0 || use_nested_undo) {
1422  UndoStack *ustack = ED_undo_stack_get();
1423  BKE_undosys_step_push(ustack, NULL, NULL);
1424  if (wm->op_undo_depth == 0) {
1426  }
1428  }
1429 }
1430 
1431 /* -------------------------------------------------------------------- */
1435 typedef struct SculptUndoStep {
1437  /* Note: will split out into list for multi-object-sculpt-mode. */
1440 
1442 {
1443  SculptUndoStep *us = (SculptUndoStep *)us_p;
1444  /* Dummy, memory is cleared anyway. */
1446 }
1447 
1449  struct Main *bmain,
1450  UndoStep *us_p)
1451 {
1452  /* Dummy, encoding is done along the way by adding tiles
1453  * to the current 'SculptUndoStep' added by encode_init. */
1454  SculptUndoStep *us = (SculptUndoStep *)us_p;
1455  us->step.data_size = us->data.undo_size;
1456 
1457  SculptUndoNode *unode = us->data.nodes.last;
1458  if (unode && unode->type == SCULPT_UNDO_DYNTOPO_END) {
1459  us->step.use_memfile_step = true;
1460  }
1461  us->step.is_applied = true;
1462 
1463  if (!BLI_listbase_is_empty(&us->data.nodes)) {
1464  bmain->is_memfile_undo_flush_needed = true;
1465  }
1466 
1467  return true;
1468 }
1469 
1472  SculptUndoStep *us)
1473 {
1474  BLI_assert(us->step.is_applied == true);
1476  us->step.is_applied = false;
1477 }
1478 
1481  SculptUndoStep *us)
1482 {
1483  BLI_assert(us->step.is_applied == false);
1485  us->step.is_applied = true;
1486 }
1487 
1490  SculptUndoStep *us,
1491  const bool is_final)
1492 {
1493  /* Walk forward over any applied steps of same type,
1494  * then walk back in the next loop, un-applying them. */
1495  SculptUndoStep *us_iter = us;
1496  while (us_iter->step.next && (us_iter->step.next->type == us_iter->step.type)) {
1497  if (us_iter->step.next->is_applied == false) {
1498  break;
1499  }
1500  us_iter = (SculptUndoStep *)us_iter->step.next;
1501  }
1502 
1503  while ((us_iter != us) || (!is_final && us_iter == us)) {
1504  BLI_assert(us_iter->step.type == us->step.type); /* Previous loop ensures this. */
1506  if (us_iter == us) {
1507  break;
1508  }
1509  us_iter = (SculptUndoStep *)us_iter->step.prev;
1510  }
1511 }
1512 
1515  SculptUndoStep *us)
1516 {
1517  SculptUndoStep *us_iter = us;
1518  while (us_iter->step.prev && (us_iter->step.prev->type == us_iter->step.type)) {
1519  if (us_iter->step.prev->is_applied == true) {
1520  break;
1521  }
1522  us_iter = (SculptUndoStep *)us_iter->step.prev;
1523  }
1524  while (us_iter && (us_iter->step.is_applied == false)) {
1526  if (us_iter == us) {
1527  break;
1528  }
1529  us_iter = (SculptUndoStep *)us_iter->step.next;
1530  }
1531 }
1532 
1534  struct bContext *C, struct Main *bmain, UndoStep *us_p, const eUndoStepDir dir, bool is_final)
1535 {
1536  /* NOTE: behavior for undo/redo closely matches image undo. */
1537  BLI_assert(dir != STEP_INVALID);
1538 
1540 
1541  /* Ensure sculpt mode. */
1542  {
1544  ViewLayer *view_layer = CTX_data_view_layer(C);
1545  Object *ob = OBACT(view_layer);
1546  if (ob && (ob->type == OB_MESH)) {
1547  if (ob->mode & OB_MODE_SCULPT) {
1548  /* Pass. */
1549  }
1550  else {
1552 
1553  /* Sculpt needs evaluated state.
1554  * Note: needs to be done here, as #ED_object_mode_generic_exit will usually invalidate
1555  * (some) evaluated data. */
1557 
1558  Mesh *me = ob->data;
1559  /* Don't add sculpt topology undo steps when reading back undo state.
1560  * The undo steps must enter/exit for us. */
1562  ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, true, NULL);
1563  }
1564 
1565  if (ob->sculpt) {
1566  ob->sculpt->needs_flush_to_id = 1;
1567  }
1568  bmain->is_memfile_undo_flush_needed = true;
1569  }
1570  else {
1571  BLI_assert(0);
1572  return;
1573  }
1574  }
1575 
1576  SculptUndoStep *us = (SculptUndoStep *)us_p;
1577  if (dir == STEP_UNDO) {
1579  }
1580  else if (dir == STEP_REDO) {
1582  }
1583 }
1584 
1586 {
1587  SculptUndoStep *us = (SculptUndoStep *)us_p;
1589 }
1590 
1591 void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
1592 {
1593  SCULPT_undo_push_begin(ob, name);
1595 }
1596 
1598 {
1601 }
1602 
1603 /* Export for ED_undo_sys. */
1605 {
1606  ut->name = "Sculpt";
1607  ut->poll = NULL; /* No poll from context for now. */
1612 
1613  ut->flags = 0;
1614 
1615  ut->step_size = sizeof(SculptUndoStep);
1616 }
1617 
1620 /* -------------------------------------------------------------------- */
1625 {
1626  SculptUndoStep *us = (SculptUndoStep *)us_p;
1627  return &us->data;
1628 }
1629 
1631 {
1632  UndoStack *ustack = ED_undo_stack_get();
1634  return sculpt_undosys_step_get_nodes(us);
1635 }
1636 
1639 /* -------------------------------------------------------------------- */
1662 {
1664  return false;
1665  }
1666 
1667  Object *object = CTX_data_active_object(C);
1668  SculptSession *sculpt_session = object->sculpt;
1669 
1670  return sculpt_session->multires.active;
1671 }
1672 
1674 {
1675  SculptSession *ss = object->sculpt;
1676 
1677  /* It is possible that undo push is done from an object state where there is no PBVH. This
1678  * happens, for example, when an operation which tagged for geometry update was performed prior
1679  * to the current operation without making any stroke in between.
1680  *
1681  * Skip pushing nodes based on the following logic: on redo SCULPT_UNDO_COORDS will ensure
1682  * PBVH for the new base geometry, which will have same coordinates as if we create PBVH here. */
1683  if (ss->pbvh == NULL) {
1684  return;
1685  }
1686 
1687  PBVHNode **nodes;
1688  int totnodes;
1689 
1690  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnodes);
1691  for (int i = 0; i < totnodes; i++) {
1692  SculptUndoNode *unode = SCULPT_undo_push_node(object, nodes[i], SCULPT_UNDO_COORDS);
1693  unode->node = NULL;
1694  }
1695 
1696  MEM_SAFE_FREE(nodes);
1697 }
1698 
1700 {
1702  return;
1703  }
1704 
1705  Object *object = CTX_data_active_object(C);
1706 
1707  SCULPT_undo_push_begin(object, str);
1708 
1709  SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY);
1710  geometry_unode->geometry_clear_pbvh = false;
1711 
1713 }
1714 
1716 {
1718  ED_undo_push(C, str);
1719  return;
1720  }
1721 
1722  Object *object = CTX_data_active_object(C);
1723 
1724  SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY);
1725  geometry_unode->geometry_clear_pbvh = false;
1726 
1728 }
1729 
typedef float(TangentPoint)[2]
struct CCGElem CCGElem
Definition: BKE_ccg.h:46
BLI_INLINE float * CCG_elem_offset_co(const CCGKey *key, CCGElem *elem, int offset)
Definition: BKE_ccg.h:145
BLI_INLINE float * CCG_elem_offset_mask(const CCGKey *key, CCGElem *elem, int offset)
Definition: BKE_ccg.h:155
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
CustomData interface, see also DNA_customdata_types.h.
void CustomData_free(struct CustomData *data, int totelem)
Definition: customdata.c:2239
@ CD_DUPLICATE
void * CustomData_get_layer(const struct CustomData *data, int type)
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, eCDAllocType alloctype, int totelem)
Definition: customdata.c:2193
const CustomData_MeshMasks CD_MASK_MESH
Definition: customdata.c:1933
#define G_MAIN
Definition: BKE_global.h:232
struct KeyBlock * BKE_keyblock_find_name(struct Key *key, const char name[])
Definition: key.c:1944
float(* BKE_keyblock_convert_to_vertcos(struct Object *ob, struct KeyBlock *kb))[3]
Definition: key.c:2413
struct Key * BKE_key_from_object(const struct Object *ob)
void BKE_mesh_calc_normals(struct Mesh *me)
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd)
Definition: mesh.c:766
void BKE_mesh_flush_hidden_from_verts(struct Mesh *me)
float(* BKE_multires_create_deformed_base_mesh_vert_coords(struct Depsgraph *depsgraph, struct Object *object, struct MultiresModifierData *mmd, int *r_num_deformed_verts))[3]
Definition: multires.c:265
void multires_mark_as_modified(struct Depsgraph *depsgraph, struct Object *object, enum MultiresModifiedFlags flags)
Definition: multires.c:406
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_original_mesh(struct Object *object)
Definition: object.c:4493
ePaintMode BKE_paintmode_get_active_from_context(const struct bContext *C)
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph, struct Object *ob_orig, bool need_pmap, bool need_mask, bool need_colors)
Definition: paint.c:1817
void BKE_sculptsession_free_deformMats(struct SculptSession *ss)
Definition: paint.c:1337
@ PAINT_MODE_SCULPT
Definition: BKE_paint.h:79
struct MultiresModifierData * BKE_sculpt_multires_active(struct Scene *scene, struct Object *ob)
Definition: paint.c:1527
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d)
void BKE_pbvh_node_mark_update(PBVHNode *node)
Definition: pbvh.c:1732
void BKE_pbvh_node_get_verts(PBVH *pbvh, PBVHNode *node, const int **r_vert_indices, struct MVert **r_verts)
Definition: pbvh.c:1820
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:384
#define PBVH_ITER_ALL
Definition: BKE_pbvh.h:334
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node)
Definition: pbvh.c:1748
void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int *r_totvert)
Definition: pbvh.c:1834
void BKE_pbvh_update_visibility(PBVH *pbvh)
Definition: pbvh.c:1574
PBVHType BKE_pbvh_type(const PBVH *pbvh)
Definition: pbvh.c:1661
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:457
@ PBVH_GRIDS
Definition: BKE_pbvh.h:211
@ PBVH_FACES
Definition: BKE_pbvh.h:210
struct GSet * BKE_pbvh_bmesh_node_faces(PBVHNode *node)
Definition: pbvh_bmesh.c:2131
bool BKE_pbvh_node_vert_update_check_any(PBVH *pbvh, PBVHNode *node)
Definition: pbvh.c:1962
void BKE_pbvh_node_get_grids(PBVH *pbvh, PBVHNode *node, int **grid_indices, int *totgrid, int *maxgrid, int *gridsize, struct CCGElem ***r_griddata)
Definition: pbvh.c:1868
void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
Definition: pbvh.c:1769
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3042
void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags)
Definition: pbvh.c:1432
void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
Definition: pbvh.c:1738
void BKE_pbvh_vert_coords_apply(struct PBVH *pbvh, const float(*vertCos)[3], const int totvert)
Definition: pbvh.c:2798
void BKE_pbvh_update_bounds(PBVH *pbvh, int flags)
Definition: pbvh.c:1410
void BKE_pbvh_search_callback(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, BKE_pbvh_HitCallback hcb, void *hit_data)
Definition: pbvh.c:876
void BKE_pbvh_node_mark_redraw(PBVHNode *node)
Definition: pbvh.c:1759
unsigned int ** BKE_pbvh_grid_hidden(const PBVH *pbvh)
Definition: pbvh.c:1688
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
Definition: pbvh.c:843
@ PBVH_UpdateVisibility
Definition: BKE_pbvh.h:72
@ PBVH_UpdateMask
Definition: BKE_pbvh.h:71
@ PBVH_UpdateBB
Definition: BKE_pbvh.h:67
@ PBVH_UpdateOriginalBB
Definition: BKE_pbvh.h:68
@ PBVH_UpdateRedraw
Definition: BKE_pbvh.h:70
void BKE_scene_graph_evaluated_ensure(struct Depsgraph *depsgraph, struct Main *bmain)
Definition: scene.c:2718
void BKE_subdiv_ccg_key_top_level(struct CCGKey *key, const SubdivCCG *subdiv_ccg)
Definition: subdiv_ccg.c:677
bool BKE_subdiv_eval_refine_from_mesh(struct Subdiv *subdiv, const struct Mesh *mesh, const float(*coarse_vertex_cos)[3])
@ MULTIRES_HIDDEN_MODIFIED
Definition: BKE_subsurf.h:94
@ MULTIRES_COORDS_MODIFIED
Definition: BKE_subsurf.h:92
const UndoType * BKE_UNDOSYS_TYPE_SCULPT
Definition: undo_system.c:104
UndoStep * BKE_undosys_step_push_init_with_type(UndoStack *ustack, struct bContext *C, const char *name, const UndoType *ut)
Definition: undo_system.c:458
UndoStep * BKE_undosys_stack_init_or_active_with_type(UndoStack *ustack, const UndoType *ut)
Definition: undo_system.c:390
eUndoStepDir
@ STEP_INVALID
@ STEP_UNDO
@ STEP_REDO
#define BKE_undosys_stack_limit_steps_and_memory_defaults(ustack)
UndoPushReturn BKE_undosys_step_push(UndoStack *ustack, struct bContext *C, const char *name)
Definition: undo_system.c:605
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:63
#define BLI_BITMAP_SIZE(_tot)
Definition: BLI_bitmap.h:47
#define BLI_BITMAP_FLIP(_bitmap, _index)
Definition: BLI_bitmap.h:88
#define BLI_BITMAP_NEW(_tot, _alloc_string)
Definition: BLI_bitmap.h:50
#define BLI_BITMAP_SET(_bitmap, _index, _set)
Definition: BLI_bitmap.h:93
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:32
struct GSet GSet
Definition: BLI_ghash.h:189
#define GSET_ITER(gs_iter_, gset_)
Definition: BLI_ghash.h:268
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition: BLI_ghash.h:255
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void normal_float_to_short_v3(short r[3], const float n[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_short(short r[3], const short a[3])
MINLINE void swap_v3_v3(float a[3], float b[3])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
void BLI_thread_unlock(int type)
Definition: threads.cc:389
void BLI_thread_lock(int type)
Definition: threads.cc:384
@ LOCK_CUSTOM1
Definition: BLI_threads.h:70
#define SWAP(type, a, b)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SHADING
Definition: DNA_ID.h:631
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
#define ID_REAL_USERS(id)
Definition: DNA_ID.h:413
@ CD_PAINT_MASK
@ CD_SCULPT_FACE_SETS
@ ME_SCULPT_DYNAMIC_TOPOLOGY
@ ME_HIDE
@ ME_VERT_PBVH_UPDATE
@ OB_MODE_SCULPT
Object is a sort of wrapper for general info.
@ OB_MESH
#define OBACT(_view_layer)
void ED_object_mode_generic_exit(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
Definition: object_modes.c:391
void ED_object_sculptmode_enter_ex(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, const bool force_dyntopo, struct ReportList *reports)
Definition: sculpt.c:8391
void ED_undo_push(struct bContext *C, const char *str)
Definition: ed_undo.c:117
struct UndoStack * ED_undo_stack_get(void)
Definition: ed_undo.c:501
void ED_undosys_stack_memfile_id_changed_tag(struct UndoStack *ustack, struct ID *id)
Definition: memfile_undo.c:328
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:39
#define ND_DATA
Definition: WM_types.h:408
#define NC_OBJECT
Definition: WM_types.h:280
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:894
void BM_log_all_added(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:987
BMLogEntry * BM_log_entry_add(BMLog *log)
Definition: bmesh_log.c:652
void BM_log_cleanup_entry(BMLogEntry *entry)
Definition: bmesh_log.c:487
void BM_log_face_modified(BMLog *log, BMFace *f)
Definition: bmesh_log.c:878
void BM_log_redo(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:781
BMLog * BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry)
Definition: bmesh_log.c:517
void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
Definition: bmesh_log.c:838
void BM_log_entry_drop(BMLogEntry *entry)
Definition: bmesh_log.c:688
void BM_log_undo(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:757
void BM_log_before_all_removed(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:1015
const BMAllocTemplate bm_mesh_allocsize_default
Definition: bmesh_mesh.c:46
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
BMesh Make Mesh.
Definition: bmesh_mesh.c:157
ATTR_WARN_UNUSED_RESULT const BMVert * v
OperationNode * node
Scene scene
const Depsgraph * depsgraph
#define str(s)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:40
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static char faces[256]
static unsigned a[3]
Definition: RandGen.cpp:92
static void update(bNodeTree *ntree)
void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float(*vertCos)[3])
Definition: sculpt.c:5763
void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
Definition: sculpt.c:598
void SCULPT_update_object_bounding_box(Object *ob)
Definition: sculpt.c:7749
void SCULPT_visibility_sync_all_face_sets_to_vertices(Object *ob)
Definition: sculpt.c:563
void SCULPT_pbvh_clear(Object *ob)
void SCULPT_dynamic_topology_disable(bContext *C, SculptUndoNode *unode)
void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
struct SculptUndoNode SculptUndoNode
SculptUndoType
@ SCULPT_UNDO_GEOMETRY
@ SCULPT_UNDO_FACE_SETS
@ SCULPT_UNDO_COORDS
@ SCULPT_UNDO_HIDDEN
@ SCULPT_UNDO_DYNTOPO_SYMMETRIZE
@ SCULPT_UNDO_COLOR
@ SCULPT_UNDO_DYNTOPO_END
@ SCULPT_UNDO_DYNTOPO_BEGIN
@ SCULPT_UNDO_MASK
static SculptUndoNodeGeometry * sculpt_undo_geometry_get(SculptUndoNode *unode)
Definition: sculpt_undo.c:1166
static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase *lb)
Definition: sculpt_undo.c:638
static void sculpt_undosys_step_decode(struct bContext *C, struct Main *bmain, UndoStep *us_p, const eUndoStepDir dir, bool is_final)
Definition: sculpt_undo.c:1533
static void sculpt_undo_geometry_restore(SculptUndoNode *unode, Object *object)
Definition: sculpt_undo.c:568
static void update_cb_partial(PBVHNode *node, void *userdata)
Definition: sculpt_undo.c:139
SculptUndoNode * SCULPT_undo_get_node(PBVHNode *node)
Definition: sculpt_undo.c:930
void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1591
static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode)
Definition: sculpt_undo.c:325
static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:1144
static bool sculpt_undo_restore_deformed(const SculptSession *ss, SculptUndoNode *unode, int uindex, int oindex, float coord[3])
Definition: sculpt_undo.c:173
SculptUndoNode * SCULPT_undo_get_first_node()
Definition: sculpt_undo.c:941
static void sculpt_undo_push_all_grids(Object *object)
Definition: sculpt_undo.c:1673
static SculptUndoNode * sculpt_undo_face_sets_push(Object *ob, SculptUndoType type)
Definition: sculpt_undo.c:1189
static bool sculpt_undo_use_multires_mesh(bContext *C)
Definition: sculpt_undo.c:1661
void ED_sculpt_undo_geometry_end(struct Object *ob)
Definition: sculpt_undo.c:1597
static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode)
Definition: sculpt_undo.c:345
static void sculpt_undo_geometry_store_data(SculptUndoNodeGeometry *geometry, Object *object)
Definition: sculpt_undo.c:504
static SculptUndoNode * sculpt_undo_alloc_node(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1008
static size_t sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *unode)
Definition: sculpt_undo.c:952
void ED_sculpt_undosys_type(UndoType *ut)
Definition: sculpt_undo.c:1604
static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p)
Definition: sculpt_undo.c:1441
static void sculpt_undo_refine_subdiv(Depsgraph *depsgraph, SculptSession *ss, Object *object, struct Subdiv *subdiv)
Definition: sculpt_undo.c:625
static bool sculpt_undo_restore_face_sets(bContext *C, SculptUndoNode *unode)
Definition: sculpt_undo.c:393
static SculptUndoNode * sculpt_undo_alloc_node_type(Object *object, SculptUndoType type)
Definition: sculpt_undo.c:978
void SCULPT_undo_push_end_ex(const bool use_nested_undo)
Definition: sculpt_undo.c:1405
static UndoSculpt * sculpt_undosys_step_get_nodes(UndoStep *us_p)
Definition: sculpt_undo.c:1624
static void sculpt_undosys_step_decode_redo(struct bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
Definition: sculpt_undo.c:1513
void ED_sculpt_undo_push_multires_mesh_begin(bContext *C, const char *str)
Definition: sculpt_undo.c:1699
static UndoSculpt * sculpt_undo_get_nodes(void)
Definition: sculpt_undo.c:1630
static SculptUndoNode * sculpt_undo_geometry_push(Object *object, SculptUndoType type)
Definition: sculpt_undo.c:1177
static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, SculptUndoNode *unode)
Definition: sculpt_undo.c:183
void SCULPT_undo_push_end(void)
Definition: sculpt_undo.c:1400
static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C), struct Main *bmain, UndoStep *us_p)
Definition: sculpt_undo.c:1448
static void sculpt_undo_bmesh_enable(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:445
void ED_sculpt_undo_push_multires_mesh_end(bContext *C, const char *str)
Definition: sculpt_undo.c:1715
static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:1123
static void sculpt_undo_bmesh_restore_begin(bContext *C, SculptUndoNode *unode, Object *ob, SculptSession *ss)
Definition: sculpt_undo.c:465
static void update_cb(PBVHNode *node, void *rebuild)
Definition: sculpt_undo.c:120
SculptUndoNode * SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1292
static SculptUndoNode * sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1214
void SCULPT_undo_push_begin(Object *ob, const char *name)
Definition: sculpt_undo.c:1383
static void sculpt_undo_store_color(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:1155
static void sculpt_undo_geometry_restore_data(SculptUndoNodeGeometry *geometry, Object *object)
Definition: sculpt_undo.c:522
static int sculpt_undo_bmesh_restore(bContext *C, SculptUndoNode *unode, Object *ob, SculptSession *ss)
Definition: sculpt_undo.c:588
static void sculpt_undo_free_list(ListBase *lb)
Definition: sculpt_undo.c:854
static void sculpt_undosys_step_decode_redo_impl(struct bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
Definition: sculpt_undo.c:1479
static SculptUndoNode * sculpt_undo_find_or_alloc_node_type(Object *object, SculptUndoType type)
Definition: sculpt_undo.c:995
static void sculpt_undosys_step_decode_undo_impl(struct bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
Definition: sculpt_undo.c:1470
struct SculptUndoStep SculptUndoStep
static void sculpt_undo_bmesh_restore_end(bContext *C, SculptUndoNode *unode, Object *ob, SculptSession *ss)
Definition: sculpt_undo.c:484
struct UndoSculpt UndoSculpt
static void sculpt_undo_bmesh_restore_generic_task_cb(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: sculpt_undo.c:405
static void sculpt_undosys_step_free(UndoStep *us_p)
Definition: sculpt_undo.c:1585
static bool test_swap_v3_v3(float a[3], float b[3])
Definition: sculpt_undo.c:163
static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:1102
static void sculpt_undosys_step_decode_undo(struct bContext *C, Depsgraph *depsgraph, SculptUndoStep *us, const bool is_final)
Definition: sculpt_undo.c:1488
static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob, SculptSession *ss)
Definition: sculpt_undo.c:413
static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode)
Definition: sculpt_undo.c:295
static void sculpt_undo_geometry_free_data(SculptUndoNodeGeometry *geometry)
Definition: sculpt_undo.c:552
CustomData vdata
Definition: bmesh_class.h:337
Definition: BKE_ccg.h:48
char name[66]
Definition: DNA_ID.h:283
char name[64]
Definition: DNA_key_types.h:68
ListBase block
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
char is_memfile_undo_flush_needed
Definition: BKE_main.h:130
struct CustomData pdata ldata
int totedge
int totvert
short flag
int totface
struct CustomData vdata edata fdata
int totpoly
int totloop
short shapenr
struct SculptSession * sculpt
void * data
short * no
Definition: BKE_pbvh.h:375
float * co
Definition: BKE_pbvh.h:374
int cd_vert_mask_offset
Definition: BKE_pbvh.h:368
float * fno
Definition: BKE_pbvh.h:376
float * col
Definition: BKE_pbvh.h:378
struct BMVert * bm_vert
Definition: BKE_pbvh.h:373
float * mask
Definition: BKE_pbvh.h:377
struct SubdivCCG * subdiv_ccg
Definition: BKE_paint.h:501
float(* orig_cos)[3]
Definition: BKE_paint.h:510
float pivot_pos[3]
Definition: BKE_paint.h:567
struct MVert * mvert
Definition: BKE_paint.h:461
struct MPropCol * vcol
Definition: BKE_paint.h:469
struct KeyBlock * shapekey_active
Definition: BKE_paint.h:468
struct BMesh * bm
Definition: BKE_paint.h:493
struct BMLog * bm_log
Definition: BKE_paint.h:498
float pivot_rot[4]
Definition: BKE_paint.h:568
float * vmask
Definition: BKE_paint.h:470
char needs_flush_to_id
Definition: BKE_paint.h:609
struct MultiresModifierData * modifier
Definition: BKE_paint.h:453
struct SculptSession::@53 multires
float(* deform_cos)[3]
Definition: BKE_paint.h:511
struct PBVH * pbvh
Definition: BKE_paint.h:504
bool deform_modifiers_active
Definition: BKE_paint.h:509
float(* col)[4]
struct BMLogEntry * bm_entry
bool geometry_clear_pbvh
BLI_bitmap * vert_hidden
float(* co)[3]
BLI_bitmap ** grid_hidden
char idname[MAX_ID_NAME]
SculptUndoNodeGeometry geometry_modified
SculptUndoNodeGeometry geometry_bmesh_enter
char shapeName[sizeof(((KeyBlock *) 0)) ->name]
short(* no)[3]
float(* orig_co)[3]
SculptUndoNodeGeometry geometry_original
SculptUndoType type
struct SculptUndoNode * next
float pivot_rot[4]
float pivot_pos[3]
UndoSculpt data
Definition: sculpt_undo.c:1438
struct CCGElem ** grids
struct Subdiv * subdiv
BLI_bitmap ** grid_hidden
size_t undo_size
Definition: sculpt_undo.c:115
ListBase nodes
Definition: sculpt_undo.c:113
const struct UndoType * type
bool is_applied
size_t data_size
struct UndoStep * prev
struct UndoStep * next
bool use_memfile_step
size_t step_size
void(* step_decode)(struct bContext *C, struct Main *bmain, UndoStep *us, const eUndoStepDir dir, bool is_final)
bool(* step_encode)(struct bContext *C, struct Main *bmain, UndoStep *us)
void(* step_encode_init)(struct bContext *C, UndoStep *us)
const char * name
void(* step_free)(UndoStep *us)
bool(* poll)(struct bContext *C)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_file_tag_modified(void)
Definition: wm_files.c:158