diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2015-03-18 21:22:38 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2015-03-26 16:13:39 +0300 |
commit | c5d1d174f2bb9f55a258adcff4cbf736c0481541 (patch) | |
tree | 518a8ca2b2410ad7960e6fbea6fa43e4cd423d20 /intern | |
parent | aebc98e06179647e0f45a1d12f7289534f0edfdd (diff) |
Cycles support for dupli caches.
If a cache is read-enabled cycles will now use the cached mesh data
instead of dupli results.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 20 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 4 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 42 |
4 files changed, 64 insertions, 7 deletions
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index c70ffea39c3..e61660fc2cb 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -587,7 +587,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 @@ -599,7 +599,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 */ @@ -624,7 +623,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 @@ -675,7 +685,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 e827d46223b..d3ef4ed299e 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 6a320ac8085..70340cc3a49 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 9f7181cc564..5878d252713 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 { |