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

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 c70ffea..e61660f 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 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 224be0f..53022a5 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;
@@ -132,6 +133,7 @@ float (*BKE_mesh_vertexCos_get(struct Mesh *me, int 
*r_numVerts))[3];
 
 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 809d213..49c8dff 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2339,3 +2339,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 29ed6e4..d5db5ee 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_poi

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to