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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs