[Bf-blender-cvs] [e1e41e44472] blender2.8: Cycles: Support rendering objects from dupli-list

Sergey Sharybin noreply at git.blender.org
Tue Jun 6 14:17:44 CEST 2017


Commit: e1e41e4447258d42a32fd77092cef26f5733e950
Author: Sergey Sharybin
Date:   Tue Jun 6 13:58:40 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBe1e41e4447258d42a32fd77092cef26f5733e950

Cycles: Support rendering objects from dupli-list

This commit extends the work from Dalai made around scene iterators to
support iterating into objects from dupli-lists.

Changes can be summarized as:

- Depsgraph iterator will hold pointer to an object which created current
  duplilist. It is available via `dupli_parent` field of the iterator.
  It is only set when duplilist is not NULL and guaranteed to be NULL
  for all other cases.

- Introduced new depsgraph.duplis collection which gives a more extended
  information about depsgraph iterator.  It is basically a collection on top
  of DEGObjectsIteratorData.

  It is used to provide access to such data as persistent ID, generated space
  and so on.

Things which still needs to be done/finished/clarified:

- Need to introduce some sort of `is_instance` boolean property which will
  indicate Python and C++ RNA that we are inside of dupli-list.

- Introduce a way to skip dupli-list for particular objects.

  So, for example, if we are culling object due to distance we can skip all
  objects it was duplicating.

- Introduce a way to skip particular duplicators.

  So we can skip iterating into particle system.

- Introduce some cleaner API for C side of operators to access all data such as
  persistent ID and friends.

  This way we wouldn't need de-reference iterator and could keep access to such
  data really abstract. Who knows how we'll be storing internal state of the
  operator in the future.

While there is still stuff to do, current state works and moves us in the proper
direction.

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

M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/blender/blender_sync.h
M	source/blender/depsgraph/DEG_depsgraph_query.h
M	source/blender/depsgraph/intern/depsgraph_query.cc
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/makesrna.c
M	source/blender/makesrna/intern/rna_depsgraph.c

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

diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 4ed9f00e51f..eaf257c0c73 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -236,19 +236,24 @@ void BlenderSync::sync_background_light(bool use_portal)
 
 /* Object */
 
-Object *BlenderSync::sync_object(BL::Object& b_parent,
-                                 int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
-                                 BL::DupliObject& b_dupli_ob,
-                                 Transform& tfm,
+Object *BlenderSync::sync_object(BL::Depsgraph::duplis_iterator& b_dupli_iter,
                                  uint layer_flag,
                                  float motion_time,
                                  bool hide_tris,
                                  BlenderObjectCulling& culling,
                                  bool *use_portal)
 {
-	BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
-	bool motion = motion_time != 0.0f;
-	
+	BL::Object b_ob = b_dupli_iter->object();
+	BL::Object b_parent = b_dupli_iter->parent() ? b_dupli_iter->parent() : b_dupli_iter->object();
+	const bool motion = motion_time != 0.0f;
+	/*const*/ Transform tfm = get_transform(b_ob.matrix_world());
+	int *persistent_id = NULL;
+	BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id_array;
+	if(b_dupli_iter->parent()) {
+		persistent_id_array = b_dupli_iter->persistent_id();
+		persistent_id = persistent_id_array.data;
+	}
+
 	/* light is handled separately */
 	if(object_is_light(b_ob)) {
 		/* don't use lamps for excluded layers used as mask layer */
@@ -380,10 +385,10 @@ Object *BlenderSync::sync_object(BL::Object& b_parent,
 		}
 
 		/* dupli texture coordinates and random_id */
-		if(b_dupli_ob) {
-			object->dupli_generated = 0.5f*get_float3(b_dupli_ob.orco()) - make_float3(0.5f, 0.5f, 0.5f);
-			object->dupli_uv = get_float2(b_dupli_ob.uv());
-			object->random_id = b_dupli_ob.random_id();
+		if(b_dupli_iter->parent()) {
+			object->dupli_generated = 0.5f*get_float3(b_dupli_iter->orco()) - make_float3(0.5f, 0.5f, 0.5f);
+			object->dupli_uv = get_float2(b_dupli_iter->uv());
+			object->random_id = b_dupli_iter->random_id();
 		}
 		else {
 			object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
@@ -495,10 +500,12 @@ void BlenderSync::sync_objects(float motion_time)
 	bool cancel = false;
 	bool use_portal = false;
 
-	BL::Depsgraph::objects_iterator b_ob_iter;
-
-	for(b_depsgraph.objects.begin(b_ob_iter); b_ob_iter != b_depsgraph.objects.end() && !cancel; ++b_ob_iter) {
-		BL::Object b_ob = *b_ob_iter;
+	BL::Depsgraph::duplis_iterator b_dupli_iter;
+	for(b_depsgraph.duplis.begin(b_dupli_iter);
+	    b_dupli_iter != b_depsgraph.duplis.end() && !cancel;
+	    ++b_dupli_iter)
+	{
+		BL::Object b_ob = b_dupli_iter->object();
 		progress.set_sync_status("Synchronizing object", b_ob.name());
 
 		/* load per-object culling data */
@@ -509,12 +516,7 @@ void BlenderSync::sync_objects(float motion_time)
 
 		 if(!object_render_hide(b_ob, true, true, hide_tris)) {
 			/* object itself */
-			Transform tfm = get_transform(b_ob.matrix_world());
-			BL::DupliObject b_empty_dupli_ob(PointerRNA_NULL);
-			sync_object(b_ob,
-			            NULL,
-			            b_empty_dupli_ob,
-			            tfm,
+			sync_object(b_dupli_iter,
 			            ~(0), /* until we get rid of layers */
 			            motion_time,
 			            hide_tris,
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index e509cce3e31..4c8772d4d8f 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -121,10 +121,7 @@ private:
 	                 BL::Object& b_ob,
 	                 bool motion,
 	                 int time_index = 0);
-	Object *sync_object(BL::Object& b_parent,
-	                    int persistent_id[OBJECT_PERSISTENT_ID_SIZE],
-	                    BL::DupliObject& b_dupli_ob,
-	                    Transform& tfm,
+	Object *sync_object(BL::Depsgraph::duplis_iterator& b_dupli_iter,
 	                    uint layer_flag,
 	                    float motion_time,
 	                    bool hide_tris,
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index ff2126992c4..888730552e9 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -75,14 +75,27 @@ typedef struct DEGObjectsIteratorData {
 	struct Depsgraph *graph;
 	struct Scene *scene;
 	struct EvaluationContext *eval_ctx;
-	struct SceneLayer *scene_layer;
+
+	/* TODO(sergey): Base should never be a thing coming FROM depsgraph. */
 	struct Base *base;
 	int base_flag;
 	int flag;
 
-	/* Dupli */
+	/* **** Iteration over dupli-list. *** */
+
+	/* Object which created the dupli-list. */
+	struct Object *dupli_parent;
+	/* List of duplicated objects. */
 	struct ListBase *dupli_list;
-	struct DupliObject *dupli_object;
+	/* Next duplicated object to step into. */
+	struct DupliObject *dupli_object_next;
+	/* Corresponds to current object: current iterator object is evaluated from
+	 * this duplicated object.
+	 */
+	struct DupliObject *dupli_object_current;
+	/* Temporary storage to report fully populated DNA to the render engine or
+	 * other users of the iterator.
+	 */
 	struct Object temp_dupli_object;
 } DEGObjectsIteratorData;
 
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index d889dccfede..0661f24fb7b 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -104,27 +104,34 @@ Object *DEG_get_object(Depsgraph * /*depsgraph*/, Object *ob)
 
 void DEG_objects_iterator_begin(BLI_Iterator *iter, DEGObjectsIteratorData *data)
 {
-	SceneLayer *scene_layer;
 	Depsgraph *graph = data->graph;
+	SceneLayer *scene_layer = DEG_get_scene_layer(graph);
 
 	iter->data = data;
 	iter->valid = true;
 
-	/* TODO: Make it in-place initilization of evaluation context. */
-	data->eval_ctx = DEG_evaluation_context_new(DAG_EVAL_RENDER);
 	data->scene = DEG_get_scene(graph);
-	scene_layer = DEG_get_scene_layer(graph);
-	data->base_flag = ~BASE_FLUSH_FLAGS;
+	/* TODO(sergey): Make it in-place initilization of evaluation context. */
+	data->eval_ctx = DEG_evaluation_context_new(DAG_EVAL_RENDER);
 
+	/* TODO(sergey): It's really confusing to store pointer to a local data. */
 	Base base = {(Base *)scene_layer->object_bases.first, NULL};
 	data->base = &base;
+
+	data->base_flag = ~(BASE_FLUSH_FLAGS);
+
+	data->dupli_parent = NULL;
+	data->dupli_list = NULL;
+	data->dupli_object_next = NULL;
+	data->dupli_object_current = NULL;
+
 	DEG_objects_iterator_next(iter);
 }
 
 /**
  * Temporary function to flush depsgraph until we get copy on write (CoW)
  */
-static void deg_flush_data(Object *ob, Base *base, const int flag)
+static void deg_flush_base_flags_and_settings(Object *ob, Base *base, const int flag)
 {
 	ob->base_flag = (base->flag | BASE_FLUSH_FLAGS) & flag;
 	ob->base_collection_properties = base->collection_properties;
@@ -134,13 +141,15 @@ static void deg_flush_data(Object *ob, Base *base, const int flag)
 static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
 {
 	DEGObjectsIteratorData *data = (DEGObjectsIteratorData *)iter->data;
-	while (data->dupli_object) {
-		DupliObject *dob = data->dupli_object;
+	while (data->dupli_object_next != NULL) {
+		DupliObject *dob = data->dupli_object_next;
 		Object *obd = dob->ob;
 
-		data->dupli_object = data->dupli_object->next;
+		data->dupli_object_next = data->dupli_object_next->next;
 
-		/* Group duplis need to set ob matrices correct, for deform. so no_draw is part handled. */
+		/* Group duplis need to set ob matrices correct, for deform. so no_draw
+		 * is part handled.
+		 */
 		if ((obd->transflag & OB_RENDER_DUPLI) == 0 && dob->no_draw) {
 			continue;
 		}
@@ -149,11 +158,15 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
 			continue;
 		}
 
+		data->dupli_object_current = dob;
+
 		/* Temporary object to evaluate. */
 		data->temp_dupli_object = *dob->ob;
 		copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
 
-		deg_flush_data(&data->temp_dupli_object, data->base, data->base_flag | BASE_FROMDUPLI);
+		deg_flush_base_flags_and_settings(&data->temp_dupli_object,
+		                                  data->base,
+		                                  data->base_flag | BASE_FROMDUPLI);
 		iter->current = &data->temp_dupli_object;
 		return true;
 	}
@@ -172,14 +185,15 @@ void DEG_objects_iterator_next(BLI_Iterator *iter)
 		}
 		else {
 			free_object_duplilist(data->dupli_list);
+			data->dupli_parent = NULL;
 			data->dupli_list = NULL;
-			data->dupli_object = NULL;
+			data->dupli_object_next = NULL;
+			data->dupli_object_current = NULL;
 		}
 	}
 
 	base = data->base->next;
-
-	while (base) {
+	while (base != NULL) {
 		if ((base->flag & BASE_VISIBLED) != 0) {
 			Object *ob = DEG_get_object(data->graph, base->object);
 			iter->current = ob;
@@ -191,15 +205,17 @@ void DEG_objects_iterator_next(BLI_Iterator *iter)
 			BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group));
 
 			/* Flushing depsgraph data. */
-			deg_flush_data(ob, base, data->base_flag);
+			deg_flush_base_flags_and_settings(ob,
+			                                  base,
+			                                  data->base_flag);
 
 			if ((data->flag & DEG_OBJECT_ITER_FLAG_DUPLI) && (ob->transflag & OB_DUPLI)) {
+				data->dupli_parent = ob;
 				data->dupli_list = object_duplilist(data->eval_ctx, data->scene, ob);
-				data->dupli_object = (DupliObject *)data->dupli_list->first;
+				data->dupli_object_next = (DupliObject *)data->dupli_list->first;
 			}
 			return;
 		}
-
 		base = base->next;
 	}
 
@@ -212,6 +228,7 @@ void DEG_objects_iterator_next(BLI_Iterator *iter)
 		/* For the sets we use the layer used for rendering. */
 		scene_layer = BKE_scene_layer_render_active(data->scene);
 
+		/* TODO(sergey): It's really confusing to store pointer to a local data. */
 		Base base = {(Base *)scene_layer->object_bases.first, NULL};
 		data->base = &base;
 	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list