From 6d4a6b957c5fd23e3b1356c86e7f16ccd0708b12 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 29 Jan 2013 08:21:21 +0000 Subject: Fix #34009: multi user curves + deform modifier behavior Issue was caused by storing BB calculated from final displist in Curve datablock and not having Object's BB at all. This is not clear at how could have been worked for so long. Changed it so Curve's BB is calculated from non-deformed displist, which matches BKE_object_min_max and BKE_curve_texspace_calc and made it so Object's BB would be calculated from final displist. --- source/blender/blenkernel/intern/displist.c | 67 ++++++++++++++++------------- 1 file changed, 38 insertions(+), 29 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 23b0d3e6e22..ada33691c15 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -63,6 +63,7 @@ #include "BLO_sys_types.h" // for intptr_t support static void boundbox_displist(Object *ob); +static void boundbox_dispbase(BoundBox *bb, ListBase *dispbase); void BKE_displist_elem_free(DispList *dl) { @@ -1598,15 +1599,15 @@ void BKE_displist_make_curveTypes(Scene *scene, Object *ob, int forOrco) if (ob->derivedFinal) { DM_set_object_boundbox(ob, ob->derivedFinal); + + /* always keep curve's BB in sync with non-deformed displist */ + if (cu->bb == NULL) + cu->bb = MEM_callocN(sizeof(BoundBox), "boundbox"); + + boundbox_dispbase(cu->bb, &cu->disp); } else { boundbox_displist(ob); - - /* if there is no derivedMesh, object's boundbox is unneeded */ - if (ob->bb) { - MEM_freeN(ob->bb); - ob->bb = NULL; - } } } @@ -1642,42 +1643,50 @@ float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *derivedFina return orco; } -/* this is confusing, there's also min_max_object, appplying the obmat... */ -static void boundbox_displist(Object *ob) +static void boundbox_dispbase(BoundBox *bb, ListBase *dispbase) { - BoundBox *bb = NULL; float min[3], max[3]; DispList *dl; float *vert; int a, tot = 0; + int doit = 0; INIT_MINMAX(min, max); + for (dl = dispbase->first; dl; dl = dl->next) { + tot = (dl->type == DL_INDEX3) ? dl->nr : dl->nr * dl->parts; + vert = dl->verts; + for (a = 0; a < tot; a++, vert += 3) { + minmax_v3v3_v3(min, max, vert); + } + doit |= (tot != 0); + } + + if (!doit) { + /* there's no geometry in displist, use zero-sized boundbox */ + zero_v3(min); + zero_v3(max); + } + + BKE_boundbox_init_from_minmax(bb, min, max); +} + +/* this is confusing, there's also min_max_object, appplying the obmat... */ +static void boundbox_displist(Object *ob) +{ if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) { Curve *cu = ob->data; - int doit = 0; - if (cu->bb == NULL) cu->bb = MEM_callocN(sizeof(BoundBox), "boundbox"); - bb = cu->bb; + /* calculate curve's BB based on non-deformed displist */ + if (cu->bb == NULL) + cu->bb = MEM_callocN(sizeof(BoundBox), "boundbox"); - for (dl = ob->disp.first; dl; dl = dl->next) { - tot = (dl->type == DL_INDEX3) ? dl->nr : dl->nr * dl->parts; - vert = dl->verts; - for (a = 0; a < tot; a++, vert += 3) { - minmax_v3v3_v3(min, max, vert); - } - doit = (tot != 0); - } + boundbox_dispbase(cu->bb, &cu->disp); - if (!doit) { - /* there's no geometry in displist, use zero-sized boundbox */ - zero_v3(min); - zero_v3(max); - } - - } + /* object's BB is calculated from final displist */ + if (ob->bb == NULL) + ob->bb = MEM_callocN(sizeof(BoundBox), "boundbox"); - if (bb) { - BKE_boundbox_init_from_minmax(bb, min, max); + boundbox_dispbase(ob->bb, &ob->disp); } } -- cgit v1.2.3