* Fixed an annoying number of undo bugs
* Original data for bmesh pbvh is no longer handled by the undo code. This should eliminate a whole class of subtle and hard to track down bugs.
This commit is contained in:
parent
55045ed85a
commit
6f91eaad39
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,39 +1044,67 @@ 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 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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
BMLogEntry *preventry = entry->prev;
|
||||
|
||||
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 */
|
||||
static void bm_log_redo_intern(BMesh *bm, BMLog *log, BMLogEntry *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;
|
||||
|
||||
bm->elem_index_dirty |= BM_VERT | BM_EDGE | BM_FACE;
|
||||
bm->elem_table_dirty |= BM_VERT | BM_EDGE | BM_FACE;
|
||||
log->bm = bm;
|
||||
|
||||
if (!entry) {
|
||||
/* Currently at the beginning of the undo stack, move to first entry */
|
||||
|
@ -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;
|
||||
BMLogEntry *nextentry = 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);
|
||||
|
||||
/* 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);
|
||||
while (entry->combined_prev) {
|
||||
entry = entry->combined_prev;
|
||||
}
|
||||
}
|
||||
|
||||
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))) {
|
||||
(*lv) = (*lv_mod);
|
||||
log_ghash_remove(log, entry->modified_verts, key, NULL, NULL);
|
||||
}
|
||||
if (lv->customdata) {
|
||||
BLI_mempool_free(entry->vdata.pool, lv->customdata);
|
||||
}
|
||||
|
||||
if (lv) {
|
||||
bm_log_vert_customdata(log->bm, log, v, lv);
|
||||
(*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);
|
||||
}
|
||||
else {
|
||||
bm_log_vert_customdata(log->bm, log, entry, v, lv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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*/
|
||||
|
|
Loading…
Reference in New Issue