Blender  V3.3
sculpt_undo.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2006 by Nicholas Bishop. All rights reserved. */
3 
9 #include <stddef.h>
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_ghash.h"
14 #include "BLI_listbase.h"
15 #include "BLI_math.h"
16 #include "BLI_string.h"
17 #include "BLI_task.h"
18 #include "BLI_threads.h"
19 #include "BLI_utildefines.h"
20 
21 #include "DNA_mesh_types.h"
22 #include "DNA_meshdata_types.h"
23 #include "DNA_object_types.h"
24 #include "DNA_scene_types.h"
25 #include "DNA_screen_types.h"
26 
27 #include "BKE_attribute.h"
28 #include "BKE_ccg.h"
29 #include "BKE_context.h"
30 #include "BKE_customdata.h"
31 #include "BKE_global.h"
32 #include "BKE_key.h"
33 #include "BKE_main.h"
34 #include "BKE_mesh.h"
35 #include "BKE_mesh_mapping.h"
36 #include "BKE_mesh_runtime.h"
37 #include "BKE_multires.h"
38 #include "BKE_object.h"
39 #include "BKE_paint.h"
40 #include "BKE_scene.h"
41 #include "BKE_subdiv_ccg.h"
42 #include "BKE_subsurf.h"
43 #include "BKE_undo_system.h"
44 
45 /* TODO(sergey): Ideally should be no direct call to such low level things. */
46 #include "BKE_subdiv_eval.h"
47 
48 #include "DEG_depsgraph.h"
49 
50 #include "WM_api.h"
51 #include "WM_types.h"
52 
53 #include "ED_geometry.h"
54 #include "ED_object.h"
55 #include "ED_sculpt.h"
56 #include "ED_undo.h"
57 
58 #include "bmesh.h"
59 #include "sculpt_intern.h"
60 
61 /* Implementation of undo system for objects in sculpt mode.
62  *
63  * Each undo step in sculpt mode consists of list of nodes, each node contains:
64  * - Node type
65  * - Data for this type.
66  *
67  * Node type used for undo depends on specific operation and active sculpt mode
68  * ("regular" or dynamic topology).
69  *
70  * Regular sculpt brushes will use COORDS, HIDDEN or MASK nodes. These nodes are
71  * created for every BVH node which is affected by the brush. The undo push for
72  * the node happens BEFORE modifications. This makes the operation undo to work
73  * in the following way: for every node in the undo step swap happens between
74  * node in the undo stack and the corresponding value in the BVH. This is how
75  * redo is possible after undo.
76  *
77  * The COORDS, HIDDEN or MASK type of nodes contains arrays of the corresponding
78  * values.
79  *
80  * Operations like Symmetrize are using GEOMETRY type of nodes which pushes the
81  * entire state of the mesh to the undo stack. This node contains all CustomData
82  * layers.
83  *
84  * The tricky aspect of this undo node type is that it stores mesh before and
85  * after modification. This allows the undo system to both undo and redo the
86  * symmetrize operation within the pre-modified-push of other node type
87  * behavior, but it uses more memory that it seems it should be.
88  *
89  * The dynamic topology undo nodes are handled somewhat separately from all
90  * other ones and the idea there is to store log of operations: which vertices
91  * and faces have been added or removed.
92  *
93  * Begin of dynamic topology sculpting mode have own node type. It contains an
94  * entire copy of mesh since just enabling the dynamic topology mode already
95  * does modifications on it.
96  *
97  * End of dynamic topology and symmetrize in this mode are handled in a special
98  * manner as well. */
99 
100 #define NO_ACTIVE_LAYER ATTR_DOMAIN_AUTO
101 
102 typedef struct UndoSculpt {
104 
105  size_t undo_size;
107 
108 typedef struct SculptAttrRef {
110  int type;
112  bool was_set;
114 
115 typedef struct SculptUndoStep {
117  /* NOTE: will split out into list for multi-object-sculpt-mode. */
119 
120  /* Active color attribute at the start of this undo step. */
122 
123  /* Active color attribute at the end of this undo step. */
125 
128 
129 static UndoSculpt *sculpt_undo_get_nodes(void);
131 static void sculpt_save_active_attribute(Object *ob, SculptAttrRef *attr);
132 
133 static void update_cb(PBVHNode *node, void *rebuild)
134 {
137  if (*((bool *)rebuild)) {
139  }
141 }
142 
145  bool rebuild;
150 };
151 
155 static void update_cb_partial(PBVHNode *node, void *userdata)
156 {
157  struct PartialUpdateData *data = userdata;
158  if (BKE_pbvh_type(data->pbvh) == PBVH_GRIDS) {
159  int *node_grid_indices;
160  int totgrid;
161  bool update = false;
162  BKE_pbvh_node_get_grids(data->pbvh, node, &node_grid_indices, &totgrid, NULL, NULL, NULL);
163  for (int i = 0; i < totgrid; i++) {
164  if (data->modified_grids[node_grid_indices[i]] == 1) {
165  update = true;
166  }
167  }
168  if (update) {
169  update_cb(node, &(data->rebuild));
170  }
171  }
172  else {
175  }
176  int verts_num;
177  const int *vert_indices;
178  BKE_pbvh_node_num_verts(data->pbvh, node, NULL, &verts_num);
179  BKE_pbvh_node_get_verts(data->pbvh, node, &vert_indices, NULL);
180  if (data->modified_mask_vertices != NULL) {
181  for (int i = 0; i < verts_num; i++) {
182  if (data->modified_mask_vertices[vert_indices[i]]) {
184  break;
185  }
186  }
187  }
188  if (data->modified_color_vertices != NULL) {
189  for (int i = 0; i < verts_num; i++) {
190  if (data->modified_color_vertices[vert_indices[i]]) {
192  break;
193  }
194  }
195  }
196  if (data->modified_hidden_vertices != NULL) {
197  for (int i = 0; i < verts_num; i++) {
198  if (data->modified_hidden_vertices[vert_indices[i]]) {
199  if (data->rebuild) {
201  }
203  break;
204  }
205  }
206  }
207  }
208 }
209 
210 static bool test_swap_v3_v3(float a[3], float b[3])
211 {
212  /* No need for float comparison here (memory is exactly equal or not). */
213  if (memcmp(a, b, sizeof(float[3])) != 0) {
214  swap_v3_v3(a, b);
215  return true;
216  }
217  return false;
218 }
219 
221  const SculptSession *ss, SculptUndoNode *unode, int uindex, int oindex, float coord[3])
222 {
223  if (test_swap_v3_v3(coord, unode->orig_co[uindex])) {
224  copy_v3_v3(unode->co[uindex], ss->deform_cos[oindex]);
225  return true;
226  }
227  return false;
228 }
229 
231 {
232  ViewLayer *view_layer = CTX_data_view_layer(C);
233  Object *ob = OBACT(view_layer);
234  SculptSession *ss = ob->sculpt;
235  SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
236  MVert *mvert;
237  int *index;
238 
239  if (unode->maxvert) {
240  /* Regular mesh restore. */
241 
242  if (ss->shapekey_active && !STREQ(ss->shapekey_active->name, unode->shapeName)) {
243  /* Shape key has been changed before calling undo operator. */
244 
245  Key *key = BKE_key_from_object(ob);
246  KeyBlock *kb = key ? BKE_keyblock_find_name(key, unode->shapeName) : NULL;
247 
248  if (kb) {
249  ob->shapenr = BLI_findindex(&key->block, kb) + 1;
250 
251  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
253  }
254  else {
255  /* Key has been removed -- skip this undo node. */
256  return false;
257  }
258  }
259 
260  /* No need for float comparison here (memory is exactly equal or not). */
261  index = unode->index;
262  mvert = ss->mvert;
263 
264  if (ss->shapekey_active) {
265  float(*vertCos)[3];
267 
268  if (unode->orig_co) {
269  if (ss->deform_modifiers_active) {
270  for (int i = 0; i < unode->totvert; i++) {
271  sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
272  }
273  }
274  else {
275  for (int i = 0; i < unode->totvert; i++) {
276  swap_v3_v3(vertCos[index[i]], unode->orig_co[i]);
277  }
278  }
279  }
280  else {
281  for (int i = 0; i < unode->totvert; i++) {
282  swap_v3_v3(vertCos[index[i]], unode->co[i]);
283  }
284  }
285 
286  /* Propagate new coords to keyblock. */
287  SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
288 
289  /* PBVH uses its own mvert array, so coords should be */
290  /* propagated to PBVH here. */
292 
293  MEM_freeN(vertCos);
294  }
295  else {
296  if (unode->orig_co) {
297  if (ss->deform_modifiers_active) {
298  for (int i = 0; i < unode->totvert; i++) {
299  sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
300  BKE_pbvh_vert_tag_update_normal(ss->pbvh, index[i]);
301  }
302  }
303  else {
304  for (int i = 0; i < unode->totvert; i++) {
305  swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]);
306  BKE_pbvh_vert_tag_update_normal(ss->pbvh, index[i]);
307  }
308  }
309  }
310  else {
311  for (int i = 0; i < unode->totvert; i++) {
312  swap_v3_v3(mvert[index[i]].co, unode->co[i]);
313  BKE_pbvh_vert_tag_update_normal(ss->pbvh, index[i]);
314  }
315  }
316  }
317  }
318  else if (unode->maxgrid && subdiv_ccg != NULL) {
319  /* Multires restore. */
320  CCGElem **grids, *grid;
321  CCGKey key;
322  float(*co)[3];
323  int gridsize;
324 
325  grids = subdiv_ccg->grids;
326  gridsize = subdiv_ccg->grid_size;
327  BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
328 
329  co = unode->co;
330  for (int j = 0; j < unode->totgrid; j++) {
331  grid = grids[unode->grids[j]];
332 
333  for (int i = 0; i < gridsize * gridsize; i++, co++) {
334  swap_v3_v3(CCG_elem_offset_co(&key, grid, i), co[0]);
335  }
336  }
337  }
338 
339  return true;
340 }
341 
342 static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
343 {
344  ViewLayer *view_layer = CTX_data_view_layer(C);
345  Object *ob = OBACT(view_layer);
346  SculptSession *ss = ob->sculpt;
347  SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
348 
349  if (unode->maxvert) {
350  MVert *mvert = ss->mvert;
351 
352  for (int i = 0; i < unode->totvert; i++) {
353  MVert *v = &mvert[unode->index[i]];
354  if ((BLI_BITMAP_TEST(unode->vert_hidden, i) != 0) != ((v->flag & ME_HIDE) != 0)) {
355  BLI_BITMAP_FLIP(unode->vert_hidden, i);
356  v->flag ^= ME_HIDE;
357  modified_vertices[unode->index[i]] = true;
358  }
359  }
360  }
361  else if (unode->maxgrid && subdiv_ccg != NULL) {
362  BLI_bitmap **grid_hidden = subdiv_ccg->grid_hidden;
363 
364  for (int i = 0; i < unode->totgrid; i++) {
365  SWAP(BLI_bitmap *, unode->grid_hidden[i], grid_hidden[unode->grids[i]]);
366  }
367  }
368 
369  return true;
370 }
371 
372 static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
373 {
374  ViewLayer *view_layer = CTX_data_view_layer(C);
375  Object *ob = OBACT(view_layer);
376  SculptSession *ss = ob->sculpt;
377 
378  bool modified = false;
379 
380  /* NOTE: even with loop colors we still store derived
381  * vertex colors for original data lookup. */
382  if (unode->col && !unode->loop_col) {
383  BKE_pbvh_swap_colors(ss->pbvh, unode->index, unode->totvert, unode->col);
384  modified = true;
385  }
386 
388 
389  if (unode->loop_col && unode->maxloop == me->totloop) {
390  BKE_pbvh_swap_colors(ss->pbvh, unode->loop_index, unode->totloop, unode->loop_col);
391 
392  modified = true;
393  }
394 
395  if (modified) {
396  for (int i = 0; i < unode->totvert; i++) {
397  modified_vertices[unode->index[i]] = true;
398  }
399  }
400 
401  return modified;
402 }
403 
404 static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
405 {
406  ViewLayer *view_layer = CTX_data_view_layer(C);
407  Object *ob = OBACT(view_layer);
408  SculptSession *ss = ob->sculpt;
409  SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
410  float *vmask;
411  int *index;
412 
413  if (unode->maxvert) {
414  /* Regular mesh restore. */
415 
416  index = unode->index;
417  vmask = ss->vmask;
418 
419  for (int i = 0; i < unode->totvert; i++) {
420  if (vmask[index[i]] != unode->mask[i]) {
421  SWAP(float, vmask[index[i]], unode->mask[i]);
422  modified_vertices[index[i]] = true;
423  }
424  }
425  }
426  else if (unode->maxgrid && subdiv_ccg != NULL) {
427  /* Multires restore. */
428  CCGElem **grids, *grid;
429  CCGKey key;
430  float *mask;
431  int gridsize;
432 
433  grids = subdiv_ccg->grids;
434  gridsize = subdiv_ccg->grid_size;
435  BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
436 
437  mask = unode->mask;
438  for (int j = 0; j < unode->totgrid; j++) {
439  grid = grids[unode->grids[j]];
440 
441  for (int i = 0; i < gridsize * gridsize; i++, mask++) {
442  SWAP(float, *CCG_elem_offset_mask(&key, grid, i), *mask);
443  }
444  }
445  }
446 
447  return true;
448 }
449 
451 {
452  ViewLayer *view_layer = CTX_data_view_layer(C);
453  Object *ob = OBACT(view_layer);
455  int *face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
456  for (int i = 0; i < me->totpoly; i++) {
457  face_sets[i] = unode->face_sets[i];
458  }
459  return false;
460 }
461 
463  void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
464 {
465  PBVHNode **nodes = userdata;
466 
467  BKE_pbvh_node_mark_redraw(nodes[n]);
468 }
469 
471 {
472  if (unode->applied) {
473  BM_log_undo(ss->bm, ss->bm_log);
474  unode->applied = false;
475  }
476  else {
477  BM_log_redo(ss->bm, ss->bm_log);
478  unode->applied = true;
479  }
480 
481  if (unode->type == SCULPT_UNDO_MASK) {
482  int totnode;
483  PBVHNode **nodes;
484 
485  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
486 
487  TaskParallelSettings settings;
488  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
490  0, totnode, nodes, sculpt_undo_bmesh_restore_generic_task_cb, &settings);
491 
492  if (nodes) {
493  MEM_freeN(nodes);
494  }
495  }
496  else {
497  SCULPT_pbvh_clear(ob);
498  }
499 }
500 
501 /* Create empty sculpt BMesh and enable logging. */
503 {
504  SculptSession *ss = ob->sculpt;
505  Mesh *me = ob->data;
506 
507  SCULPT_pbvh_clear(ob);
508 
509  /* Create empty BMesh and enable logging. */
511  &((struct BMeshCreateParams){
512  .use_toolflags = false,
513  }));
517 
518  /* Restore the BMLog using saved entries. */
520 }
521 
523  SculptUndoNode *unode,
524  Object *ob,
525  SculptSession *ss)
526 {
527  if (unode->applied) {
529  unode->applied = false;
530  }
531  else {
532  sculpt_undo_bmesh_enable(ob, unode);
533 
534  /* Restore the mesh from the first log entry. */
535  BM_log_redo(ss->bm, ss->bm_log);
536 
537  unode->applied = true;
538  }
539 }
540 
542  SculptUndoNode *unode,
543  Object *ob,
544  SculptSession *ss)
545 {
546  if (unode->applied) {
547  sculpt_undo_bmesh_enable(ob, unode);
548 
549  /* Restore the mesh from the last log entry. */
550  BM_log_undo(ss->bm, ss->bm_log);
551 
552  unode->applied = false;
553  }
554  else {
555  /* Disable dynamic topology sculpting. */
557  unode->applied = true;
558  }
559 }
560 
562 {
563  Mesh *mesh = object->data;
564 
565  BLI_assert(!geometry->is_initialized);
566  geometry->is_initialized = true;
567 
572 
573  geometry->totvert = mesh->totvert;
574  geometry->totedge = mesh->totedge;
575  geometry->totloop = mesh->totloop;
576  geometry->totpoly = mesh->totpoly;
577 }
578 
580 {
581  Mesh *mesh = object->data;
582 
583  BLI_assert(geometry->is_initialized);
584 
590 
591  mesh->totvert = geometry->totvert;
592  mesh->totedge = geometry->totedge;
593  mesh->totloop = geometry->totloop;
594  mesh->totpoly = geometry->totpoly;
595  mesh->totface = 0;
596 
598  &geometry->vdata, &mesh->vdata, CD_MASK_MESH.vmask, CD_DUPLICATE, geometry->totvert);
600  &geometry->edata, &mesh->edata, CD_MASK_MESH.emask, CD_DUPLICATE, geometry->totedge);
602  &geometry->ldata, &mesh->ldata, CD_MASK_MESH.lmask, CD_DUPLICATE, geometry->totloop);
604  &geometry->pdata, &mesh->pdata, CD_MASK_MESH.pmask, CD_DUPLICATE, geometry->totpoly);
605 
607 
609 }
610 
612 {
613  if (geometry->totvert) {
614  CustomData_free(&geometry->vdata, geometry->totvert);
615  }
616  if (geometry->totedge) {
617  CustomData_free(&geometry->edata, geometry->totedge);
618  }
619  if (geometry->totloop) {
620  CustomData_free(&geometry->ldata, geometry->totloop);
621  }
622  if (geometry->totpoly) {
623  CustomData_free(&geometry->pdata, geometry->totpoly);
624  }
625 }
626 
628 {
629  if (unode->geometry_clear_pbvh) {
630  SCULPT_pbvh_clear(object);
631  }
632 
633  if (unode->applied) {
635  unode->applied = false;
636  }
637  else {
639  unode->applied = true;
640  }
641 }
642 
643 /* Handle all dynamic-topology updates
644  *
645  * Returns true if this was a dynamic-topology undo step, otherwise
646  * returns false to indicate the non-dyntopo code should run. */
648  SculptUndoNode *unode,
649  Object *ob,
650  SculptSession *ss)
651 {
652  switch (unode->type) {
654  sculpt_undo_bmesh_restore_begin(C, unode, ob, ss);
655  return true;
656 
658  sculpt_undo_bmesh_restore_end(C, unode, ob, ss);
659  return true;
660  default:
661  if (ss->bm_log) {
662  sculpt_undo_bmesh_restore_generic(unode, ob, ss);
663  return true;
664  }
665  break;
666  }
667 
668  return false;
669 }
670 
671 /* Geometry updates (such as Apply Base, for example) will re-evaluate the object and refine its
672  * Subdiv descriptor. Upon undo it is required that mesh, grids, and subdiv all stay consistent
673  * with each other. This means that when geometry coordinate changes the undo should refine the
674  * subdiv to the new coarse mesh coordinates. Tricky part is: this needs to happen without using
675  * dependency graph tag: tagging object for geometry update will either loose sculpted data from
676  * the sculpt grids, or will wrongly "commit" them to the CD_MDISPS.
677  *
678  * So what we do instead is do minimum object evaluation to get base mesh coordinates for the
679  * multires modifier input. While this is expensive, it is less expensive than dependency graph
680  * evaluation and is only happening when geometry coordinates changes on undo.
681  *
682  * Note that the dependency graph is ensured to be evaluated prior to the undo step is decoded,
683  * so if the object's modifier stack references other object it is all fine. */
685  SculptSession *ss,
686  Object *object,
687  struct Subdiv *subdiv)
688 {
690  depsgraph, object, ss->multires.modifier, NULL);
691 
692  BKE_subdiv_eval_refine_from_mesh(subdiv, object->data, deformed_verts);
693 
694  MEM_freeN(deformed_verts);
695 }
696 
698 {
700  ViewLayer *view_layer = CTX_data_view_layer(C);
702  Object *ob = OBACT(view_layer);
703  SculptSession *ss = ob->sculpt;
704  SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
705  SculptUndoNode *unode;
706  bool update = false, rebuild = false, update_mask = false, update_visibility = false;
707  bool need_mask = false;
708  bool need_refine_subdiv = false;
709 
710  for (unode = lb->first; unode; unode = unode->next) {
711  /* Restore pivot. */
712  copy_v3_v3(ss->pivot_pos, unode->pivot_pos);
713  copy_v3_v3(ss->pivot_rot, unode->pivot_rot);
714  if (STREQ(unode->idname, ob->id.name)) {
715  if (unode->type == SCULPT_UNDO_MASK) {
716  /* Is possible that we can't do the mask undo (below)
717  * because of the vertex count. */
718  need_mask = true;
719  break;
720  }
721  }
722  }
723 
725 
726  if (lb->first) {
727  unode = lb->first;
728  if (unode->type == SCULPT_UNDO_FACE_SETS) {
730 
731  rebuild = true;
733 
734  BKE_sculpt_update_object_for_edit(depsgraph, ob, true, need_mask, false);
735 
737 
739 
740  if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
742  }
743 
745  if (!BKE_sculptsession_use_pbvh_draw(ob, rv3d)) {
747  }
748 
749  unode->applied = true;
750  return;
751  }
752  }
753 
754  if (lb->first != NULL) {
755  /* Only do early object update for edits if first node needs this.
756  * Undo steps like geometry does not need object to be updated before they run and will
757  * ensure object is updated after the node is handled. */
758  const SculptUndoNode *first_unode = (const SculptUndoNode *)lb->first;
759  if (first_unode->type != SCULPT_UNDO_GEOMETRY) {
760  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask, false);
761  }
762 
763  if (sculpt_undo_bmesh_restore(C, lb->first, ob, ss)) {
764  return;
765  }
766  }
767 
768  /* The PBVH already keeps track of which vertices need updated normals, but it doesn't keep track
769  * of other updated. In order to tell the corresponding PBVH nodes to update, keep track of which
770  * elements were updated for specific layers. */
774  char *undo_modified_grids = NULL;
775  bool use_multires_undo = false;
776 
777  for (unode = lb->first; unode; unode = unode->next) {
778 
779  if (!STREQ(unode->idname, ob->id.name)) {
780  continue;
781  }
782 
783  /* Check if undo data matches current data well enough to
784  * continue. */
785  if (unode->maxvert) {
786  if (ss->totvert != unode->maxvert) {
787  continue;
788  }
789  }
790  else if (unode->maxgrid && subdiv_ccg != NULL) {
791  if ((subdiv_ccg->num_grids != unode->maxgrid) ||
792  (subdiv_ccg->grid_size != unode->gridsize)) {
793  continue;
794  }
795 
796  use_multires_undo = true;
797  }
798 
799  switch (unode->type) {
800  case SCULPT_UNDO_COORDS:
801  if (sculpt_undo_restore_coords(C, depsgraph, unode)) {
802  update = true;
803  }
804  break;
805  case SCULPT_UNDO_HIDDEN:
807  modified_hidden_vertices = MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__);
808  }
810  rebuild = true;
811  update_visibility = true;
812  }
813  break;
814  case SCULPT_UNDO_MASK:
815  if (modified_mask_vertices == NULL) {
816  modified_mask_vertices = MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__);
817  }
819  update = true;
820  update_mask = true;
821  }
822  break;
824  break;
825  case SCULPT_UNDO_COLOR:
826  if (modified_color_vertices == NULL) {
827  modified_color_vertices = MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__);
828  }
830  update = true;
831  }
832 
833  break;
835  need_refine_subdiv = true;
836  sculpt_undo_geometry_restore(unode, ob);
837  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask, false);
838  break;
839 
843  BLI_assert_msg(0, "Dynamic topology should've already been handled");
844  break;
845  }
846  }
847 
848  if (use_multires_undo) {
849  for (unode = lb->first; unode; unode = unode->next) {
850  if (!STREQ(unode->idname, ob->id.name)) {
851  continue;
852  }
853  if (unode->maxgrid == 0) {
854  continue;
855  }
856 
857  if (undo_modified_grids == NULL) {
858  undo_modified_grids = MEM_callocN(sizeof(char) * unode->maxgrid, "undo_grids");
859  }
860 
861  for (int i = 0; i < unode->totgrid; i++) {
862  undo_modified_grids[unode->grids[i]] = 1;
863  }
864  }
865  }
866 
867  if (subdiv_ccg != NULL && need_refine_subdiv) {
868  sculpt_undo_refine_subdiv(depsgraph, ss, ob, subdiv_ccg->subdiv);
869  }
870 
871  if (update || rebuild) {
872  bool tag_update = false;
873  /* We update all nodes still, should be more clever, but also
874  * needs to work correct when exiting/entering sculpt mode and
875  * the nodes get recreated, though in that case it could do all. */
876  struct PartialUpdateData data = {
877  .rebuild = rebuild,
878  .pbvh = ss->pbvh,
879  .modified_grids = undo_modified_grids,
880  .modified_hidden_vertices = modified_hidden_vertices,
881  .modified_mask_vertices = modified_mask_vertices,
882  .modified_color_vertices = modified_color_vertices,
883 
884  };
887 
888  if (update_mask) {
890  }
891 
892  if (update_visibility) {
895  }
896 
898  if (rebuild) {
900  }
901  else {
903  }
904  }
905 
906  tag_update |= ID_REAL_USERS(ob->data) > 1 || !BKE_sculptsession_use_pbvh_draw(ob, rv3d) ||
908 
909  if (tag_update) {
910  Mesh *mesh = ob->data;
912 
914  }
915 
916  if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && update_visibility) {
917  Mesh *mesh = ob->data;
919  }
920 
921  if (tag_update) {
923  }
924  else {
926  }
927  }
928 
932  MEM_SAFE_FREE(undo_modified_grids);
933 }
934 
936 {
937  SculptUndoNode *unode = lb->first;
938  while (unode != NULL) {
939  SculptUndoNode *unode_next = unode->next;
940  if (unode->co) {
941  MEM_freeN(unode->co);
942  }
943  if (unode->col) {
944  MEM_freeN(unode->col);
945  }
946  if (unode->loop_col) {
947  MEM_freeN(unode->loop_col);
948  }
949  if (unode->no) {
950  MEM_freeN(unode->no);
951  }
952  if (unode->index) {
953  MEM_freeN(unode->index);
954  }
955  if (unode->loop_index) {
956  MEM_freeN(unode->loop_index);
957  }
958  if (unode->grids) {
959  MEM_freeN(unode->grids);
960  }
961  if (unode->orig_co) {
962  MEM_freeN(unode->orig_co);
963  }
964  if (unode->vert_hidden) {
965  MEM_freeN(unode->vert_hidden);
966  }
967  if (unode->grid_hidden) {
968  for (int i = 0; i < unode->totgrid; i++) {
969  if (unode->grid_hidden[i]) {
970  MEM_freeN(unode->grid_hidden[i]);
971  }
972  }
973  MEM_freeN(unode->grid_hidden);
974  }
975  if (unode->mask) {
976  MEM_freeN(unode->mask);
977  }
978 
979  if (unode->bm_entry) {
980  BM_log_entry_drop(unode->bm_entry);
981  }
982 
986 
987  if (unode->face_sets) {
988  MEM_freeN(unode->face_sets);
989  }
990 
991  MEM_freeN(unode);
992 
993  unode = unode_next;
994  }
995 }
996 
997 /* Most likely we don't need this. */
998 #if 0
999 static bool sculpt_undo_cleanup(bContext *C, ListBase *lb)
1000 {
1002  ViewLayer *view_layer = CTX_data_view_layer(C);
1003  Object *ob = OBACT(view_layer);
1004  SculptUndoNode *unode;
1005 
1006  unode = lb->first;
1007 
1008  if (unode && !STREQ(unode->idname, ob->id.name)) {
1009  if (unode->bm_entry) {
1011  }
1012 
1013  return true;
1014  }
1015 
1016  return false;
1017 }
1018 #endif
1019 
1021 {
1022  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1023 
1024  if (usculpt == NULL) {
1025  return NULL;
1026  }
1027 
1028  LISTBASE_FOREACH (SculptUndoNode *, unode, &usculpt->nodes) {
1029  if (unode->node == node && unode->type == type) {
1030  return unode;
1031  }
1032  }
1033 
1034  return NULL;
1035 }
1036 
1038 {
1039  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1040 
1041  if (usculpt == NULL) {
1042  return NULL;
1043  }
1044 
1045  return usculpt->nodes.first;
1046 }
1047 
1049 {
1050  PBVHNode *node = unode->node;
1051  BLI_bitmap **grid_hidden = BKE_pbvh_grid_hidden(pbvh);
1052 
1053  int *grid_indices, totgrid;
1054  BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, NULL);
1055 
1056  size_t alloc_size = sizeof(*unode->grid_hidden) * (size_t)totgrid;
1057  unode->grid_hidden = MEM_callocN(alloc_size, "unode->grid_hidden");
1058 
1059  for (int i = 0; i < totgrid; i++) {
1060  if (grid_hidden[grid_indices[i]]) {
1061  unode->grid_hidden[i] = MEM_dupallocN(grid_hidden[grid_indices[i]]);
1062  alloc_size += MEM_allocN_len(unode->grid_hidden[i]);
1063  }
1064  else {
1065  unode->grid_hidden[i] = NULL;
1066  }
1067  }
1068 
1069  return alloc_size;
1070 }
1071 
1072 /* Allocate node and initialize its default fields specific for the given undo type.
1073  * Will also add the node to the list in the undo step. */
1075 {
1076  const size_t alloc_size = sizeof(SculptUndoNode);
1077  SculptUndoNode *unode = MEM_callocN(alloc_size, "SculptUndoNode");
1078  BLI_strncpy(unode->idname, object->id.name, sizeof(unode->idname));
1079  unode->type = type;
1080 
1081  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1082  BLI_addtail(&usculpt->nodes, unode);
1083  usculpt->undo_size += alloc_size;
1084 
1085  return unode;
1086 }
1087 
1088 /* Will return first existing undo node of the given type.
1089  * If such node does not exist will allocate node of this type, register it in the undo step and
1090  * return it. */
1092 {
1093  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1094 
1095  LISTBASE_FOREACH (SculptUndoNode *, unode, &usculpt->nodes) {
1096  if (unode->type == type) {
1097  return unode;
1098  }
1099  }
1100 
1101  return sculpt_undo_alloc_node_type(object, type);
1102 }
1103 
1105 {
1106  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1107  SculptSession *ss = ob->sculpt;
1108  int totvert = 0;
1109  int allvert = 0;
1110  int totgrid = 0;
1111  int maxgrid = 0;
1112  int gridsize = 0;
1113  int *grids = NULL;
1114 
1116  unode->node = node;
1117 
1118  if (node) {
1119  BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
1120  BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid, &maxgrid, &gridsize, NULL);
1121 
1122  unode->totvert = totvert;
1123  }
1124 
1125  bool need_loops = type == SCULPT_UNDO_COLOR;
1126 
1127  if (need_loops) {
1128  int totloop;
1129 
1130  BKE_pbvh_node_num_loops(ss->pbvh, node, &totloop);
1131 
1132  unode->loop_index = MEM_calloc_arrayN(totloop, sizeof(int), __func__);
1133  unode->maxloop = 0;
1134  unode->totloop = totloop;
1135 
1136  size_t alloc_size = sizeof(int) * (size_t)totloop;
1137  usculpt->undo_size += alloc_size;
1138  }
1139 
1140  switch (type) {
1141  case SCULPT_UNDO_COORDS: {
1142  size_t alloc_size = sizeof(*unode->co) * (size_t)allvert;
1143  unode->co = MEM_callocN(alloc_size, "SculptUndoNode.co");
1144  usculpt->undo_size += alloc_size;
1145 
1146  /* FIXME: Should explain why this is allocated here, to be freed in
1147  * `SCULPT_undo_push_end_ex()`? */
1148  alloc_size = sizeof(*unode->no) * (size_t)allvert;
1149  unode->no = MEM_callocN(alloc_size, "SculptUndoNode.no");
1150  usculpt->undo_size += alloc_size;
1151  break;
1152  }
1153  case SCULPT_UNDO_HIDDEN: {
1154  if (maxgrid) {
1155  usculpt->undo_size += sculpt_undo_alloc_and_store_hidden(ss->pbvh, unode);
1156  }
1157  else {
1158  unode->vert_hidden = BLI_BITMAP_NEW(allvert, "SculptUndoNode.vert_hidden");
1159  usculpt->undo_size += BLI_BITMAP_SIZE(allvert);
1160  }
1161 
1162  break;
1163  }
1164  case SCULPT_UNDO_MASK: {
1165  const size_t alloc_size = sizeof(*unode->mask) * (size_t)allvert;
1166  unode->mask = MEM_callocN(alloc_size, "SculptUndoNode.mask");
1167  usculpt->undo_size += alloc_size;
1168  break;
1169  }
1170  case SCULPT_UNDO_COLOR: {
1171  /* Allocate vertex colors, even for loop colors we still
1172  * need this for original data lookup. */
1173  const size_t alloc_size = sizeof(*unode->col) * (size_t)allvert;
1174  unode->col = MEM_callocN(alloc_size, "SculptUndoNode.col");
1175  usculpt->undo_size += alloc_size;
1176 
1177  /* Allocate loop colors separately too. */
1178  if (ss->vcol_domain == ATTR_DOMAIN_CORNER) {
1179  size_t alloc_size_loop = sizeof(float) * 4 * (size_t)unode->totloop;
1180 
1181  unode->loop_col = MEM_calloc_arrayN(
1182  unode->totloop, sizeof(float) * 4, "SculptUndoNode.loop_col");
1183  usculpt->undo_size += alloc_size_loop;
1184  }
1185  break;
1186  }
1190  BLI_assert_msg(0, "Dynamic topology should've already been handled");
1191  case SCULPT_UNDO_GEOMETRY:
1192  case SCULPT_UNDO_FACE_SETS:
1193  break;
1194  }
1195 
1196  if (maxgrid) {
1197  /* Multires. */
1198  unode->maxgrid = maxgrid;
1199  unode->totgrid = totgrid;
1200  unode->gridsize = gridsize;
1201 
1202  const size_t alloc_size = sizeof(*unode->grids) * (size_t)totgrid;
1203  unode->grids = MEM_callocN(alloc_size, "SculptUndoNode.grids");
1204  usculpt->undo_size += alloc_size;
1205  }
1206  else {
1207  /* Regular mesh. */
1208  unode->maxvert = ss->totvert;
1209 
1210  const size_t alloc_size = sizeof(*unode->index) * (size_t)allvert;
1211  unode->index = MEM_callocN(alloc_size, "SculptUndoNode.index");
1212  usculpt->undo_size += alloc_size;
1213  }
1214 
1215  if (ss->deform_modifiers_active) {
1216  const size_t alloc_size = sizeof(*unode->orig_co) * (size_t)allvert;
1217  unode->orig_co = MEM_callocN(alloc_size, "undoSculpt orig_cos");
1218  usculpt->undo_size += alloc_size;
1219  }
1220 
1221  return unode;
1222 }
1223 
1225 {
1226  SculptSession *ss = ob->sculpt;
1227  PBVHVertexIter vd;
1228 
1229  BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) {
1230  copy_v3_v3(unode->co[vd.i], vd.co);
1231  if (vd.no) {
1232  copy_v3_v3(unode->no[vd.i], vd.no);
1233  }
1234  else {
1235  copy_v3_v3(unode->no[vd.i], vd.fno);
1236  }
1237 
1238  if (ss->deform_modifiers_active) {
1239  copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]);
1240  }
1241  }
1243 }
1244 
1246 {
1247  PBVH *pbvh = ob->sculpt->pbvh;
1248  PBVHNode *node = unode->node;
1249 
1250  if (unode->grids) {
1251  /* Already stored during allocation. */
1252  }
1253  else {
1254  MVert *mvert;
1255  const int *vert_indices;
1256  int allvert;
1257 
1258  BKE_pbvh_node_num_verts(pbvh, node, NULL, &allvert);
1259  BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert);
1260  for (int i = 0; i < allvert; i++) {
1261  BLI_BITMAP_SET(unode->vert_hidden, i, mvert[vert_indices[i]].flag & ME_HIDE);
1262  }
1263  }
1264 }
1265 
1267 {
1268  SculptSession *ss = ob->sculpt;
1269  PBVHVertexIter vd;
1270 
1271  BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) {
1272  unode->mask[vd.i] = *vd.mask;
1273  }
1275 }
1276 
1278 {
1279  SculptSession *ss = ob->sculpt;
1280 
1282 
1283  int allvert;
1284  BKE_pbvh_node_num_verts(ss->pbvh, unode->node, NULL, &allvert);
1285 
1286  /* NOTE: even with loop colors we still store (derived)
1287  * vertex colors for original data lookup. */
1288  BKE_pbvh_store_colors_vertex(ss->pbvh, unode->index, allvert, unode->col);
1289 
1290  if (unode->loop_col && unode->totloop) {
1291  BKE_pbvh_store_colors(ss->pbvh, unode->loop_index, unode->totloop, unode->loop_col);
1292  }
1293 }
1294 
1296 {
1297  if (!unode->geometry_original.is_initialized) {
1298  return &unode->geometry_original;
1299  }
1300 
1302 
1303  return &unode->geometry_modified;
1304 }
1305 
1307 {
1309  unode->applied = false;
1310  unode->geometry_clear_pbvh = true;
1311 
1313  sculpt_undo_geometry_store_data(geometry, object);
1314 
1315  return unode;
1316 }
1317 
1319 {
1320  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1321  SculptUndoNode *unode = MEM_callocN(sizeof(*unode), __func__);
1322 
1323  BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
1324  unode->type = type;
1325  unode->applied = true;
1326 
1328 
1329  unode->face_sets = MEM_callocN(me->totpoly * sizeof(int), "sculpt face sets");
1330 
1331  const int *face_sets = CustomData_get_layer(&me->pdata, CD_SCULPT_FACE_SETS);
1332  for (int i = 0; i < me->totpoly; i++) {
1333  unode->face_sets[i] = face_sets[i];
1334  }
1335 
1336  BLI_addtail(&usculpt->nodes, unode);
1337 
1338  return unode;
1339 }
1340 
1342 {
1343  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1344  SculptSession *ss = ob->sculpt;
1345  PBVHVertexIter vd;
1346 
1347  SculptUndoNode *unode = usculpt->nodes.first;
1348 
1349  if (unode == NULL) {
1350  unode = MEM_callocN(sizeof(*unode), __func__);
1351 
1352  BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
1353  unode->type = type;
1354  unode->applied = true;
1355 
1356  if (type == SCULPT_UNDO_DYNTOPO_END) {
1357  unode->bm_entry = BM_log_entry_add(ss->bm_log);
1359  }
1360  else if (type == SCULPT_UNDO_DYNTOPO_BEGIN) {
1361  /* Store a copy of the mesh's current vertices, loops, and
1362  * polys. A full copy like this is needed because entering
1363  * dynamic-topology immediately does topological edits
1364  * (converting polys to triangles) that the BMLog can't
1365  * fully restore from. */
1366  SculptUndoNodeGeometry *geometry = &unode->geometry_bmesh_enter;
1367  sculpt_undo_geometry_store_data(geometry, ob);
1368 
1369  unode->bm_entry = BM_log_entry_add(ss->bm_log);
1370  BM_log_all_added(ss->bm, ss->bm_log);
1371  }
1372  else {
1373  unode->bm_entry = BM_log_entry_add(ss->bm_log);
1374  }
1375 
1376  BLI_addtail(&usculpt->nodes, unode);
1377  }
1378 
1379  if (node) {
1380  switch (type) {
1381  case SCULPT_UNDO_COORDS:
1382  case SCULPT_UNDO_MASK:
1383  /* Before any vertex values get modified, ensure their
1384  * original positions are logged. */
1387  }
1389  break;
1390 
1391  case SCULPT_UNDO_HIDDEN: {
1392  GSetIterator gs_iter;
1396  }
1398 
1399  GSET_ITER (gs_iter, faces) {
1400  BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
1401  BM_log_face_modified(ss->bm_log, f);
1402  }
1403  break;
1404  }
1405 
1409  case SCULPT_UNDO_GEOMETRY:
1410  case SCULPT_UNDO_FACE_SETS:
1411  case SCULPT_UNDO_COLOR:
1412  break;
1413  }
1414  }
1415 
1416  return unode;
1417 }
1418 
1420 {
1421  SculptSession *ss = ob->sculpt;
1422  SculptUndoNode *unode;
1423 
1424  /* List is manipulated by multiple threads, so we lock. */
1426 
1427  ss->needs_flush_to_id = 1;
1428 
1430  /* Dynamic topology stores only one undo node per stroke,
1431  * regardless of the number of PBVH nodes modified. */
1432  unode = sculpt_undo_bmesh_push(ob, node, type);
1434  return unode;
1435  }
1436  if (type == SCULPT_UNDO_GEOMETRY) {
1437  unode = sculpt_undo_geometry_push(ob, type);
1439  return unode;
1440  }
1441  if (type == SCULPT_UNDO_FACE_SETS) {
1442  unode = sculpt_undo_face_sets_push(ob, type);
1444  return unode;
1445  }
1446  if ((unode = SCULPT_undo_get_node(node, type))) {
1448  return unode;
1449  }
1450 
1451  unode = sculpt_undo_alloc_node(ob, node, type);
1452 
1453  /* NOTE: If this ever becomes a bottleneck, make a lock inside of the node.
1454  * so we release global lock sooner, but keep data locked for until it is
1455  * fully initialized.
1456  */
1457 
1458  if (unode->grids) {
1459  int totgrid, *grids;
1460  BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid, NULL, NULL, NULL);
1461  memcpy(unode->grids, grids, sizeof(int) * totgrid);
1462  }
1463  else {
1464  const int *vert_indices, *loop_indices;
1465  int allvert, allloop;
1466 
1467  BKE_pbvh_node_num_verts(ss->pbvh, unode->node, NULL, &allvert);
1468  BKE_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL);
1469  memcpy(unode->index, vert_indices, sizeof(int) * allvert);
1470 
1471  if (unode->loop_index) {
1472  BKE_pbvh_node_num_loops(ss->pbvh, unode->node, &allloop);
1473  BKE_pbvh_node_get_loops(ss->pbvh, unode->node, &loop_indices, NULL);
1474 
1475  if (allloop) {
1476  memcpy(unode->loop_index, loop_indices, sizeof(int) * allloop);
1477 
1479  }
1480  }
1481  }
1482 
1483  switch (type) {
1484  case SCULPT_UNDO_COORDS:
1485  sculpt_undo_store_coords(ob, unode);
1486  break;
1487  case SCULPT_UNDO_HIDDEN:
1488  sculpt_undo_store_hidden(ob, unode);
1489  break;
1490  case SCULPT_UNDO_MASK:
1491  sculpt_undo_store_mask(ob, unode);
1492  break;
1493  case SCULPT_UNDO_COLOR:
1494  sculpt_undo_store_color(ob, unode);
1495  break;
1499  BLI_assert_msg(0, "Dynamic topology should've already been handled");
1500  case SCULPT_UNDO_GEOMETRY:
1501  case SCULPT_UNDO_FACE_SETS:
1502  break;
1503  }
1504 
1505  /* Store sculpt pivot. */
1506  copy_v3_v3(unode->pivot_pos, ss->pivot_pos);
1507  copy_v3_v3(unode->pivot_rot, ss->pivot_rot);
1508 
1509  /* Store active shape key. */
1510  if (ss->shapekey_active) {
1511  BLI_strncpy(unode->shapeName, ss->shapekey_active->name, sizeof(ss->shapekey_active->name));
1512  }
1513  else {
1514  unode->shapeName[0] = '\0';
1515  }
1516 
1518 
1519  return unode;
1520 }
1521 
1523 {
1524  return a->domain == b->domain && a->type == b->type && STREQ(a->name, b->name);
1525 }
1526 
1528 {
1530  const CustomDataLayer *layer;
1531 
1532  if (ob && me && (layer = BKE_id_attributes_active_color_get((ID *)me))) {
1533  attr->domain = BKE_id_attribute_domain((ID *)me, layer);
1534  BLI_strncpy(attr->name, layer->name, sizeof(attr->name));
1535  attr->type = layer->type;
1536  }
1537  else {
1538  attr->domain = NO_ACTIVE_LAYER;
1539  attr->name[0] = 0;
1540  }
1541 
1542  attr->was_set = true;
1543 }
1544 
1545 void SCULPT_undo_push_begin(Object *ob, const char *name)
1546 {
1547  UndoStack *ustack = ED_undo_stack_get();
1548 
1549  if (ob != NULL) {
1550  /* If possible, we need to tag the object and its geometry data as 'changed in the future' in
1551  * the previous undo step if it's a memfile one. */
1554  }
1555 
1556  /* Special case, we never read from this. */
1557  bContext *C = NULL;
1558 
1560  ustack, C, name, BKE_UNDOSYS_TYPE_SCULPT);
1561 
1562  if (!us->active_color_start.was_set) {
1564  }
1565 
1566  /* Set end attribute in case SCULPT_undo_push_end is not called,
1567  * so we don't end up with corrupted state.
1568  */
1569  if (!us->active_color_end.was_set) {
1571  us->active_color_end.was_set = false;
1572  }
1573 }
1574 
1576 {
1577  SCULPT_undo_push_end_ex(ob, false);
1578 }
1579 
1580 void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo)
1581 {
1582  UndoSculpt *usculpt = sculpt_undo_get_nodes();
1583  SculptUndoNode *unode;
1584 
1585  /* We don't need normals in the undo stack. */
1586  for (unode = usculpt->nodes.first; unode; unode = unode->next) {
1587  if (unode->no) {
1588  usculpt->undo_size -= MEM_allocN_len(unode->no);
1589  MEM_freeN(unode->no);
1590  unode->no = NULL;
1591  }
1592  }
1593 
1594  /* We could remove this and enforce all callers run in an operator using 'OPTYPE_UNDO'. */
1595  wmWindowManager *wm = G_MAIN->wm.first;
1596  if (wm->op_undo_depth == 0 || use_nested_undo) {
1597  UndoStack *ustack = ED_undo_stack_get();
1598  BKE_undosys_step_push(ustack, NULL, NULL);
1599  if (wm->op_undo_depth == 0) {
1601  }
1603  }
1604 
1605  UndoStack *ustack = ED_undo_stack_get();
1607  ustack, BKE_UNDOSYS_TYPE_SCULPT);
1608 
1610 }
1611 
1612 /* -------------------------------------------------------------------- */
1617 {
1618  if (attr->domain == ATTR_DOMAIN_AUTO) {
1619  return;
1620  }
1621 
1624 
1625  SculptAttrRef existing;
1626  sculpt_save_active_attribute(ob, &existing);
1627 
1628  CustomDataLayer *layer;
1629  layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain);
1630 
1631  /* Temporary fix for T97408. This is a fundamental
1632  * bug in the undo stack; the operator code needs to push
1633  * an extra undo step before running an operator if a
1634  * non-memfile undo system is active.
1635  *
1636  * For now, detect if the layer does exist but with a different
1637  * domain and just unconvert it.
1638  */
1639  if (!layer) {
1641  eAttrDomain domain = layer ? BKE_id_attribute_domain(&me->id, layer) : ATTR_DOMAIN_NUM;
1642 
1643  if (layer && ED_geometry_attribute_convert(
1644  me, attr->name, layer->type, domain, attr->type, attr->domain)) {
1645  layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain);
1646  }
1647  }
1648 
1649  if (!layer) {
1650  /* Memfile undo killed the layer; re-create it. */
1651  CustomData *cdata = attr->domain == ATTR_DOMAIN_POINT ? &me->vdata : &me->ldata;
1652  int totelem = attr->domain == ATTR_DOMAIN_POINT ? me->totvert : me->totloop;
1653 
1654  CustomData_add_layer_named(cdata, attr->type, CD_DEFAULT, NULL, totelem, attr->name);
1655  layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain);
1656  }
1657 
1658  if (layer) {
1660 
1661  if (ob->sculpt && ob->sculpt->pbvh) {
1663 
1664  if (!sculpt_attribute_ref_equals(&existing, attr)) {
1666  }
1667  }
1668  }
1669 }
1670 
1672 {
1673  SculptUndoStep *us = (SculptUndoStep *)us_p;
1674  /* Dummy, memory is cleared anyway. */
1676 }
1677 
1679  struct Main *bmain,
1680  UndoStep *us_p)
1681 {
1682  /* Dummy, encoding is done along the way by adding tiles
1683  * to the current 'SculptUndoStep' added by encode_init. */
1684  SculptUndoStep *us = (SculptUndoStep *)us_p;
1685  us->step.data_size = us->data.undo_size;
1686 
1687  SculptUndoNode *unode = us->data.nodes.last;
1688  if (unode && unode->type == SCULPT_UNDO_DYNTOPO_END) {
1689  us->step.use_memfile_step = true;
1690  }
1691  us->step.is_applied = true;
1692 
1693  if (!BLI_listbase_is_empty(&us->data.nodes)) {
1694  bmain->is_memfile_undo_flush_needed = true;
1695  }
1696 
1697  return true;
1698 }
1699 
1702  SculptUndoStep *us)
1703 {
1704  BLI_assert(us->step.is_applied == true);
1705 
1707  us->step.is_applied = false;
1708 }
1709 
1712  SculptUndoStep *us)
1713 {
1714  BLI_assert(us->step.is_applied == false);
1715 
1717  us->step.is_applied = true;
1718 }
1719 
1722  SculptUndoStep *us,
1723  const bool is_final)
1724 {
1725  /* Walk forward over any applied steps of same type,
1726  * then walk back in the next loop, un-applying them. */
1727  SculptUndoStep *us_iter = us;
1728  while (us_iter->step.next && (us_iter->step.next->type == us_iter->step.type)) {
1729  if (us_iter->step.next->is_applied == false) {
1730  break;
1731  }
1732  us_iter = (SculptUndoStep *)us_iter->step.next;
1733  }
1734 
1735  while ((us_iter != us) || (!is_final && us_iter == us)) {
1736  BLI_assert(us_iter->step.type == us->step.type); /* Previous loop ensures this. */
1737 
1738  sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_color_start);
1740 
1741  if (us_iter == us) {
1742  if (us_iter->step.prev && us_iter->step.prev->type == BKE_UNDOSYS_TYPE_SCULPT) {
1743  sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter->step.prev)->active_color_end);
1744  }
1745  break;
1746  }
1747 
1748  us_iter = (SculptUndoStep *)us_iter->step.prev;
1749  }
1750 }
1751 
1754  SculptUndoStep *us)
1755 {
1756  SculptUndoStep *us_iter = us;
1757  while (us_iter->step.prev && (us_iter->step.prev->type == us_iter->step.type)) {
1758  if (us_iter->step.prev->is_applied == true) {
1759  break;
1760  }
1761  us_iter = (SculptUndoStep *)us_iter->step.prev;
1762  }
1763  while (us_iter && (us_iter->step.is_applied == false)) {
1764  sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_color_start);
1766 
1767  if (us_iter == us) {
1768  sculpt_undo_set_active_layer(C, &((SculptUndoStep *)us_iter)->active_color_end);
1769  break;
1770  }
1771  us_iter = (SculptUndoStep *)us_iter->step.next;
1772  }
1773 }
1774 
1776  struct bContext *C, struct Main *bmain, UndoStep *us_p, const eUndoStepDir dir, bool is_final)
1777 {
1778  /* NOTE: behavior for undo/redo closely matches image undo. */
1779  BLI_assert(dir != STEP_INVALID);
1780 
1782 
1783  /* Ensure sculpt mode. */
1784  {
1786  ViewLayer *view_layer = CTX_data_view_layer(C);
1787  Object *ob = OBACT(view_layer);
1788  if (ob && (ob->type == OB_MESH)) {
1789  if (ob->mode & (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT)) {
1790  /* Pass. */
1791  }
1792  else {
1794 
1795  /* Sculpt needs evaluated state.
1796  * NOTE: needs to be done here, as #ED_object_mode_generic_exit will usually invalidate
1797  * (some) evaluated data. */
1799 
1800  Mesh *me = ob->data;
1801  /* Don't add sculpt topology undo steps when reading back undo state.
1802  * The undo steps must enter/exit for us. */
1804  ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, true, NULL);
1805  }
1806 
1807  if (ob->sculpt) {
1808  ob->sculpt->needs_flush_to_id = 1;
1809  }
1810  bmain->is_memfile_undo_flush_needed = true;
1811  }
1812  else {
1813  BLI_assert(0);
1814  return;
1815  }
1816  }
1817 
1818  SculptUndoStep *us = (SculptUndoStep *)us_p;
1819  if (dir == STEP_UNDO) {
1821  }
1822  else if (dir == STEP_REDO) {
1824  }
1825 }
1826 
1828 {
1829  SculptUndoStep *us = (SculptUndoStep *)us_p;
1831 }
1832 
1833 void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
1834 {
1835  SCULPT_undo_push_begin(ob, name);
1837 }
1838 
1840 {
1843 }
1844 
1846 {
1847  ut->name = "Sculpt";
1848  ut->poll = NULL; /* No poll from context for now. */
1853 
1855 
1856  ut->step_size = sizeof(SculptUndoStep);
1857 }
1858 
1861 /* -------------------------------------------------------------------- */
1866 {
1867  SculptUndoStep *us = (SculptUndoStep *)us_p;
1868  return &us->data;
1869 }
1870 
1872 {
1873  UndoStack *ustack = ED_undo_stack_get();
1875  return sculpt_undosys_step_get_nodes(us);
1876 }
1877 
1880 /* -------------------------------------------------------------------- */
1903 {
1905  return false;
1906  }
1907 
1908  Object *object = CTX_data_active_object(C);
1909  SculptSession *sculpt_session = object->sculpt;
1910 
1911  return sculpt_session->multires.active;
1912 }
1913 
1915 {
1916  SculptSession *ss = object->sculpt;
1917 
1918  /* It is possible that undo push is done from an object state where there is no PBVH. This
1919  * happens, for example, when an operation which tagged for geometry update was performed prior
1920  * to the current operation without making any stroke in between.
1921  *
1922  * Skip pushing nodes based on the following logic: on redo SCULPT_UNDO_COORDS will ensure
1923  * PBVH for the new base geometry, which will have same coordinates as if we create PBVH here. */
1924  if (ss->pbvh == NULL) {
1925  return;
1926  }
1927 
1928  PBVHNode **nodes;
1929  int totnodes;
1930 
1931  BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnodes);
1932  for (int i = 0; i < totnodes; i++) {
1933  SculptUndoNode *unode = SCULPT_undo_push_node(object, nodes[i], SCULPT_UNDO_COORDS);
1934  unode->node = NULL;
1935  }
1936 
1937  MEM_SAFE_FREE(nodes);
1938 }
1939 
1941 {
1943  return;
1944  }
1945 
1946  Object *object = CTX_data_active_object(C);
1947 
1948  SCULPT_undo_push_begin(object, str);
1949 
1950  SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY);
1951  geometry_unode->geometry_clear_pbvh = false;
1952 
1954 }
1955 
1957 {
1959  ED_undo_push(C, str);
1960  return;
1961  }
1962 
1963  Object *object = CTX_data_active_object(C);
1964 
1965  SculptUndoNode *geometry_unode = SCULPT_undo_push_node(object, NULL, SCULPT_UNDO_GEOMETRY);
1966  geometry_unode->geometry_clear_pbvh = false;
1967 
1968  SCULPT_undo_push_end(object);
1969 }
1970 
typedef float(TangentPoint)[2]
Generic geometry attributes built on CustomData.
void BKE_id_attributes_active_color_set(struct ID *id, struct CustomDataLayer *active_layer)
Definition: attribute.cc:715
eAttrDomain
Definition: BKE_attribute.h:25
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
@ ATTR_DOMAIN_CORNER
Definition: BKE_attribute.h:30
@ ATTR_DOMAIN_AUTO
Definition: BKE_attribute.h:26
struct CustomDataLayer * BKE_id_attribute_find(const struct ID *id, const char *name, int type, eAttrDomain domain)
struct CustomDataLayer * BKE_id_attributes_active_color_get(const struct ID *id)
@ ATTR_DOMAIN_MASK_ALL
Definition: BKE_attribute.h:42
eAttrDomain BKE_id_attribute_domain(const struct ID *id, const struct CustomDataLayer *layer)
#define ATTR_DOMAIN_NUM
Definition: BKE_attribute.h:34
struct CustomDataLayer * BKE_id_attribute_search(struct ID *id, const char *name, eCustomDataMask type, eAttrDomainMask domain_mask)
Definition: attribute.cc:348
struct CCGElem CCGElem
Definition: BKE_ccg.h:30
BLI_INLINE float * CCG_elem_offset_co(const CCGKey *key, CCGElem *elem, int offset)
Definition: BKE_ccg.h:129
BLI_INLINE float * CCG_elem_offset_mask(const CCGKey *key, CCGElem *elem, int offset)
Definition: BKE_ccg.h:139
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
CustomData interface, see also DNA_customdata_types.h.
void CustomData_free(struct CustomData *data, int totelem)
Definition: customdata.cc:2373
@ CD_DUPLICATE
@ CD_DEFAULT
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
Definition: customdata.cc:2792
void * CustomData_get_layer(const struct CustomData *data, int type)
const CustomData_MeshMasks CD_MASK_MESH
Definition: customdata.cc:2065
#define G_MAIN
Definition: BKE_global.h:267
struct KeyBlock * BKE_keyblock_find_name(struct Key *key, const char name[])
Definition: key.c:1930
struct Key * BKE_key_from_object(struct Object *ob)
Definition: key.c:1803
float(* BKE_keyblock_convert_to_vertcos(const struct Object *ob, const struct KeyBlock *kb))[3]
void BKE_mesh_update_customdata_pointers(struct Mesh *me, bool do_ensure_tess_cd)
Definition: mesh.cc:874
void BKE_mesh_flush_hidden_from_verts(struct Mesh *me)
void BKE_mesh_tag_coords_changed(struct Mesh *mesh)
void BKE_mesh_runtime_clear_cache(struct Mesh *mesh)
This function clears runtime cache of the given mesh.
Definition: mesh_runtime.cc:99
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:249
void multires_mark_as_modified(struct Depsgraph *depsgraph, struct Object *object, enum MultiresModifiedFlags flags)
Definition: multires.c:387
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_original_mesh(const struct Object *object)
ePaintMode BKE_paintmode_get_active_from_context(const struct bContext *C)
struct MultiresModifierData * BKE_sculpt_multires_active(const struct Scene *scene, struct Object *ob)
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph, struct Object *ob_orig, bool need_pmap, bool need_mask, bool is_paint_tool)
Definition: paint.c:1914
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct RegionView3D *rv3d)
void BKE_sculptsession_free_deformMats(struct SculptSession *ss)
Definition: paint.c:1342
@ PAINT_MODE_SCULPT
Definition: BKE_paint.h:68
void BKE_pbvh_node_mark_update(PBVHNode *node)
Definition: pbvh.c:1869
void BKE_pbvh_node_get_verts(PBVH *pbvh, PBVHNode *node, const int **r_vert_indices, struct MVert **r_verts)
Definition: pbvh.c:1989
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:439
#define PBVH_ITER_ALL
Definition: BKE_pbvh.h:390
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node)
Definition: pbvh.c:1895
void BKE_pbvh_node_mark_update_color(PBVHNode *node)
Definition: pbvh.c:1880
void BKE_pbvh_update_active_vcol(PBVH *pbvh, const struct Mesh *mesh)
void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int *r_totvert)
Definition: pbvh.c:2003
void BKE_pbvh_swap_colors(PBVH *pbvh, const int *indices, const int indices_num, float(*colors)[4])
Definition: pbvh.cc:163
void BKE_pbvh_update_visibility(PBVH *pbvh)
Definition: pbvh.c:1711
void BKE_pbvh_store_colors_vertex(PBVH *pbvh, const int *indices, const int indices_num, float(*colors)[4])
Definition: pbvh.cc:193
PBVHType BKE_pbvh_type(const PBVH *pbvh)
Definition: pbvh.c:1798
void BKE_pbvh_store_colors(PBVH *pbvh, const int *indices, const int indices_num, float(*colors)[4])
Definition: pbvh.cc:179
bool BKE_pbvh_node_has_vert_with_normal_update_tag(PBVH *pbvh, PBVHNode *node)
Definition: pbvh.c:2126
void BKE_pbvh_vert_coords_apply(struct PBVH *pbvh, const float(*vertCos)[3], int totvert)
Definition: pbvh.c:2966
void BKE_pbvh_node_get_loops(PBVH *pbvh, PBVHNode *node, const int **r_loop_indices, const struct MLoop **r_loops)
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:509
void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, int index)
Definition: pbvh.c:1967
@ PBVH_GRIDS
Definition: BKE_pbvh.h:235
@ PBVH_FACES
Definition: BKE_pbvh.h:234
struct GSet * BKE_pbvh_bmesh_node_faces(PBVHNode *node)
Definition: pbvh_bmesh.c:2113
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:2037
void BKE_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden)
Definition: pbvh.c:1916
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3211
void BKE_pbvh_node_num_loops(PBVH *pbvh, PBVHNode *node, int *r_totloop)
Definition: pbvh.c:3260
void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags)
Definition: pbvh.c:1567
void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
Definition: pbvh.c:1875
void BKE_pbvh_update_bounds(PBVH *pbvh, int flags)
Definition: pbvh.c:1545
void BKE_pbvh_search_callback(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, BKE_pbvh_HitCallback hcb, void *hit_data)
Definition: pbvh.c:871
void BKE_pbvh_node_mark_redraw(PBVHNode *node)
Definition: pbvh.c:1906
unsigned int ** BKE_pbvh_grid_hidden(const PBVH *pbvh)
Definition: pbvh.c:1825
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
Definition: pbvh.c:838
@ PBVH_UpdateVisibility
Definition: BKE_pbvh.h:72
@ PBVH_UpdateMask
Definition: BKE_pbvh.h:71
@ PBVH_UpdateColor
Definition: BKE_pbvh.h:80
@ 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.cc:2653
void BKE_subdiv_ccg_key_top_level(struct CCGKey *key, const SubdivCCG *subdiv_ccg)
Definition: subdiv_ccg.c:668
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:69
@ MULTIRES_COORDS_MODIFIED
Definition: BKE_subsurf.h:67
@ UNDOTYPE_FLAG_DECODE_ACTIVE_STEP
const UndoType * BKE_UNDOSYS_TYPE_SCULPT
Definition: undo_system.c:57
UndoStep * BKE_undosys_step_push_init_with_type(UndoStack *ustack, struct bContext *C, const char *name, const UndoType *ut)
Definition: undo_system.c:449
eUndoPushReturn BKE_undosys_step_push(UndoStack *ustack, struct bContext *C, const char *name)
Definition: undo_system.c:593
UndoStep * BKE_undosys_stack_init_or_active_with_type(UndoStack *ustack, const UndoType *ut)
Definition: undo_system.c:373
eUndoStepDir
@ STEP_INVALID
@ STEP_UNDO
@ STEP_REDO
#define BKE_undosys_stack_limit_steps_and_memory_defaults(ustack)
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition: BLI_bitmap.h:40
#define BLI_BITMAP_TEST(_bitmap, _index)
Definition: BLI_bitmap.h:64
#define BLI_BITMAP_SIZE(_num)
Definition: BLI_bitmap.h:35
#define BLI_BITMAP_FLIP(_bitmap, _index)
Definition: BLI_bitmap.h:95
#define BLI_BITMAP_SET(_bitmap, _index, _set)
Definition: BLI_bitmap.h:102
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
struct GSet GSet
Definition: BLI_ghash.h:340
#define GSET_ITER(gs_iter_, gset_)
Definition: BLI_ghash.h:471
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition: BLI_ghash.h:458
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void swap_v3_v3(float a[3], float b[3])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
void BLI_thread_unlock(int type)
Definition: threads.cc:361
@ LOCK_CUSTOM1
Definition: BLI_threads.h:69
void BLI_thread_lock(int type)
Definition: threads.cc:356
#define SWAP(type, a, b)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_SHADING
Definition: DNA_ID.h:811
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
#define ID_REAL_USERS(id)
Definition: DNA_ID.h:553
#define MAX_CUSTOMDATA_LAYER_NAME
#define CD_MASK_PROP_ALL
@ CD_PAINT_MASK
@ CD_SCULPT_FACE_SETS
@ ME_SCULPT_DYNAMIC_TOPOLOGY
@ ME_HIDE
@ OB_MODE_SCULPT
@ OB_MODE_VERTEX_PAINT
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:387
void ED_object_sculptmode_enter_ex(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, bool force_dyntopo, struct ReportList *reports)
Definition: sculpt_ops.c:326
void ED_undo_push(struct bContext *C, const char *str)
Definition: ed_undo.c:100
struct UndoStack * ED_undo_stack_get(void)
Definition: ed_undo.c:473
void ED_undosys_stack_memfile_id_changed_tag(struct UndoStack *ustack, struct ID *id)
Definition: memfile_undo.c:352
_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:25
#define ND_DATA
Definition: WM_types.h:456
#define NC_OBJECT
Definition: WM_types.h:329
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:839
void BM_log_all_added(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:870
BMLogEntry * BM_log_entry_add(BMLog *log)
Definition: bmesh_log.c:620
void BM_log_cleanup_entry(BMLogEntry *entry)
Definition: bmesh_log.c:476
void BM_log_face_modified(BMLog *log, BMFace *f)
Definition: bmesh_log.c:797
void BM_log_redo(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:734
BMLog * BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry)
Definition: bmesh_log.c:498
void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
Definition: bmesh_log.c:768
void BM_log_entry_drop(BMLogEntry *entry)
Definition: bmesh_log.c:647
void BM_log_undo(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:713
void BM_log_before_all_removed(BMesh *bm, BMLog *log)
Definition: bmesh_log.c:897
const BMAllocTemplate bm_mesh_allocsize_default
Definition: bmesh_mesh.cc:23
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
Definition: bmesh_mesh.cc:125
ATTR_WARN_UNUSED_RESULT const BMVert * v
OperationNode * node
Scene scene
const Depsgraph * depsgraph
#define str(s)
bool ED_geometry_attribute_convert(Mesh *mesh, const char *layer_name, eCustomDataType old_type, eAttrDomain old_domain, eCustomDataType new_type, eAttrDomain new_domain)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:26
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static char faces[256]
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static void update(bNodeTree *ntree)
void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float(*vertCos)[3])
Definition: sculpt.c:3097
void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
Definition: sculpt.c:591
void SCULPT_update_object_bounding_box(Object *ob)
Definition: sculpt.c:5134
void SCULPT_visibility_sync_all_face_sets_to_vertices(Object *ob)
Definition: sculpt.c:557
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:1295
static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase *lb)
Definition: sculpt_undo.c:697
static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
Definition: sculpt_undo.c:342
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:1775
static void sculpt_undo_geometry_restore(SculptUndoNode *unode, Object *object)
Definition: sculpt_undo.c:627
static void update_cb_partial(PBVHNode *node, void *userdata)
Definition: sculpt_undo.c:155
struct SculptAttrRef SculptAttrRef
void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1833
static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:1266
static bool sculpt_undo_restore_deformed(const SculptSession *ss, SculptUndoNode *unode, int uindex, int oindex, float coord[3])
Definition: sculpt_undo.c:220
SculptUndoNode * SCULPT_undo_get_first_node()
Definition: sculpt_undo.c:1037
static void sculpt_undo_push_all_grids(Object *object)
Definition: sculpt_undo.c:1914
static SculptUndoNode * sculpt_undo_face_sets_push(Object *ob, SculptUndoType type)
Definition: sculpt_undo.c:1318
static bool sculpt_undo_use_multires_mesh(bContext *C)
Definition: sculpt_undo.c:1902
void ED_sculpt_undo_geometry_end(struct Object *ob)
Definition: sculpt_undo.c:1839
static void sculpt_undo_geometry_store_data(SculptUndoNodeGeometry *geometry, Object *object)
Definition: sculpt_undo.c:561
static SculptUndoNode * sculpt_undo_alloc_node(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1104
static size_t sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *unode)
Definition: sculpt_undo.c:1048
void SCULPT_undo_push_end(Object *ob)
Definition: sculpt_undo.c:1575
void ED_sculpt_undosys_type(UndoType *ut)
Definition: sculpt_undo.c:1845
static bool sculpt_attribute_ref_equals(SculptAttrRef *a, SculptAttrRef *b)
Definition: sculpt_undo.c:1522
static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p)
Definition: sculpt_undo.c:1671
static void sculpt_undo_refine_subdiv(Depsgraph *depsgraph, SculptSession *ss, Object *object, struct Subdiv *subdiv)
Definition: sculpt_undo.c:684
static bool sculpt_undo_restore_face_sets(bContext *C, SculptUndoNode *unode)
Definition: sculpt_undo.c:450
void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo)
Definition: sculpt_undo.c:1580
#define NO_ACTIVE_LAYER
Definition: sculpt_undo.c:100
static SculptUndoNode * sculpt_undo_alloc_node_type(Object *object, SculptUndoType type)
Definition: sculpt_undo.c:1074
static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr)
Definition: sculpt_undo.c:1616
static UndoSculpt * sculpt_undosys_step_get_nodes(UndoStep *us_p)
Definition: sculpt_undo.c:1865
static void sculpt_undosys_step_decode_redo(struct bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
Definition: sculpt_undo.c:1752
void ED_sculpt_undo_push_multires_mesh_begin(bContext *C, const char *str)
Definition: sculpt_undo.c:1940
static UndoSculpt * sculpt_undo_get_nodes(void)
Definition: sculpt_undo.c:1871
static SculptUndoNode * sculpt_undo_geometry_push(Object *object, SculptUndoType type)
Definition: sculpt_undo.c:1306
static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, SculptUndoNode *unode)
Definition: sculpt_undo.c:230
static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
Definition: sculpt_undo.c:404
static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C), struct Main *bmain, UndoStep *us_p)
Definition: sculpt_undo.c:1678
static void sculpt_undo_bmesh_enable(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:502
void ED_sculpt_undo_push_multires_mesh_end(bContext *C, const char *str)
Definition: sculpt_undo.c:1956
static bool sculpt_undo_restore_color(bContext *C, SculptUndoNode *unode, bool *modified_vertices)
Definition: sculpt_undo.c:372
static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:1245
static void sculpt_undo_bmesh_restore_begin(bContext *C, SculptUndoNode *unode, Object *ob, SculptSession *ss)
Definition: sculpt_undo.c:522
static void update_cb(PBVHNode *node, void *rebuild)
Definition: sculpt_undo.c:133
SculptUndoNode * SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1419
SculptUndoNode * SCULPT_undo_get_node(PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1020
static SculptUndoNode * sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1341
void SCULPT_undo_push_begin(Object *ob, const char *name)
Definition: sculpt_undo.c:1545
static void sculpt_undo_store_color(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:1277
static void sculpt_undo_geometry_restore_data(SculptUndoNodeGeometry *geometry, Object *object)
Definition: sculpt_undo.c:579
static int sculpt_undo_bmesh_restore(bContext *C, SculptUndoNode *unode, Object *ob, SculptSession *ss)
Definition: sculpt_undo.c:647
static void sculpt_undo_free_list(ListBase *lb)
Definition: sculpt_undo.c:935
static void sculpt_undosys_step_decode_redo_impl(struct bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
Definition: sculpt_undo.c:1710
static SculptUndoNode * sculpt_undo_find_or_alloc_node_type(Object *object, SculptUndoType type)
Definition: sculpt_undo.c:1091
static void sculpt_undosys_step_decode_undo_impl(struct bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
Definition: sculpt_undo.c:1700
struct SculptUndoStep SculptUndoStep
static void sculpt_undo_bmesh_restore_end(bContext *C, SculptUndoNode *unode, Object *ob, SculptSession *ss)
Definition: sculpt_undo.c:541
static void sculpt_save_active_attribute(Object *ob, SculptAttrRef *attr)
Definition: sculpt_undo.c:1527
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:462
static void sculpt_undosys_step_free(UndoStep *us_p)
Definition: sculpt_undo.c:1827
static bool test_swap_v3_v3(float a[3], float b[3])
Definition: sculpt_undo.c:210
static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode)
Definition: sculpt_undo.c:1224
static void sculpt_undosys_step_decode_undo(struct bContext *C, Depsgraph *depsgraph, SculptUndoStep *us, const bool is_final)
Definition: sculpt_undo.c:1720
static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob, SculptSession *ss)
Definition: sculpt_undo.c:470
static void sculpt_undo_geometry_free_data(SculptUndoNodeGeometry *geometry)
Definition: sculpt_undo.c:611
CustomData vdata
Definition: bmesh_class.h:337
Definition: BKE_ccg.h:32
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
char name[64]
Definition: DNA_key_types.h:52
ListBase block
Definition: DNA_key_types.h:84
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
char is_memfile_undo_flush_needed
Definition: BKE_main.h:145
CustomData vdata
uint16_t flag
int totedge
int totvert
int totface
CustomData pdata
CustomData fdata
int totpoly
CustomData edata
int totloop
CustomData ldata
short shapenr
struct SculptSession * sculpt
void * data
float * co
Definition: BKE_pbvh.h:430
int cd_vert_mask_offset
Definition: BKE_pbvh.h:424
float * fno
Definition: BKE_pbvh.h:432
float * no
Definition: BKE_pbvh.h:431
struct BMVert * bm_vert
Definition: BKE_pbvh.h:429
float * mask
Definition: BKE_pbvh.h:433
bool * modified_mask_vertices
Definition: sculpt_undo.c:148
bool * modified_hidden_vertices
Definition: sculpt_undo.c:147
bool * modified_color_vertices
Definition: sculpt_undo.c:149
char name[MAX_CUSTOMDATA_LAYER_NAME]
Definition: sculpt_undo.c:111
eAttrDomain domain
Definition: sculpt_undo.c:109
struct SubdivCCG * subdiv_ccg
Definition: BKE_paint.h:547
float(* orig_cos)[3]
Definition: BKE_paint.h:556
float pivot_pos[3]
Definition: BKE_paint.h:612
struct MVert * mvert
Definition: BKE_paint.h:498
struct KeyBlock * shapekey_active
Definition: BKE_paint.h:505
struct BMesh * bm
Definition: BKE_paint.h:539
struct BMLog * bm_log
Definition: BKE_paint.h:544
float pivot_rot[4]
Definition: BKE_paint.h:613
float * vmask
Definition: BKE_paint.h:512
struct SculptSession::@52 multires
char needs_flush_to_id
Definition: BKE_paint.h:651
struct MultiresModifierData * modifier
Definition: BKE_paint.h:490
eAttrDomain vcol_domain
Definition: BKE_paint.h:509
float(* deform_cos)[3]
Definition: BKE_paint.h:557
struct PBVH * pbvh
Definition: BKE_paint.h:550
bool deform_modifiers_active
Definition: BKE_paint.h:555
float(* col)[4]
struct BMLogEntry * bm_entry
bool geometry_clear_pbvh
float(* no)[3]
BLI_bitmap * vert_hidden
float(* co)[3]
BLI_bitmap ** grid_hidden
char idname[MAX_ID_NAME]
float(* loop_col)[4]
SculptUndoNodeGeometry geometry_modified
SculptUndoNodeGeometry geometry_bmesh_enter
char shapeName[sizeof(((KeyBlock *) 0)) ->name]
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:118
bContext * C
Definition: sculpt_undo.c:126
UndoStep step
Definition: sculpt_undo.c:116
SculptAttrRef active_color_start
Definition: sculpt_undo.c:121
SculptAttrRef active_color_end
Definition: sculpt_undo.c:124
struct CCGElem ** grids
struct Subdiv * subdiv
BLI_bitmap ** grid_hidden
size_t undo_size
Definition: sculpt_undo.c:105
ListBase nodes
Definition: sculpt_undo.c:103
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, 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)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_file_tag_modified(void)
Definition: wm_files.c:150