[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