[Bf-blender-cvs] [307f13aee57] sculpt-dev: Sculpt-dev: new PBVH caching system

Joseph Eagar noreply at git.blender.org
Sat Mar 19 05:16:21 CET 2022


Commit: 307f13aee5773a60a3f9acca272599695c04b00a
Author: Joseph Eagar
Date:   Fri Mar 18 21:12:43 2022 -0700
Branches: sculpt-dev
https://developer.blender.org/rB307f13aee5773a60a3f9acca272599695c04b00a

Sculpt-dev: new PBVH caching system

* Still experimental
* PBVHs are cached in a global map keyed by
  object name (though at the moment only one pbvh
  is cached at a time).
* ss->pmap is now freed managed by pbvh.
* ss->bm is freed by the pbvh cache in some
  circumstances but is stilled owned by SculptSession.

===================================================================

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/blender.c
M	source/blender/blenkernel/intern/object.cc
M	source/blender/blenkernel/intern/object_update.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_detail.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_ops.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/makesdna/DNA_object_types.h
M	source/creator/creator.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 0e39e98f383..c34f9406c5d 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -767,6 +767,8 @@ typedef struct SculptSession {
 
   /* PBVH acceleration structure */
   struct PBVH *pbvh;
+  struct PBVH *last_pbvh;
+
   bool show_mask;
   bool show_face_sets;
 
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 4f13b164415..8d1020a2c4e 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -80,8 +80,8 @@ BLI_INLINE SculptFaceRef BKE_pbvh_make_fref(intptr_t i)
 
 typedef struct PBVHTri {
   int v[3];       // references into PBVHTriBuf->verts
-  intptr_t l[3];  // loops
   int eflag;      // bitmask of which edges in the tri are real edges in the mesh
+  intptr_t l[3];  // loops
 
   float no[3];
   SculptFaceRef f;
@@ -323,6 +323,7 @@ void BKE_pbvh_update_offsets(PBVH *pbvh,
 void BKE_pbvh_free(PBVH *pbvh);
 
 void BKE_pbvh_set_bm_log(PBVH *pbvh, struct BMLog *log);
+struct BMLog *BKE_pbvh_get_bm_log(PBVH *pbvh);
 
 /* update MSculptVerts, doesn't take pbvh argument to allow usage if pbvh doesn't currently exist
  */
@@ -1127,3 +1128,17 @@ void BKE_pbvh_pmap_to_edges(PBVH *pbvh,
 void BKE_pbvh_set_vemap(PBVH *pbvh, struct MeshElemMap *vemap);
 
 void BKE_pbvh_ignore_uvs_set(PBVH *pbvh, bool value);
+bool BKE_pbvh_cache_is_valid(const struct Object *ob, const struct Mesh *me, const PBVH *old, int pbvh_type);
+bool BKE_pbvh_cache(const struct Mesh *me, PBVH *pbvh);
+PBVH *BKE_pbvh_get_or_free_cached(struct Object *ob, struct Mesh *me, PBVHType pbvh_type);
+void BKE_pbvh_set_cached(struct Object *ob, PBVH *pbvh);
+void BKE_pbvh_set_face_areas(PBVH *pbvh, float *face_areas);
+void BKE_pbvh_set_sculpt_verts(PBVH *pbvh, struct MSculptVert *sverts);
+void BKE_pbvh_set_pmap(PBVH *pbvh, struct MeshElemMap *pmap, void *pmap_mem);
+struct MeshElemMap *BKE_pbvh_get_pmap(PBVH *pbvh);
+struct MeshElemMap *BKE_pbvh_get_pmap_ex(PBVH *pbvh, int **r_mem);
+void BKE_pbvh_cache_remove(PBVH *pbvh);
+void BKE_pbvh_set_bmesh(PBVH *pbvh, struct BMesh *bm);
+void BKE_pbvh_free_bmesh(PBVH *pbvh, struct BMesh *bm);
+void BKE_pbvh_system_init();
+void BKE_pbvh_system_exit();
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 947cdc0c8bf..799952df576 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -34,6 +34,7 @@
 #include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_node.h"
+#include "BKE_pbvh.h"
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
@@ -76,6 +77,7 @@ void BKE_blender_free(void)
   DEG_free_node_types();
 
   BKE_brush_system_exit();
+  BKE_pbvh_system_exit();
   RE_texture_rng_exit();
 
   BKE_callback_global_finalize();
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 985c9edac1a..518a543b9bf 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -528,10 +528,19 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
     ob->mode &= ~OB_MODE_EDIT;
   }
 
+  PBVH *cached_pbvh = ob->cached_pbvh2;
+  if (!is_undo) {
+    ob->cached_pbvh2 = NULL;
+  }
+
   /* write LibData */
   BLO_write_id_struct(writer, Object, id_address, &ob->id);
   BKE_id_blend_write(writer, &ob->id);
 
+  if (!is_undo) {
+    ob->cached_pbvh2 = cached_pbvh;
+  }
+
   if (ob->adt) {
     BKE_animdata_blend_write(writer, ob->adt);
   }
@@ -4959,6 +4968,8 @@ void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag))
 
   runtime->crazyspace_deform_imats = nullptr;
   runtime->crazyspace_deform_cos = nullptr;
+
+  object->cached_pbvh2 = runtime->cached_pbvh = NULL;
 }
 
 void BKE_object_runtime_free_data(Object *object)
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 3bc2139ca0c..340bd35bcbe 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -272,6 +272,8 @@ void BKE_object_sync_to_original(Depsgraph *depsgraph, Object *object)
   object_orig->transflag = object->transflag;
   object_orig->flag = object->flag;
 
+  //object_orig->cached_pbvh2 = object->cached_pbvh2;
+
   /* Copy back error messages from modifiers. */
   for (ModifierData *md = object->modifiers.first, *md_orig = object_orig->modifiers.first;
        md != NULL && md_orig != NULL;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 0ef6fa8961d..38e15708795 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1448,15 +1448,16 @@ static void sculptsession_free_pbvh(Object *object)
   }
 
   if (ss->pbvh) {
-    BKE_pbvh_free(ss->pbvh);
+    BKE_pbvh_set_cached(object, ss->pbvh);
     ss->pbvh = NULL;
   }
+  else {
+    MEM_SAFE_FREE(ss->pmap);
+    MEM_SAFE_FREE(ss->pmap_mem);
+  }
 
   MEM_SAFE_FREE(ss->face_areas);
 
-  MEM_SAFE_FREE(ss->pmap);
-  MEM_SAFE_FREE(ss->pmap_mem);
-
   MEM_SAFE_FREE(ss->epmap);
   MEM_SAFE_FREE(ss->epmap_mem);
 
@@ -1516,21 +1517,24 @@ void BKE_sculptsession_free(Object *ob)
       SCULPT_on_sculptsession_bmesh_free(ss);
 
       BKE_sculptsession_bm_to_me(ob, true);
-      BM_mesh_free(ss->bm);
+      ss->bm = NULL;
+      // BM_mesh_free(ss->bm);
     }
 
     CustomData_free(&ss->temp_vdata, ss->temp_vdata_elems);
     CustomData_free(&ss->temp_pdata, ss->temp_pdata_elems);
 
+    if (!ss->pbvh) {
+      MEM_SAFE_FREE(ss->pmap);
+      MEM_SAFE_FREE(ss->pmap_mem);
+    }
+
     sculptsession_free_pbvh(ob);
 
     for (int i = 0; i < SCULPT_SCL_LAYER_MAX; i++) {
       MEM_SAFE_FREE(ss->custom_layers[i]);
     }
 
-    MEM_SAFE_FREE(ss->pmap);
-    MEM_SAFE_FREE(ss->pmap_mem);
-
     MEM_SAFE_FREE(ss->epmap);
     MEM_SAFE_FREE(ss->epmap_mem);
 
@@ -1822,16 +1826,26 @@ static void sculpt_update_object(Depsgraph *depsgraph,
   BKE_pbvh_face_sets_color_set(ss->pbvh, me->face_sets_color_seed, me->face_sets_color_default);
 
   if (need_pmap && ob->type == OB_MESH && !ss->pmap) {
-    BKE_mesh_vert_poly_map_create(&ss->pmap,
-                                  &ss->pmap_mem,
-                                  me->mvert,
-                                  me->medge,
-                                  me->mpoly,
-                                  me->mloop,
-                                  me->totvert,
-                                  me->totpoly,
-                                  me->totloop,
-                                  false);
+    if (!ss->pmap && ss->pbvh) {
+      ss->pmap = BKE_pbvh_get_pmap_ex(ss->pbvh, &ss->pmap_mem);
+    }
+
+    if (!ss->pmap) {
+      BKE_mesh_vert_poly_map_create(&ss->pmap,
+                                    &ss->pmap_mem,
+                                    me->mvert,
+                                    me->medge,
+                                    me->mpoly,
+                                    me->mloop,
+                                    me->totvert,
+                                    me->totpoly,
+                                    me->totloop,
+                                    false);
+
+      if (ss->pbvh) {
+        BKE_pbvh_set_pmap(ss->pbvh, ss->pmap, ss->pmap_mem);
+      }
+    }
   }
 
   pbvh_show_mask_set(ss->pbvh, ss->show_mask);
@@ -2396,42 +2410,72 @@ void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object)
   DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
 }
 
-static PBVH *build_pbvh_for_dynamic_topology(Object *ob, bool update_sculptverts)
+ATTR_NO_OPT static PBVH *build_pbvh_for_dynamic_topology(Object *ob, bool update_sculptverts)
 {
-  PBVH *pbvh = BKE_pbvh_new();
+  Mesh *me = BKE_object_get_original_mesh(ob);
+
+  PBVH *pbvh = BKE_pbvh_get_or_free_cached(ob, me, PBVH_BMESH);
+  if (!pbvh) {
+    pbvh = BKE_pbvh_new();
+
+    BKE_pbvh_build_bmesh(pbvh,
+                         BKE_object_get_original_mesh(ob),
+                         ob->sculpt->bm,
+                         ob->sculpt->bm_smooth_shading,
+                         ob->sculpt->bm_log,
+                         ob->sculpt->cd_vert_node_offset,
+                         ob->sculpt->cd_face_node_offset,
+                         ob->sculpt->cd_sculpt_vert,
+                         ob->sculpt->cd_face_areas,
+                         ob->sculpt->fast_draw,
+                         update_sculptverts);
+  }
+  else {
+    BMesh *bm = BKE_pbvh_get_bmesh(pbvh);
+
+    if (bm && bm != ob->sculpt->bm) {
+      printf("%s: ss->bm != bm!\n", __func__);
+
+      ob->sculpt->bm = bm;
+
+      if (ob->sculpt->bm_log) {
+        BM_log_set_bm(bm, ob->sculpt->bm_log);
+      }
+    }
+    else if (!bm) {
+      BKE_pbvh_set_bmesh(pbvh, ob->sculpt->bm);
+    }
+  }
+
+  if (ob->sculpt->bm_log) {
+    BKE_pbvh_set_bm_log(pbvh, ob->sculpt->bm_log);
+  }
 
   BKE_pbvh_set_symmetry(pbvh, 0, (int)BKE_get_fset_boundary_symflag(ob));
 
-  BKE_pbvh_build_bmesh(pbvh,
-                       BKE_object_get_original_mesh(ob),
-                       ob->sculpt->bm,
-                       ob->sculpt->bm_smooth_shading,
-                       ob->sculpt->bm_log,
-                       ob->sculpt->cd_vert_node_offset,
-                       ob->sculpt->cd_face_node_offset,
-                       ob->sculpt->cd_sculpt_vert,
-                       ob->sculpt->cd_face_areas,
-                       ob->sculpt->fast_draw,
-                       update_sculptverts);
   pbvh_show_mask_set(pbvh, ob->sculpt->show_mask);
   pbvh_show_face_sets_set(pbvh, false);
 
+  BKE_pbvh_set_cached(ob, pbvh);
+
   return pbvh;
 }
 
-static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool respect_hide)
+ATTR_NO_OPT static PBVH *build_pbvh_from_regular_mesh(Object *ob,
+                                                      Mesh *me_eval_deform,
+                                                      bool respect_hide)
 {
   SculptSession *ss = ob->sculpt;
   Mesh *me = BKE_object_get_original_mesh(ob

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list