Cycles: add "From Dupli" option for texture coordinate node. This gets the
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 4 Oct 2012 21:40:39 +0000 (21:40 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 4 Oct 2012 21:40:39 +0000 (21:40 +0000)
Generated and UV coordinates from the duplicator of instance instead of the
object itself.

This was used in e.g. Big Buck Bunny for texturing instanced feathers with
a UV map on the bird. Many files changed, mainly to do some refactoring to
get rid of G.rendering global in duplilist code.

32 files changed:
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_shader.cpp
intern/cycles/blender/blender_sync.h
intern/cycles/blender/blender_util.h
intern/cycles/kernel/kernel_object.h
intern/cycles/kernel/kernel_types.h
intern/cycles/kernel/svm/svm_tex_coord.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/nodes.cpp
intern/cycles/render/nodes.h
intern/cycles/render/object.cpp
intern/cycles/render/object.h
source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/object/object_add.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/transform/transform_snap.c
source/blender/gpu/intern/gpu_material.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_nodetree_types.h
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_object_api.c
source/blender/nodes/shader/nodes/node_shader_tex_coord.c
source/blender/render/intern/source/convertblender.c

index 8fbb223..2730102 100644 (file)
@@ -194,8 +194,10 @@ void BlenderSync::sync_background_light()
 
 /* Object */
 
-void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag, int motion, int particle_id)
+void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, int particle_id)
 {
+       BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
+       
        /* light is handled separately */
        if(object_is_light(b_ob)) {
                if(!motion)
@@ -274,6 +276,15 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob,
                        object->visibility &= ~PATH_RAY_CAMERA;
                }
 
+               if (b_dupli_ob) {
+                       object->dupli_generated = get_float3(b_dupli_ob.orco());
+                       object->dupli_uv = get_float2(b_dupli_ob.uv());
+               }
+               else {
+                       object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f);
+                       object->dupli_uv = make_float2(0.0f, 0.0f);
+               }
+
                object->particle_id = particle_id;
 
                object->tag_update(scene);
@@ -328,7 +339,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
                                                bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
 
                                                if(!(b_dup->hide() || dup_hide)) {
-                                                       sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset);
+                                                       sync_object(*b_ob, b_index, *b_dup, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset);
                                                }
                                                
                                                ++b_index;
@@ -346,7 +357,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
                                if(!hide) {
                                        /* object itself */
                                        Transform tfm = get_transform(b_ob->matrix_world());
-                                       sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion, 0);
+                                       sync_object(*b_ob, 0, PointerRNA_NULL, tfm, ob_layer, motion, 0);
                                }
 
                                particle_offset += num_particles;
index ebf8bb4..b6d5cc6 100644 (file)
@@ -490,7 +490,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
                        break;
                }
                case BL::ShaderNode::type_TEX_COORD: {
-                       node = new TextureCoordinateNode();
+                       BL::ShaderNodeTexCoord b_tex_coord_node(b_node);
+                       TextureCoordinateNode *tex_coord = new TextureCoordinateNode();
+                       tex_coord->from_dupli = b_tex_coord_node.from_dupli();
+                       node = tex_coord;
                        break;
                }
                case BL::ShaderNode::type_TEX_SKY: {
index 27f6b6e..ce56308 100644 (file)
@@ -81,7 +81,7 @@ private:
 
        void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
        Mesh *sync_mesh(BL::Object b_ob, bool object_updated);
-       void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag, int motion, int particle_id);
+       void sync_object(BL::Object b_parent, int b_index, BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion, int particle_id);
        void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm);
        void sync_background_light();
        void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
index 46fbead..da8f30e 100644 (file)
@@ -36,7 +36,7 @@ struct RenderResult;
 
 ID *rna_Object_to_mesh(void *_self, void *reports, void *scene, int apply_modifiers, int settings);
 void rna_Main_meshes_remove(void *bmain, void *reports, void *mesh);
-void rna_Object_create_duplilist(void *ob, void *reports, void *sce);
+void rna_Object_create_duplilist(void *ob, void *reports, void *sce, int settings);
 void rna_Object_free_duplilist(void *ob);
 void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
 void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
@@ -84,7 +84,7 @@ static inline void object_remove_mesh(BL::BlendData data, BL::Mesh mesh)
 
 static inline void object_create_duplilist(BL::Object self, BL::Scene scene)
 {
-       rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data);
+       rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data, 2);
 }
 
 static inline void object_free_duplilist(BL::Object self)
index 222ade5..01da505 100644 (file)
@@ -23,7 +23,8 @@ enum ObjectTransform {
        OBJECT_INVERSE_TRANSFORM = 3,
        OBJECT_PROPERTIES = 6,
        OBJECT_TRANSFORM_MOTION_PRE = 8,
-       OBJECT_TRANSFORM_MOTION_POST = 12
+       OBJECT_TRANSFORM_MOTION_POST = 12,
+       OBJECT_DUPLI = 16
 };
 
 __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type)
@@ -164,6 +165,27 @@ __device_inline uint object_particle_id(KernelGlobals *kg, int object)
        return __float_as_int(f.w);
 }
 
+__device_inline float3 object_dupli_generated(KernelGlobals *kg, int object)
+{
+       if(object == ~0)
+               return make_float3(0.0f, 0.0f, 0.0f);
+
+       int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
+       float4 f = kernel_tex_fetch(__objects, offset);
+       return make_float3(f.x, f.y, f.z);
+}
+
+__device_inline float3 object_dupli_uv(KernelGlobals *kg, int object)
+{
+       if(object == ~0)
+               return make_float3(0.0f, 0.0f, 0.0f);
+
+       int offset = object*OBJECT_SIZE + OBJECT_DUPLI;
+       float4 f = kernel_tex_fetch(__objects, offset + 1);
+       return make_float3(f.x, f.y, 0.0f);
+}
+
+
 __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
 {
        return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1);
index ce21ab9..48e271a 100644 (file)
@@ -29,7 +29,7 @@
 CCL_NAMESPACE_BEGIN
 
 /* constants */
-#define OBJECT_SIZE            16
+#define OBJECT_SIZE            18
 #define LIGHT_SIZE                     4
 #define FILTER_TABLE_SIZE      256
 #define RAMP_TABLE_SIZE                256
index fbaf253..6bd8f2a 100644 (file)
@@ -92,6 +92,14 @@ __device void svm_node_tex_coord(KernelGlobals *kg, ShaderData *sd, float *stack
                                data = sd->I;
                        break;
                }
+               case NODE_TEXCO_DUPLI_GENERATED: {
+                       data = object_dupli_generated(kg, sd->object);
+                       break;
+               }
+               case NODE_TEXCO_DUPLI_UV: {
+                       data = object_dupli_uv(kg, sd->object);
+                       break;
+               }
        }
 
        stack_store_float3(stack, out_offset, data);
@@ -141,6 +149,14 @@ __device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, ShaderData *sd, floa
                                data = sd->I;
                        break;
                }
+               case NODE_TEXCO_DUPLI_GENERATED: {
+                       data = object_dupli_generated(kg, sd->object);
+                       break;
+               }
+               case NODE_TEXCO_DUPLI_UV: {
+                       data = object_dupli_uv(kg, sd->object);
+                       break;
+               }
        }
 
        stack_store_float3(stack, out_offset, data);
@@ -193,6 +209,14 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa
                                data = sd->I;
                        break;
                }
+               case NODE_TEXCO_DUPLI_GENERATED: {
+                       data = object_dupli_generated(kg, sd->object);
+                       break;
+               }
+               case NODE_TEXCO_DUPLI_UV: {
+                       data = object_dupli_uv(kg, sd->object);
+                       break;
+               }
        }
 
        stack_store_float3(stack, out_offset, data);
index c82eafc..3cf44a3 100644 (file)
@@ -43,6 +43,7 @@ typedef enum NodeType {
        NODE_TEX_IMAGE_BOX,
        NODE_TEX_SKY,
        NODE_GEOMETRY,
+       NODE_GEOMETRY_DUPLI,
        NODE_LIGHT_PATH,
        NODE_VALUE_F,
        NODE_VALUE_V,
@@ -149,7 +150,9 @@ typedef enum NodeTexCoord {
        NODE_TEXCO_OBJECT,
        NODE_TEXCO_CAMERA,
        NODE_TEXCO_WINDOW,
-       NODE_TEXCO_REFLECTION
+       NODE_TEXCO_REFLECTION,
+       NODE_TEXCO_DUPLI_GENERATED,
+       NODE_TEXCO_DUPLI_UV
 } NodeTexCoord;
 
 typedef enum NodeMix {
index eabb97e..b878bde 100644 (file)
@@ -1681,9 +1681,15 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler)
                        compiler.add_node(geom_node, NODE_GEOM_P, out->stack_offset);
                }
                else {
-                       int attr = compiler.attribute(ATTR_STD_GENERATED);
-                       compiler.stack_assign(out);
-                       compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
+                       if(from_dupli) {
+                               compiler.stack_assign(out);
+                               compiler.add_node(texco_node, NODE_TEXCO_DUPLI_GENERATED, out->stack_offset);
+                       }
+                       else {
+                               int attr = compiler.attribute(ATTR_STD_GENERATED);
+                               compiler.stack_assign(out);
+                               compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
+                       }
                }
        }
 
@@ -1695,9 +1701,15 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler)
 
        out = output("UV");
        if(!out->links.empty()) {
-               int attr = compiler.attribute(ATTR_STD_UV);
-               compiler.stack_assign(out);
-               compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
+               if(from_dupli) {
+                       int attr = compiler.attribute(ATTR_STD_UV);
+                       compiler.stack_assign(out);
+                       compiler.add_node(attr_node, attr, out->stack_offset, NODE_ATTR_FLOAT3);
+               }
+               else {
+                       compiler.stack_assign(out);
+                       compiler.add_node(texco_node, NODE_TEXCO_DUPLI_UV, out->stack_offset);
+               }
        }
 
        out = output("Object");
index 82bead7..e8e584d 100644 (file)
@@ -284,6 +284,8 @@ class TextureCoordinateNode : public ShaderNode {
 public:
        SHADER_NODE_CLASS(TextureCoordinateNode)
        void attributes(AttributeRequestSet *attributes);
+       
+       bool from_dupli;
 };
 
 class LightPathNode : public ShaderNode {
index 7389b23..d78a82d 100644 (file)
@@ -235,6 +235,10 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
                        }
                }
 
+               /* dupli object coords */
+               objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
+               objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
+
                /* object flag */
                if(ob->use_holdout)
                        flag |= SD_HOLDOUT_MASK;
index 88677d7..e2c3ad4 100644 (file)
@@ -49,6 +49,9 @@ public:
        bool use_motion;
        bool use_holdout;
 
+       float3 dupli_generated;
+       float2 dupli_uv;
+
        int particle_id;
 
        Object();
index f506c67..1153796 100644 (file)
@@ -65,8 +65,8 @@ int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], fl
 /* ---------------------------------------------------- */
 /* Dupli-Geometry */
 
-struct ListBase *object_duplilist_ex(struct Scene *sce, struct Object *ob, int update);
-struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob);
+struct ListBase *object_duplilist_ex(struct Scene *sce, struct Object *ob, int update, int for_render);
+struct ListBase *object_duplilist(struct Scene *sce, struct Object *ob, int for_render);
 void free_object_duplilist(struct ListBase *lb);
 int count_duplilist(struct Object *ob);
 
index 080eb7b..56dfdf4 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         264
-#define BLENDER_SUBVERSION      0
+#define BLENDER_SUBVERSION      1
 
 /* 262 was the last editmesh release but its has compatibility code for bmesh data,
  * so set the minversion to 2.61 */
index ec15e2e..58d20ff 100644 (file)
@@ -75,7 +75,7 @@
 /* forward declarations */
 
 static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index,
-                                       int level, short animated, short update);
+                                       int level, short flag);
 
 /* ******************************************************************** */
 /* Animation Visualization */
@@ -700,7 +700,11 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua
 /* ******************************************************************** */
 /* Dupli-Geometry */
 
-static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short animated)
+#define DUPLILIST_DO_UPDATE            1
+#define DUPLILIST_FOR_RENDER   2
+#define DUPLILIST_ANIMATED             4
+
+static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short flag)
 {
        DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject");
        
@@ -712,14 +716,14 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i
        dob->index = index;
        dob->particle_index = par_index;
        dob->type = type;
-       dob->animated = (type == OB_DUPLIGROUP) && animated;
+       dob->animated = (type == OB_DUPLIGROUP) && (flag & DUPLILIST_ANIMATED);
        ob->lay = lay;
        
        return dob;
 }
 
 static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index,
-                            int level, short animated, short update)
+                            int level, short flag)
 {
        DupliObject *dob;
        Group *group;
@@ -735,13 +739,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde
        /* handles animated groups, and */
 
        /* we need to check update for objects that are not in scene... */
-       if (update) {
+       if (flag & DUPLILIST_DO_UPDATE) {
                /* note: update is optional because we don't always need object
                 * transformations to be correct. Also fixes bug [#29616]. */
                group_handle_recalc_and_update(scene, ob, group);
        }
 
-       animated = animated || group_is_animated(ob, group);
+       if (group_is_animated(ob, group))
+               flag |= DUPLILIST_ANIMATED;
        
        for (go = group->gobject.first; go; go = go->next) {
                /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
@@ -757,7 +762,7 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde
                                mult_m4_m4m4(mat, ob->obmat, go->ob->obmat);
                        }
                        
-                       dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, animated);
+                       dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, flag);
 
                        /* check the group instance and object layers match, also that the object visible flags are ok. */
                        if ((dob->origlay & group->layer) == 0 ||
@@ -772,14 +777,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde
 
                        if (go->ob->transflag & OB_DUPLI) {
                                copy_m4_m4(dob->ob->obmat, dob->mat);
-                               object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, animated, update);
+                               object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, flag);
                                copy_m4_m4(dob->ob->obmat, dob->omat);
                        }
                }
        }
 }
 
-static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short animated)
+static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short flag)
 {
        extern int enable_cu_speed; /* object.c */
        Object copyob;
@@ -827,7 +832,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind
                        BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */
                        BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra);
                        
-                       dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, animated);
+                       dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, flag);
                        copy_m4_m4(dob->omat, copyob.obmat);
                }
        }
@@ -851,8 +856,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind
 typedef struct VertexDupliData {
        ID *id; /* scene or group, for recursive loops */
        int level;
-       short animated;
-       short update;
+       short flag;
        ListBase *lb;
        float pmat[4][4];
        float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */
@@ -896,7 +900,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
 
        origlay = vdd->ob->lay;
        
-       dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->animated);
+       dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->flag);
 
        /* restore the original layer so that each dupli will have proper dob->origlay */
        vdd->ob->lay = origlay;
@@ -908,13 +912,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
                float tmpmat[4][4];
                copy_m4_m4(tmpmat, vdd->ob->obmat);
                copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
-               object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->animated, vdd->update);
+               object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->flag);
                copy_m4_m4(vdd->ob->obmat, tmpmat);
        }
 }
 
 static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index,
-                             int level, short animated, short update)
+                             int level, short flag)
 {
        Object *ob, *ob_iter;
        Mesh *me = par->data;
@@ -942,7 +946,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
        else
                dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
        
-       if (G.is_rendering) {
+       if (flag & DUPLILIST_FOR_RENDER) {
                vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
                BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0);
        }
@@ -992,8 +996,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
 
                                        vdd.id = id;
                                        vdd.level = level;
-                                       vdd.animated = animated;
-                                       vdd.update = update;
+                                       vdd.flag = flag;
                                        vdd.lb = lb;
                                        vdd.ob = ob;
                                        vdd.scene = scene;
@@ -1039,7 +1042,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
 }
 
 static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index,
-                           int level, short animated, short update)
+                           int level, short flag)
 {
        Object *ob, *ob_iter;
        Base *base = NULL;
@@ -1076,8 +1079,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
        mloop = dm->getLoopArray(dm);
        mvert = dm->getVertArray(dm);
 
-       if (G.is_rendering) {
-
+       if (flag & DUPLILIST_FOR_RENDER) {
                orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
                BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0);
                mloopuv = me->mloopuv;
@@ -1182,8 +1184,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                                                copy_m4_m4(tmat, obmat);
                                                mul_m4_m4m3(obmat, tmat, mat);
                                                
-                                               dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, animated);
-                                               if (G.is_rendering) {
+                                               dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, (flag & DUPLILIST_ANIMATED));
+                                               if (flag & DUPLILIST_FOR_RENDER) {
                                                        w = 1.0f / (float)mp->totloop;
 
                                                        if (orco) {
@@ -1205,7 +1207,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
                                                        float tmpmat[4][4];
                                                        copy_m4_m4(tmpmat, ob->obmat);
                                                        copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */
-                                                       object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, animated, update);
+                                                       object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, flag);
                                                        copy_m4_m4(ob->obmat, tmpmat);
                                                }
                                        }
@@ -1226,7 +1228,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
 }
 
 static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys,
-                                   int level, short animated, short update)
+                                   int level, short flag)
 {
        GroupObject *go;
        Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL;
@@ -1309,7 +1311,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
 
                /* gather list of objects or single object */
                if (part->ren_as == PART_DRAW_GR) {
-                       if (update) {
+                       if (flag & DUPLILIST_DO_UPDATE) {
                                group_handle_recalc_and_update(scene, par, part->dup_group);
                        }
 
@@ -1452,9 +1454,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                                        else
                                                copy_m4_m4(mat, tmat);
 
-                                       dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, animated);
+                                       dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED));
                                        copy_m4_m4(dob->omat, obcopylist[b].obmat);
-                                       if (G.is_rendering)
+                                       if (flag & DUPLILIST_FOR_RENDER)
                                                psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
                                }
                        }
@@ -1512,9 +1514,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
                                if (part->draw & PART_DRAW_GLOBAL_OB)
                                        add_v3_v3v3(mat[3], mat[3], vec);
 
-                               dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated);
+                               dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED));
                                copy_m4_m4(dob->omat, oldobmat);
-                               if (G.is_rendering)
+                               if (flag & DUPLILIST_FOR_RENDER)
                                        psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
                        }
 
@@ -1566,7 +1568,7 @@ static Object *find_family_object(Object **obar, char *family, char ch)
 }
 
 
-static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short animated)
+static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short flag)
 {
        Object *ob, *obar[256] = {NULL};
        Curve *cu;
@@ -1605,7 +1607,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde
                        copy_m4_m4(obmat, par->obmat);
                        copy_v3_v3(obmat[3], vec);
                        
-                       new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, animated);
+                       new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, flag);
                }
        }
        
@@ -1615,7 +1617,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde
 /* ------------- */
 
 static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index,
-                                       int level, short animated, short update)
+                                       int level, short flag)
 {      
        if ((ob->transflag & OB_DUPLI) == 0)
                return;
@@ -1635,31 +1637,31 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas
        if (ob->transflag & OB_DUPLIPARTS) {
                ParticleSystem *psys = ob->particlesystem.first;
                for (; psys; psys = psys->next)
-                       new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, animated, update);
+                       new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, flag);
        }
        else if (ob->transflag & OB_DUPLIVERTS) {
                if (ob->type == OB_MESH) {
-                       vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update);
+                       vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag);
                }
                else if (ob->type == OB_FONT) {
                        if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */
-                               font_duplilist(duplilist, scene, ob, par_index, level + 1, animated);
+                               font_duplilist(duplilist, scene, ob, par_index, level + 1, flag);
                        }
                }
        }
        else if (ob->transflag & OB_DUPLIFACES) {
                if (ob->type == OB_MESH)
-                       face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated, update);
+                       face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag);
        }
        else if (ob->transflag & OB_DUPLIFRAMES) {
                if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */
-                       frames_duplilist(duplilist, scene, ob, par_index, level + 1, animated);
+                       frames_duplilist(duplilist, scene, ob, par_index, level + 1, flag);
                }
        }
        else if (ob->transflag & OB_DUPLIGROUP) {
                DupliObject *dob;
                
-               group_duplilist(duplilist, scene, ob, par_index, level + 1, animated, update); /* now recursive */
+               group_duplilist(duplilist, scene, ob, par_index, level + 1, flag); /* now recursive */
 
                if (level == 0) {
                        for (dob = duplilist->first; dob; dob = dob->next)
@@ -1671,19 +1673,24 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas
 
 /* Returns a list of DupliObject
  * note; group dupli's already set transform matrix. see note in group_duplilist() */
-ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update)
+ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render)
 {
        ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist");
+       int flag = 0;
+
+       if(update) flag |= DUPLILIST_DO_UPDATE;
+       if(for_render) flag |= DUPLILIST_FOR_RENDER;
+
        duplilist->first = duplilist->last = NULL;
-       object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, 0, update);
+       object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag);
        return duplilist;
 }
 
 /* note: previously updating was always done, this is why it defaults to be on
  * but there are likely places it can be called without updating */
-ListBase *object_duplilist(Scene *sce, Object *ob)
+ListBase *object_duplilist(Scene *sce, Object *ob, int for_render)
 {
-       return object_duplilist_ex(sce, ob, TRUE);
+       return object_duplilist_ex(sce, ob, TRUE, for_render);
 }
 
 
index 72a43da..65ab97e 100644 (file)
@@ -2362,7 +2362,7 @@ int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_ma
                ListBase *lb;
                DupliObject *dob;
                
-               lb = object_duplilist(scene, ob);
+               lb = object_duplilist(scene, ob, FALSE);
                for (dob = lb->first; dob; dob = dob->next) {
                        if ((use_hidden == FALSE) && (dob->no_draw != 0)) {
                                /* pass */
@@ -2439,7 +2439,7 @@ void BKE_scene_foreach_display_point(
                                ListBase *lb;
                                DupliObject *dob;
 
-                               lb = object_duplilist(scene, ob);
+                               lb = object_duplilist(scene, ob, FALSE);
                                for (dob = lb->first; dob; dob = dob->next) {
                                        if (dob->no_draw == 0) {
                                                BKE_object_foreach_display_point(dob->ob, dob->mat, func_cb, user_data);
index 0d01bb3..8c0d19b 100644 (file)
@@ -1030,7 +1030,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
                ListBase *lb_dupli_ob;
 
                /* don't update the dupli groups, we only wan't their pid's */
-               if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE))) {
+               if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE, FALSE))) {
                        DupliObject *dob;
                        for (dob= lb_dupli_ob->first; dob; dob= dob->next) {
                                if (dob->ob != ob) { /* avoids recursive loops with dupliframes: bug 22988 */
index 41d300a..f8777f8 100644 (file)
@@ -744,7 +744,7 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
                                                 * this enters eternal loop because of 
                                                 * makeDispListMBall getting called inside of group_duplilist */
                                                if ((*base)->object->dup_group == NULL) {
-                                                       duplilist = object_duplilist((*scene), (*base)->object);
+                                                       duplilist = object_duplilist((*scene), (*base)->object, FALSE);
                                                        
                                                        dupob = duplilist->first;
 
index 9aa7da3..26d9fb9 100644 (file)
@@ -7038,6 +7038,15 @@ static void do_version_ntree_keying_despill_balance(void *UNUSED(data), ID *UNUS
        }
 }
 
+static void do_version_ntree_tex_coord_from_dupli_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree)
+{
+       bNode *node;
+
+       for (node = ntree->nodes.first; node; node = node->next)
+               if (node->type == SH_NODE_TEX_COORD)
+                       node->flag |= NODE_OPTIONS;
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -7995,6 +8004,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                }
        }
 
+       if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 1)) {
+               bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER);
+               bNodeTree *ntree;
+
+               if (ntreetype && ntreetype->foreach_nodetree)
+                       ntreetype->foreach_nodetree(main, NULL, do_version_ntree_tex_coord_from_dupli_264);
+               
+               for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
+                       if (ntree->type==NTREE_SHADER)
+                               do_version_ntree_tex_coord_from_dupli_264(NULL, NULL, ntree);
+       }
+
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
        /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
 
index 4942b9e..c2e5f14 100644 (file)
@@ -1086,7 +1086,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
        if (!(base->object->transflag & OB_DUPLI))
                return;
        
-       lb = object_duplilist(scene, base->object);
+       lb = object_duplilist(scene, base->object, FALSE);
 
        if (use_hierarchy || use_base_parent) {
                dupli_gh = BLI_ghash_ptr_new("make_object_duplilist_real dupli_gh");
index 1d04855..470f821 100644 (file)
@@ -1389,6 +1389,11 @@ static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C),
        uiItemR(layout, ptr, "coloring", 0, "", ICON_NONE);
 }
 
+static void node_shader_buts_tex_coord(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+       uiItemR(layout, ptr, "from_dupli", 0, NULL, 0);
+}
+
 static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
 {
        uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
@@ -1470,6 +1475,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
                case SH_NODE_TEX_VORONOI:
                        ntype->uifunc = node_shader_buts_tex_voronoi;
                        break;
+               case SH_NODE_TEX_COORD:
+                       ntype->uifunc = node_shader_buts_tex_coord;
+                       break;
                case SH_NODE_BSDF_GLOSSY:
                case SH_NODE_BSDF_GLASS:
                        ntype->uifunc = node_shader_buts_glossy;
index cb197ab..ca768f2 100644 (file)
@@ -1918,7 +1918,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas
        if (base->object->restrictflag & OB_RESTRICT_VIEW) return;
        
        tbase.flag = OB_FROMDUPLI | base->flag;
-       lb = object_duplilist(scene, base->object);
+       lb = object_duplilist(scene, base->object, FALSE);
        // BLI_sortlist(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
 
        dob = dupli_step(lb->first);
@@ -2331,7 +2331,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
                
                if (ob->transflag & OB_DUPLI) {
                        DupliObject *dob;
-                       ListBase *lb = object_duplilist(scene, ob);
+                       ListBase *lb = object_duplilist(scene, ob, FALSE);
                        
                        for (dob = lb->first; dob; dob = dob->next)
                                if (dob->ob->type == OB_LAMP)
index b3dd54c..cdb75cd 100644 (file)
@@ -1326,7 +1326,7 @@ short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int b
                                                Base tbase;
                                                
                                                tbase.flag = OB_FROMDUPLI;
-                                               lb = object_duplilist(scene, base->object);
+                                               lb = object_duplilist(scene, base->object, FALSE);
                                                
                                                for (dob = lb->first; dob; dob = dob->next) {
                                                        tbase.object = dob->ob;
index cee1c91..700869e 100644 (file)
@@ -1708,7 +1708,7 @@ static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, c
                        
                        if (ob->transflag & OB_DUPLI) {
                                DupliObject *dupli_ob;
-                               ListBase *lb = object_duplilist(scene, ob);
+                               ListBase *lb = object_duplilist(scene, ob, FALSE);
                                
                                for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
                                        Object *dob = dupli_ob->ob;
@@ -1914,7 +1914,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L
 
                        if (ob->transflag & OB_DUPLI) {
                                DupliObject *dupli_ob;
-                               ListBase *lb = object_duplilist(scene, ob);
+                               ListBase *lb = object_duplilist(scene, ob, FALSE);
                                
                                for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
                                        Object *dob = dupli_ob->ob;
index 4732586..e035f1c 100644 (file)
@@ -841,7 +841,7 @@ static void material_lights(GPUShadeInput *shi, GPUShadeResult *shr)
 
                if (ob->transflag & OB_DUPLI) {
                        DupliObject *dob;
-                       ListBase *lb = object_duplilist(shi->gpumat->scene, ob);
+                       ListBase *lb = object_duplilist(shi->gpumat->scene, ob, FALSE);
                        
                        for (dob=lb->first; dob; dob=dob->next) {
                                Object *ob_iter = dob->ob;
index 6e20375..ffc78ef 100644 (file)
@@ -409,7 +409,7 @@ int rna_IDMaterials_assign_int(struct PointerRNA *ptr, int key, const struct Poi
 /* Internal functions that cycles uses so we need to declare (tsk tsk) */
 struct Mesh *rna_Object_to_mesh(struct Object *ob, struct ReportList *reports, struct Scene *sce, int apply_modifiers, int settings);
 void rna_Main_meshes_remove(struct Main *bmain, struct ReportList *reports, struct Mesh *mesh);
-void rna_Object_create_duplilist(struct Object *ob, struct ReportList *reports, struct Scene *sce);
+void rna_Object_create_duplilist(struct Object *ob, struct ReportList *reports, struct Scene *sce, int settings);
 void rna_Object_free_duplilist(struct Object *ob);
 void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
 void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
index b03d348..d650c8d 100644 (file)
@@ -1720,6 +1720,16 @@ static void def_sh_tex_wave(StructRNA *srna)
        RNA_def_property_update(prop, 0, "rna_Node_update");
 }
 
+static void def_sh_tex_coord(StructRNA *srna)
+{
+       PropertyRNA *prop;
+       
+       prop = RNA_def_property(srna, "from_dupli", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
+       RNA_def_property_ui_text(prop, "From Dupli", "Use the parent of the dupli object if possible");
+       RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
 static void def_glossy(StructRNA *srna)
 {
        PropertyRNA *prop;
index 0baa4cc..db1e1e1 100644 (file)
@@ -92,7 +92,7 @@ DefNode( ShaderNode,     SH_NODE_TEX_MUSGRAVE,       def_sh_tex_musgrave,    "TE
 DefNode( ShaderNode,     SH_NODE_TEX_VORONOI,        def_sh_tex_voronoi,     "TEX_VORONOI",        TexVoronoi,       "Voronoi Texture",   ""       )
 DefNode( ShaderNode,     SH_NODE_TEX_CHECKER,        def_sh_tex_checker,     "TEX_CHECKER",        TexChecker,       "Checker Texture",   ""       )
 DefNode( ShaderNode,     SH_NODE_TEX_BRICK,             def_sh_tex_brick,       "TEX_BRICK",          TexBrick,         "Brick Texture",     ""       )
-DefNode( ShaderNode,     SH_NODE_TEX_COORD,          0,                      "TEX_COORD",          TexCoord,         "Texture Coordinate",""       )
+DefNode( ShaderNode,     SH_NODE_TEX_COORD,          def_sh_tex_coord,       "TEX_COORD",          TexCoord,         "Texture Coordinate",""       )
 
 DefNode( CompositorNode, CMP_NODE_VIEWER,         def_cmp_viewer,         "VIEWER",         Viewer,           "Viewer",            ""              )
 DefNode( CompositorNode, CMP_NODE_RGB,            0,                      "RGB",            RGB,              "RGB",               ""              )
index a10c153..758b433 100644 (file)
@@ -2572,7 +2572,16 @@ static void rna_def_dupli_object(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
        RNA_def_property_ui_text(prop, "Particle Index", "Index in the lowest-level particle dupli list");
 
-       /* TODO: DupliObject has more properties that can be wrapped */
+       prop = RNA_def_property(srna, "orco", PROP_FLOAT, PROP_TRANSLATION);
+       RNA_def_property_float_sdna(prop, NULL, "orco");
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "Generated Coordinates", "Generated coordinates in parent object space");
+
+       prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "uv");
+       RNA_def_property_array(prop, 2);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+       RNA_def_property_ui_text(prop, "UV Coordinates", "UV coordinates in parent object space");
 }
 
 static void rna_def_object_base(BlenderRNA *brna)
index a6f49d8..b0b76c9 100644 (file)
@@ -337,8 +337,10 @@ static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int e
                dupli_render_particle_set(scene, go->ob, level + 1, enable);
 }
 /* When no longer needed, duplilist should be freed with Object.free_duplilist */
-void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce)
+void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, int settings)
 {
+       int for_render = settings == eModifierMode_Render;
+
        if (!(ob->transflag & OB_DUPLI)) {
                BKE_report(reports, RPT_ERROR, "Object does not have duplis");
                return;
@@ -353,7 +355,7 @@ void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce)
        }
        if (G.is_rendering)
                dupli_render_particle_set(sce, ob, 0, 1);
-       ob->duplilist = object_duplilist(sce, ob);
+       ob->duplilist = object_duplilist(sce, ob, for_render);
        if (G.is_rendering)
                dupli_render_particle_set(sce, ob, 0, 0);
        /* ob->duplilist should now be freed with Object.free_duplilist */
@@ -608,6 +610,7 @@ void RNA_api_object(StructRNA *srna)
                                        "objects real matrix and layers");
        parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate duplis");
        RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
+       parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Generate texture coordinates for rendering");
        RNA_def_function_flag(func, FUNC_USE_REPORTS);
 
        func = RNA_def_function(srna, "dupli_list_clear", "rna_Object_free_duplilist");
index 86f71f6..62b1cab 100644 (file)
@@ -57,7 +57,7 @@ void register_node_type_sh_tex_coord(bNodeTreeType *ttype)
 {
        static bNodeType ntype;
 
-       node_type_base(ttype, &ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT, 0);
+       node_type_base(ttype, &ntype, SH_NODE_TEX_COORD, "Texture Coordinate", NODE_CLASS_INPUT, NODE_OPTIONS);
        node_type_compatibility(&ntype, NODE_NEW_SHADING);
        node_type_socket_templates(&ntype, NULL, sh_node_tex_coord_out);
        node_type_size(&ntype, 150, 60, 200);
index 78b4c3b..b394856 100644 (file)
@@ -4895,7 +4895,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
                                /* create list of duplis generated by this object, particle
                                 * system need to have render settings set for dupli particles */
                                dupli_render_particle_set(re, ob, timeoffset, 0, 1);
-                               lb= object_duplilist(re->scene, ob);
+                               lb= object_duplilist(re->scene, ob, TRUE);
                                dupli_render_particle_set(re, ob, timeoffset, 0, 0);
 
                                for (dob= lb->first; dob; dob= dob->next) {