diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_undo.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_undo.c | 92 |
1 files changed, 85 insertions, 7 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index c08ed2e85b9..d233c45a230 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -47,6 +47,7 @@ #include "DNA_scene_types.h" #include "DNA_mesh_types.h" +#include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -76,7 +77,10 @@ static void update_cb(PBVHNode *node, void *rebuild) BLI_pbvh_node_fully_hidden_set(node, 0); } -static void sculpt_undo_restore_deformed(SculptSession *ss, SculptUndoNode *unode, int uindex, int oindex, float coord[3]) +static void sculpt_undo_restore_deformed(const SculptSession *ss, + SculptUndoNode *unode, + int uindex, int oindex, + float coord[3]) { if (unode->orig_co) { swap_v3_v3(coord, unode->orig_co[uindex]); @@ -154,19 +158,21 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo } else if (unode->maxgrid && dm->getGridData) { /* multires restore */ - DMGridData **grids, *grid; + CCGElem **grids, *grid; + CCGKey key; float (*co)[3]; int gridsize; grids = dm->getGridData(dm); gridsize = dm->getGridSize(dm); + dm->getGridKey(dm, &key); co = unode->co; for (j = 0; j < unode->totgrid; j++) { grid = grids[unode->grids[j]]; for (i = 0; i < gridsize * gridsize; i++, co++) - swap_v3_v3(grid[i].co, co[0]); + swap_v3_v3(CCG_elem_offset_co(&key, grid, i), co[0]); } } @@ -211,6 +217,49 @@ static int sculpt_undo_restore_hidden(bContext *C, DerivedMesh *dm, return 1; } +static int sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNode *unode) +{ + Object *ob = CTX_data_active_object(C); + SculptSession *ss = ob->sculpt; + MVert *mvert; + float *vmask; + int *index, i, j; + + if (unode->maxvert) { + /* regular mesh restore */ + + index = unode->index; + mvert = ss->mvert; + vmask = ss->vmask; + + for (i = 0; i < unode->totvert; i++) { + SWAP(float, vmask[index[i]], unode->mask[i]); + mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE; + } + } + else if (unode->maxgrid && dm->getGridData) { + /* multires restore */ + CCGElem **grids, *grid; + CCGKey key; + float *mask; + int gridsize; + + grids = dm->getGridData(dm); + gridsize = dm->getGridSize(dm); + dm->getGridKey(dm, &key); + + mask = unode->mask; + for (j = 0; j < unode->totgrid; j++) { + grid = grids[unode->grids[j]]; + + for (i = 0; i < gridsize * gridsize; i++, mask++) + SWAP(float, *CCG_elem_offset_mask(&key, grid, i), *mask); + } + } + + return 1; +} + static void sculpt_undo_restore(bContext *C, ListBase *lb) { Scene *scene = CTX_data_scene(C); @@ -254,6 +303,10 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) if (sculpt_undo_restore_hidden(C, dm, unode)) rebuild = 1; break; + case SCULPT_UNDO_MASK: + if (sculpt_undo_restore_mask(C, dm, unode)) + update = 1; + break; } } @@ -276,8 +329,8 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb) if (ss->modifiers_active) { Mesh *mesh = ob->data; - mesh_calc_normals_tessface(mesh->mvert, mesh->totvert, - mesh->mface, mesh->totface, NULL); + BKE_mesh_calc_normals_tessface(mesh->mvert, mesh->totvert, + mesh->mface, mesh->totface, NULL); free_sculptsession_deformMats(ss); tag_update |= 1; @@ -318,6 +371,8 @@ static void sculpt_undo_free(ListBase *lb) } MEM_freeN(unode->grid_hidden); } + if (unode->mask) + MEM_freeN(unode->mask); } } @@ -385,7 +440,10 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, case SCULPT_UNDO_COORDS: unode->co = MEM_mapallocN(sizeof(float) * 3 * allvert, "SculptUndoNode.co"); unode->no = MEM_mapallocN(sizeof(short) * 3 * allvert, "SculptUndoNode.no"); - undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float) * 3 + sizeof(short) * 3 + sizeof(int)) * allvert); + undo_paint_push_count_alloc(UNDO_PAINT_MESH, + (sizeof(float) * 3 + + sizeof(short) * 3 + + sizeof(int)) * allvert); break; case SCULPT_UNDO_HIDDEN: if (maxgrid) @@ -394,6 +452,10 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, unode->vert_hidden = BLI_BITMAP_NEW(allvert, "SculptUndoNode.vert_hidden"); break; + case SCULPT_UNDO_MASK: + unode->mask = MEM_mapallocN(sizeof(float) * allvert, "SculptUndoNode.mask"); + undo_paint_push_count_alloc(UNDO_PAINT_MESH, (sizeof(float) * sizeof(int)) * allvert); + break; } BLI_addtail(lb, unode); @@ -422,7 +484,8 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode) SculptSession *ss = ob->sculpt; PBVHVertexIter vd; - BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL) { + BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL) + { copy_v3_v3(unode->co[vd.i], vd.co); if (vd.no) copy_v3_v3_short(unode->no[vd.i], vd.no); else normal_float_to_short_v3(unode->no[vd.i], vd.fno); @@ -455,6 +518,18 @@ static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode) } } +static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode) +{ + SculptSession *ss = ob->sculpt; + PBVHVertexIter vd; + + BLI_pbvh_vertex_iter_begin(ss->pbvh, unode->node, vd, PBVH_ITER_ALL) + { + unode->mask[vd.i] = *vd.mask; + } + BLI_pbvh_vertex_iter_end; +} + SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type) { @@ -495,6 +570,9 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, case SCULPT_UNDO_HIDDEN: sculpt_undo_store_hidden(ob, unode); break; + case SCULPT_UNDO_MASK: + sculpt_undo_store_mask(ob, unode); + break; } /* store active shape key */ |