[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