[Bf-blender-cvs] [a84118b] depsgraph_refactor: Depsgraph: Update armatures when leaving edit mode

Sergey Sharybin noreply at git.blender.org
Thu Dec 4 14:05:31 CET 2014


Commit: a84118b564e7ce8979e074386f565bd2ebe68611
Author: Sergey Sharybin
Date:   Thu Dec 4 17:52:56 2014 +0500
Branches: depsgraph_refactor
https://developer.blender.org/rBa84118b564e7ce8979e074386f565bd2ebe68611

Depsgraph: Update armatures when leaving edit mode

The idea is to have proper operation nodes after editing the armature.

This isn't so trivial as it sounds to be, because:

- Dependency graph is being built from the pose channels, which means
  adding/deleting bones are not visible to the depsgraph because those
  operations doesn't rebuild pose.

- Updating pose after every topology change is rather costy and better
  to be avoid.

Currently experimenting with rebuilding dependency graph when leaving
edit mode. This way i can work on partial graph rebuild which would
be really handy for such relations edits.

For now this partial update is rather a place holder and it invokes
full dependency graph rebuild. Actual partial rebuild brains would
be implemented as one of the next steps.

However all this work unleashed rather fundamental questions:

- it is already known that dependency graph uses pose channels for
  building.

- Pose channels are being passed to the callback functions as arguments.

- One of operation nodes rebuilds the pose when it's missing or when
  it's tagged for update.

- Hrm, ok. Now, what if the pose is tagged for update and some topology
  changed? This could change some pose channel pointers leading to the
  bad memory access in the callback.

  How do we solve this?

- A bit easier question: What should operations do if armature is
  edit mode?

  Simplest answer would be to copy matricies from bones, skipping
  pose rebuild, eval init, pose callbacks and eval flush callbacks.

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

M	source/blender/blenkernel/BKE_depsgraph.h
M	source/blender/blenkernel/intern/depsgraph.c
M	source/blender/editors/object/object_edit.c

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

diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index ebe00b0..faa3604 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -92,6 +92,7 @@ void DAG_exit(void);
  */
 
 void DAG_scene_relations_update(struct Main *bmain, struct Scene *sce);
+void DAG_relations_tag_id_update(struct Main *bmain, struct ID *UNUSED(id));
 void DAG_scene_relations_validate(struct Main *bmain, struct Scene *sce);
 void DAG_relations_tag_update(struct Main *bmain);
 void DAG_scene_relations_rebuild(struct Main *bmain, struct Scene *scene);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 67029e8..f0425a1 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1656,6 +1656,15 @@ void DAG_scene_relations_update(Main *bmain, Scene *sce)
 		dag_scene_build(bmain, sce);
 }
 
+/* Tag specific ID node for rebuild, keep rest of the graph untouched. */
+void DAG_relations_tag_id_update(Main *bmain, ID *UNUSED(id))
+{
+	/* TODO(sergey): For now we tag the whole graph for rebuild,
+	 * once we'll have partial rebuilds implemented we'll use them.
+	 */
+	DAG_relations_tag_update(bmain);
+}
+
 void DAG_scene_relations_validate(Main *bmain, Scene *sce)
 {
 	Depsgraph *depsgraph = DEG_graph_new();
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 9395612..40e0777 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -63,6 +63,7 @@
 #include "BKE_curve.h"
 #include "BKE_effect.h"
 #include "BKE_depsgraph.h"
+#include "BKE_global.h"
 #include "BKE_image.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
@@ -315,7 +316,7 @@ void OBJECT_OT_hide_render_set(wmOperatorType *ot)
  * Load EditMode data back into the object,
  * optionally freeing the editmode data.
  */
-static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata)
+static bool ED_object_editmode_load_ex(Main *bmain, Object *obedit, const bool freedata)
 {
 	if (obedit == NULL) {
 		return false;
@@ -345,6 +346,7 @@ static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata)
 		ED_armature_from_edit(obedit->data);
 		if (freedata)
 			ED_armature_edit_free(obedit->data);
+		DAG_relations_tag_id_update(bmain, (ID*)obedit->data);
 	}
 	else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
 		load_editNurb(obedit);
@@ -373,7 +375,8 @@ static bool ED_object_editmode_load_ex(Object *obedit, const bool freedata)
 
 bool ED_object_editmode_load(Object *obedit)
 {
-	return ED_object_editmode_load_ex(obedit, false);
+	/* TODO(sergey): use proper main here? */
+	return ED_object_editmode_load_ex(G.main, obedit, false);
 }
 
 void ED_object_editmode_exit(bContext *C, int flag)
@@ -386,7 +389,7 @@ void ED_object_editmode_exit(bContext *C, int flag)
 
 	if (flag & EM_WAITCURSOR) waitcursor(1);
 
-	if (ED_object_editmode_load_ex(obedit, freedata) == false) {
+	if (ED_object_editmode_load_ex(CTX_data_main(C), obedit, freedata) == false) {
 		/* in rare cases (background mode) its possible active object
 		 * is flagged for editmode, without 'obedit' being set [#35489] */
 		if (UNLIKELY(scene->basact && (scene->basact->object->mode & OB_MODE_EDIT))) {




More information about the Bf-blender-cvs mailing list