More fixes for dyntopo undo and vertices (face data still isn't
implemented).
This commit is contained in:
parent
faf8402c19
commit
e2c92c1341
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue