diff options
Diffstat (limited to 'source/blender/blenkernel/intern/object_dupli.c')
-rw-r--r-- | source/blender/blenkernel/intern/object_dupli.c | 123 |
1 files changed, 70 insertions, 53 deletions
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 85635cb7d77..a16acd9d564 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -50,8 +50,9 @@ #include "BKE_animsys.h" #include "BKE_DerivedMesh.h" #include "BKE_font.h" -#include "BKE_group.h" #include "BKE_global.h" +#include "BKE_group.h" +#include "BKE_idprop.h" #include "BKE_lattice.h" #include "BKE_main.h" #include "BKE_mesh.h" @@ -143,7 +144,8 @@ static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Obj */ static DupliObject *make_dupli(const DupliContext *ctx, Object *ob, float mat[4][4], int index, - bool animated, bool hide) + bool animated, bool hide, + IDProperty *collection_properties) { DupliObject *dob; int i; @@ -198,6 +200,10 @@ static DupliObject *make_dupli(const DupliContext *ctx, dob->random_id ^= BLI_hash_int(BLI_hash_string(ctx->object->id.name + 2)); } + if (collection_properties) { + dob->collection_properties = IDP_CopyProperty(collection_properties); + } + return dob; } @@ -238,23 +244,23 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild Object *obedit = ctx->scene->obedit; if (ctx->group) { - unsigned int lay = ctx->group->layer; int groupid = 0; - GroupObject *go; - for (go = ctx->group->gobject.first; go; go = go->next, groupid++) { - Object *ob = go->ob; - - if ((ob->lay & lay) && ob != obedit && is_child(ob, parent)) { + FOREACH_GROUP_BASE(ctx->group, base) + { + Object *ob = base->object; + if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) { DupliContext pctx; copy_dupli_context(&pctx, ctx, ctx->object, NULL, groupid, false); /* mballs have a different dupli handling */ - if (ob->type != OB_MBALL) + if (ob->type != OB_MBALL) { ob->flag |= OB_DONE; /* doesnt render */ - + } make_child_duplis_cb(&pctx, userdata, ob); } + groupid++; } + FOREACH_GROUP_BASE_END } else { int baseid = 0; @@ -281,13 +287,12 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild /* OB_DUPLIGROUP */ static void make_duplis_group(const DupliContext *ctx) { - bool for_render = (ctx->eval_ctx->mode == DAG_EVAL_RENDER); Object *ob = ctx->object; Group *group; - GroupObject *go; + Base *base; float group_mat[4][4]; int id; - bool animated, hide; + bool animated; if (ob->dup_group == NULL) return; group = ob->dup_group; @@ -309,34 +314,18 @@ static void make_duplis_group(const DupliContext *ctx) animated = BKE_group_is_animated(group, ob); - for (go = group->gobject.first, id = 0; go; go = go->next, id++) { - /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ - if (go->ob != ob) { + for (base = group->view_layer->object_bases.first, id = 0; base; base = base->next, id++) { + if (base->object != ob && (base->flag & BASE_VISIBLED)) { float mat[4][4]; - /* Special case for instancing dupli-groups, see: T40051 - * this object may be instanced via dupli-verts/faces, in this case we don't want to render - * (blender convention), but _do_ show in the viewport. - * - * Regular objects work fine but not if we're instancing dupli-groups, - * because the rules for rendering aren't applied to objects they instance. - * We could recursively pass down the 'hide' flag instead, but that seems unnecessary. - */ - if (for_render && go->ob->parent && go->ob->parent->transflag & (OB_DUPLIVERTS | OB_DUPLIFACES)) { - continue; - } - /* group dupli offset, should apply after everything else */ - mul_m4_m4m4(mat, group_mat, go->ob->obmat); + mul_m4_m4m4(mat, group_mat, base->object->obmat); - /* check the group instance and object layers match, also that the object visible flags are ok. */ - hide = (go->ob->lay & group->layer) == 0 || - (for_render ? go->ob->restrictflag & OB_RESTRICT_RENDER : go->ob->restrictflag & OB_RESTRICT_VIEW); - - make_dupli(ctx, go->ob, mat, id, animated, hide); + BLI_assert(base->collection_properties != NULL); + make_dupli(ctx, base->object, mat, id, animated, false, base->collection_properties); /* recursion */ - make_recursive_duplis(ctx, go->ob, group_mat, id, animated); + make_recursive_duplis(ctx, base->object, group_mat, id, animated); } } } @@ -399,7 +388,7 @@ static void make_duplis_frames(const DupliContext *ctx) 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(ctx->eval_ctx, scene, ob, (float)scene->r.cfra); - make_dupli(ctx, ob, ob->obmat, scene->r.cfra, false, false); + make_dupli(ctx, ob, ob->obmat, scene->r.cfra, false, false, NULL); } } @@ -484,7 +473,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], */ mul_m4_m4m4(space_mat, obmat, inst_ob->imat); - dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index, false, false); + dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index, false, false, NULL); if (vdd->orco) copy_v3_v3(dob->orco, vdd->orco[index]); @@ -669,7 +658,7 @@ static void make_duplis_font(const DupliContext *ctx) copy_v3_v3(obmat[3], vec); - make_dupli(ctx, ob, obmat, a, false, false); + make_dupli(ctx, ob, obmat, a, false, false, NULL); } } @@ -775,7 +764,7 @@ static void make_child_duplis_faces(const DupliContext *ctx, void *userdata, Obj */ mul_m4_m4m4(space_mat, obmat, inst_ob->imat); - dob = make_dupli(ctx, inst_ob, obmat, a, false, false); + dob = make_dupli(ctx, inst_ob, obmat, a, false, false, NULL); if (use_texcoords) { float w = 1.0f / (float)mp->totloop; @@ -858,7 +847,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem bool for_render = ctx->eval_ctx->mode == DAG_EVAL_RENDER; bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW); - GroupObject *go; Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL; DupliObject *dob; ParticleDupliWeight *dw; @@ -912,10 +900,10 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem return; } else { /*PART_DRAW_GR */ - if (part->dup_group == NULL || BLI_listbase_is_empty(&part->dup_group->gobject)) + if (part->dup_group == NULL || BLI_listbase_is_empty(&part->dup_group->view_layer->object_bases)) return; - if (BLI_findptr(&part->dup_group->gobject, par, offsetof(GroupObject, ob))) { + if (BLI_findptr(&part->dup_group->view_layer->object_bases, par, offsetof(Base, object))) { return; } } @@ -947,8 +935,12 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem totgroup += dw->count; } else { - for (go = part->dup_group->gobject.first; go; go = go->next) + FOREACH_GROUP_OBJECT(part->dup_group, object) + { + (void) object; totgroup++; + } + FOREACH_GROUP_OBJECT_END } /* we also copy the actual objects to restore afterwards, since @@ -967,11 +959,18 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem } } else { - go = part->dup_group->gobject.first; - for (a = 0; a < totgroup; a++, go = go->next) { - oblist[a] = go->ob; - obcopylist[a] = *go->ob; + a = 0; + FOREACH_GROUP_OBJECT(part->dup_group, object) + { + oblist[a] = object; + obcopylist[a] = *object; + a++; + + if (a >= totgroup) { + continue; + } } + FOREACH_GROUP_OBJECT_END } } else { @@ -1060,23 +1059,33 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem } if (part->ren_as == PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) { - for (go = part->dup_group->gobject.first, b = 0; go; go = go->next, b++) { - + b = 0; + FOREACH_GROUP_OBJECT(part->dup_group, object) + { copy_m4_m4(tmat, oblist[b]->obmat); + /* apply particle scale */ mul_mat3_m4_fl(tmat, size * scale); mul_v3_fl(tmat[3], size * scale); + /* group dupli offset, should apply after everything else */ - if (!is_zero_v3(part->dup_group->dupli_ofs)) + if (!is_zero_v3(part->dup_group->dupli_ofs)) { sub_v3_v3(tmat[3], part->dup_group->dupli_ofs); + } + /* individual particle transform */ mul_m4_m4m4(mat, pamat, tmat); - dob = make_dupli(ctx, go->ob, mat, a, false, false); + dob = make_dupli(ctx, object, mat, a, false, false, NULL); dob->particle_system = psys; - if (use_texcoords) + + if (use_texcoords) { psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); + } + + b++; } + FOREACH_GROUP_OBJECT_END } else { /* to give ipos in object correct offset */ @@ -1121,7 +1130,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem if (part->draw & PART_DRAW_GLOBAL_OB) add_v3_v3v3(mat[3], mat[3], vec); - dob = make_dupli(ctx, ob, mat, a, false, false); + dob = make_dupli(ctx, ob, mat, a, false, false, NULL); dob->particle_system = psys; if (use_texcoords) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); @@ -1238,6 +1247,14 @@ ListBase *object_duplilist(const EvaluationContext *eval_ctx, Scene *sce, Object void free_object_duplilist(ListBase *lb) { + + for (DupliObject *dob = lb->first; dob; dob = dob->next) { + if (dob->collection_properties) { + IDP_FreeProperty(dob->collection_properties); + MEM_freeN(dob->collection_properties); + } + } + BLI_freelistN(lb); MEM_freeN(lb); } |