Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_customdata.h6
-rw-r--r--source/blender/blenkernel/BKE_paint.h8
-rw-r--r--source/blender/blenkernel/intern/customdata.c131
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c1
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c204
-rw-r--r--source/blender/bmesh/intern/bmesh_log.h9
-rw-r--r--source/blender/draw/engines/overlay/overlay_lattice.c1
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c84
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_dyntopo.c11
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c18
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h5
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*/