[Bf-blender-cvs] [e0d8e62] master: Fix T41010: MetaBall Duplivert Unwanted Movement Bug.

Bastien Montagne noreply at git.blender.org
Sat Jul 19 00:42:47 CEST 2014


Commit: e0d8e62f2bb97d75088f7f1fd9f0fab578a02410
Author: Bastien Montagne
Date:   Fri Jul 18 22:31:33 2014 +0200
https://developer.blender.org/rBe0d8e62f2bb97d75088f7f1fd9f0fab578a02410

Fix T41010: MetaBall Duplivert Unwanted Movement Bug.

BKE_scene_base_iter_next() was completely messing poor dupli objects' matrices...

Note this func should be reworked, but as stated in comments, it should not exist at all,
DAG should be used here, so until we have new shinny one we can live with this.

Also, mballs do not behave correctly when used as duplis (org object remains visible/rendered,
unlike any other object type). This will be fixed in a separate patch/commit,
since it proved to be rather tricky to handle.

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

M	source/blender/blenkernel/BKE_scene.h
M	source/blender/blenkernel/intern/scene.c

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

diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index a10a3f3..452e23b 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -84,6 +84,7 @@ typedef struct SceneBaseIter {
 	struct ListBase *duplilist;
 	struct DupliObject *dupob;
 	float omat[4][4];
+	struct Object *dupli_refob;
 	int phase;
 } SceneBaseIter;
 
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index f8ce31f..66b2e3c 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -804,9 +804,7 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
 	BKE_libblock_free(bmain, sce);
 }
 
-/* used by metaballs
- * doesn't return the original duplicated object, only dupli's
- */
+/* Used by metaballs, return *all* objects (including duplis) existing in the scene (including scene's sets) */
 int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
                              Scene **scene, int val, Base **base, Object **ob)
 {
@@ -817,11 +815,12 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
 		iter->phase = F_START;
 		iter->dupob = NULL;
 		iter->duplilist = NULL;
+		iter->dupli_refob = NULL;
 	}
 	else {
 		/* run_again is set when a duplilist has been ended */
 		while (run_again) {
-			run_again = 0;
+			run_again = false;
 
 			/* the first base */
 			if (iter->phase == F_START) {
@@ -879,34 +878,46 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
 							
 							iter->dupob = iter->duplilist->first;
 
-							if (!iter->dupob)
+							if (!iter->dupob) {
 								free_object_duplilist(iter->duplilist);
+								iter->duplilist = NULL;
+							}
+							iter->dupli_refob = NULL;
 						}
 					}
 				}
 				/* handle dupli's */
 				if (iter->dupob) {
-					
-					copy_m4_m4(iter->omat, iter->dupob->ob->obmat);
-					copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->mat);
-					
 					(*base)->flag |= OB_FROMDUPLI;
 					*ob = iter->dupob->ob;
 					iter->phase = F_DUPLI;
-					
+
+					if (iter->dupli_refob != *ob) {
+						if (iter->dupli_refob) {
+							/* Restore previous object's real matrix. */
+							copy_m4_m4(iter->dupli_refob->obmat, iter->omat);
+						}
+						/* Backup new object's real matrix. */
+						iter->dupli_refob = *ob;
+						copy_m4_m4(iter->omat, iter->dupli_refob->obmat);
+					}
+					copy_m4_m4((*ob)->obmat, iter->dupob->mat);
+
 					iter->dupob = iter->dupob->next;
 				}
 				else if (iter->phase == F_DUPLI) {
 					iter->phase = F_SCENE;
 					(*base)->flag &= ~OB_FROMDUPLI;
 					
-					for (iter->dupob = iter->duplilist->first; iter->dupob; iter->dupob = iter->dupob->next) {
-						copy_m4_m4(iter->dupob->ob->obmat, iter->omat);
+					if (iter->dupli_refob) {
+						/* Restore last object's real matrix. */
+						copy_m4_m4(iter->dupli_refob->obmat, iter->omat);
+						iter->dupli_refob = NULL;
 					}
 					
 					free_object_duplilist(iter->duplilist);
 					iter->duplilist = NULL;
-					run_again = 1;
+					run_again = true;
 				}
 			}
 		}




More information about the Bf-blender-cvs mailing list