[Bf-blender-cvs] [e19d6d2f188] sculpt-dev: sculpt-dev: part one of new id system for dyntopo

Joseph Eagar noreply at git.blender.org
Sat Dec 3 12:27:04 CET 2022


Commit: e19d6d2f188858e7e323bde624dc093fa71213d3
Author: Joseph Eagar
Date:   Tue Nov 22 12:39:49 2022 -0800
Branches: sculpt-dev
https://developer.blender.org/rBe19d6d2f188858e7e323bde624dc093fa71213d3

sculpt-dev: part one of new id system for dyntopo

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

M	source/blender/blenkernel/intern/customdata.cc
M	source/blender/bmesh/CMakeLists.txt
A	source/blender/bmesh/intern/bmesh_idmap.cc
A	source/blender/bmesh/intern/bmesh_idmap.h
M	source/blender/makesdna/DNA_customdata_types.h

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

diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index 5a6b2f4abc3..504b705bde8 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -220,6 +220,7 @@ struct LayerTypeInfo {
   /** a function to determine max allowed number of layers,
    * should be null or return -1 if no limit */
   int (*layers_max)();
+  bool use_default_data;
 };
 
 /** \} */
@@ -1848,7 +1849,21 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
      nullptr,
      nullptr,
      layerInterp_propInt,
-     nullptr},
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     nullptr,
+     true},
     /* 12: CD_PROP_STRING */
     {sizeof(MStringProperty),
      "MStringProperty",
@@ -2624,6 +2639,10 @@ bool CustomData_merge(const CustomData *source,
     }
 
     if (newlayer) {
+      if (layer->default_data) {
+        newlayer->default_data = MEM_dupallocN(layer->default_data);
+      }
+
       newlayer->uid = layer->uid;
 
       newlayer->active = lastactive;
@@ -2759,6 +2778,10 @@ static void customData_free_layer__internal(CustomDataLayer *layer, const int to
     if (layer->data) {
       MEM_freeN(layer->data);
     }
+
+    if (layer->default_data) {
+      MEM_freeN(layer->default_data);
+    }
   }
 }
 
@@ -4295,7 +4318,7 @@ static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
       ptr += cd_tflags;
 
       MToolFlags *flags = (MToolFlags *)ptr;
-      flags->flag = NULL;
+      flags->flag = nullptr;
     }
   }
   else {
@@ -4345,7 +4368,12 @@ static void CustomData_bmesh_set_default_n(CustomData *data, void **block, const
     typeInfo->set_default_value(POINTER_OFFSET(*block, offset), 1);
   }
   else {
-    memset(POINTER_OFFSET(*block, offset), 0, typeInfo->size);
+    if (typeInfo->use_default_data && data->layers[n].default_data) {
+      memcpy(POINTER_OFFSET(*block, offset), data->layers[n].default_data, typeInfo->size);
+    }
+    else {
+      memset(POINTER_OFFSET(*block, offset), 0, typeInfo->size);
+    }
   }
 }
 
@@ -4850,9 +4878,16 @@ void CustomData_bmesh_interp(CustomData *data,
                          1);
         }
         else {
-          memcpy(POINTER_OFFSET(dst_block, layer->offset),
-                 POINTER_OFFSET(src_blocks[0], layer->offset),
-                 typeInfo->size);
+          if (layer->default_data && typeInfo->use_default_data) {
+            memcpy(POINTER_OFFSET(dst_block, layer->offset),
+                   layer->default_data,
+                   typeInfo->size);
+          }
+          else {
+            memcpy(POINTER_OFFSET(dst_block, layer->offset),
+                   POINTER_OFFSET(src_blocks[0], layer->offset),
+                   typeInfo->size);
+          }
         }
       }
 
@@ -5846,6 +5881,12 @@ void CustomData_blend_write(BlendWriter *writer,
       writer, CustomDataLayer, data->totlayer, data->layers, layers_to_write.data());
 
   for (const CustomDataLayer &layer : layers_to_write) {
+    const LayerTypeInfo *typeInfo = layerType_getInfo(layer.type);
+
+    if (typeInfo->use_default_data && layer.default_data) {
+      BLO_write_struct_by_name(writer, typeInfo->structname, layer.default_data);
+    }
+
     switch (layer.type) {
       case CD_MDEFORMVERT:
         BKE_defvert_blend_write(writer, count, static_cast<const MDeformVert *>(layer.data));
@@ -5956,6 +5997,14 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, const int
   int i = 0;
   while (i < data->totlayer) {
     CustomDataLayer *layer = &data->layers[i];
+    const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
+
+    if (layer->default_data && typeInfo->use_default_data) {
+      BLO_read_data_address(reader, &layer->default_data);
+    }
+    else {
+      layer->default_data = nullptr;
+    }
 
     if (layer->flag & CD_FLAG_EXTERNAL) {
       layer->flag &= ~CD_FLAG_IN_MEMORY;
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 88cf6a8fa04..f7d53176cdb 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -73,6 +73,8 @@ set(SRC
   intern/bmesh_delete.h
   intern/bmesh_edgeloop.c
   intern/bmesh_edgeloop.h
+  intern/bmesh_idmap.cc
+  intern/bmesh_idmap.h
   intern/bmesh_inline.h
   intern/bmesh_interp.c
   intern/bmesh_interp.h
diff --git a/source/blender/bmesh/intern/bmesh_idmap.cc b/source/blender/bmesh/intern/bmesh_idmap.cc
new file mode 100644
index 00000000000..ee7c705dfc7
--- /dev/null
+++ b/source/blender/bmesh/intern/bmesh_idmap.cc
@@ -0,0 +1,315 @@
+#include "MEM_guardedalloc.h"
+
+#include "BLI_assert.h"
+#include "BLI_index_range.hh"
+#include "BLI_map.hh"
+#include "BLI_set.hh"
+#include "BLI_vector.hh"
+
+#include "BKE_customdata.h"
+
+#include "DNA_customdata_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "bmesh_idmap.h"
+#include <cstdio>
+
+using namespace blender;
+
+#define FREELIST_HASHMAP_THRESHOLD_HIGH 1024
+#define FREELIST_HASHMAP_THRESHOLD_LOW 700
+
+BMIdMap *BM_idmap_new(BMesh *bm, int elem_mask)
+{
+  BMIdMap *idmap = MEM_new<BMIdMap>("BMIdMap");
+
+  for (int i = 0; i < ARRAY_SIZE(idmap->cd_id_off); i++) {
+    idmap->cd_id_off[i] = -1;
+  }
+
+  idmap->flag = elem_mask;
+  idmap->bm = bm;
+
+  BM_idmap_check_attributes(idmap);
+
+  return idmap;
+}
+
+static void idmap_grow_map(BMIdMap *idmap, int newid)
+{
+  if (idmap->map_size > newid) {
+    return;
+  }
+
+  int newsize = (newid + 1);
+  newsize += newsize >> 1;
+
+  if (idmap->map) {
+    idmap->map = (BMElem **)MEM_recallocN((void *)idmap->map, sizeof(void *) * newsize);
+  }
+  else {
+    idmap->map = (BMElem **)MEM_calloc_arrayN(newsize, sizeof(void *), "bm idmap");
+  }
+
+  idmap->map_size = newsize;
+}
+
+void BM_idmap_check_ids(BMIdMap *idmap)
+{
+  BMIter iter;
+  BMVert *v;
+  BMEdge *e;
+  BMFace *f;
+
+  idmap->freelist.clear();
+  if (idmap->free_idx_map) {
+    MEM_delete<BMIdMap::FreeIdxMap>(idmap->free_idx_map);
+    idmap->free_idx_map = nullptr;
+  }
+
+  Set<int> used;
+  int max_id = 0;
+
+  if (idmap->flag & BM_VERT) {
+    BM_ITER_MESH (v, &iter, idmap->bm, BM_VERTS_OF_MESH) {
+      int id = BM_ELEM_CD_GET_INT(v, idmap->cd_id_off[BM_VERT]);
+
+      max_id = max_ff(max_id, id);
+    }
+  }
+  if (idmap->flag & BM_EDGE) {
+    BM_ITER_MESH (e, &iter, idmap->bm, BM_EDGES_OF_MESH) {
+      int id = BM_ELEM_CD_GET_INT(e, idmap->cd_id_off[BM_EDGE]);
+
+      max_id = max_ff(max_id, id);
+    }
+  }
+  if (idmap->flag & (BM_FACE | BM_LOOP)) {
+    BM_ITER_MESH (f, &iter, idmap->bm, BM_FACES_OF_MESH) {
+      if (idmap->flag & BM_FACE) {
+        int id = BM_ELEM_CD_GET_INT(f, idmap->cd_id_off[BM_FACE]);
+        max_id = max_ff(max_id, id);
+      }
+
+      if (idmap->flag & BM_LOOP) {
+        BMLoop *l = f->l_first;
+        do {
+          int id = BM_ELEM_CD_GET_INT(l, idmap->cd_id_off[BM_LOOP]);
+          max_id = max_ff(max_id, id);
+        } while ((l = l->next) != f->l_first);
+      }
+    }
+  }
+
+  if (idmap->map_size >= max_id) {
+    memset((void *)idmap->map, 0, sizeof(void *) * idmap->map_size);
+  }
+  else {
+    MEM_SAFE_FREE(idmap->map);
+    idmap->map_size = max_id;
+    idmap->map = (BMElem **)MEM_calloc_arrayN(max_id, sizeof(BMElem *), "bm idmap->map");
+  }
+
+  auto check_elem = [&](auto *elem) {
+    int id = BM_ELEM_CD_GET_INT(elem, idmap->cd_id_off[(int)elem->head.htype]);
+
+    if (id < 0 || used.contains(id)) {
+      id = max_id++;
+    }
+
+    idmap_grow_map(idmap, id);
+    idmap->map[id] = reinterpret_cast<BMElem *>(elem);
+
+    used.add(id);
+  };
+
+  idmap->maxid = max_id;
+
+  if (idmap->flag & BM_VERT) {
+    BM_ITER_MESH (v, &iter, idmap->bm, BM_VERTS_OF_MESH) {
+      check_elem(v);
+    }
+  }
+  if (idmap->flag & BM_EDGE) {
+    BM_ITER_MESH (e, &iter, idmap->bm, BM_EDGES_OF_MESH) {
+      check_elem(e);
+    }
+  }
+  if (idmap->flag & (BM_FACE | BM_LOOP)) {
+    BM_ITER_MESH (f, &iter, idmap->bm, BM_FACES_OF_MESH) {
+      check_elem(f);
+      if (idmap->flag & BM_LOOP) {
+        BMLoop *l = f->l_first;
+
+        do {
+          check_elem(l);
+        } while ((l = l->next) != f->l_first);
+      }
+    }
+  }
+  if (idmap->flag & BM_VERT) {
+    BM_ITER_MESH (v, &iter, idmap->bm, BM_VERTS_OF_MESH) {
+      check_elem(v);
+    }
+  }
+}
+
+void BM_idmap_check_attributes(BMIdMap *idmap)
+{
+  auto check_attr = [&](int type) {
+    if (!(idmap->flag & type)) {
+      return;
+    }
+
+    CustomData *cdata;
+    const char *name;
+
+    switch (type) {
+      case BM_VERT:
+        name = ".sculpt.vertex.id";
+        cdata = &idmap->bm->vdata;
+        break;
+      case BM_EDGE:
+        name = ".sculpt.edge.id";
+        cdata = &idmap->bm->edata;
+        break;
+      case BM_LOOP:
+        name = ".sculpt.loop.id";
+        cdata = &idmap->bm->ldata;
+        break;
+      case BM_FACE:
+        name = ".sculpt.face.id";
+        cdata = &idmap->bm->pdata;
+        break;
+      default:
+        BLI_assert_unreachable();
+        return;
+    }
+
+    int idx = CustomData_get_named_layer(cdata, CD_PROP_INT32, name);
+
+    if (idx < 0) {
+      BM_data_layer_add_named(idmap->bm, cdata, CD_PROP_INT32, name);
+      idx = CustomData_get_named_layer(cdata, CD_PROP_INT32, name);
+    }
+
+    if (!cdata->layers[idx].default_data) {
+      cdata->layers[idx].default_data = MEM_cnew<MIntProperty>("MIntProperty");
+    }
+
+    cdata->layers[idx].flag |= CD_FLAG_ELEM_NOINTERP | CD_FLAG_ELEM_NOCOPY;
+
+    int *default_data = static_cast<int *>(cdata->layers[idx].default_data);
+    *default_data = -1;
+
+    idmap->cd_id_off[type] = cdata->layers[idx].offset;
+  };
+
+  check_attr(BM_VERT);
+  check_attr(BM_EDGE);
+  check_attr(BM_LOOP);
+  check_attr(BM_FACE);
+}
+
+void BM_idmap_destroy(BMIdMap *idmap)
+{
+  MEM_SAFE_FREE(idmap->map);
+  MEM_delete<BMIdMap>(idmap);
+}
+
+static void check_idx_map(BMIdMap *idmap)
+{
+  if (idmap->free_idx_map && idmap->freelist.size() < FREELIST_HASHMAP_THRESHOLD_LOW) {
+    printf("%s: Deleting free_idx_map\n", __func

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list