diff options
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 131 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_bmesh.c | 1 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_log.c | 204 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_log.h | 9 | ||||
-rw-r--r-- | source/blender/draw/engines/overlay/overlay_lattice.c | 1 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 84 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_dyntopo.c | 11 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_undo.c | 18 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 5 |
11 files changed, 280 insertions, 198 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index b31f004628d..5e8eb60f94d 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -268,6 +268,12 @@ void CustomData_copy_data_named(const struct CustomData *source, int dest_index, int count); void CustomData_copy_elements(int type, void *src_data_ofs, void *dst_data_ofs, int count); + +void CustomData_bmesh_swap_data(struct CustomData *source, + struct CustomData *dest, + void *src_block, + void **dest_block); + void CustomData_bmesh_copy_data(const struct CustomData *source, struct CustomData *dest, void *src_block, diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 66ffb6541ea..930c7b6f7e5 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -23,11 +23,11 @@ * \ingroup bke */ +#include "BKE_pbvh.h" #include "BLI_bitmap.h" #include "BLI_utildefines.h" #include "DNA_brush_enums.h" #include "DNA_object_enums.h" -#include "BKE_pbvh.h" #ifdef __cplusplus extern "C" { @@ -344,7 +344,7 @@ typedef struct SculptClothSimulation { struct GHash *node_state_index; eSculptClothNodeSimState *node_state; - //persistent base customdata layer offsets + // persistent base customdata layer offsets int cd_pers_co; int cd_pers_no; int cd_pers_disp; @@ -624,6 +624,10 @@ typedef struct SculptSession { */ char needs_flush_to_id; char update_boundary_info_bmesh; + + // id of current stroke, used to detect + // if vertex original data needs to be updated + int stroke_id; } SculptSession; void BKE_sculptsession_free(struct Object *ob); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 01968542ac1..c39082dbf46 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1533,6 +1533,7 @@ void layerDynTopoVert_interp( if (i == 0) { // copy flag from first source mv->flag = mv2->flag; + mv->stroke_id = mv2->stroke_id; } if (sub_weights) { @@ -1949,10 +1950,9 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { NULL, // flag singleton layer 1, N_("DynTopoVert"), - layerDynTopoVert_copy, - NULL, - layerDynTopoVert_interp - }}; + layerDynTopoVert_copy, + NULL, + layerDynTopoVert_interp}}; static const char *LAYERTYPENAMES[CD_NUMTYPES] = { /* 0-4 */ "CDMVert", @@ -3818,7 +3818,71 @@ void CustomData_bmesh_set_default(CustomData *data, void **block) } } -void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source, +__attribute__((optnone)) void CustomData_bmesh_swap_data(CustomData *source, + CustomData *dest, + void *src_block, + void **dest_block) +{ + int src_i = 0; + int dest_i = 0; + int dest_i_start = 0; + + if (*dest_block == NULL) { + CustomData_bmesh_alloc_block(dest, dest_block); + + if (*dest_block) { + memset(*dest_block, 0, dest->totsize); + CustomData_bmesh_set_default(dest, dest_block); + } + } + + for (src_i = 0; src_i < source->totlayer; src_i++) { + /* find the first dest layer with type >= the source type + * (this should work because layers are ordered by type) + */ + while (dest_i_start < dest->totlayer && + dest->layers[dest_i_start].type < source->layers[src_i].type) { + dest_i_start++; + } + + /* if there are no more dest layers, we're done */ + if (dest_i_start >= dest->totlayer) { + return; + } + + dest_i = dest_i_start; + + while (dest_i < dest->totlayer && dest->layers[dest_i].type == source->layers[src_i].type) { + /* if we found a matching layer, copy the data */ + if (dest->layers[dest_i].type == source->layers[src_i].type && + STREQ(dest->layers[dest_i].name, source->layers[src_i].name)) { + void *src_data = POINTER_OFFSET(src_block, source->layers[src_i].offset); + void *dest_data = POINTER_OFFSET(*dest_block, dest->layers[dest_i].offset); + const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers[src_i].type); + const uint size = typeInfo->size; + + // swap data + char *bsrc = (char *)src_data; + char *bdst = (char *)dest_data; + + for (int j = 0; j < size; j++) { + char t = *bsrc; + *bsrc = *bdst; + *bdst = t; + + bsrc++; + bdst++; + } + + break; + } + + dest_i++; + } + } +} + +__attribute__ ((optnone)) void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source, CustomData *dest, void *src_block, void **dest_block, @@ -3835,50 +3899,55 @@ void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source, } } + for (int dest_i=0; dest_i < dest->totlayer; dest_i++) { + CustomData_bmesh_set_default_n(dest, dest_block, dest_i); + dest_i++; + } + /* copies a layer at a time */ - int dest_i = 0; + int dest_i_start = 0; + for (int src_i = 0; src_i < source->totlayer; src_i++) { /* find the first dest layer with type >= the source type * (this should work because layers are ordered by type) */ - while (dest_i < dest->totlayer && dest->layers[dest_i].type < source->layers[src_i].type) { - CustomData_bmesh_set_default_n(dest, dest_block, dest_i); - dest_i++; + while (dest_i_start < dest->totlayer && + dest->layers[dest_i_start].type < source->layers[src_i].type) { + dest_i_start++; } /* if there are no more dest layers, we're done */ - if (dest_i >= dest->totlayer) { + if (dest_i_start >= dest->totlayer) { return; } - /* if we found a matching layer, copy the data */ - if (dest->layers[dest_i].type == source->layers[src_i].type && - STREQ(dest->layers[dest_i].name, source->layers[src_i].name)) { - if (no_mask || ((CD_TYPE_AS_MASK(dest->layers[dest_i].type) & mask_exclude) == 0)) { - const void *src_data = POINTER_OFFSET(src_block, source->layers[src_i].offset); - void *dest_data = POINTER_OFFSET(*dest_block, dest->layers[dest_i].offset); - const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers[src_i].type); - if (typeInfo->copy) { - typeInfo->copy(src_data, dest_data, 1); - } - else { - memcpy(dest_data, src_data, typeInfo->size); + int dest_i = dest_i_start; + + /*Previously this code was only checking one source layer against one destination. + Now it scans all the layers of that type. - joeedh + */ + while (dest_i < dest->totlayer && dest->layers[dest_i].type == source->layers[src_i].type) { + /* if we found a matching layer, copy the data */ + if (STREQ(dest->layers[dest_i].name, source->layers[src_i].name)) { + if (no_mask || ((CD_TYPE_AS_MASK(dest->layers[dest_i].type) & mask_exclude) == 0)) { + const void *src_data = POINTER_OFFSET(src_block, source->layers[src_i].offset); + void *dest_data = POINTER_OFFSET(*dest_block, dest->layers[dest_i].offset); + const LayerTypeInfo *typeInfo = layerType_getInfo(source->layers[src_i].type); + if (typeInfo->copy) { + typeInfo->copy(src_data, dest_data, 1); + } + else { + memcpy(dest_data, src_data, typeInfo->size); + } } + + break; } - /* if there are multiple source & dest layers of the same type, - * we don't want to copy all source layers to the same dest, so - * increment dest_i - */ dest_i++; } } - - while (dest_i < dest->totlayer) { - CustomData_bmesh_set_default_n(dest, dest_block, dest_i); - dest_i++; - } } void CustomData_bmesh_copy_data(const CustomData *source, diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index 0d4bac4a2b9..f7581db5fd8 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -4091,6 +4091,7 @@ void BKE_pbvh_update_offsets(PBVH *pbvh, pbvh->cd_face_node_offset = cd_face_node_offset; pbvh->cd_vert_node_offset = cd_vert_node_offset; pbvh->cd_vert_mask_offset = CustomData_get_offset(&pbvh->bm->vdata, CD_PAINT_MASK); + pbvh->cd_vcol_offset = CustomData_get_offset(&pbvh->bm->vdata, CD_PROP_COLOR); pbvh->cd_dyn_vert = cd_dyn_vert; } diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index ecebc017e14..e6e1be15804 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -119,9 +119,6 @@ struct BMLog { */ BMLogEntry *current_entry; - int cd_origco_offset; - int cd_origno_offset; - int cd_origvcol_offset; int cd_dyn_vert; }; @@ -260,17 +257,13 @@ 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) +__attribute__((optnone)) static void bm_log_vert_customdata( + BMesh *bm, BMLog *log, BMLogEntry *entry, BMVert *v, BMLogVert *lv) { #ifdef CUSTOMDATA // if (!lv) { // return; //} - BMLogEntry *entry = log->current_entry; - - if (!entry) { - return; - } if (lv->customdata) { BLI_mempool_free(entry->vdata.pool, lv->customdata); @@ -336,27 +329,34 @@ static void vert_mask_set(BMVert *v, const float new_mask, const int cd_vert_mas } /* Update a BMLogVert with data from a BMVert */ -static void bm_log_vert_bmvert_copy(BMLog *log, - BMLogVert *lv, - BMVert *v, - const int cd_vert_mask_offset) +__attribute__((optnone)) static void bm_log_vert_bmvert_copy(BMLog *log, + BMLog *entry, + BMLogVert *lv, + BMVert *v, + const int cd_vert_mask_offset, + bool copy_customdata) { copy_v3_v3(lv->co, v->co); normal_float_to_short_v3(lv->no, v->no); lv->mask = vert_mask_get(v, cd_vert_mask_offset); lv->hflag = v->head.hflag; - bm_log_vert_customdata(log->bm, log, v, lv); + if (copy_customdata) { + bm_log_vert_customdata(log->bm, log, entry, v, lv); + } } /* Allocate and initialize a BMLogVert */ -static BMLogVert *bm_log_vert_alloc(BMLog *log, BMVert *v, const int cd_vert_mask_offset) +static BMLogVert *bm_log_vert_alloc(BMLog *log, + BMVert *v, + const int cd_vert_mask_offset, + bool log_customdata) { BMLogEntry *entry = log->current_entry; BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts); lv->customdata = NULL; - bm_log_vert_bmvert_copy(log, lv, v, cd_vert_mask_offset); + bm_log_vert_bmvert_copy(log, entry, lv, v, cd_vert_mask_offset, log_customdata); return lv; } @@ -384,7 +384,10 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f) /************************ Helpers for undo/redo ***********************/ -static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts) +__attribute__((optnone)) static void bm_log_verts_unmake(BMesh *bm, + BMLog *log, + GHash *verts, + BMLogEntry *entry) { const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK); @@ -397,13 +400,13 @@ static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts) /* Ensure the log has the final values of the vertex before * deleting it */ - bm_log_vert_bmvert_copy(log, lv, v, cd_vert_mask_offset); + bm_log_vert_bmvert_copy(log, entry, lv, v, cd_vert_mask_offset, true); BM_vert_kill(bm, v); } } -static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces) +static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces, BMLogEntry *entry) { GHashIterator gh_iter; GHASH_ITER (gh_iter, faces) { @@ -435,10 +438,12 @@ static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces) } } -static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts, BMLogEntry *entry) +__attribute__((optnone)) 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); - int cd_vcol_offset = CustomData_get_offset(&bm->vdata, CD_PROP_COLOR); GHashIterator gh_iter; GHASH_ITER (gh_iter, verts) { @@ -455,18 +460,6 @@ static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts, BMLogEntry CustomData_bmesh_copy_data(&entry->vdata, &bm->vdata, lv->customdata, &v->head.data); } #endif - - if (log->cd_dyn_vert >= 0) { - MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, log->cd_dyn_vert); - copy_v3_v3(mv->origco, v->co); - copy_v3_v3(mv->origno, v->no); - - if (cd_vcol_offset >= 0) { - float *color = BM_ELEM_CD_GET_VOID_P(v, cd_vcol_offset); - - copy_v4_v4(mv->origcolor, color); - } - } } } @@ -504,12 +497,13 @@ static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces, BMLogEntry } } -static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts, BMLogEntry *entry) +__attribute__((optnone)) static void bm_log_vert_values_swap(BMesh *bm, + BMLog *log, + GHash *verts, + BMLogEntry *entry) { const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK); - int cd_vcol_offset = CustomData_get_offset(&bm->vdata, CD_PROP_COLOR); - GHashIterator gh_iter; GHASH_ITER (gh_iter, verts) { void *key = BLI_ghashIterator_getKey(&gh_iter); @@ -530,7 +524,7 @@ static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts, BMLogEn #ifdef CUSTOMDATA if (lv->customdata) { - CustomData_bmesh_copy_data(&entry->vdata, &bm->vdata, lv->customdata, &v->head.data); + CustomData_bmesh_swap_data(&entry->vdata, &bm->vdata, lv->customdata, &v->head.data); } #endif } @@ -549,14 +543,14 @@ static void bm_log_face_values_swap(BMLog *log, GHash *faces, BMLogEntry *entry) #ifdef CUSTOMDATA if (lf->customdata_f) { - CustomData_bmesh_copy_data(&entry->pdata, &log->bm->pdata, lf->customdata_f, &f->head.data); + CustomData_bmesh_swap_data(&entry->pdata, &log->bm->pdata, lf->customdata_f, &f->head.data); } BMLoop *ls[3] = {f->l_first, f->l_first->next, f->l_first->prev}; for (int i = 0; i < 3; i++) { if (lf->customdata[i]) { - CustomData_bmesh_copy_data( + CustomData_bmesh_swap_data( &entry->ldata, &log->bm->ldata, lf->customdata[i], &ls[i]->head.data); } } @@ -695,15 +689,13 @@ static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash) /***************************** Public API *****************************/ -void BM_log_set_cd_offsets( - BMLog *log, int cd_origco_offset, int cd_origno_offset, int cd_origvol_offset, int cd_dyn_vert) +void BM_log_set_cd_offsets(BMLog *log, int cd_dyn_vert) { log->cd_dyn_vert = cd_dyn_vert; } /* Allocate, initialize, and assign a new BMLog */ -BMLog *BM_log_create( - BMesh *bm, int cd_origco_offset, int cd_origno_offset, int cd_origvcol_offset, int cd_dyn_vert) +BMLog *BM_log_create(BMesh *bm, int cd_dyn_vert) { BMLog *log = MEM_callocN(sizeof(*log), __func__); const uint reserve_num = (uint)(bm->totvert + bm->totface); @@ -714,7 +706,7 @@ BMLog *BM_log_create( log->id_to_elem = BLI_ghash_new_ex(logkey_hash, logkey_cmp, __func__, reserve_num); log->elem_to_id = BLI_ghash_ptr_new_ex(__func__, reserve_num); - BM_log_set_cd_offsets(log, cd_origco_offset, cd_origno_offset, cd_origvcol_offset, cd_dyn_vert); + BM_log_set_cd_offsets(log, cd_dyn_vert); /* Assign IDs to all existing vertices and faces */ bm_log_assign_ids(bm, log); @@ -754,7 +746,7 @@ void BM_log_cleanup_entry(BMLogEntry *entry) */ BMLog *BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry) { - BMLog *log = BM_log_create(bm, -1, -1, -1, -1); + BMLog *log = BM_log_create(bm, -1); if (entry->prev) { log->current_entry = entry; @@ -947,13 +939,14 @@ BMLogEntry *BM_log_entry_add_ex(BMesh *bm, BMLog *log, bool combine_with_last) entry = bm_log_entry_create(); BLI_addtail(&log->entries, entry); entry->log = log; - log->current_entry = entry; #ifdef CUSTOMDATA if (combine_with_last) { if (log->current_entry) { log->current_entry->combined_next = entry; + BLI_remlink(&log->entries, log->current_entry); } + entry->combined_prev = log->current_entry; } @@ -968,6 +961,8 @@ BMLogEntry *BM_log_entry_add_ex(BMesh *bm, BMLog *log, bool combine_with_last) CustomData_bmesh_init_pool(&entry->pdata, 0, BM_FACE); #endif + log->current_entry = entry; + return entry; } @@ -1049,40 +1044,68 @@ void BM_log_entry_drop(BMLogEntry *entry) /* Undo one BMLogEntry * * Has no effect if there's nothing left to undo */ -void BM_log_undo(BMesh *bm, BMLog *log) +static void bm_log_undo_intern(BMesh *bm, BMLog *log, BMLogEntry *entry) { - BMLogEntry *entry = log->current_entry; - bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE; bm->elem_table_dirty |= BM_VERT | BM_EDGE | BM_FACE; - if (entry) { - log->current_entry = entry->prev; + /* Delete added faces and verts */ + bm_log_faces_unmake(bm, log, entry->added_faces, entry); + bm_log_verts_unmake(bm, log, entry->added_verts, entry); - /* Delete added faces and verts */ - bm_log_faces_unmake(bm, log, entry->added_faces); - bm_log_verts_unmake(bm, log, entry->added_verts); + /* Restore deleted verts and faces */ + bm_log_verts_restore(bm, log, entry->deleted_verts, entry); + bm_log_faces_restore(bm, log, entry->deleted_faces, entry); + + /* Restore vertex coordinates, mask, and hflag */ + bm_log_vert_values_swap(bm, log, entry->modified_verts, entry); + bm_log_face_values_swap(log, entry->modified_faces, entry); +} + +void BM_log_undo(BMesh *bm, BMLog *log) { + BMLogEntry *entry = log->current_entry; + log->bm = bm; + + if (!entry) { + return; + } - /* Restore deleted verts and faces */ - bm_log_verts_restore(bm, log, entry->deleted_verts, entry); - bm_log_faces_restore(bm, log, entry->deleted_faces, entry); + BMLogEntry *preventry = entry->prev; - /* Restore vertex coordinates, mask, and hflag */ - bm_log_vert_values_swap(bm, log, entry->modified_verts, entry); - bm_log_face_values_swap(log, entry->modified_faces, entry); + while (entry) { + bm_log_undo_intern(bm, log, entry); + entry = entry->combined_prev; } + + log->current_entry = preventry; } /* Redo one BMLogEntry * * Has no effect if there's nothing left to redo */ -void BM_log_redo(BMesh *bm, BMLog *log) +static void bm_log_redo_intern(BMesh *bm, BMLog *log, BMLogEntry *entry) { - BMLogEntry *entry = log->current_entry; - bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE; bm->elem_table_dirty |= BM_VERT | BM_EDGE | BM_FACE; + /* Re-delete previously deleted faces and verts */ + bm_log_faces_unmake(bm, log, entry->deleted_faces, entry); + bm_log_verts_unmake(bm, log, entry->deleted_verts, entry); + + /* Restore previously added verts and faces */ + bm_log_verts_restore(bm, log, entry->added_verts, entry); + bm_log_faces_restore(bm, log, entry->added_faces, entry); + + /* Restore vertex coordinates, mask, and hflag */ + bm_log_vert_values_swap(bm, log, entry->modified_verts, entry); + bm_log_face_values_swap(log, entry->modified_faces, entry); +} + +void BM_log_redo(BMesh *bm, BMLog *log) +{ + BMLogEntry *entry = log->current_entry; + log->bm = bm; + if (!entry) { /* Currently at the beginning of the undo stack, move to first entry */ entry = log->entries.first; @@ -1091,28 +1114,25 @@ void BM_log_redo(BMesh *bm, BMLog *log) /* Move to next undo entry */ entry = entry->next; } - else { + + if (!entry) { /* Currently at the end of the undo stack, nothing left to redo */ return; } - log->current_entry = entry; - - if (entry) { - /* Re-delete previously deleted faces and verts */ - bm_log_faces_unmake(bm, log, entry->deleted_faces); - bm_log_verts_unmake(bm, log, entry->deleted_verts); + BMLogEntry *nextentry = entry; - /* Restore previously added verts and faces */ - bm_log_verts_restore(bm, log, entry->added_verts, entry); - bm_log_faces_restore(bm, log, entry->added_faces, entry); + while (entry->combined_prev) { + entry = entry->combined_prev; + } - /* Restore vertex coordinates, mask, and hflag */ - bm_log_vert_values_swap(bm, log, entry->modified_verts, entry); - bm_log_face_values_swap(log, entry->modified_faces, entry); + while (entry) { + bm_log_redo_intern(bm, log, entry); + entry = entry->combined_next; } -} + log->current_entry = nextentry; +} /* Log a vertex before it is modified * * Before modifying vertex coordinates, masks, or hflags, call this @@ -1149,16 +1169,12 @@ void BM_log_vert_before_modified(BMLog *log, /* Find or create the BMLogVert entry */ if ((lv = log_ghash_lookup(log, entry->added_verts, key))) { - bm_log_vert_bmvert_copy(log, lv, v, cd_vert_mask_offset); + bm_log_vert_bmvert_copy(log, entry, lv, v, cd_vert_mask_offset, log_customdata); } else if (!log_ghash_ensure_p(log, entry->modified_verts, key, &val_p)) { - lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset); + lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset, true); *val_p = lv; } - - if (lv && log_customdata) { - bm_log_vert_customdata(log->bm, log, v, lv); - } } /* Log a new vertex as added to the BMesh @@ -1174,10 +1190,8 @@ void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset) void *key = POINTER_FROM_UINT(v_id); bm_log_vert_id_set(log, v, v_id); - lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset); + lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset, true); log_ghash_insert(log, log->current_entry->added_verts, key, lv); - - // bm_log_vert_customdata(log->bm, log, v, lv); } /* Log a face before it is modified @@ -1235,7 +1249,9 @@ void BM_log_face_added(BMLog *log, BMFace *f) * If there's a move record for the vertex, that's used as the * vertices original location, then the move record is deleted. */ -void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset) +__attribute__((optnone)) void BM_log_vert_removed(BMLog *log, + BMVert *v, + const int cd_vert_mask_offset) { BMLogEntry *entry = log->current_entry; uint v_id = bm_log_vert_id_get(log, v); @@ -1251,18 +1267,24 @@ void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset) else { BMLogVert *lv, *lv_mod; - lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset); + lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset, false); log_ghash_insert(log, entry->deleted_verts, key, lv); /* If the vertex was modified before deletion, ensure that the * original vertex values are stored */ if ((lv_mod = log_ghash_lookup(log, entry->modified_verts, key))) { + if (lv->customdata) { + BLI_mempool_free(entry->vdata.pool, lv->customdata); + } + (*lv) = (*lv_mod); + lv_mod->customdata = NULL; + log_ghash_remove(log, entry->modified_verts, key, NULL, NULL); + BLI_mempool_free(entry->pool_verts, lv_mod); } - - if (lv) { - bm_log_vert_customdata(log->bm, log, v, lv); + else { + bm_log_vert_customdata(log->bm, log, entry, v, lv); } } } diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h index 4a50a031b24..8dae3f4696e 100644 --- a/source/blender/bmesh/intern/bmesh_log.h +++ b/source/blender/bmesh/intern/bmesh_log.h @@ -29,13 +29,8 @@ typedef struct BMLog BMLog; typedef struct BMLogEntry BMLogEntry; /* Allocate and initialize a new BMLog */ -BMLog *BM_log_create( - BMesh *bm, int cd_origco_offset, int cd_origno_offset, int cd_origvol_offset, int cd_dyn_vert); -void BM_log_set_cd_offsets(BMLog *log, - int cd_origco_offset, - int cd_origno_offset, - int cd_origvcol_offset, - int cd_dyn_vert); +BMLog *BM_log_create(BMesh *bm, int cd_dyn_vert); +void BM_log_set_cd_offsets(BMLog *log, int cd_dyn_vert); /* Allocate and initialize a new BMLog using existing BMLogEntries */ BMLog *BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry); diff --git a/source/blender/draw/engines/overlay/overlay_lattice.c b/source/blender/draw/engines/overlay/overlay_lattice.c index 84d9dcc3e94..c9fd45baaf0 100644 --- a/source/blender/draw/engines/overlay/overlay_lattice.c +++ b/source/blender/draw/engines/overlay/overlay_lattice.c @@ -68,6 +68,7 @@ void OVERLAY_lattice_cache_populate(OVERLAY_Data *vedata, Object *ob) struct GPUBatch *geom = DRW_cache_lattice_wire_get(ob, false); OVERLAY_extra_wire(cb, geom, ob->obmat, color); + } void OVERLAY_edit_lattice_draw(OVERLAY_Data *vedata) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index dcb1a6c9c20..6fc69544fc8 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1677,6 +1677,29 @@ void SCULPT_orig_vert_data_init(SculptOrigVertData *data, */ void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter) { + // check if we need to update original data for current stroke + if (orig_data->bm_log) { + MDynTopoVert *mv = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert); + if (mv->stroke_id != orig_data->ss->stroke_id) { + mv->stroke_id = orig_data->ss->stroke_id; + + copy_v3_v3(mv->origco, iter->bm_vert->co); + copy_v3_v3(mv->origno, iter->bm_vert->no); + + const int cd_vcol = iter->cd_vcol_offset; + const int cd_mask = iter->cd_vert_mask_offset; + + if (cd_vcol >= 0) { + MPropCol *col = BM_ELEM_CD_GET_VOID_P(iter->bm_vert, cd_vcol); + copy_v4_v4(mv->origcolor, col->color); + } + + if (cd_mask >= 0) { + mv->origmask = BM_ELEM_CD_GET_FLOAT(iter->bm_vert, cd_mask); + } + } + } + if (orig_data->datatype == SCULPT_UNDO_COORDS) { if (orig_data->bm_log) { orig_data->co = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert)->origco; @@ -1704,8 +1727,7 @@ void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter } else if (orig_data->datatype == SCULPT_UNDO_MASK) { if (orig_data->bm_log) { - orig_data->mask = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert) - ->origmask; // BM_log_original_mask(orig_data->bm_log, iter->bm_vert); + orig_data->mask = BKE_PBVH_DYNVERT(iter->cd_dyn_vert, iter->bm_vert)->origmask; } else { orig_data->mask = orig_data->vmasks[iter->i]; @@ -2439,16 +2461,11 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, if (use_original) { if (unode->bm_entry) { - float *temp_co; - float *temp_no; + BMVert *v = vd.bm_vert; + MDynTopoVert *mv = BKE_PBVH_DYNVERT(vd.cd_dyn_vert, v); - BKE_pbvh_bmesh_update_origvert(ss->pbvh, vd.bm_vert, &temp_co, &temp_no, NULL); - if (temp_no) { - normal_float_to_short_v3(no_s, temp_no); - } - // BM_log_original_vert_data(ss->bm, ss->bm_log, vd.bm_vert, &temp_co, &temp_no_s, - // false); - copy_v3_v3(co, temp_co); + normal_float_to_short_v3(no_s, mv->origno); + copy_v3_v3(co, mv->origco); } else { copy_v3_v3(co, unode->co[vd.i]); @@ -5110,10 +5127,6 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, *disp_factor = 0.0f; - // update orig data to while we're at it, just to be paranoid - float *dummy; - - BKE_pbvh_bmesh_update_origvert(ss->pbvh, v, &dummy, &dummy, NULL); BLI_BITMAP_SET(ss->cache->layer_disp_map, nidx, true); } BKE_pbvh_vertex_iter_end; @@ -5255,6 +5268,12 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode cd_pers_disp = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT, SCULPT_LAYER_PERS_DISP); cd_layer_disp = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT, SCULPT_LAYER_DISP); + + //should never happen + if (cd_pers_co < 0 || cd_pers_no < 0 || cd_pers_disp < 0 || cd_layer_disp < 0) { + printf("error!! $d $d $d $d\n", cd_pers_co, cd_pers_no, cd_pers_disp, cd_layer_disp); + return; + } } else if (ss->cache->layer_displacement_factor == NULL) { ss->cache->layer_displacement_factor = MEM_callocN(sizeof(float) * SCULPT_vertex_count_get(ss), @@ -5265,7 +5284,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode SculptThreadedTaskData data = { .sd = sd, - .ob = ob, + .ob = ob, .brush = brush, .nodes = nodes, .cd_pers_co = cd_pers_co, @@ -6492,16 +6511,8 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe for (int i = 0; i < totnode; i++) { int other = brush->vcol_boundary_factor > 0.0f ? SCULPT_UNDO_COORDS : -1; - if (SCULPT_ensure_dyntopo_node_undo(ob, nodes[i], SCULPT_UNDO_COLOR, other)) { - BKE_pbvh_update_origcolor_bmesh(ss->pbvh, nodes[i]); - - if (other != -1) { - BKE_pbvh_update_origco_bmesh(ss->pbvh, nodes[i]); - } - } - + SCULPT_ensure_dyntopo_node_undo(ob, nodes[i], SCULPT_UNDO_COLOR, other); BKE_pbvh_node_mark_update_color(nodes[i]); - // SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COLOR); } } else if (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) { @@ -6515,26 +6526,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe BKE_pbvh_node_mark_update(nodes[i]); } - } - else if (brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) { - PBVHNode **nodes2; - int totnode2 = 0; - - BKE_pbvh_get_nodes(ss->pbvh, PBVH_Leaf, &nodes2, &totnode2); - - for (int i = 0; i < totnode2; i++) { - if (SCULPT_ensure_dyntopo_node_undo(ob, nodes2[i], SCULPT_UNDO_COORDS, -1)) { - BKE_pbvh_update_origco_bmesh(ss->pbvh, nodes2[i]); - BKE_pbvh_node_free_proxies(nodes2[i]); - } - BKE_pbvh_node_mark_update(nodes2[i]); - } - } - else { + } else { for (int i = 0; i < totnode; i++) { - if (SCULPT_ensure_dyntopo_node_undo(ob, nodes[i], SCULPT_UNDO_COORDS, -1)) { - // BKE_pbvh_update_origco_bmesh(ss->pbvh, nodes[i]); - } + SCULPT_ensure_dyntopo_node_undo(ob, nodes[i], SCULPT_UNDO_COORDS, -1); BKE_pbvh_node_mark_update(nodes[i]); } } @@ -8516,6 +8510,8 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const f ED_view3d_init_mats_rv3d(ob, CTX_wm_region_view3d(C)); + // increment stroke_id to flag origdata update + ss->stroke_id++; sculpt_update_cache_invariants(C, sd, ss, op, mouse); SCULPT_undo_push_begin(ob, sculpt_tool_name(sd)); diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c index ab7cf550b65..59d5dee7b42 100644 --- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c +++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c @@ -134,6 +134,8 @@ static char layer_id[] = "_dyntopo_node_id"; void SCULPT_dyntopo_node_layers_update_offsets(SculptSession *ss) { SCULPT_dyntopo_node_layers_add(ss); + BKE_pbvh_update_offsets( + ss->pbvh, ss->cd_vert_node_offset, ss->cd_face_node_offset, ss->cd_dyn_vert); } bool SCULPT_dyntopo_has_templayer(SculptSession *ss, int type, const char *name) @@ -148,8 +150,6 @@ void SCULPT_dyntopo_ensure_templayer(SculptSession *ss, int type, const char *na if (li < 0) { BM_data_layer_add_named(ss->bm, &ss->bm->vdata, type, name); SCULPT_dyntopo_node_layers_update_offsets(ss); - BKE_pbvh_update_offsets( - ss->pbvh, ss->cd_vert_node_offset, ss->cd_face_node_offset, ss->cd_dyn_vert); li = CustomData_get_named_layer_index(&ss->bm->vdata, type, name); ss->bm->vdata.layers[li].flag |= CD_FLAG_TEMPORARY; @@ -319,8 +319,6 @@ void SCULPT_dynamic_topology_sync_layers(Object *ob, Mesh *me) if (modified) { SCULPT_dyntopo_node_layers_update_offsets(ss); - BKE_pbvh_update_offsets( - ss->pbvh, ss->cd_vert_node_offset, ss->cd_face_node_offset, ss->cd_dyn_vert); } } @@ -378,8 +376,6 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene cd_layer_disp = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT, SCULPT_LAYER_DISP); SCULPT_dyntopo_node_layers_update_offsets(ss); - BKE_pbvh_update_offsets( - ss->pbvh, ss->cd_vert_node_offset, ss->cd_face_node_offset, ss->cd_dyn_vert); cd_vcol_offset = CustomData_get_offset(&ss->bm->vdata, CD_PROP_COLOR); } @@ -430,8 +426,7 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene ss->update_boundary_info_bmesh = 1; /* Enable logging for undo/redo. */ - ss->bm_log = BM_log_create( - ss->bm, ss->cd_origco_offset, ss->cd_origno_offset, ss->cd_origvcol_offset, ss->cd_dyn_vert); + ss->bm_log = BM_log_create(ss->bm, ss->cd_dyn_vert); /* Update dependency graph, so modifiers that depend on dyntopo being enabled * are re-evaluated and the PBVH is re-created. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index cdff1610e2f..b1578af8b3f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -459,15 +459,12 @@ static void sculpt_undo_bmesh_enable(Object *ob, SculptUndoNode *unode) })); BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK); SCULPT_dyntopo_node_layers_add(ss); - SCULPT_dyntopo_save_origverts(ss); - me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY; /* Restore the BMLog using saved entries. */ ss->bm_log = BM_log_from_existing_entries_create(ss->bm, unode->bm_entry); - BM_log_set_cd_offsets( - ss->bm_log, ss->cd_origco_offset, ss->cd_origno_offset, ss->cd_origvcol_offset, ss->cd_dyn_vert); + BM_log_set_cd_offsets(ss->bm_log, ss->cd_dyn_vert); } static void sculpt_undo_bmesh_restore_begin(bContext *C, @@ -601,8 +598,7 @@ static int sculpt_undo_bmesh_restore(bContext *C, SculptSession *ss) { if (ss->bm_log) { - BM_log_set_cd_offsets( - ss->bm_log, ss->cd_origco_offset, ss->cd_origno_offset, ss->cd_origvcol_offset, ss->cd_dyn_vert); + BM_log_set_cd_offsets(ss->bm_log, ss->cd_dyn_vert); } switch (unode->type) { @@ -1325,12 +1321,9 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt switch (type) { case SCULPT_UNDO_COORDS: case SCULPT_UNDO_MASK: - /* Before any vertex values get modified, ensure their - * original positions are logged. */ BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { float *dummy; - BKE_pbvh_bmesh_update_origvert(ss->pbvh, vd.bm_vert, &dummy, &dummy, &dummy); - // BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset, false); + BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset, false); } BKE_pbvh_vertex_iter_end; break; @@ -1341,7 +1334,6 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset, true); - // BKE_pbvh_bmesh_update_origvert(ss->pbvh, vd.bm_vert, &dummy, &dummy, &dummy); } BKE_pbvh_vertex_iter_end; @@ -1353,13 +1345,11 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt } case SCULPT_UNDO_COLOR: { -#if 1 BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { float *dummy; - BKE_pbvh_bmesh_update_origvert(ss->pbvh, vd.bm_vert, NULL, NULL, &dummy); + BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset, true); } BKE_pbvh_vertex_iter_end; -#endif break; } case SCULPT_UNDO_FACE_SETS: { diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 6b0985b850f..996946bfa71 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -536,7 +536,10 @@ typedef struct MDynTopoVert { float origmask; float curvature_dir[3]; - int _pad[1]; + + /* id of current stroke, used to detect + if vertex original data needs to be updated*/ + int stroke_id; } MDynTopoVert; /*MDynTopoVert->flag*/ |