[Bf-blender-cvs] [af8fe4e94e7] sculpt-mode-features: Voxel remesher: Add support for undo from sculpt mode
Pablo Dobarro
noreply at git.blender.org
Tue Mar 19 23:08:19 CET 2019
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;
More information about the Bf-blender-cvs
mailing list