[Bf-blender-cvs] [edf089a] gooseberry: Cycles support for dupli caches.

Lukas Tönne noreply at git.blender.org
Mon Mar 23 13:04:08 CET 2015


Commit: edf089a57206c930dfa181b2f3c949a96fae9322
Author: Lukas Tönne
Date:   Wed Mar 18 19:22:38 2015 +0100
Branches: gooseberry
https://developer.blender.org/rBedf089a57206c930dfa181b2f3c949a96fae9322

Cycles support for dupli caches.

If a cache is read-enabled cycles will now use the cached mesh data
instead of dupli results.

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

M	intern/cycles/blender/blender_mesh.cpp
M	intern/cycles/blender/blender_object.cpp
M	intern/cycles/blender/blender_sync.h
M	intern/cycles/blender/blender_util.h
M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/intern/mesh.c
M	source/blender/makesrna/intern/rna_main_api.c
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/makesrna/intern/rna_object_api.c

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

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index e9a70db..a075024 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -634,7 +634,7 @@ static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, PointerR
 
 /* Sync */
 
-Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris)
+Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris, BL::Object b_ob_parent)
 {
 	/* When viewport display is not needed during render we can force some
 	 * caches to be releases from blender side in order to reduce peak memory
@@ -646,7 +646,6 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
 
 	/* test if we can instance or if the object is modified */
 	BL::ID b_ob_data = b_ob.data();
-	BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
 	BL::Material material_override = render_layer.material_override;
 
 	/* find shader indices */
@@ -671,7 +670,18 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
 	bool use_mesh_geometry = render_layer.use_surfaces || render_layer.use_hair;
 	Mesh *mesh;
 
-	if(!mesh_map.sync(&mesh, key)) {
+	BL::DupliObjectData b_dup_data = (b_ob_parent && b_ob_parent.use_dupli_cache())? b_ob_parent.find_dupli_cache(b_ob): BL::DupliObjectData(PointerRNA_NULL);
+	bool need_update;
+	if (b_dup_data) {
+		MeshKey key = MeshKey(b_ob_parent, b_ob);
+		need_update = mesh_map.sync(&mesh, b_ob_parent, PointerRNA_NULL, key);
+	}
+	else {
+		BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob_data;
+		need_update = mesh_map.sync(&mesh, key);
+	}
+
+	if(!need_update) {
 		/* if transform was applied to mesh, need full update */
 		if(object_updated && mesh->transform_applied);
 		/* test if shaders changed, these can be object level so mesh
@@ -722,7 +732,9 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri
 			b_ob.update_from_editmode();
 
 		bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED);
-		BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed);
+		BL::Mesh b_mesh = (b_dup_data)?
+		            dupli_cache_to_mesh(b_data, b_dup_data, need_undeformed):
+		            object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed);
 
 		if(b_mesh) {
 			if(render_layer.use_surfaces && !hide_tris) {
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index e827d46..d3ef4ed 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -280,7 +280,10 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P
 	bool use_holdout = (layer_flag & render_layer.holdout_layer) != 0;
 	
 	/* mesh sync */
-	object->mesh = sync_mesh(b_ob, object_updated, hide_tris);
+	if (b_dupli_ob)
+		object->mesh = sync_mesh(b_ob, object_updated, hide_tris, b_parent);
+	else
+		object->mesh = sync_mesh(b_ob, object_updated, hide_tris);
 
 	/* special case not tracked by object update flags */
 
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 6a320ac..70340cc 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -83,7 +83,7 @@ private:
 	void sync_curve_settings();
 
 	void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
-	Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris);
+	Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris, BL::Object b_ob_parent = PointerRNA_NULL);
 	void sync_curves(Mesh *mesh, BL::Mesh b_mesh, 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, uint layer_flag, float motion_time, bool hide_tris);
@@ -108,7 +108,7 @@ private:
 
 	id_map<void*, Shader> shader_map;
 	id_map<ObjectKey, Object> object_map;
-	id_map<void*, Mesh> mesh_map;
+	id_map<MeshKey, Mesh> mesh_map;
 	id_map<ObjectKey, Light> light_map;
 	id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
 	set<Mesh*> mesh_synced;
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index 9f7181c..5878d25 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -52,6 +52,18 @@ static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL:
 	return me;
 }
 
+static inline BL::Mesh dupli_cache_to_mesh(BL::BlendData data, BL::DupliObjectData dupli_data, bool calc_undeformed)
+{
+	BL::Mesh me = data.meshes.new_from_dupli_cache(dupli_data, false, calc_undeformed);
+	if ((bool)me) {
+		if (me.use_auto_smooth()) {
+			me.calc_normals_split();
+		}
+		me.calc_tessface(true);
+	}
+	return me;
+}
+
 static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size)
 {
 	for(int i = 0; i < size; i++) {
@@ -568,6 +580,36 @@ struct ObjectKey {
 	}
 };
 
+/* Mesh Key */
+
+struct MeshKey {
+	void *parent;
+	void *mesh;
+
+	MeshKey(void *mesh_)
+	: parent(NULL), mesh(mesh_)
+	{
+	}
+	
+	MeshKey(void *parent_, void *mesh_)
+	: parent(parent_), mesh(mesh_)
+	{
+	}
+
+	bool operator<(const MeshKey& k) const
+	{
+		if(mesh < k.mesh) {
+			return true;
+		}
+		else if(mesh == k.mesh) {
+			return parent < k.parent;
+				return true;
+		}
+
+		return false;
+	}
+};
+
 /* Particle System Key */
 
 struct ParticleSystemKey {
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 1f3458c..a694c91 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -41,6 +41,7 @@ struct BLI_Stack;
 struct MemArena;
 struct BMEditMesh;
 struct BMesh;
+struct DupliObjectData;
 struct Main;
 struct Mesh;
 struct MPoly;
@@ -135,6 +136,7 @@ void BKE_mesh_split_faces(struct Mesh *mesh);
 
 struct Mesh *BKE_mesh_new_from_object(struct Main *bmain, struct Scene *sce, struct Object *ob,
                                       int apply_modifiers, int settings, int calc_tessface, int calc_undeformed);
+struct Mesh *BKE_mesh_new_from_dupli_cache(struct Main *bmain, struct DupliObjectData *data, bool calc_tessface, bool calc_undeformed);
 
 /* vertex level transformations & checks (no derived mesh) */
 
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 14e1c34..053ebfc 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2479,3 +2479,63 @@ Mesh *BKE_mesh_new_from_object(
 	return tmpmesh;
 }
 
+
+/* settings: 1 - preview, 2 - render */
+Mesh *BKE_mesh_new_from_dupli_cache(
+        Main *bmain, DupliObjectData *data,
+        bool calc_tessface, bool calc_undeformed)
+{
+	Object *ob = data->ob;
+	DerivedMesh *dm = data->cache_dm;
+	CustomDataMask mask;
+	
+	Mesh *tmpmesh;
+	
+	if (!ob || !dm)
+		return NULL;
+	
+	mask = CD_MASK_MESH; /* this seems more suitable, exporter,
+	                      * for example, needs CD_MASK_MDEFORMVERT */
+	if (calc_undeformed)
+		mask |= CD_MASK_ORCO;
+	
+	tmpmesh = BKE_mesh_add(bmain, "Mesh");
+	DM_to_mesh(dm, tmpmesh, ob, mask, true);
+	
+	/* BKE_mesh_add/copy gives us a user count we don't need */
+	tmpmesh->id.us--;
+
+	/* Copy materials to new mesh */
+	switch (ob->type) {
+		case OB_MESH: {
+			Mesh *origmesh = ob->data;
+			int i;
+			
+			tmpmesh->flag = origmesh->flag;
+			tmpmesh->mat = MEM_dupallocN(origmesh->mat);
+			tmpmesh->totcol = origmesh->totcol;
+			tmpmesh->smoothresh = origmesh->smoothresh;
+			if (origmesh->mat) {
+				for (i = origmesh->totcol; i-- > 0; ) {
+					/* are we an object material or data based? */
+					tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
+					
+					if (tmpmesh->mat[i]) {
+						tmpmesh->mat[i]->id.us++;
+					}
+				}
+			}
+			break;
+		}
+	} /* end copy materials */
+	
+	if (calc_tessface) {
+		/* cycles and exporters rely on this still */
+		BKE_mesh_tessface_ensure(tmpmesh);
+	}
+	
+	/* make sure materials get updated in objects */
+	test_object_materials(bmain, &tmpmesh->id);
+	
+	return tmpmesh;
+}
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index b922f6c..13307a1 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -48,6 +48,7 @@
 #ifdef RNA_RUNTIME
 
 #include "BKE_main.h"
+#include "BKE_anim.h"
 #include "BKE_cache_library.h"
 #include "BKE_camera.h"
 #include "BKE_curve.h"
@@ -310,6 +311,15 @@ Mesh *rna_Main_meshes_new_from_object(
 	return BKE_mesh_new_from_object(bmain, sce, ob, apply_modifiers, settings, calc_tessface, calc_undeformed);
 }
 
+/* copied from Mesh_getFromObject and adapted to RNA interface */
+/* settings: 1 - preview, 2 - render */
+Mesh *rna_Main_meshes_new_from_dupli_cache(
+        Main *bmain, ReportList *UNUSED(reports), DupliObjectData *data,
+        int calc_tessface, int calc_undeformed)
+{
+	return BKE_mesh_new_from_dupli_cache(bmain, data, calc_tessface, calc_undeformed);
+}
+
 static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, PointerRNA *mesh_ptr)
 {
 	Mesh *mesh = mesh_ptr->data;
@@ -1057,6 +1067,17 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
 	                       "Mesh created from object, remove it if it is only used for export");
 	RNA_def_function_return(func, parm);
 
+	func = RNA_def_function(srna, "new_from_dupli_cache", "rna_Main_meshes_new_from_dupli_cache");
+	RNA_def_function_ui_description(func, "Add a new mesh created from dupli cache data");
+	RNA_def_function_flag(func, FUNC_USE_REPORTS);
+	parm = RNA_def_pointer(func, "data", "DupliObjectData", "", "Dupli Object Data");
+	RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+	RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces");
+	RNA_def_boolean(func, "calc_undeformed", false, "Calculate Undeformed", "Calculate undeformed vertex coordinates");
+	parm = RNA_def_pointer(func, "mesh", "Mesh

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list