[Bf-blender-cvs] [faf8402c190] temp_bmesh_multires: Added initial support for customdata to dyntopo undo (BMLog).

Joseph Eagar noreply at git.blender.org
Mon Oct 26 10:47:20 CET 2020


Commit: faf8402c190d1af34b08fdd89561854095b612ee
Author: Joseph Eagar
Date:   Mon Oct 26 02:45:56 2020 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rBfaf8402c190d1af34b08fdd89561854095b612ee

Added initial support for customdata to dyntopo undo (BMLog).

TODO:
 - Handle face (loop) data
 - Figure out what to do about edge data (warn user? actually handle
   it?)
 - Handle sculpt color undo push nodes properly (shouldn't be hard).

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

M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/intern/customdata.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/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_log.h
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_undo.c

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

diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 51650d161ea..8ac7b625805 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -104,6 +104,8 @@ bool CustomData_has_math(const struct CustomData *data);
 bool CustomData_has_interp(const struct CustomData *data);
 bool CustomData_bmesh_has_free(const struct CustomData *data);
 
+bool CustomData_layout_is_same(const struct CustomData *_a, const struct CustomData *_b);
+
 /**
  * Checks if any of the customdata layers is referenced.
  */
@@ -140,6 +142,10 @@ void CustomData_copy(const struct CustomData *source,
 /* BMESH_TODO, not really a public function but readfile.c needs it */
 void CustomData_update_typemap(struct CustomData *data);
 
+/* copies all customdata layers without allocating data,
+ * and without respect to type masks or NO_COPY/etc flags*/
+void CustomData_copy_all_layout(const struct CustomData *source, struct CustomData *dest);
+
 /* same as the above, except that this will preserve existing layers, and only
  * add the layers that were not there yet */
 bool CustomData_merge(const struct CustomData *source,
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 466a0115a9d..a047cee3168 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -72,6 +72,32 @@ BLI_STATIC_ASSERT(ARRAY_SIZE(((CustomData *)NULL)->typemap) == CD_NUMTYPES, "siz
 
 static CLG_LogRef LOG = {"bke.customdata"};
 
+bool CustomData_layout_is_same(const CustomData *_a, const CustomData *_b)
+{
+  CustomData a = *_a;
+  CustomData b = *_b;
+
+  a.layers = b.layers = NULL;
+  a.pool = b.pool = NULL;
+
+  if (memcmp((void *)&a, (void *)&b, sizeof(CustomData)) != 0) {
+    return false;
+  }
+
+  for (int i = 0; i < a.totlayer; i++) {
+    CustomDataLayer cla = _a->layers[i];
+    CustomDataLayer clb = _b->layers[i];
+
+    cla.data = clb.data = NULL;
+
+    if (memcmp((void *)&cla, (void *)&clb, sizeof(CustomDataLayer)) != 0) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 /** Update mask_dst with layers defined in mask_src (equivalent to a bitwise OR). */
 void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst,
                                  const CustomData_MeshMasks *mask_src)
@@ -2072,6 +2098,26 @@ static bool customdata_typemap_is_valid(const CustomData *data)
 }
 #endif
 
+/* copies all customdata layers without allocating data,
+ * and without respect to type masks or NO_COPY/etc flags*/
+void CustomData_copy_all_layout(const struct CustomData *source, struct CustomData *dest)
+{
+  *dest = *source;
+
+  if (dest->pool) {
+    dest->pool = NULL;
+  }
+
+  if (source->layers) {
+    dest->layers = MEM_mallocN(sizeof(*dest->layers) * source->totlayer, __func__);
+
+    for (int i = 0; i < source->totlayer; i++) {
+      dest->layers[i] = source->layers[i];
+      dest->layers[i].data = NULL;
+    }
+  }
+}
+
 bool CustomData_merge(const struct CustomData *source,
                       struct CustomData *dest,
                       CustomDataMask mask,
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 80fe1d659ed..8a40bde0a7e 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -2048,6 +2048,9 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect
   return pbvh;
 }
 
+//XXX hack
+extern SCULPT_dynamic_topology_sync_layers(Object *ob, Mesh *me);
+
 PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
 {
   if (ob == NULL || ob->sculpt == NULL) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 31f945262bd..936205c91ce 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1362,11 +1362,17 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
   CustomData *ldata;
 
   if (pbvh->type == PBVH_BMESH) {
-    vdata = &pbvh->bm->vdata;
-    ldata = &pbvh->bm->ldata;
-  } else {
-    vdata = &pbvh->vdata;
-    ldata = &pbvh->ldata;
+    if (pbvh->bm) {
+      vdata = &pbvh->bm->vdata;
+      ldata = &pbvh->bm->ldata;
+    }
+    else {
+      vdata = ldata = NULL;
+    }
+  }
+  else {
+    vdata = pbvh->vdata;
+    ldata = pbvh->ldata;
   }
 
   GPU_pbvh_update_attribute_names(vdata, ldata);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index f45eb2e0a53..611ba8ec2a1 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1762,7 +1762,10 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
   /* Move v_conn to the midpoint of v_conn and v_del (if v_conn still exists, it
    * may have been deleted above) */
   if (v_conn != NULL) {
-    BM_log_vert_before_modified(pbvh->bm_log, v_conn, eq_ctx->cd_vert_mask_offset);
+    //BM_log_vert_before_modified(pbvh->bm, pbvh->bm_log, v_conn, eq_ctx->cd_vert_mask_offset, false);
+    void *dummy;
+    BKE_pbvh_bmesh_update_origvert(pbvh, v_conn, &dummy, &dummy, &dummy);
+
     mid_v3_v3v3(v_conn->co, v_conn->co, v_del->co);
     add_v3_v3(v_conn->no, v_del->no);
     normalize_v3(v_conn->no);
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index aeaa2eb646a..1273a2e40df 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -1,3 +1,4 @@
+
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -45,6 +46,8 @@
 
 #include "BLI_strict_flags.h"
 
+#define CUSTOMDATA
+
 struct BMLogEntry {
   struct BMLogEntry *next, *prev;
 
@@ -75,6 +78,9 @@ struct BMLogEntry {
    * This field is not guaranteed to be valid, any use of it should
    * check for NULL. */
   BMLog *log;
+
+  CustomData vdata, edata, ldata, pdata;
+  struct BMLogEntry *combined_prev, *combined_next;
 };
 
 struct BMLog {
@@ -93,6 +99,8 @@ struct BMLog {
   GHash *id_to_elem;
   GHash *elem_to_id;
 
+  BMesh *bm;
+
   /* All BMLogEntrys, ordered from earliest to most recent */
   ListBase entries;
 
@@ -177,6 +185,51 @@ static BMFace *bm_log_face_from_id(BMLog *log, uint id)
 
 /************************ BMLogVert / BMLogFace ***********************/
 
+static void bm_log_vert_customdata(BMesh *bm, BMLog *log, BMVert *v, BMLogVert *lv)
+{
+#ifdef CUSTOMDATA
+  // if (!lv) {
+  //  return;
+  //}
+  BMLogEntry *entry = log->current_entry;
+
+  if (lv->customdata) {
+    BLI_mempool_free(entry->vdata.pool, lv->customdata);
+    lv->customdata = NULL;
+  }
+
+  CustomData_bmesh_copy_data(&bm->vdata, &entry->vdata, v->head.data, &lv->customdata);
+#endif
+}
+
+static void bm_log_face_customdata(BMesh *bm, BMLog *log, BMFace *f, BMLogFace *lf)
+{
+#ifdef CUSTOMDATA
+  // if (!lf) {
+  //  return;
+  //}
+  BMLogEntry *entry = log->current_entry;
+  uint f_id = bm_log_face_id_get(log, f);
+  void *key = POINTER_FROM_UINT(f_id);
+
+  BLI_ghash_insert(log->current_entry->modified_faces, key, lf);
+
+  BMLoop *l1 = f->l_first;
+  BMLoop *l2 = f->l_first->next;
+  BMLoop *l3 = f->l_first->prev;
+  BMLoop *ls[3] = {l1, l2, l3};
+
+  for (int i = 0; i < 3; i++) {
+    if (lf->customdata[i]) {
+      BLI_mempool_free(entry->ldata.pool, lf->customdata[i]);
+      lf->customdata[i] = NULL;
+    }
+
+    CustomData_bmesh_copy_data(&bm->ldata, &entry->ldata, ls[i]->head.data, &lf->customdata[i]);
+  }
+#endif
+}
+
 /* Get a vertex's paint-mask value
  *
  * Returns zero if no paint-mask layer is present */
@@ -212,6 +265,7 @@ static BMLogVert *bm_log_vert_alloc(BMLog *log, BMVert *v, const int cd_vert_mas
 {
   BMLogEntry *entry = log->current_entry;
   BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts);
+  lv->customdata = NULL;
 
   bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
 
@@ -225,6 +279,7 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
   BMLogFace *lf = BLI_mempool_alloc(entry->pool_faces);
   BMVert *v[3];
 
+  lf->customdata[0] = lf->customdata[1] = lf->customdata[2] = NULL;
   BLI_assert(f->len == 3);
 
   // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
@@ -285,7 +340,7 @@ static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces)
   }
 }
 
-static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts)
+static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts, BMLogEntry *entry)
 {
   const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
 
@@ -298,6 +353,12 @@ static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts)
     v->head.hflag = lv->hflag;
     normal_short_to_float_v3(v->no, lv->no);
     bm_log_vert_id_set(log, v, POINTER_AS_UINT(key));
+
+#ifdef CUSTOMDATA
+    if (lv->customdata) {
+      CustomData_bmesh_copy_data(&bm->vdata, &entry->vdata, lv->customdata, &v->head.data);
+    }
+#endif
   }
 }
 
@@ -641,6 +702,31 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
   MEM_freeN(farr);
 }
 
+BMLogEntry *BM_log_entry_check_customdata(BMesh *bm, BMLog *log)
+{
+  BMLogEntry *entry = log->current_entry;
+
+  if (!entry) {
+    return BM_log_entry_add_ex(bm, log, false);
+  }
+
+#ifndef CUSTOMDATA
+  return entry;
+#else
+
+  CustomData *cd1[4] = {&bm->vdata, &bm->edata, &bm->ldata, &bm->pdata};
+  CustomData *cd2[4] = {&entry->vdata, &entry->edata, &entry->ldata, &entry->pdata};
+
+  for (int i = 0; i < 4; i++) {
+    if (!CustomData_layout_is_same(cd1[i], cd2[i])) {
+      return BM_log_entry_add_ex(bm, log, true);
+    }
+  }
+
+  return entry;
+#endif
+}
+
 /* Start a new log entry and update the log entry list
  *
  * If the log entry list is empty, or if the current log entry is the
@@ -651,8 +737,15 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
  *
  * In either case, the new entry is set as the current log entry.
  */
-BMLogEntry *BM_log_entry_add(BMLog *log)
+BMLogEntry *BM_log_entry_add(BMesh *bm, BMLog *log)
 {
+  return BM_log_entry_add_ex(bm, log, false);
+}
+
+BMLogE

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list