[Bf-blender-cvs] [c71768d] gooseberry: Alternative dupli generator function for creating duplis in a group without a specific parent.
Lukas Tönne
noreply at git.blender.org
Mon Mar 23 13:03:28 CET 2015
Commit: c71768d86432ee1151ac1085055066e461adbc39
Author: Lukas Tönne
Date: Fri Mar 13 16:40:50 2015 +0100
Branches: gooseberry
https://developer.blender.org/rBc71768d86432ee1151ac1085055066e461adbc39
Alternative dupli generator function for creating duplis in a group
without a specific parent.
===================================================================
M source/blender/blenkernel/BKE_anim.h
M source/blender/blenkernel/intern/group.c
M source/blender/blenkernel/intern/object_dupli.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 4f3f6e2..6d4eb1b 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -71,8 +71,10 @@ int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], fl
/* ---------------------------------------------------- */
/* Dupli-Geometry */
-struct ListBase *object_duplilist_ex(struct EvaluationContext *eval_ctx, struct Scene *sce, struct Object *ob, bool update);
-struct ListBase *object_duplilist(struct EvaluationContext *eval_ctx, struct Scene *sce, struct Object *ob);
+struct ListBase *object_duplilist_ex(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, bool update);
+struct ListBase *object_duplilist(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
+struct ListBase *group_duplilist_ex(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Group *group, bool update);
+struct ListBase *group_duplilist(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Group *group);
void free_object_duplilist(struct ListBase *lb);
int count_duplilist(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index f3869e4..f24eab8 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -327,7 +327,7 @@ bool BKE_group_is_animated(Group *group, Object *UNUSED(parent))
GroupObject *go;
#if 0 /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */
- if (parent->nlastrips.first)
+ if (parent && parent->nlastrips.first)
return 1;
#endif
@@ -394,7 +394,7 @@ void BKE_group_handle_recalc_and_update(EvaluationContext *eval_ctx, Scene *scen
* but when its enabled at some point it will need to be changed so as not to update so much - campbell */
/* if animated group... */
- if (parent->nlastrips.first) {
+ if (parent && parent->nlastrips.first) {
int cfrao;
/* switch to local time */
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 636c554..bcdd3ab 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -99,7 +99,7 @@ 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_ex(DupliContext *r_ctx, EvaluationContext *eval_ctx, Scene *scene, Object *ob, float space_mat[4][4], const DupliGenerator *gen, bool update)
{
r_ctx->eval_ctx = eval_ctx;
r_ctx->scene = scene;
@@ -113,14 +113,19 @@ 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->lay = ob ? ob->lay : 0;
r_ctx->level = 0;
- r_ctx->gen = get_dupli_generator(r_ctx);
+ r_ctx->gen = gen ? gen : get_dupli_generator(r_ctx);
r_ctx->duplilist = NULL;
}
+static void init_context(DupliContext *r_ctx, EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update)
+{
+ init_context_ex(r_ctx, eval_ctx, scene, ob, NULL, NULL, update);
+}
+
/* create sub-context for recursive duplis */
static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Object *ob, float mat[4][4], int index, bool animated)
{
@@ -129,7 +134,7 @@ static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Obj
r_ctx->animated |= animated; /* object animation makes all children animated */
/* XXX annoying, previously was done by passing an ID* argument, this at least is more explicit */
- if (ctx->gen->type == OB_DUPLIGROUP)
+ if (ctx->gen->type == OB_DUPLIGROUP && ctx->object)
r_ctx->group = ctx->object->dup_group;
r_ctx->object = ob;
@@ -222,7 +227,10 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
{
Object *parent = ctx->object;
Object *obedit = ctx->scene->obedit;
-
+
+ if (!parent)
+ return;
+
if (ctx->group) {
unsigned int lay = ctx->group->layer;
GroupObject *go;
@@ -258,69 +266,84 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
/*---- Implementations ----*/
-/* OB_DUPLIGROUP */
-static void make_duplis_group(const DupliContext *ctx)
+/* Intern function for creating instances of group content
+ * with or without a parent (parent == NULL is allowed!)
+ * Note: some of the group animation update functions use the parent object,
+ * but this is old NLA code that is currently disabled and might be removed entirely.
+ */
+static void make_duplis_group_intern(const DupliContext *ctx, Group *group, Object *parent)
{
- bool for_render = (ctx->eval_ctx->mode == DAG_EVAL_RENDER);
- Object *ob = ctx->object;
- Group *group;
+ const bool for_render = (ctx->eval_ctx->mode == DAG_EVAL_RENDER);
+
GroupObject *go;
float group_mat[4][4];
int id;
- bool animated, hide;
-
- if (ob->dup_group == NULL) return;
- group = ob->dup_group;
-
- /* combine group offset and obmat */
+ bool animated;
+
unit_m4(group_mat);
sub_v3_v3(group_mat[3], group->dupli_ofs);
- mul_m4_m4m4(group_mat, ob->obmat, group_mat);
- /* don't access 'ob->obmat' from now on. */
-
+
+ if (parent) {
+ /* combine group offset and obmat */
+ mul_m4_m4m4(group_mat, parent->obmat, group_mat);
+ /* don't access 'parent->obmat' from now on. */
+ }
+
/* handles animated groups */
-
+
/* we need to check update for objects that are not in scene... */
if (ctx->do_update) {
/* note: update is optional because we don't always need object
* transformations to be correct. Also fixes bug [#29616]. */
- BKE_group_handle_recalc_and_update(ctx->eval_ctx, ctx->scene, ob, group);
+ BKE_group_handle_recalc_and_update(ctx->eval_ctx, ctx->scene, parent, group);
}
-
- animated = BKE_group_is_animated(group, ob);
-
+
+ animated = BKE_group_is_animated(group, parent);
+
for (go = group->gobject.first, id = 0; go; go = go->next, id++) {
+ float mat[4][4];
+ bool hide;
+
/* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
- if (go->ob != ob) {
- 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);
-
- /* 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);
-
- /* recursion */
- make_recursive_duplis(ctx, go->ob, group_mat, id, animated);
+ if (go->ob == parent)
+ continue;
+
+ /* 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);
+
+ /* 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);
+
+ /* recursion */
+ make_recursive_duplis(ctx, go->ob, group_mat, id, animated);
}
}
+/* OB_DUPLIGROUP */
+static void make_duplis_group(const DupliContext *ctx)
+{
+ Object *ob = ctx->object;
+ if (!ob || !ob->dup_group)
+ return;
+
+ make_duplis_group_intern(ctx, ob->dup_group, ob);
+}
+
const DupliGenerator gen_dupli_group = {
OB_DUPLIGROUP, /* type */
make_duplis_group /* make_duplis */
@@ -334,8 +357,9 @@ static void make_duplis_frames(const DupliContext *ctx)
extern int enable_cu_speed; /* object.c */
Object copyob;
int cfrao = scene->r.cfra;
- int dupend = ob->dupend;
+ if (!ob)
+ return;
/* dupliframes not supported inside groups */
if (ctx->group)
return;
@@ -344,7 +368,7 @@ static void make_duplis_frames(const DupliContext *ctx)
*/
if (ob->parent == NULL && BLI_listbase_is_empty(&ob->constraints) && ob->adt == NULL)
return;
-
+
/* make a copy of the object's original data (before any dupli-data overwrites it)
* as we'll need this to keep track of unkeyed data
* - this doesn't take into account other data that can be reached from the object,
@@ -359,7 +383,7 @@ static void make_duplis_frames(const DupliContext *ctx)
* updates, as this is not a permanent change to the object */
ob->id.flag |= LIB_ANIM_NO_RECALC;
- for (scene->r.cfra = ob->dupsta; scene->r.cfra <= dupend; scene->r.cfra++) {
+ for (scene->r.cfra = ob->dupsta; scene->r.cfra <= ob->dupend; scene->r.cfra++) {
int ok = 1;
/* - dupoff = how often a frames within the range shouldn't be made into duplis
@@ -515
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list