[Bf-blender-cvs] [b44e6f2b3d3] blender2.8: Fix T57760: Depsgraph 'object_instances' showing incorrect list of objects.

Bastien Montagne noreply at git.blender.org
Wed Nov 14 17:07:16 CET 2018


Commit: b44e6f2b3d32e604c3030eaf61b15e0e2a20d520
Author: Bastien Montagne
Date:   Wed Nov 14 17:04:10 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBb44e6f2b3d32e604c3030eaf61b15e0e2a20d520

Fix T57760: Depsgraph 'object_instances' showing incorrect list of objects.

It appears that Python gets next item before using current one, which
would break our Depsgraph instance iterator (since only current item is
valid there, we use the same memory at each iteration).

Working around that with an ugly ping-pong game between two sets of
iterator data, so that previous one (C RNA-iterator-wise) remains valid
memory for Python to access to.

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

M	source/blender/makesrna/intern/rna_depsgraph.c

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

diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index 7bfd3f679d8..4c455915361 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -280,38 +280,59 @@ static PointerRNA rna_Depsgraph_objects_get(CollectionPropertyIterator *iter)
  * Contains extra information about duplicator and persistent ID.
  */
 
+/* XXX Ugly python seems to query next item of an iterator before using current one (see T57558).
+ * This forces us to use that nasty ping-pong game between two sets of iterator data, so that previous one remains
+ * valid memory for python to access to. Yuck.
+ */
+typedef struct RNA_Depsgraph_Instances_Iterator
+{
+	BLI_Iterator iterators[2];
+	DEGObjectIterData deg_data[2];
+	int counter;
+} RNA_Depsgraph_Instances_Iterator;
+
 static void rna_Depsgraph_object_instances_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
-	iter->internal.custom = MEM_callocN(sizeof(BLI_Iterator), __func__);
-	DEGObjectIterData *data = MEM_callocN(sizeof(DEGObjectIterData), __func__);
+	RNA_Depsgraph_Instances_Iterator *di_it = iter->internal.custom = MEM_callocN(sizeof(*di_it), __func__);
 
+	DEGObjectIterData *data = &di_it->deg_data[0];
 	data->graph = (Depsgraph *)ptr->data;
 	data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY |
 	             DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
 	             DEG_ITER_OBJECT_FLAG_VISIBLE |
 	             DEG_ITER_OBJECT_FLAG_DUPLI;
 
-	((BLI_Iterator *)iter->internal.custom)->valid = true;
-	DEG_iterator_objects_begin(iter->internal.custom, data);
-	iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
+	di_it->iterators[0].valid = true;
+	DEG_iterator_objects_begin(&di_it->iterators[0], data);
+	iter->valid = di_it->iterators[0].valid;
 }
 
 static void rna_Depsgraph_object_instances_next(CollectionPropertyIterator *iter)
 {
-	DEG_iterator_objects_next(iter->internal.custom);
-	iter->valid = ((BLI_Iterator *)iter->internal.custom)->valid;
+	RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *)iter->internal.custom;
+
+	/* We need to copy current iterator status to next one beeing worked on. */
+	di_it->iterators[(di_it->counter + 1) % 2] = di_it->iterators[di_it->counter % 2];
+	di_it->deg_data[(di_it->counter + 1) % 2] = di_it->deg_data[di_it->counter % 2];
+	di_it->counter++;
+
+	di_it->iterators[di_it->counter % 2].data = &di_it->deg_data[di_it->counter % 2];
+	DEG_iterator_objects_next(&di_it->iterators[di_it->counter % 2]);
+	iter->valid = di_it->iterators[di_it->counter % 2].valid;
 }
 
 static void rna_Depsgraph_object_instances_end(CollectionPropertyIterator *iter)
 {
-	DEG_iterator_objects_end(iter->internal.custom);
-	MEM_freeN(((BLI_Iterator *)iter->internal.custom)->data);
-	MEM_freeN(iter->internal.custom);
+	RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *)iter->internal.custom;
+	DEG_iterator_objects_end(&di_it->iterators[0]);
+	DEG_iterator_objects_end(&di_it->iterators[1]);
+	MEM_freeN(di_it);
 }
 
 static PointerRNA rna_Depsgraph_object_instances_get(CollectionPropertyIterator *iter)
 {
-	BLI_Iterator *iterator = (BLI_Iterator *)iter->internal.custom;
+	RNA_Depsgraph_Instances_Iterator *di_it = (RNA_Depsgraph_Instances_Iterator *)iter->internal.custom;
+	BLI_Iterator *iterator = &di_it->iterators[di_it->counter % 2];
 	return rna_pointer_inherit_refine(&iter->parent, &RNA_DepsgraphObjectInstance, iterator);
 }



More information about the Bf-blender-cvs mailing list