[Bf-blender-cvs] [5c17dbd991d] blender2.8: Fix missing Cycles 3D viewport updates when editing materials, lamps.

Brecht Van Lommel noreply at git.blender.org
Wed May 30 14:16:54 CEST 2018


Commit: 5c17dbd991d64257f99b179343b453bb60823d44
Author: Brecht Van Lommel
Date:   Tue May 29 15:57:14 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB5c17dbd991d64257f99b179343b453bb60823d44

Fix missing Cycles 3D viewport updates when editing materials, lamps.

This introduces a new depsgraph API for getting updated datablocks,
rather than getting it from bpy.data.

* depsgraph.ids_updated gives a list of all datablocks in the depsgraph
  which have been updated.
* depsgraph.id_type_updated('TYPE') is true if any datablock of the given
  type has been added, removed or modified.

More API updates are coming to properly handle multiple depsgraphs and
finer update granularity, but this should make Cycles work again.

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

M	intern/cycles/blender/blender_session.cpp
M	intern/cycles/blender/blender_shader.cpp
M	intern/cycles/blender/blender_sync.cpp
M	intern/cycles/blender/blender_sync.h
M	intern/cycles/render/shader.cpp
M	intern/cycles/render/shader.h
M	source/blender/blenkernel/BKE_main.h
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.c
M	source/blender/blenkernel/intern/scene.c
M	source/blender/depsgraph/DEG_depsgraph.h
M	source/blender/depsgraph/DEG_depsgraph_query.h
M	source/blender/depsgraph/intern/depsgraph.h
M	source/blender/depsgraph/intern/depsgraph_query.cc
M	source/blender/depsgraph/intern/depsgraph_query_iter.cc
M	source/blender/depsgraph/intern/depsgraph_tag.cc
M	source/blender/depsgraph/intern/eval/deg_eval_flush.cc
M	source/blender/makesrna/intern/rna_ID.c
M	source/blender/makesrna/intern/rna_depsgraph.c
M	source/blender/makesrna/intern/rna_main_api.c

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

diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index bfaa843eb18..7a9d411b9bb 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -773,7 +773,7 @@ void BlenderSession::synchronize(BL::Depsgraph& b_depsgraph_)
 
 	/* copy recalc flags, outside of mutex so we can decide to do the real
 	 * synchronization at a later time to not block on running updates */
-	sync->sync_recalc();
+	sync->sync_recalc(b_depsgraph_);
 
 	/* don't do synchronization if on pause */
 	if(session_pause) {
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 8847d651b02..e991533a17e 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -1238,33 +1238,32 @@ void BlenderSync::sync_materials(BL::Depsgraph& b_depsgraph, bool update_all)
 	TaskPool pool;
 	set<Shader*> updated_shaders;
 
-	/* material loop */
-	BL::BlendData::materials_iterator b_mat_orig;
-	for(b_data.materials.begin(b_mat_orig);
-	    b_mat_orig != b_data.materials.end();
-	    ++b_mat_orig)
-	{
-		/* TODO(sergey): Iterate over evaluated data rather than using mapping. */
-		BL::Material b_mat_(b_depsgraph.id_eval_get(*b_mat_orig));
-		BL::Material *b_mat = &b_mat_;
+	BL::Depsgraph::ids_iterator b_id;
+	for(b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
+		if (!b_id->is_a(&RNA_Material)) {
+			continue;
+		}
+
+		BL::Material b_mat(*b_id);
 		Shader *shader;
 
 		/* test if we need to sync */
-		if(shader_map.sync(&shader, *b_mat) || update_all) {
+		if(shader_map.sync(&shader, b_mat) || shader->need_sync_object || update_all) {
 			ShaderGraph *graph = new ShaderGraph();
 
-			shader->name = b_mat->name().c_str();
-			shader->pass_id = b_mat->pass_index();
+			shader->name = b_mat.name().c_str();
+			shader->pass_id = b_mat.pass_index();
+			shader->need_sync_object = false;
 
 			/* create nodes */
-			if(b_mat->use_nodes() && b_mat->node_tree()) {
-				BL::ShaderNodeTree b_ntree(b_mat->node_tree());
+			if(b_mat.use_nodes() && b_mat.node_tree()) {
+				BL::ShaderNodeTree b_ntree(b_mat.node_tree());
 
 				add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
 			}
 			else {
 				DiffuseBsdfNode *diffuse = new DiffuseBsdfNode();
-				diffuse->color = get_float3(b_mat->diffuse_color());
+				diffuse->color = get_float3(b_mat.diffuse_color());
 				graph->add(diffuse);
 
 				ShaderNode *out = graph->output();
@@ -1272,7 +1271,7 @@ void BlenderSync::sync_materials(BL::Depsgraph& b_depsgraph, bool update_all)
 			}
 
 			/* settings */
-			PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles");
+			PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
 			shader->use_mis = get_boolean(cmat, "sample_as_light");
 			shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow");
 			shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume");
@@ -1412,41 +1411,39 @@ void BlenderSync::sync_lamps(BL::Depsgraph& b_depsgraph, bool update_all)
 {
 	shader_map.set_default(scene->default_light);
 
-	/* lamp loop */
-	BL::BlendData::lamps_iterator b_lamp_orig;
-	for(b_data.lamps.begin(b_lamp_orig);
-	    b_lamp_orig != b_data.lamps.end();
-	    ++b_lamp_orig)
-	{
-		/* TODO(sergey): Iterate over evaluated data rather than using mapping. */
-		BL::Lamp b_lamp_(b_depsgraph.id_eval_get(*b_lamp_orig));
-		BL::Lamp *b_lamp = &b_lamp_;
+	BL::Depsgraph::ids_iterator b_id;
+	for(b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
+		if (!b_id->is_a(&RNA_Lamp)) {
+			continue;
+		}
+
+		BL::Lamp b_lamp(*b_id);
 		Shader *shader;
 
 		/* test if we need to sync */
-		if(shader_map.sync(&shader, *b_lamp) || update_all) {
+		if(shader_map.sync(&shader, b_lamp) || update_all) {
 			ShaderGraph *graph = new ShaderGraph();
 
 			/* create nodes */
-			if(b_lamp->use_nodes() && b_lamp->node_tree()) {
-				shader->name = b_lamp->name().c_str();
+			if(b_lamp.use_nodes() && b_lamp.node_tree()) {
+				shader->name = b_lamp.name().c_str();
 
-				BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
+				BL::ShaderNodeTree b_ntree(b_lamp.node_tree());
 
 				add_nodes(scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree);
 			}
 			else {
 				float strength = 1.0f;
 
-				if(b_lamp->type() == BL::Lamp::type_POINT ||
-				   b_lamp->type() == BL::Lamp::type_SPOT ||
-				   b_lamp->type() == BL::Lamp::type_AREA)
+				if(b_lamp.type() == BL::Lamp::type_POINT ||
+				   b_lamp.type() == BL::Lamp::type_SPOT ||
+				   b_lamp.type() == BL::Lamp::type_AREA)
 				{
 					strength = 100.0f;
 				}
 
 				EmissionNode *emission = new EmissionNode();
-				emission->color = get_float3(b_lamp->color());
+				emission->color = get_float3(b_lamp.color());
 				emission->strength = strength;
 				graph->add(emission);
 
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index c175ed252f7..e54fe1246dc 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -76,31 +76,12 @@ BlenderSync::~BlenderSync()
 
 /* Sync */
 
-bool BlenderSync::sync_recalc()
+void BlenderSync::sync_recalc(BL::Depsgraph& b_depsgraph)
 {
-	/* sync recalc flags from blender to cycles. actual update is done separate,
-	 * so we can do it later on if doing it immediate is not suitable */
-
-	BL::BlendData::materials_iterator b_mat;
-	bool has_updated_objects = b_data.objects.is_updated();
-	for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
-		if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated())) {
-			shader_map.set_recalc(*b_mat);
-		}
-		else {
-			Shader *shader = shader_map.find(*b_mat);
-			if(has_updated_objects && shader != NULL && shader->has_object_dependency) {
-				shader_map.set_recalc(*b_mat);
-			}
-		}
-	}
-
-	BL::BlendData::lamps_iterator b_lamp;
-
-	for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp)
-		if(b_lamp->is_updated() || (b_lamp->node_tree() && b_lamp->node_tree().is_updated()))
-			shader_map.set_recalc(*b_lamp);
+	/* Sync recalc flags from blender to cycles. Actual update is done separate,
+	 * so we can do it later on if doing it immediate is not suitable. */
 
+	bool has_updated_objects = b_depsgraph.id_type_updated(BL::DriverTarget::id_type_OBJECT);
 	bool dicing_prop_changed = false;
 
 	if(experimental) {
@@ -122,70 +103,73 @@ bool BlenderSync::sync_recalc()
 		}
 	}
 
-	BL::BlendData::objects_iterator b_ob;
-
-	for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
-		if(b_ob->is_updated()) {
-			object_map.set_recalc(*b_ob);
-			light_map.set_recalc(*b_ob);
+	/* Iterate over all IDs in this depsgraph. */
+	BL::Depsgraph::ids_updated_iterator b_id;
+	for(b_depsgraph.ids_updated.begin(b_id); b_id != b_depsgraph.ids_updated.end(); ++b_id) {
+		/* Material */
+		if (b_id->is_a(&RNA_Material)) {
+			BL::Material b_mat(*b_id);
+			shader_map.set_recalc(b_mat);
+		}
+		/* Lamp */
+		else if (b_id->is_a(&RNA_Lamp)) {
+			BL::Lamp b_lamp(*b_id);
+			shader_map.set_recalc(b_lamp);
 		}
+		/* Object */
+		else if (b_id->is_a(&RNA_Object)) {
+			BL::Object b_ob(*b_id);
+			const bool updated_data = b_ob.is_updated_data();
+
+			object_map.set_recalc(b_ob);
+			light_map.set_recalc(b_ob);
+
+			if(object_is_mesh(b_ob)) {
+				if(updated_data ||
+				   (dicing_prop_changed && object_subdivision_type(b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
+				{
+					BL::ID key = BKE_object_is_modified(b_ob)? b_ob: b_ob.data();
+					mesh_map.set_recalc(key);
+				}
+			}
+			else if(object_is_light(b_ob)) {
+				if(updated_data) {
+					light_map.set_recalc(b_ob);
+				}
+			}
 
-		if(object_is_mesh(*b_ob)) {
-			if(b_ob->is_updated_data() || b_ob->data().is_updated() ||
-			   (dicing_prop_changed && object_subdivision_type(*b_ob, preview, experimental) != Mesh::SUBDIVISION_NONE))
-			{
-				BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data();
-				mesh_map.set_recalc(key);
+			if(updated_data) {
+				BL::Object::particle_systems_iterator b_psys;
+				for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys)
+					particle_system_map.set_recalc(b_ob);
 			}
 		}
-		else if(object_is_light(*b_ob)) {
-			if(b_ob->is_updated_data() || b_ob->data().is_updated())
-				light_map.set_recalc(*b_ob);
+		/* Mesh */
+		else if (b_id->is_a(&RNA_Mesh)) {
+			BL::Mesh b_mesh(*b_id);
+			mesh_map.set_recalc(b_mesh);
 		}
-		
-		if(b_ob->is_updated_data()) {
-			BL::Object::particle_systems_iterator b_psys;
-			for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
-				particle_system_map.set_recalc(*b_ob);
+		/* World */
+		else if (b_id->is_a(&RNA_World)) {
+			BL::World b_world(*b_id);
+			if(world_map == b_world.ptr.data) {
+				world_recalc = true;
+			}
 		}
 	}
 
-	BL::BlendData::meshes_iterator b_mesh;
-
-	for(b_data.meshes.begin(b_mesh); b_mesh != b_data.meshes.end(); ++b_mesh) {
-		if(b_mesh->is_updated()) {
-			mesh_map.set_recalc(*b_mesh);
+	/* Updates shader with object dependency if objects changed. */
+	if (has_updated_objects) {
+		if(scene->default_background->has_object_dependency) {
+			world_recalc = true;
 		}
-	}
-
-	BL::BlendData::worlds_iterator b_world;
 
-	for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) {
-		if(world_map == b_world->ptr.data) {
-			if(b_world->is_updated() ||
-			   (b_world->node_tree() && b_world->node_tree().is_updated()))
-			{
-				world_recalc = true;
-			}
-			else if(b_world->node_tree() && b_world->use_nodes()) {
-				Shader *shader = scene->default_background;
-				if(has_updated_objects && shader->has_object_dependency) {
-					world_recalc = true;
-				}
+		foreach(Shader *shader, scene->shaders) {
+			if (shader->has_object_dependency) {
+				shader->need_sync_object = true;
 			}
 		}
 	}
-
-	bool recalc =
-		shader_map.has_recalc() ||
-		object_map.has_recalc() ||
-		light_map.has_recalc() ||
-		mesh_map.has_recalc() ||
-		particle_system_map.has_recalc() ||
-		BlendDataObjects_is_updated_get(&b_data.ptr) ||
-		world_recalc;
-
-	return r

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list