Fix T44183 particles in linked group offset from object

A nice bug combining all the broken features of blender:
Particles, duplis and multiple scene dependencies.

Fortunately this was solvable: Basically, we need to
make sure derivedmesh for dupli instance is generated before
obmat is overriden. This also makes sense, since no instance
has "true" obmat apart from original. Lazy initialization of
derivedmesh just does not work here (or it -does- work but first
use should be before instance drawing).

Fingers crossed nothing else breaks after this...
This commit is contained in:
Antony Riakiotakis
2015-04-02 17:13:24 +02:00
parent 018dc3aeda
commit 43101289a6
5 changed files with 14 additions and 5 deletions

View File

@@ -80,7 +80,7 @@ typedef struct DupliApplyData {
DupliExtraData *extra; DupliExtraData *extra;
} DupliApplyData; } DupliApplyData;
DupliApplyData *duplilist_apply(struct Object *ob, struct ListBase *duplilist); DupliApplyData *duplilist_apply(struct Object *ob, struct Scene *scene, struct ListBase *duplilist);
void duplilist_restore(struct ListBase *duplilist, DupliApplyData *apply_data); void duplilist_restore(struct ListBase *duplilist, DupliApplyData *apply_data);
void duplilist_free_apply_data(DupliApplyData *apply_data); void duplilist_free_apply_data(DupliApplyData *apply_data);

View File

@@ -1237,7 +1237,7 @@ int count_duplilist(Object *ob)
return 1; return 1;
} }
DupliApplyData *duplilist_apply(Object *ob, ListBase *duplilist) DupliApplyData *duplilist_apply(Object *ob, Scene *scene, ListBase *duplilist)
{ {
DupliApplyData *apply_data = NULL; DupliApplyData *apply_data = NULL;
int num_objects = BLI_listbase_count(duplilist); int num_objects = BLI_listbase_count(duplilist);
@@ -1253,6 +1253,13 @@ DupliApplyData *duplilist_apply(Object *ob, ListBase *duplilist)
for (dob = duplilist->first, i = 0; dob; dob = dob->next, ++i) { for (dob = duplilist->first, i = 0; dob; dob = dob->next, ++i) {
/* copy obmat from duplis */ /* copy obmat from duplis */
copy_m4_m4(apply_data->extra[i].obmat, dob->ob->obmat); copy_m4_m4(apply_data->extra[i].obmat, dob->ob->obmat);
/* 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);
dob->ob->transflag |= OB_DUPLICALCDERIVED;
}
copy_m4_m4(dob->ob->obmat, dob->mat); copy_m4_m4(dob->ob->obmat, dob->mat);
/* copy layers from the main duplicator object */ /* copy layers from the main duplicator object */
@@ -1273,6 +1280,7 @@ void duplilist_restore(ListBase *duplilist, DupliApplyData *apply_data)
*/ */
for (dob = duplilist->last, i = apply_data->num_objects - 1; dob; dob = dob->prev, --i) { for (dob = duplilist->last, i = apply_data->num_objects - 1; dob; dob = dob->prev, --i) {
copy_m4_m4(dob->ob->obmat, apply_data->extra[i].obmat); copy_m4_m4(dob->ob->obmat, apply_data->extra[i].obmat);
dob->ob->transflag &= ~OB_DUPLICALCDERIVED;
dob->ob->lay = apply_data->extra[i].lay; dob->ob->lay = apply_data->extra[i].lay;
} }

View File

@@ -55,6 +55,7 @@
#include "BKE_camera.h" #include "BKE_camera.h"
#include "BKE_context.h" #include "BKE_context.h"
#include "BKE_customdata.h" #include "BKE_customdata.h"
#include "BKE_DerivedMesh.h"
#include "BKE_image.h" #include "BKE_image.h"
#include "BKE_key.h" #include "BKE_key.h"
#include "BKE_main.h" #include "BKE_main.h"
@@ -2051,7 +2052,7 @@ static void draw_dupli_objects_color(
lb = object_duplilist(G.main->eval_ctx, scene, base->object); lb = object_duplilist(G.main->eval_ctx, scene, base->object);
// BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ // BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
apply_data = duplilist_apply(base->object, lb); apply_data = duplilist_apply(base->object, scene, lb);
dob = dupli_step(lb->first); dob = dupli_step(lb->first);
if (dob) dob_next = dupli_step(dob->next); if (dob) dob_next = dupli_step(dob->next);

View File

@@ -397,7 +397,7 @@ enum {
OB_DUPLIVERTS = 1 << 4, OB_DUPLIVERTS = 1 << 4,
OB_DUPLIROT = 1 << 5, OB_DUPLIROT = 1 << 5,
OB_DUPLINOSPEED = 1 << 6, OB_DUPLINOSPEED = 1 << 6,
/* OB_POWERTRACK = 1 << 7,*/ /*UNUSED*/ OB_DUPLICALCDERIVED = 1 << 7, /* runtime, calculate derivedmesh for dupli before it's used */
OB_DUPLIGROUP = 1 << 8, OB_DUPLIGROUP = 1 << 8,
OB_DUPLIFACES = 1 << 9, OB_DUPLIFACES = 1 << 9,
OB_DUPLIFACES_SCALE = 1 << 10, OB_DUPLIFACES_SCALE = 1 << 10,

View File

@@ -5002,7 +5002,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp
* system need to have render settings set for dupli particles */ * system need to have render settings set for dupli particles */
dupli_render_particle_set(re, ob, timeoffset, 0, 1); dupli_render_particle_set(re, ob, timeoffset, 0, 1);
duplilist = object_duplilist(re->eval_ctx, re->scene, ob); duplilist = object_duplilist(re->eval_ctx, re->scene, ob);
duplilist_apply_data = duplilist_apply(ob, duplilist); duplilist_apply_data = duplilist_apply(ob, NULL, duplilist);
dupli_render_particle_set(re, ob, timeoffset, 0, 0); dupli_render_particle_set(re, ob, timeoffset, 0, 0);
for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) { for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) {