More fixes for dyntopo undo and vertices (face data still isn't

implemented).
This commit is contained in:
Joseph Eagar 2020-10-26 18:46:12 -07:00
parent faf8402c19
commit e2c92c1341
4 changed files with 126 additions and 20 deletions

View File

@ -1792,9 +1792,9 @@ void BKE_pbvh_bmesh_update_origvert(
{
float *co = NULL, *no = NULL;
if (r_co || r_no) {
BM_log_vert_before_modified(pbvh->bm_log, v, pbvh->cd_vert_mask_offset);
BM_log_vert_before_modified(pbvh->bm_log, v, pbvh->cd_vert_mask_offset, r_color != NULL);
if (r_co || r_no) {
co = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origco_offset);
no = BM_ELEM_CD_GET_VOID_P(v, pbvh->cd_origno_offset);

View File

@ -252,12 +252,14 @@ 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(BMLogVert *lv, BMVert *v, const int cd_vert_mask_offset)
static void bm_log_vert_bmvert_copy(BMLog *log, BMLogVert *lv, BMVert *v, const int cd_vert_mask_offset)
{
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);
}
/* Allocate and initialize a BMLogVert */
@ -267,7 +269,7 @@ static BMLogVert *bm_log_vert_alloc(BMLog *log, BMVert *v, const int cd_vert_mas
BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts);
lv->customdata = NULL;
bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
bm_log_vert_bmvert_copy(log, lv, v, cd_vert_mask_offset);
return lv;
}
@ -308,7 +310,7 @@ 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(lv, v, cd_vert_mask_offset);
bm_log_vert_bmvert_copy(log, lv, v, cd_vert_mask_offset);
BM_vert_kill(bm, v);
}
@ -381,7 +383,7 @@ static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces)
}
}
static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts)
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);
@ -402,6 +404,12 @@ static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts)
mask = lv->mask;
lv->mask = vert_mask_get(v, cd_vert_mask_offset);
vert_mask_set(v, mask, cd_vert_mask_offset);
#ifdef CUSTOMDATA
if (lv->customdata) {
CustomData_bmesh_copy_data(&bm->vdata, &entry->vdata, lv->customdata, &v->head.data);
}
#endif
}
}
@ -707,6 +715,8 @@ BMLogEntry *BM_log_entry_check_customdata(BMesh *bm, BMLog *log)
BMLogEntry *entry = log->current_entry;
if (!entry) {
printf("no current entry; creating...\n");
fflush(stdout);
return BM_log_entry_add_ex(bm, log, false);
}
@ -719,6 +729,8 @@ BMLogEntry *BM_log_entry_check_customdata(BMesh *bm, BMLog *log)
for (int i = 0; i < 4; i++) {
if (!CustomData_layout_is_same(cd1[i], cd2[i])) {
printf("Customdata changed for undo\n");
fflush(stdout);
return BM_log_entry_add_ex(bm, log, true);
}
}
@ -884,7 +896,7 @@ void BM_log_undo(BMesh *bm, BMLog *log)
bm_log_faces_restore(bm, log, entry->deleted_faces);
/* Restore vertex coordinates, mask, and hflag */
bm_log_vert_values_swap(bm, log, entry->modified_verts);
bm_log_vert_values_swap(bm, log, entry->modified_verts, entry);
bm_log_face_values_swap(log, entry->modified_faces);
}
}
@ -921,7 +933,7 @@ void BM_log_redo(BMesh *bm, BMLog *log)
bm_log_faces_restore(bm, log, entry->added_faces);
/* Restore vertex coordinates, mask, and hflag */
bm_log_vert_values_swap(bm, log, entry->modified_verts);
bm_log_vert_values_swap(bm, log, entry->modified_verts, entry);
bm_log_face_values_swap(log, entry->modified_faces);
}
}
@ -949,7 +961,7 @@ void BM_log_redo(BMesh *bm, BMLog *log)
* state so that a subsequent redo operation will restore the newer
* vertex state.
*/
void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_offset, bool log_customdata)
{
BMLogEntry *entry = log->current_entry;
BMLogVert *lv;
@ -959,14 +971,14 @@ void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_o
/* Find or create the BMLogVert entry */
if ((lv = BLI_ghash_lookup(entry->added_verts, key))) {
bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
bm_log_vert_bmvert_copy(log, lv, v, cd_vert_mask_offset);
}
else if (!BLI_ghash_ensure_p(entry->modified_verts, key, &val_p)) {
lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
*val_p = lv;
}
if (lv) {
if (lv && log_customdata) {
bm_log_vert_customdata(log->bm, log, v, lv);
}
}
@ -986,6 +998,8 @@ void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
bm_log_vert_id_set(log, v, v_id);
lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
BLI_ghash_insert(log->current_entry->added_verts, key, lv);
bm_log_vert_customdata(log->bm, log, v, lv);
}
/* Log a face before it is modified
@ -1064,6 +1078,10 @@ void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
(*lv) = (*lv_mod);
BLI_ghash_remove(entry->modified_verts, key, NULL, NULL);
}
if (lv) {
bm_log_vert_customdata(log->bm, log, v, lv);
}
}
}

View File

@ -62,7 +62,7 @@ void BM_log_undo(BMesh *bm, BMLog *log);
void BM_log_redo(BMesh *bm, BMLog *log);
/* Log a vertex before it is modified */
void BM_log_vert_before_modified(BMLog *log, struct BMVert *v, const int cd_vert_mask_offset);
void BM_log_vert_before_modified(BMLog *log, struct BMVert *v, const int cd_vert_mask_offset, bool log_customdata);
/* Log a new vertex as added to the BMesh */
void BM_log_vert_added(BMLog *log, struct BMVert *v, const int cd_vert_mask_offset);

View File

@ -116,6 +116,7 @@ typedef struct UndoSculpt {
} UndoSculpt;
static UndoSculpt *sculpt_undo_get_nodes(void);
static void sculpt_undo_print_nodes(void *active);
static void update_cb(PBVHNode *node, void *rebuild)
{
@ -133,6 +134,8 @@ struct PartialUpdateData {
char *modified_grids;
};
static UndoSculpt *sculpt_undosys_step_get_nodes(UndoStep *us_p);
/**
* A version of #update_cb that tests for 'ME_VERT_PBVH_UPDATE'
*/
@ -421,7 +424,7 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob,
unode->applied = true;
}
if (unode->type == SCULPT_UNDO_MASK) {
if (unode->type == SCULPT_UNDO_MASK || unode->type == SCULPT_UNDO_COLOR) {
int totnode;
PBVHNode **nodes;
@ -971,6 +974,7 @@ static SculptUndoNode *sculpt_undo_find_or_alloc_node_type(Object *object, Sculp
return sculpt_undo_alloc_node_type(object, type);
}
static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, SculptUndoType type)
{
UndoSculpt *usculpt = sculpt_undo_get_nodes();
@ -1173,7 +1177,10 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
SculptUndoNode *unode = usculpt->nodes.first;
bool new_node = false;
if (unode == NULL) {
new_node = true;
unode = MEM_callocN(sizeof(*unode), __func__);
BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname));
@ -1216,8 +1223,8 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL)
{
void *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);
// 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);
}
BKE_pbvh_vertex_iter_end;
break;
@ -1228,7 +1235,8 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL)
{
BM_log_vert_before_modified(ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset);
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;
@ -1240,16 +1248,16 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
}
case SCULPT_UNDO_COLOR: {
#if 0
#if 1
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL)
{
BM_log_vert_before_modified(
ss->bm, ss->bm_log, vd.bm_vert, vd.cd_vert_mask_offset, true);
void *dummy;
BKE_pbvh_bmesh_update_origvert(ss->pbvh, vd.bm_vert, NULL, NULL, &dummy);
}
BKE_pbvh_vertex_iter_end;
#endif
break;
}
}
case SCULPT_UNDO_DYNTOPO_BEGIN:
case SCULPT_UNDO_DYNTOPO_END:
case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
@ -1259,6 +1267,10 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt
}
}
if (new_node) {
//sculpt_undo_print_nodes(NULL);
}
return unode;
}
@ -1401,6 +1413,7 @@ typedef struct SculptUndoStep {
UndoStep step;
/* Note: will split out into list for multi-object-sculpt-mode. */
UndoSculpt data;
int id;
} SculptUndoStep;
static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p)
@ -1439,6 +1452,8 @@ static void sculpt_undosys_step_decode_undo_impl(struct bContext *C,
BLI_assert(us->step.is_applied == true);
sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
us->step.is_applied = false;
//sculpt_undo_print_nodes(us);
}
static void sculpt_undosys_step_decode_redo_impl(struct bContext *C,
@ -1448,6 +1463,8 @@ static void sculpt_undosys_step_decode_redo_impl(struct bContext *C,
BLI_assert(us->step.is_applied == false);
sculpt_undo_restore_list(C, depsgraph, &us->data.nodes);
us->step.is_applied = true;
//sculpt_undo_print_nodes(us);
}
static void sculpt_undosys_step_decode_undo(struct bContext *C,
@ -1677,3 +1694,74 @@ void ED_sculpt_undo_push_multires_mesh_end(bContext *C, const char *str)
}
/** \} */
#ifdef _
# undef _
#endif
#define _(type) \
case type: \
return #type;
static char *undo_type_to_str(int type)
{
switch (type) {
_(SCULPT_UNDO_DYNTOPO_BEGIN)
_(SCULPT_UNDO_DYNTOPO_END)
_(SCULPT_UNDO_COORDS)
_(SCULPT_UNDO_GEOMETRY)
_(SCULPT_UNDO_DYNTOPO_SYMMETRIZE)
_(SCULPT_UNDO_FACE_SETS)
_(SCULPT_UNDO_HIDDEN)
_(SCULPT_UNDO_MASK)
_(SCULPT_UNDO_COLOR)
default:
return "unknown node type";
}
}
#undef _
static int nodeidgen = 1;
static void sculpt_undo_print_nodes(void *active)
{
UndoStack *ustack = ED_undo_stack_get();
UndoStep *us = ustack->steps.first;
if (active == NULL) {
active = ustack->step_active;
}
SculptUndoNode *node;
if (!us) {
return;
}
printf("\n");
int i = 0;
for (; us; us = us->next, i++) {
int id = -1;
if (us->type == BKE_UNDOSYS_TYPE_SCULPT) {
SculptUndoStep *su = (SculptUndoStep *)us;
if (!su->id) {
su->id = nodeidgen++;
}
id = su->id;
}
printf("%d %s %d %s\n", id, us == active ? "->" : " ", i, us->name);
if (us->type == BKE_UNDOSYS_TYPE_SCULPT) {
UndoSculpt *usculpt = sculpt_undosys_step_get_nodes(us);
for (node = usculpt->nodes.first; node; node = node->next) {
printf(" %s:%s {applied=%d bm_entry=%p}\n",
undo_type_to_str(node->type),
node->idname,
node->applied,
node->bm_entry);
}
}
}
}