Commit: af8fe4e94e79baf2830a6766781d21fe60bc06c2
Author: Pablo Dobarro
Date:   Tue Mar 19 23:07:22 2019 +0100
Branches: sculpt-mode-features
https://developer.blender.org/rBaf8fe4e94e79baf2830a6766781d21fe60bc06c2

Voxel remesher: Add support for undo from sculpt mode

Only undo for now, no redo.
This will need a lot of work and refactoring in the future (it has a lot
of bugs), but now it is safer to test new features without losing work.

===================================================================

M       source/blender/editors/object/CMakeLists.txt
M       source/blender/editors/object/object_edit.c
M       source/blender/editors/sculpt_paint/sculpt_intern.h
M       source/blender/editors/sculpt_paint/sculpt_undo.c

===================================================================

diff --git a/source/blender/editors/object/CMakeLists.txt 
b/source/blender/editors/object/CMakeLists.txt
index 3211784e126..90294bc6f67 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -33,6 +33,7 @@ set(INC
        ../../python
        ../../render/extern/include
        ../../windowmanager
+       ../sculpt_paint
        ../../../../intern/guardedalloc
        ../../../../intern/glew-mx
 )
diff --git a/source/blender/editors/object/object_edit.c 
b/source/blender/editors/object/object_edit.c
index 7a807206bda..ba1c07c24b6 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -113,6 +113,7 @@
 #include "WM_toolsystem.h"
 
 #include "object_intern.h"  // own include
+#include "sculpt_intern.h"
 
 #ifdef WITH_OPENVDB
        #include "openvdb_capi.h"
@@ -1764,6 +1765,20 @@ static int remesh_exec(bContext *C, wmOperator *op)
        }
 
        if (ob->type == OB_MESH) {
+
+               if (ob->mode == OB_MODE_SCULPT) {
+                       Depsgraph *depsgraph = CTX_data_depsgraph(C);
+                       struct Scene *scene = CTX_data_scene(C);
+                       Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+                       BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, 
ob, true, true);
+                       PBVH *pbvh;
+                       PBVHNode **nodes;
+                       int totnode;
+                       pbvh = ob->sculpt->pbvh;
+                       BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, 
&totnode);
+                       sculpt_undo_push_begin("voxel remesh");
+                       sculpt_undo_push_node(ob, nodes[0], SCULPT_UNDO_REMESH);
+               }
                Mesh *mesh = ob->data;
                BKE_mesh_runtime_looptri_recalc(mesh);
                const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
@@ -1816,6 +1831,9 @@ static int remesh_exec(bContext *C, wmOperator *op)
                if (RNA_boolean_get(op->ptr, "smooth_normals")) {
                        BKE_mesh_smooth_flag_set(ob, true);
                }
+               if (ob->mode == OB_MODE_SCULPT) {
+                       sculpt_undo_push_end();
+               }
 
                BKE_mesh_batch_cache_dirty_tag(ob->data, 
BKE_MESH_BATCH_DIRTY_ALL);
                DEG_relations_tag_update(bmain);
@@ -1828,7 +1846,6 @@ static int remesh_exec(bContext *C, wmOperator *op)
                MEM_freeN(verttri);
                MEM_freeN(rmd.out_verts);
                MEM_freeN(rmd.out_faces);
-
                return OPERATOR_FINISHED;
        }
        return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h 
b/source/blender/editors/sculpt_paint/sculpt_intern.h
index bc1462cbb7e..acc5d60df20 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -28,11 +28,13 @@
 #include "DNA_listBase.h"
 #include "DNA_vec_types.h"
 #include "DNA_key_types.h"
+#include "DNA_mesh_types.h"
 
 #include "BLI_bitmap.h"
 #include "BLI_threads.h"
 
 #include "BKE_pbvh.h"
+#include "BKE_mesh.h"
 
 struct KeyBlock;
 struct Object;
@@ -83,6 +85,7 @@ typedef enum {
        SCULPT_UNDO_DYNTOPO_BEGIN,
        SCULPT_UNDO_DYNTOPO_END,
        SCULPT_UNDO_DYNTOPO_SYMMETRIZE,
+       SCULPT_UNDO_REMESH,
 } SculptUndoType;
 
 typedef struct SculptUndoNode {
@@ -126,6 +129,17 @@ typedef struct SculptUndoNode {
        /* shape keys */
        char shapeName[sizeof(((KeyBlock *)0))->name];
 
+       /* remesh operations */
+       bool remesh_applied;
+       CustomData remesh_vdata;
+       CustomData remesh_edata;
+       CustomData remesh_ldata;
+       CustomData remesh_pdata;
+       int remesh_totvert;
+       int remesh_totedge;
+       int remesh_totloop;
+       int remesh_totpoly;
+
        size_t undo_size;
 } SculptUndoNode;
 
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c 
b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 9c76292aaa7..b8b599a6479 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -55,8 +55,11 @@
 #include "BKE_undo_system.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
+#include "BKE_pointcache.h"
+#include "BKE_particle.h"
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -449,6 +452,7 @@ static int sculpt_undo_bmesh_restore(bContext *C,
                                      Object *ob,
                                      SculptSession *ss)
 {
+       Mesh *me;
        switch (unode->type) {
                case SCULPT_UNDO_DYNTOPO_BEGIN:
                        sculpt_undo_bmesh_restore_begin(C, unode, ob, ss);
@@ -457,7 +461,29 @@ static int sculpt_undo_bmesh_restore(bContext *C,
                case SCULPT_UNDO_DYNTOPO_END:
                        sculpt_undo_bmesh_restore_end(C, unode, ob, ss);
                        return true;
-
+               case SCULPT_UNDO_REMESH:
+                       sculpt_pbvh_clear(ob);
+                       me = ob->data;
+                       CustomData_free(&me->vdata, me->totvert);
+                       CustomData_free(&me->edata, me->totedge);
+                       CustomData_free(&me->fdata, me->totface);
+                       CustomData_free(&me->ldata, me->totloop);
+                       CustomData_free(&me->pdata, me->totpoly);
+                       me->totvert = unode->remesh_totvert;
+                       me->totedge = unode->remesh_totedge;
+                       me->totloop = unode->remesh_totloop;
+                       me->totpoly = unode->remesh_totpoly;
+                       me->totface = 0;
+                       CustomData_copy(&unode->remesh_vdata, &me->vdata, 
CD_MASK_MESH.vmask,
+                                       CD_DUPLICATE, unode->remesh_totvert);
+                       CustomData_copy(&unode->remesh_edata, &me->edata, 
CD_MASK_MESH.emask,
+                                       CD_DUPLICATE, unode->remesh_totedge);
+                       CustomData_copy(&unode->remesh_ldata, &me->ldata, 
CD_MASK_MESH.lmask,
+                                       CD_DUPLICATE, unode->remesh_totloop);
+                       CustomData_copy(&unode->remesh_pdata, &me->pdata, 
CD_MASK_MESH.pmask,
+                                       CD_DUPLICATE, unode->remesh_totpoly);
+                       BKE_mesh_update_customdata_pointers(me, false);
+                       return false;
                default:
                        if (ss->bm_log) {
                                sculpt_undo_bmesh_restore_generic(C, unode, ob, 
ss);
@@ -476,14 +502,19 @@ static void sculpt_undo_restore_list(bContext *C, 
ListBase *lb)
        ViewLayer *view_layer = CTX_data_view_layer(C);
        Object *ob = OBACT(view_layer);
        Depsgraph *depsgraph = CTX_data_depsgraph(C);
+       Main *bmain = CTX_data_main(C);
        SculptSession *ss = ob->sculpt;
        SubdivCCG *subdiv_ccg = ss->subdiv_ccg;
        SculptUndoNode *unode;
        bool update = false, rebuild = false;
        bool need_mask = false;
        bool partial_update = true;
+       bool remesh_update = false;
 
        for (unode = lb->first; unode; unode = unode->next) {
+               if (unode->type == SCULPT_UNDO_REMESH) {
+                       remesh_update = true;
+               }
                if (STREQ(unode->idname, ob->id.name)) {
                        if (unode->type == SCULPT_UNDO_MASK) {
                                /* is possible that we can't do the mask undo 
(below)
@@ -541,9 +572,21 @@ static void sculpt_undo_restore_list(bContext *C, ListBase 
*lb)
                        case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
                                BLI_assert(!"Dynamic topology should've already 
been handled");
                                break;
+                       case SCULPT_UNDO_REMESH:
+                               break;
                }
        }
 
+       if (remesh_update) {
+               BKE_particlesystem_reset_all(ob);
+               BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED);
+               DEG_relations_tag_update(bmain);
+               DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+               BKE_sculpt_update_mesh_elements(depsgraph, scene, sd, ob, 
false, false);
+               WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
+               WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
+       }
+
        if (update || rebuild) {
                bool tag_update = false;
                /* we update all nodes still, should be more clever, but also
@@ -627,6 +670,15 @@ static void sculpt_undo_free_list(ListBase *lb)
                if (unode->bm_enter_totpoly)
                        CustomData_free(&unode->bm_enter_pdata, 
unode->bm_enter_totpoly);
 
+               if (unode->remesh_totvert)
+                       CustomData_free(&unode->remesh_vdata, 
unode->remesh_totvert);
+               if (unode->remesh_totedge)
+                       CustomData_free(&unode->remesh_edata, 
unode->remesh_totedge);
+               if (unode->remesh_totloop)
+                       CustomData_free(&unode->remesh_ldata, 
unode->remesh_totloop);
+               if (unode->remesh_totpoly)
+                       CustomData_free(&unode->remesh_pdata, 
unode->remesh_totpoly);
+
                MEM_freeN(unode);
 
                unode = unode_next;
@@ -861,6 +913,22 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
                        unode->bm_entry = BM_log_entry_add(ss->bm_log);
                        BM_log_all_added(ss->bm, ss->bm_log);
                }
+               else if (type == SCULPT_UNDO_REMESH) {
+                       Mesh *me = ob->data;
+
+                       CustomData_copy(&me->vdata, &unode->remesh_vdata, 
CD_MASK_MESH.vmask,
+                                       CD_DUPLICATE, me->totvert);
+                       CustomData_copy(&me->edata, &unode->remesh_edata, 
CD_MASK_MESH.emask,
+                                       CD_DUPLICATE, me->totedge);
+                       CustomData_copy(&me->ldata, &unode->remesh_ldata, 
CD_MASK_MESH.lmask,
+                                       CD_DUPLICATE, me->totloop);
+                       CustomData_copy(&me->pdata, &unode->remesh_pdata, 
CD_MASK_MESH.pmask,
+                                       CD_DUPLICATE, me->totpoly);
+                       unode->remesh_totvert = me->totvert;
+                       unode->remesh_totedge = me->totedge;
+                       unode->remesh_totloop = me->totloop;
+                       unode->remesh_totpoly = me->totpoly;
+               }
                else {
                        unode->bm_entry = BM_log_entry_add(ss->bm_log);
                }
@@ -899,6 +967,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
                        case SCULPT_UNDO_DYNTOPO_BEGIN:
                        case SCULPT_UNDO_DYNTOPO_END:
                        case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
+                       case SCULPT_UNDO_REMESH:
                                break;
                }
        }
@@ -919,7 +988,7 @@ SculptUndoNode *sculpt_undo_push_node(
        if (ss->bm ||
            ELEM(type,
                 SCULPT_UNDO_DYNTOPO_BEGIN,
-                SCULPT_UNDO_DYNTOPO_END))
+                SCULPT_UNDO_DYNTOPO_END, SCULPT_UNDO_REMESH))
        {
                /* Dynamic topology stores only one undo node per stroke,
                 * regardless of the number of PBVH nodes modified */
@@ -968,6 +1037,8 @@ SculptUndoNode *sculpt_undo_push_node(
                case SCULPT_UNDO_DYNTOPO_SYMMETRIZE:
                        BLI_assert(!"Dynamic topology should've already been 
handled");
                        break;
+               case SCULPT_UNDO_REMESH:
+                       break;
        }
 
        /* store active shape key */
@@ -1046,7 +1117,7 @@ static bool sculpt_undosys_step_encode(struct bContext 
*UNUSED(C), struct Main *
        us->step.data_size = us->data.undo_size;
 
        SculptUndoNode *unode = us->data.nodes.last;
-       if (unode && unode->type == SCULPT_UNDO_DYNTOPO_END) {
+       if (unode && (unode->type == SCULPT_UNDO_DYNTOPO_END)) {
                us->step.use_memfile_step = true;
        }
        us->step.is_applied = true;

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to