diff options
author | Antony Riakiotakis <kalast@gmail.com> | 2014-04-11 03:29:37 +0400 |
---|---|---|
committer | Antony Riakiotakis <kalast@gmail.com> | 2014-04-11 03:29:59 +0400 |
commit | 69d2af764354f515816ec0d187b824c325d4788d (patch) | |
tree | 6c0d2c28272d9ace6aedfadd49f30d86570cce90 /source/blender | |
parent | 45f336c3a10e17227a3a7a4cb599c019d9e761d2 (diff) |
Support logging of modified faces in dyntopo.
This is meant to support undo when hiding parts of the mesh.
Also avoid rebuilding the PBVH in that case as well (no nodes split)
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_log.c | 37 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_log.h | 3 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_undo.c | 19 |
3 files changed, 57 insertions, 2 deletions
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index f7c2b7d7fe6..d9bbb5c421d 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -67,6 +67,7 @@ struct BMLogEntry { /* Vertices whose coordinates, mask value, or hflag have changed */ GHash *modified_verts; + GHash *modified_faces; BLI_mempool *pool_verts; BLI_mempool *pool_faces; @@ -120,6 +121,7 @@ typedef struct { typedef struct { unsigned int v_ids[3]; + char hflag; } BMLogFace; /************************* Get/set element IDs ************************/ @@ -234,6 +236,7 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f) lf->v_ids[1] = bm_log_vert_id_get(log, v[1]); lf->v_ids[2] = bm_log_vert_id_get(log, v[2]); + lf->hflag = f->head.hflag; return lf; } @@ -341,6 +344,19 @@ static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts) } } +static void bm_log_face_values_swap(BMLog *log, GHash *faces) +{ + GHashIterator gh_iter; + GHASH_ITER (gh_iter, faces) { + void *key = BLI_ghashIterator_getKey(&gh_iter); + BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter); + unsigned int id = GET_UINT_FROM_POINTER(key); + BMFace *f = bm_log_face_from_id(log, id); + + SWAP(char, f->head.hflag, lf->hflag); + } +} + /**********************************************************************/ @@ -374,6 +390,7 @@ static BMLogEntry *bm_log_entry_create(void) entry->added_verts = BLI_ghash_ptr_new(__func__); entry->added_faces = BLI_ghash_ptr_new(__func__); entry->modified_verts = BLI_ghash_ptr_new(__func__); + entry->modified_faces = BLI_ghash_ptr_new(__func__); entry->pool_verts = BLI_mempool_create(sizeof(BMLogVert), 0, 64, BLI_MEMPOOL_NOP); entry->pool_faces = BLI_mempool_create(sizeof(BMLogFace), 0, 64, BLI_MEMPOOL_NOP); @@ -391,6 +408,7 @@ static void bm_log_entry_free(BMLogEntry *entry) BLI_ghash_free(entry->added_verts, NULL, NULL); BLI_ghash_free(entry->added_faces, NULL, NULL); BLI_ghash_free(entry->modified_verts, NULL, NULL); + BLI_ghash_free(entry->modified_faces, NULL, NULL); BLI_mempool_destroy(entry->pool_verts); BLI_mempool_destroy(entry->pool_faces); @@ -706,6 +724,7 @@ void BM_log_undo(BMesh *bm, BMLog *log) /* Restore vertex coordinates, mask, and hflag */ bm_log_vert_values_swap(bm, log, entry->modified_verts); + bm_log_face_values_swap(log, entry->modified_faces); } } @@ -742,6 +761,7 @@ void BM_log_redo(BMesh *bm, BMLog *log) /* Restore vertex coordinates, mask, and hflag */ bm_log_vert_values_swap(bm, log, entry->modified_verts); + bm_log_face_values_swap(log, entry->modified_faces); } } @@ -785,6 +805,7 @@ void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_o } } + /* Log a new vertex as added to the BMesh * * The new vertex gets a unique ID assigned. It is then added to a map @@ -802,6 +823,22 @@ void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset) BLI_ghash_insert(log->current_entry->added_verts, key, lv); } + +/* Log a face before it is modified + * + * This is intended to handle only header flags and we always + * assume face has been added before + */ +void BM_log_face_modified(BMLog *log, BMFace *f) +{ + BMLogFace *lf; + unsigned int f_id = bm_log_face_id_get(log, f); + void *key = SET_UINT_IN_POINTER(f_id); + + lf = bm_log_face_alloc(log, f); + BLI_ghash_insert(log->current_entry->modified_faces, key, lf); +} + /* Log a new face as added to the BMesh * * The new face gets a unique ID assigned. It is then added to a map diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h index dab17268d96..7a26506439f 100644 --- a/source/blender/bmesh/intern/bmesh_log.h +++ b/source/blender/bmesh/intern/bmesh_log.h @@ -66,6 +66,9 @@ void BM_log_vert_before_modified(BMLog *log, struct BMVert *v, const int cd_vert /* 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); +/* Log a face before it is modified */ +void BM_log_face_modified(BMLog *log, struct BMFace *f); + /* Log a new face as added to the BMesh */ void BM_log_face_added(BMLog *log, struct BMFace *f); diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 90e26f03b2e..673e4d90d99 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -280,7 +280,7 @@ static void sculpt_undo_bmesh_restore_generic(bContext *C, unode->applied = true; } - if (unode->type == SCULPT_UNDO_MASK) { + if (ELEM(unode->type, SCULPT_UNDO_MASK, SCULPT_UNDO_MASK)) { int i, totnode; PBVHNode **nodes; @@ -756,7 +756,6 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, if (node) { switch (type) { case SCULPT_UNDO_COORDS: - case SCULPT_UNDO_HIDDEN: case SCULPT_UNDO_MASK: /* Before any vertex values get modified, ensure their * original positions are logged */ @@ -766,6 +765,22 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, BKE_pbvh_vertex_iter_end; break; + case SCULPT_UNDO_HIDDEN: + { + GSetIterator gs_iter; + GSet *faces = BKE_pbvh_bmesh_node_faces(node); + 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); + } + BKE_pbvh_vertex_iter_end; + + GSET_ITER (gs_iter, faces) { + BMFace *f = BLI_gsetIterator_getKey(&gs_iter); + BM_log_face_modified(ss->bm_log, f); + } + break; + } + case SCULPT_UNDO_DYNTOPO_BEGIN: case SCULPT_UNDO_DYNTOPO_END: case SCULPT_UNDO_DYNTOPO_SYMMETRIZE: |