Fix T44183 particles in linked group offset from object
authorAntony Riakiotakis <kalast@gmail.com>
Thu, 2 Apr 2015 15:13:24 +0000 (17:13 +0200)
committerAntony Riakiotakis <kalast@gmail.com>
Thu, 2 Apr 2015 15:13:45 +0000 (17:13 +0200)
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...

source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/intern/object_dupli.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/makesdna/DNA_object_types.h
source/blender/render/intern/source/convertblender.c

index e2b9c66780b269025e93c977172247097c4790ab..584f0da323aef29aa7bd9d9434b21cb10fee7710 100644 (file)
@@ -80,7 +80,7 @@ typedef struct DupliApplyData {
        DupliExtraData *extra;
 } 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_free_apply_data(DupliApplyData *apply_data);
 
index c77f65f69e1ea27b3aaeba63897e00def326d0af..8abe4bdbb97f2032f743033f98696c1b616bc36c 100644 (file)
@@ -1237,7 +1237,7 @@ int count_duplilist(Object *ob)
        return 1;
 }
 
-DupliApplyData *duplilist_apply(Object *ob, ListBase *duplilist)
+DupliApplyData *duplilist_apply(Object *ob, Scene *scene, ListBase *duplilist)
 {
        DupliApplyData *apply_data = NULL;
        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) {
                        /* copy obmat from duplis */
                        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 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) {
                copy_m4_m4(dob->ob->obmat, apply_data->extra[i].obmat);
+               dob->ob->transflag &= ~OB_DUPLICALCDERIVED;
                
                dob->ob->lay = apply_data->extra[i].lay;
        }
index e51993ce91f037e631e21aee451c639681ef38b3..8600c1190d4d900029c67ccf507b68782ebd1723 100644 (file)
@@ -55,6 +55,7 @@
 #include "BKE_camera.h"
 #include "BKE_context.h"
 #include "BKE_customdata.h"
+#include "BKE_DerivedMesh.h"
 #include "BKE_image.h"
 #include "BKE_key.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);
        // 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);
        if (dob) dob_next = dupli_step(dob->next);
index 702d9acfb5873f5deda5e91f0acf5342a0be5bd5..286461f1b6983fa6b14ce331ad3b9c1aecaee0d2 100644 (file)
@@ -397,7 +397,7 @@ enum {
        OB_DUPLIVERTS       = 1 << 4,
        OB_DUPLIROT         = 1 << 5,
        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_DUPLIFACES       = 1 << 9,
        OB_DUPLIFACES_SCALE = 1 << 10,
index e900d29aa1940be7ada7405b698853d4d62af76e..8c9bebe7ff9150d4f8d4bf01d5fcfce712cdf93f 100644 (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 */
                                dupli_render_particle_set(re, ob, timeoffset, 0, 1);
                                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);
 
                                for (dob= duplilist->first, i = 0; dob; dob= dob->next, ++i) {