Blender  V2.93
sculpt_dyntopo.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) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_blenlib.h"
27 #include "BLI_hash.h"
28 #include "BLI_math.h"
29 #include "BLI_task.h"
30 
31 #include "BLT_translation.h"
32 
33 #include "DNA_mesh_types.h"
34 #include "DNA_meshdata_types.h"
35 #include "DNA_modifier_types.h"
36 
37 #include "BKE_brush.h"
38 #include "BKE_context.h"
39 #include "BKE_global.h"
40 #include "BKE_main.h"
41 #include "BKE_mesh.h"
42 #include "BKE_mesh_mapping.h"
43 #include "BKE_modifier.h"
44 #include "BKE_object.h"
45 #include "BKE_paint.h"
46 #include "BKE_particle.h"
47 #include "BKE_pbvh.h"
48 #include "BKE_pointcache.h"
49 #include "BKE_scene.h"
50 #include "BKE_screen.h"
51 
52 #include "DEG_depsgraph.h"
53 
54 #include "WM_api.h"
55 #include "WM_message.h"
56 #include "WM_toolsystem.h"
57 #include "WM_types.h"
58 
59 #include "ED_object.h"
60 #include "ED_screen.h"
61 #include "ED_sculpt.h"
62 #include "ED_undo.h"
63 #include "ED_view3d.h"
64 #include "paint_intern.h"
65 #include "sculpt_intern.h"
66 
67 #include "RNA_access.h"
68 #include "RNA_define.h"
69 
70 #include "UI_interface.h"
71 #include "UI_resources.h"
72 
73 #include "bmesh.h"
74 #include "bmesh_tools.h"
75 
76 #include <math.h>
77 #include <stdlib.h>
78 
80 {
81  if (bm->totloop != bm->totface * 3) {
84  }
85 }
86 
88 {
89  SculptSession *ss = ob->sculpt;
90 
91  /* Clear out any existing DM and PBVH. */
92  if (ss->pbvh) {
93  BKE_pbvh_free(ss->pbvh);
94  ss->pbvh = NULL;
95  }
96 
97  if (ss->pmap) {
98  MEM_freeN(ss->pmap);
99  ss->pmap = NULL;
100  }
101 
102  if (ss->pmap_mem) {
103  MEM_freeN(ss->pmap_mem);
104  ss->pmap_mem = NULL;
105  }
106 
108 
109  /* Tag to rebuild PBVH in depsgraph. */
111 }
112 
114 {
115  int cd_node_layer_index;
116 
117  char layer_id[] = "_dyntopo_node_id";
118 
119  cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_INT32, layer_id);
120  if (cd_node_layer_index == -1) {
121  BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_INT32, layer_id);
122  cd_node_layer_index = CustomData_get_named_layer_index(
123  &ss->bm->vdata, CD_PROP_INT32, layer_id);
124  }
125 
127  &ss->bm->vdata,
129  cd_node_layer_index - CustomData_get_layer_index(&ss->bm->vdata, CD_PROP_INT32));
130 
131  ss->bm->vdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
132 
133  cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT32, layer_id);
134  if (cd_node_layer_index == -1) {
135  BM_data_layer_add_named(ss->bm, &ss->bm->pdata, CD_PROP_INT32, layer_id);
136  cd_node_layer_index = CustomData_get_named_layer_index(
137  &ss->bm->pdata, CD_PROP_INT32, layer_id);
138  }
139 
141  &ss->bm->pdata,
143  cd_node_layer_index - CustomData_get_layer_index(&ss->bm->pdata, CD_PROP_INT32));
144 
145  ss->bm->pdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY;
146 }
147 
149 {
150  SculptSession *ss = ob->sculpt;
151  Mesh *me = ob->data;
152  const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
153 
154  SCULPT_pbvh_clear(ob);
155 
157  0;
158 
159  /* Dynamic topology doesn't ensure selection state is valid, so remove T36280. */
161 
162  /* Create triangles-only BMesh. */
163  ss->bm = BM_mesh_create(&allocsize,
164  &((struct BMeshCreateParams){
165  .use_toolflags = false,
166  }));
167 
169  me,
170  (&(struct BMeshFromMeshParams){
171  .calc_face_normal = true,
172  .use_shapekey = true,
173  .active_shapekey = ob->shapenr,
174  }));
178  /* Make sure the data for existing faces are initialized. */
179  if (me->totpoly != ss->bm->totface) {
181  }
182 
183  /* Enable dynamic topology. */
185 
186  /* Enable logging for undo/redo. */
187  ss->bm_log = BM_log_create(ss->bm);
188 
189  /* Update dependency graph, so modifiers that depend on dyntopo being enabled
190  * are re-evaluated and the PBVH is re-created. */
193 }
194 
195 /* Free the sculpt BMesh and BMLog
196  *
197  * If 'unode' is given, the BMesh's data is copied out to the unode
198  * before the BMesh is deleted so that it can be restored from. */
200  Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, SculptUndoNode *unode)
201 {
202  SculptSession *ss = ob->sculpt;
203  Mesh *me = ob->data;
204 
205  SCULPT_pbvh_clear(ob);
206 
207  if (unode) {
208  /* Free all existing custom data. */
209  CustomData_free(&me->vdata, me->totvert);
210  CustomData_free(&me->edata, me->totedge);
211  CustomData_free(&me->fdata, me->totface);
212  CustomData_free(&me->ldata, me->totloop);
213  CustomData_free(&me->pdata, me->totpoly);
214 
215  /* Copy over stored custom data. */
216  SculptUndoNodeGeometry *geometry = &unode->geometry_bmesh_enter;
217  me->totvert = geometry->totvert;
218  me->totloop = geometry->totloop;
219  me->totpoly = geometry->totpoly;
220  me->totedge = geometry->totedge;
221  me->totface = 0;
223  &geometry->vdata, &me->vdata, CD_MASK_MESH.vmask, CD_DUPLICATE, geometry->totvert);
225  &geometry->edata, &me->edata, CD_MASK_MESH.emask, CD_DUPLICATE, geometry->totedge);
227  &geometry->ldata, &me->ldata, CD_MASK_MESH.lmask, CD_DUPLICATE, geometry->totloop);
229  &geometry->pdata, &me->pdata, CD_MASK_MESH.pmask, CD_DUPLICATE, geometry->totpoly);
230 
232  }
233  else {
234  BKE_sculptsession_bm_to_me(ob, true);
235 
236  /* Reset Face Sets as they are no longer valid. */
237  if (!CustomData_has_layer(&me->pdata, CD_SCULPT_FACE_SETS)) {
239  }
241  for (int i = 0; i < me->totpoly; i++) {
242  ss->face_sets[i] = 1;
243  }
244  me->face_sets_color_default = 1;
245 
246  /* Sync the visibility to vertices manually as the pmap is still not initialized. */
247  for (int i = 0; i < me->totvert; i++) {
248  me->mvert[i].flag &= ~ME_HIDE;
249  me->mvert[i].flag |= ME_VERT_PBVH_UPDATE;
250  }
251  }
252 
253  /* Clear data. */
255 
256  /* Typically valid but with global-undo they can be NULL, see: T36234. */
257  if (ss->bm) {
258  BM_mesh_free(ss->bm);
259  ss->bm = NULL;
260  }
261  if (ss->bm_log) {
262  BM_log_free(ss->bm_log);
263  ss->bm_log = NULL;
264  }
265 
268 
269  /* Update dependency graph, so modifiers that depend on dyntopo being enabled
270  * are re-evaluated and the PBVH is re-created. */
273 }
274 
276 {
277  Main *bmain = CTX_data_main(C);
282 }
283 
286  Scene *scene,
287  Object *ob)
288 {
289  SculptSession *ss = ob->sculpt;
290  if (ss->bm != NULL) {
291  /* May be false in background mode. */
292  const bool use_undo = G.background ? (ED_undo_stack_get() != NULL) : true;
293  if (use_undo) {
294  SCULPT_undo_push_begin(ob, "Dynamic topology disable");
296  }
298  if (use_undo) {
300  }
301  }
302 }
303 
306  Scene *scene,
307  Object *ob)
308 {
309  SculptSession *ss = ob->sculpt;
310  if (ss->bm == NULL) {
311  /* May be false in background mode. */
312  const bool use_undo = G.background ? (ED_undo_stack_get() != NULL) : true;
313  if (use_undo) {
314  SCULPT_undo_push_begin(ob, "Dynamic topology enable");
315  }
317  if (use_undo) {
320  }
321  }
322 }
323 
325 {
326  Main *bmain = CTX_data_main(C);
330  SculptSession *ss = ob->sculpt;
331 
332  WM_cursor_wait(true);
333 
334  if (ss->bm) {
336  }
337  else {
339  }
340 
341  WM_cursor_wait(false);
343 
344  return OPERATOR_FINISHED;
345 }
346 
348 {
349  uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Warning!"), ICON_ERROR);
350  uiLayout *layout = UI_popup_menu_layout(pup);
351 
353  const char *msg_error = TIP_("Vertex Data Detected!");
354  const char *msg = TIP_("Dyntopo will not preserve vertex colors, UVs, or other customdata");
355  uiItemL(layout, msg_error, ICON_INFO);
356  uiItemL(layout, msg, ICON_NONE);
357  uiItemS(layout);
358  }
359 
360  if (flag & DYNTOPO_WARN_MODIFIER) {
361  const char *msg_error = TIP_("Generative Modifiers Detected!");
362  const char *msg = TIP_(
363  "Keeping the modifiers will increase polycount when returning to object mode");
364 
365  uiItemL(layout, msg_error, ICON_INFO);
366  uiItemL(layout, msg, ICON_NONE);
367  uiItemS(layout);
368  }
369 
370  uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, NULL);
371 
372  UI_popup_menu_end(C, pup);
373 
374  return OPERATOR_INTERFACE;
375 }
376 
378 {
379  Mesh *me = ob->data;
380  SculptSession *ss = ob->sculpt;
381 
382  enum eDynTopoWarnFlag flag = 0;
383 
384  BLI_assert(ss->bm == NULL);
385  UNUSED_VARS_NDEBUG(ss);
386 
387  for (int i = 0; i < CD_NUMTYPES; i++) {
389  if (CustomData_has_layer(&me->vdata, i)) {
390  flag |= DYNTOPO_WARN_VDATA;
391  }
392  if (CustomData_has_layer(&me->edata, i)) {
393  flag |= DYNTOPO_WARN_EDATA;
394  }
395  if (CustomData_has_layer(&me->ldata, i)) {
396  flag |= DYNTOPO_WARN_LDATA;
397  }
398  }
399  }
400 
401  {
402  VirtualModifierData virtualModifierData;
403  ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
404 
405  /* Exception for shape keys because we can edit those. */
406  for (; md; md = md->next) {
407  const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
409  continue;
410  }
411 
412  if (mti->type == eModifierTypeType_Constructive) {
413  flag |= DYNTOPO_WARN_MODIFIER;
414  break;
415  }
416  }
417  }
418 
419  return flag;
420 }
421 
423  wmOperator *op,
424  const wmEvent *UNUSED(event))
425 {
427  SculptSession *ss = ob->sculpt;
428 
429  if (!ss->bm) {
432 
433  if (flag) {
434  /* The mesh has customdata that will be lost, let the user confirm this is OK. */
435  return dyntopo_warning_popup(C, op->type, flag);
436  }
437  }
438 
440 }
441 
443 {
444  /* Identifiers. */
445  ot->name = "Dynamic Topology Toggle";
446  ot->idname = "SCULPT_OT_dynamic_topology_toggle";
447  ot->description = "Dynamic topology alters the mesh topology while sculpting";
448 
449  /* API callbacks. */
453 
455 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
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 Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
void CustomData_free(struct CustomData *data, int totelem)
Definition: customdata.c:2239
@ CD_CALLOC
@ CD_DUPLICATE
bool CustomData_has_layer(const struct CustomData *data, int type)
int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name)
int CustomData_get_layer_index(const struct CustomData *data, int type)
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.c:2620
int CustomData_get_n_offset(const struct CustomData *data, int type, int n)
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
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd)
Definition: mesh.c:766
void BKE_mesh_mselect_clear(struct Mesh *me)
Definition: mesh.c:1608
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
bool BKE_modifier_is_enabled(const struct Scene *scene, struct ModifierData *md, int required_mode)
struct ModifierData * BKE_modifiers_get_virtual_modifierlist(const struct Object *ob, struct VirtualModifierData *data)
@ eModifierTypeType_Constructive
Definition: BKE_modifier.h:61
General operations, lookup, etc. for blender objects.
void BKE_object_free_derived_caches(struct Object *ob)
Definition: object.c:1719
void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder)
Definition: paint.c:1398
void BKE_particlesystem_reset_all(struct Object *object)
A BVH for high poly meshes.
void BKE_pbvh_free(PBVH *pbvh)
Definition: pbvh.c:679
#define PTCACHE_RESET_OUTDATED
int BKE_ptcache_object_reset(struct Scene *scene, struct Object *ob, int mode)
Definition: pointcache.c:2953
void BKE_scene_graph_update_tagged(struct Depsgraph *depsgraph, struct Main *bmain)
Definition: scene.c:2713
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define ELEM(...)
#define TIP_(msgid)
#define IFACE_(msgid)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ CD_PAINT_MASK
@ CD_ORIGINDEX
@ CD_NUMTYPES
@ CD_PROP_INT32
@ CD_SCULPT_FACE_SETS
@ CD_MVERT
@ CD_FLAG_TEMPORARY
@ ME_SCULPT_DYNAMIC_TOPOLOGY
@ ME_HIDE
@ ME_VERT_PBVH_UPDATE
@ MOD_TRIANGULATE_QUAD_BEAUTY
@ eModifierMode_Realtime
@ MOD_TRIANGULATE_NGON_EARCLIP
@ SCULPT_DYNTOPO_SMOOTH_SHADING
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
struct UndoStack * ED_undo_stack_get(void)
Definition: ed_undo.c:501
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
void uiItemL(uiLayout *layout, const char *name, int icon)
struct uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void uiItemS(uiLayout *layout)
void uiItemFullO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr)
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL()
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:204
#define NC_SCENE
Definition: WM_types.h:279
#define ND_TOOLSETTINGS
Definition: WM_types.h:349
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
Definition: bmesh_interp.c:894
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name)
Definition: bmesh_interp.c:912
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMLog * BM_log_create(BMesh *bm)
Definition: bmesh_log.c:472
void BM_log_free(BMLog *log)
Definition: bmesh_log.c:559
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
Definition: bmesh_mesh.c:307
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
BMesh Make Mesh.
Definition: bmesh_mesh.c:157
void BM_mesh_normals_update(BMesh *bm)
BMesh Compute Normals.
Definition: bmesh_mesh.c:500
#define BMALLOC_TEMPLATE_FROM_ME(...)
Definition: bmesh_mesh.h:163
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
Mesh -> BMesh.
void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const int min_vertices, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out)
Scene scene
const Depsgraph * depsgraph
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
bool SCULPT_mode_poll(bContext *C)
Definition: sculpt.c:6601
static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op))
static void SCULPT_dynamic_topology_disable_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, SculptUndoNode *unode)
enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob)
void SCULPT_pbvh_clear(Object *ob)
void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot)
static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoWarnFlag flag)
void sculpt_dynamic_topology_disable_with_undo(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
void SCULPT_dynamic_topology_disable(bContext *C, SculptUndoNode *unode)
void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
void SCULPT_dynamic_topology_triangulate(BMesh *bm)
static void sculpt_dynamic_topology_enable_with_undo(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
void SCULPT_undo_push_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1383
void SCULPT_undo_push_end(void)
Definition: sculpt_undo.c:1400
eDynTopoWarnFlag
@ DYNTOPO_WARN_LDATA
@ DYNTOPO_WARN_MODIFIER
@ DYNTOPO_WARN_VDATA
@ DYNTOPO_WARN_EDATA
SculptUndoNode * SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1292
@ SCULPT_UNDO_DYNTOPO_END
@ SCULPT_UNDO_DYNTOPO_BEGIN
CustomData vdata
Definition: bmesh_class.h:337
int totloop
Definition: bmesh_class.h:297
CustomData pdata
Definition: bmesh_class.h:337
int totface
Definition: bmesh_class.h:297
CustomDataLayer * layers
Definition: BKE_main.h:116
struct CustomData pdata ldata
struct MVert * mvert
int totedge
int totvert
short flag
int totface
struct CustomData vdata edata fdata
int totpoly
int face_sets_color_default
int totloop
struct ModifierData * next
ModifierTypeType type
Definition: BKE_modifier.h:173
struct SculptSession * sculpt
void * data
struct ToolSettings * toolsettings
int cd_face_node_offset
Definition: BKE_paint.h:495
bool bm_smooth_shading
Definition: BKE_paint.h:496
int cd_vert_node_offset
Definition: BKE_paint.h:494
int * face_sets
Definition: BKE_paint.h:490
int * pmap_mem
Definition: BKE_paint.h:475
struct BMesh * bm
Definition: BKE_paint.h:493
struct BMLog * bm_log
Definition: BKE_paint.h:498
struct MeshElemMap * pmap
Definition: BKE_paint.h:474
struct PBVH * pbvh
Definition: BKE_paint.h:504
SculptUndoNodeGeometry geometry_bmesh_enter
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct wmOperatorType * type
#define G(x, y, z)
void WM_cursor_wait(bool val)
Definition: wm_cursors.c:226
void WM_main_add_notifier(unsigned int type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3156