Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/object_dupli.c')
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c172
1 files changed, 92 insertions, 80 deletions
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 56d5cb609fc..13589866e48 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -49,10 +49,10 @@
#include "BKE_animsys.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_depsgraph.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"
@@ -62,6 +62,7 @@
#include "BKE_editmesh.h"
#include "BKE_anim.h"
+#include "DEG_depsgraph.h"
#include "BLI_strict_flags.h"
#include "BLI_hash.h"
@@ -69,15 +70,15 @@
/* Dupli-Geometry */
typedef struct DupliContext {
- EvaluationContext *eval_ctx;
+ const EvaluationContext *eval_ctx;
bool do_update;
bool animated;
Group *group; /* XXX child objects are selected from this group if set, could be nicer */
Scene *scene;
+ ViewLayer *view_layer;
Object *object;
float space_mat[4][4];
- unsigned int lay;
int persistent_id[MAX_DUPLI_RECUR];
int level;
@@ -96,10 +97,11 @@ typedef struct DupliGenerator {
static const DupliGenerator *get_dupli_generator(const DupliContext *ctx);
/* create initial context for root object */
-static void init_context(DupliContext *r_ctx, EvaluationContext *eval_ctx, Scene *scene, Object *ob, float space_mat[4][4], bool update)
+static void init_context(DupliContext *r_ctx, const EvaluationContext *eval_ctx, Scene *scene, Object *ob, float space_mat[4][4], bool update)
{
r_ctx->eval_ctx = eval_ctx;
r_ctx->scene = scene;
+ r_ctx->view_layer = eval_ctx->view_layer;
/* don't allow BKE_object_handle_update for viewport during render, can crash */
r_ctx->do_update = update && !(G.is_rendering && eval_ctx->mode != DAG_EVAL_RENDER);
r_ctx->animated = false;
@@ -110,7 +112,6 @@ static void init_context(DupliContext *r_ctx, EvaluationContext *eval_ctx, Scene
copy_m4_m4(r_ctx->space_mat, space_mat);
else
unit_m4(r_ctx->space_mat);
- r_ctx->lay = ob->lay;
r_ctx->level = 0;
r_ctx->gen = get_dupli_generator(r_ctx);
@@ -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,32 +244,30 @@ 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 {
- unsigned int lay = ctx->scene->lay;
int baseid = 0;
- Base *base;
- for (base = ctx->scene->base.first; base; base = base->next, baseid++) {
+ ViewLayer *view_layer = ctx->view_layer;
+ for (Base *base = view_layer->object_bases.first; base; base = base->next, baseid++) {
Object *ob = base->object;
-
- if ((base->lay & lay) && ob != obedit && is_child(ob, parent)) {
+ if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) {
DupliContext pctx;
copy_dupli_context(&pctx, ctx, ctx->object, NULL, baseid, false);
@@ -283,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;
@@ -311,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);
}
}
}
@@ -377,10 +364,6 @@ static void make_duplis_frames(const DupliContext *ctx)
/* duplicate over the required range */
if (ob->transflag & OB_DUPLINOSPEED) enable_cu_speed = 0;
- /* special flag to avoid setting recalc flags to notify the depsgraph of
- * updates, as this is not a permanent change to the object */
- ob->id.recalc |= ID_RECALC_SKIP_ANIM_TAG;
-
for (scene->r.cfra = ob->dupsta; scene->r.cfra <= dupend; scene->r.cfra++) {
int ok = 1;
@@ -399,9 +382,9 @@ static void make_duplis_frames(const DupliContext *ctx)
* However, this has always been the way that this worked (i.e. pre 2.5), so I guess that it'll be fine!
*/
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);
+ 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);
}
}
@@ -413,7 +396,7 @@ static void make_duplis_frames(const DupliContext *ctx)
scene->r.cfra = cfrao;
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);
+ BKE_object_where_is_calc_time(ctx->eval_ctx, scene, ob, (float)scene->r.cfra);
/* but, to make sure unkeyed object transforms are still sane,
* let's copy object's original data back over
@@ -486,7 +469,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]);
@@ -548,13 +531,13 @@ static void make_duplis_verts(const DupliContext *ctx)
CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH);
if (ctx->eval_ctx->mode == DAG_EVAL_RENDER) {
- vdd.dm = mesh_create_derived_render(scene, parent, dm_mask);
+ vdd.dm = mesh_create_derived_render(ctx->eval_ctx, scene, parent, dm_mask);
}
else if (em) {
- vdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
+ vdd.dm = editbmesh_get_derived_cage(ctx->eval_ctx, scene, parent, em, dm_mask);
}
else {
- vdd.dm = mesh_get_derived_final(scene, parent, dm_mask);
+ vdd.dm = mesh_get_derived_final(ctx->eval_ctx, scene, parent, dm_mask);
}
vdd.edit_btmesh = me->edit_btmesh;
@@ -671,7 +654,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);
}
}
@@ -777,7 +760,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;
@@ -816,13 +799,13 @@ static void make_duplis_faces(const DupliContext *ctx)
CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH);
if (ctx->eval_ctx->mode == DAG_EVAL_RENDER) {
- fdd.dm = mesh_create_derived_render(scene, parent, dm_mask);
+ fdd.dm = mesh_create_derived_render(ctx->eval_ctx, scene, parent, dm_mask);
}
else if (em) {
- fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
+ fdd.dm = editbmesh_get_derived_cage(ctx->eval_ctx, scene, parent, em, dm_mask);
}
else {
- fdd.dm = mesh_get_derived_final(scene, parent, dm_mask);
+ fdd.dm = mesh_get_derived_final(ctx->eval_ctx, scene, parent, dm_mask);
}
if (use_texcoords) {
@@ -860,7 +843,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;
@@ -900,6 +882,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
if ((psys->renderdata || part->draw_as == PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
ParticleSimulationData sim = {NULL};
+ sim.eval_ctx = ctx->eval_ctx;
sim.scene = scene;
sim.ob = par;
sim.psys = psys;
@@ -913,10 +896,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;
}
}
@@ -948,8 +931,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
@@ -968,11 +955,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 {
@@ -1061,27 +1055,37 @@ 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 */
- BKE_object_where_is_calc_time(scene, ob, ctime - pa_time);
+ BKE_object_where_is_calc_time(ctx->eval_ctx, scene, ob, ctime - pa_time);
copy_v3_v3(vec, obmat[3]);
obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f;
@@ -1122,7 +1126,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);
@@ -1217,7 +1221,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
/* ---- ListBase dupli container implementation ---- */
/* Returns a list of DupliObject */
-ListBase *object_duplilist_ex(EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update)
+ListBase *object_duplilist_ex(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update)
{
ListBase *duplilist = MEM_callocN(sizeof(ListBase), "duplilist");
DupliContext ctx;
@@ -1232,13 +1236,21 @@ ListBase *object_duplilist_ex(EvaluationContext *eval_ctx, Scene *scene, Object
/* 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(EvaluationContext *eval_ctx, Scene *sce, Object *ob)
+ListBase *object_duplilist(const EvaluationContext *eval_ctx, Scene *sce, Object *ob)
{
return object_duplilist_ex(eval_ctx, sce, ob, true);
}
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);
}
@@ -1273,7 +1285,7 @@ int count_duplilist(Object *ob)
return 1;
}
-DupliApplyData *duplilist_apply(Object *ob, Scene *scene, ListBase *duplilist)
+DupliApplyData *duplilist_apply(const EvaluationContext *eval_ctx, Object *ob, Scene *scene, ListBase *duplilist)
{
DupliApplyData *apply_data = NULL;
int num_objects = BLI_listbase_count(duplilist);
@@ -1289,7 +1301,7 @@ DupliApplyData *duplilist_apply(Object *ob, Scene *scene, ListBase *duplilist)
for (dob = duplilist->first, i = 0; dob; dob = dob->next, ++i) {
/* make sure derivedmesh is calculated once, before drawing */
if (scene && !(dob->ob->transflag & OB_DUPLICALCDERIVED) && dob->ob->type == OB_MESH) {
- mesh_get_derived_final(scene, dob->ob, scene->customdata_mask);
+ mesh_get_derived_final(eval_ctx, scene, dob->ob, scene->customdata_mask);
dob->ob->transflag |= OB_DUPLICALCDERIVED;
}
}