diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 8fbb223cbc5..27301026d35 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -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; diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index ebf8bb45420..b6d5cc623bb 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -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: { diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 27f6b6ee4ee..ce563087b4a 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -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); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 46fbead9bc1..da8f30ea169 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -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) diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 222ade504cc..01da5050c8d 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -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); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index ce21ab994f0..48e271a9f3f 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -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 diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index fbaf253177d..6bd8f2ac69c 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -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); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index c82eafc790a..3cf44a3409a 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -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 { diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index eabb97e7238..b878bdee3c7 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -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"); diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 82bead7e41a..e8e584dd8ef 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -284,6 +284,8 @@ class TextureCoordinateNode : public ShaderNode { public: SHADER_NODE_CLASS(TextureCoordinateNode) void attributes(AttributeRequestSet *attributes); + + bool from_dupli; }; class LightPathNode : public ShaderNode { diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 7389b239627..d78a82d589a 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -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; diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index 88677d79dff..e2c3ad4e071 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -49,6 +49,9 @@ public: bool use_motion; bool use_holdout; + float3 dupli_generated; + float2 dupli_uv; + int particle_id; Object(); diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index f506c67a36c..11537964e32 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -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); diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 080eb7bc541..56dfdf404f8 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -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 */ diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index ec15e2ea87f..58d20fff2bc 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -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); } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 72a43da94b6..65ab97e0dad 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 0d01bb33fc5..8c0d19ba1fd 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -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 */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 41d300a95de..f8777f87369 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -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; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9aa7da3ca6e..26d9fb9e829 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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! */ diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 4942b9e4390..c2e5f145ff7 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -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"); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 1d04855666e..470f82195a4 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -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; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index cb197ab93b0..ca768f2ef17 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -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) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index b3dd54c6261..cdb75cdfa74 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -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; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index cee1c91abe7..700869e10d5 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -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; diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 4732586b912..e035f1c3f5a 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -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; diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 6e20375d9c6..ffc78ef8ca4 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -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); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b03d348b49d..d650c8dbf69 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -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; diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 0baa4cc0838..db1e1e16adf 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -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", "" ) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index a10c153515a..758b433b1cb 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -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) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index a6f49d80b25..b0b76c9e38f 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -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"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c index 86f71f6f05b..62b1cabd491 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_coord.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_coord.c @@ -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); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 78b4c3b8787..b3948563a87 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -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) {