code cleanup: change order of args in void BKE_object_where_is_calc_time_ex() so...
[blender.git] / source / blender / blenkernel / intern / object.c
index 72a43da94b61b1563bdda66de620fe8f99875d6f..ef3c98ee3f4ee7b13e8f60789c7d8b3b5e382ed9 100644 (file)
 #include "DNA_view3d_types.h"
 #include "DNA_world_types.h"
 #include "DNA_object_types.h"
+#include "DNA_property_types.h"
+#include "DNA_rigidbody_types.h"
 
 #include "BLI_blenlib.h"
-#include "BLI_bpath.h"
 #include "BLI_math.h"
-#include "BLI_pbvh.h"
 #include "BLI_utildefines.h"
 #include "BLI_linklist.h"
 
+#include "BKE_pbvh.h"
 #include "BKE_main.h"
 #include "BKE_global.h"
 #include "BKE_idprop.h"
@@ -83,6 +84,7 @@
 #include "BKE_fcurve.h"
 #include "BKE_group.h"
 #include "BKE_icons.h"
+#include "BKE_image.h"
 #include "BKE_key.h"
 #include "BKE_lamp.h"
 #include "BKE_lattice.h"
@@ -97,6 +99,7 @@
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_property.h"
+#include "BKE_rigidbody.h"
 #include "BKE_sca.h"
 #include "BKE_scene.h"
 #include "BKE_sequencer.h"
@@ -196,18 +199,18 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
        return TRUE;
 }
 
-void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
+void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
 {
        ModifierData *md;
-       BKE_object_free_modifiers(ob);
+       BKE_object_free_modifiers(ob_dst);
 
-       if (!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
+       if (!ELEM5(ob_dst->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
                /* only objects listed above can have modifiers and linking them to objects
                 * which doesn't have modifiers stack is quite silly */
                return;
        }
 
-       for (md = from->modifiers.first; md; md = md->next) {
+       for (md = ob_src->modifiers.first; md; md = md->next) {
                ModifierData *nmd = NULL;
 
                if (ELEM4(md->type,
@@ -219,16 +222,18 @@ void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
                        continue;
                }
 
-               if (!BKE_object_support_modifier_type_check(ob, md->type))
+               if (!BKE_object_support_modifier_type_check(ob_dst, md->type))
                        continue;
 
                nmd = modifier_new(md->type);
+               BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
                modifier_copyData(md, nmd);
-               BLI_addtail(&ob->modifiers, nmd);
+               BLI_addtail(&ob_dst->modifiers, nmd);
+               modifier_unique_name(&ob_dst->modifiers, nmd);
        }
 
-       BKE_object_copy_particlesystems(ob, from);
-       BKE_object_copy_softbody(ob, from);
+       BKE_object_copy_particlesystems(ob_dst, ob_src);
+       BKE_object_copy_softbody(ob_dst, ob_src);
 
        /* TODO: smoke?, cloth? */
 }
@@ -262,20 +267,53 @@ void free_sculptsession_deformMats(SculptSession *ss)
        ss->deform_imats = NULL;
 }
 
+/* Write out the sculpt dynamic-topology BMesh to the Mesh */
+void sculptsession_bm_to_me(struct Object *ob, int reorder)
+{
+       if (ob && ob->sculpt) {
+               SculptSession *ss = ob->sculpt;
+
+               if (ss->bm) {
+                       if (ob->data) {
+                               BMIter iter;
+                               BMFace *efa;
+                               BM_ITER_MESH (efa, &iter, ss->bm, BM_FACES_OF_MESH) {
+                                       BM_elem_flag_set(efa, BM_ELEM_SMOOTH,
+                                                        ss->bm_smooth_shading);
+                               }
+                               if (reorder)
+                                       BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
+                               BM_mesh_bm_to_me(ss->bm, ob->data, FALSE);
+                       }
+               }
+       }
+}
+
 void free_sculptsession(Object *ob)
 {
        if (ob && ob->sculpt) {
                SculptSession *ss = ob->sculpt;
                DerivedMesh *dm = ob->derivedFinal;
 
+               if (ss->bm) {
+                       sculptsession_bm_to_me(ob, TRUE);
+                       BM_mesh_free(ss->bm);
+               }
+
                if (ss->pbvh)
-                       BLI_pbvh_free(ss->pbvh);
+                       BKE_pbvh_free(ss->pbvh);
+               if (ss->bm_log)
+                       BM_log_free(ss->bm_log);
+
                if (dm && dm->getPBVH)
                        dm->getPBVH(NULL, dm);  /* signal to clear */
 
                if (ss->texcache)
                        MEM_freeN(ss->texcache);
 
+               if (ss->tex_pool)
+                       BKE_image_pool_free(ss->tex_pool);
+
                if (ss->layer_co)
                        MEM_freeN(ss->layer_co);
 
@@ -300,11 +338,11 @@ void BKE_object_free(Object *ob)
        
        BKE_object_free_display(ob);
        
-       /* disconnect specific data */
+       /* disconnect specific data, but not for lib data (might be indirect data, can get relinked) */
        if (ob->data) {
                ID *id = ob->data;
                id->us--;
-               if (id->us == 0) {
+               if (id->us == 0 && id->lib == NULL) {
                        switch (ob->type) {
                                case OB_MESH:
                                        BKE_mesh_unlink((Mesh *)id);
@@ -347,9 +385,11 @@ void BKE_object_free(Object *ob)
        free_controllers(&ob->controllers);
        free_actuators(&ob->actuators);
        
-       free_constraints(&ob->constraints);
+       BKE_free_constraints(&ob->constraints);
        
        free_partdeflect(ob->pd);
+       BKE_rigidbody_free_object(ob);
+       BKE_rigidbody_free_constraint(ob);
 
        if (ob->soft) sbFree(ob->soft);
        if (ob->bsoft) bsbFree(ob->bsoft);
@@ -432,7 +472,7 @@ void BKE_object_unlink(Object *ob)
                        bPoseChannel *pchan;
                        for (pchan = obt->pose->chanbase.first; pchan; pchan = pchan->next) {
                                for (con = pchan->constraints.first; con; con = con->next) {
-                                       bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+                                       bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
                                        ListBase targets = {NULL, NULL};
                                        bConstraintTarget *ct;
                                        
@@ -454,7 +494,7 @@ void BKE_object_unlink(Object *ob)
                                if (pchan->custom == ob)
                                        pchan->custom = NULL;
                        }
-               } 
+               }
                else if (ELEM(OB_MBALL, ob->type, obt->type)) {
                        if (BKE_mball_is_basis_for(obt, ob))
                                obt->recalc |= OB_RECALC_DATA;
@@ -463,7 +503,7 @@ void BKE_object_unlink(Object *ob)
                sca_remove_ob_poin(obt, ob);
                
                for (con = obt->constraints.first; con; con = con->next) {
-                       bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+                       bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
                        ListBase targets = {NULL, NULL};
                        bConstraintTarget *ct;
                        
@@ -689,8 +729,8 @@ void BKE_object_unlink(Object *ob)
 
                                        if (so->treestore) {
                                                TreeStoreElem *tselem = so->treestore->data;
-                                               int a;
-                                               for (a = 0; a < so->treestore->usedelem; a++, tselem++) {
+                                               int i;
+                                               for (i = 0; i < so->treestore->usedelem; i++, tselem++) {
                                                        if (tselem->id == (ID *)ob) tselem->id = NULL;
                                                }
                                        }
@@ -727,6 +767,50 @@ void BKE_object_unlink(Object *ob)
        }
 }
 
+/* actual check for internal data, not context or flags */
+int BKE_object_is_in_editmode(Object *ob)
+{
+       if (ob->data == NULL)
+               return 0;
+       
+       if (ob->type == OB_MESH) {
+               Mesh *me = ob->data;
+               if (me->edit_btmesh)
+                       return 1;
+       }
+       else if (ob->type == OB_ARMATURE) {
+               bArmature *arm = ob->data;
+               
+               if (arm->edbo)
+                       return 1;
+       }
+       else if (ob->type == OB_FONT) {
+               Curve *cu = ob->data;
+               
+               if (cu->editfont)
+                       return 1;
+       }
+       else if (ob->type == OB_MBALL) {
+               MetaBall *mb = ob->data;
+               
+               if (mb->editelems)
+                       return 1;
+       }
+       else if (ob->type == OB_LATTICE) {
+               Lattice *lt = ob->data;
+               
+               if (lt->editlatt)
+                       return 1;
+       }
+       else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
+               Curve *cu = ob->data;
+
+               if (cu->editnurb)
+                       return 1;
+       }
+       return 0;
+}
+
 int BKE_object_exists_check(Object *obtest)
 {
        Object *ob;
@@ -746,16 +830,16 @@ int BKE_object_exists_check(Object *obtest)
 void *BKE_object_obdata_add_from_type(int type)
 {
        switch (type) {
-               case OB_MESH:      return BKE_mesh_add("Mesh");
-               case OB_CURVE:     return BKE_curve_add("Curve", OB_CURVE);
-               case OB_SURF:      return BKE_curve_add("Surf", OB_SURF);
-               case OB_FONT:      return BKE_curve_add("Text", OB_FONT);
-               case OB_MBALL:     return BKE_mball_add("Meta");
-               case OB_CAMERA:    return BKE_camera_add("Camera");
-               case OB_LAMP:      return BKE_lamp_add("Lamp");
-               case OB_LATTICE:   return BKE_lattice_add("Lattice");
-               case OB_ARMATURE:  return BKE_armature_add("Armature");
-               case OB_SPEAKER:   return BKE_speaker_add("Speaker");
+               case OB_MESH:      return BKE_mesh_add(G.main, "Mesh");
+               case OB_CURVE:     return BKE_curve_add(G.main, "Curve", OB_CURVE);
+               case OB_SURF:      return BKE_curve_add(G.main, "Surf", OB_SURF);
+               case OB_FONT:      return BKE_curve_add(G.main, "Text", OB_FONT);
+               case OB_MBALL:     return BKE_mball_add(G.main, "Meta");
+               case OB_CAMERA:    return BKE_camera_add(G.main, "Camera");
+               case OB_LAMP:      return BKE_lamp_add(G.main, "Lamp");
+               case OB_LATTICE:   return BKE_lattice_add(G.main, "Lattice");
+               case OB_ARMATURE:  return BKE_armature_add(G.main, "Armature");
+               case OB_SPEAKER:   return BKE_speaker_add(G.main, "Speaker");
                case OB_EMPTY:     return NULL;
                default:
                        printf("BKE_object_obdata_add_from_type: Internal error, bad type: %d\n", type);
@@ -784,14 +868,14 @@ static const char *get_obdata_defname(int type)
 }
 
 /* more general add: creates minimum required data, but without vertices etc. */
-Object *BKE_object_add_only_object(int type, const char *name)
+Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
 {
        Object *ob;
 
        if (!name)
                name = get_obdata_defname(type);
 
-       ob = BKE_libblock_alloc(&G.main->object, ID_OB, name);
+       ob = BKE_libblock_alloc(&bmain->object, ID_OB, name);
 
        /* default object vars */
        ob->type = type;
@@ -854,7 +938,9 @@ Object *BKE_object_add_only_object(int type, const char *name)
        ob->step_height = 0.15f;
        ob->jump_speed = 10.0f;
        ob->fall_speed = 55.0f;
-       
+       ob->col_group = 0x01;
+       ob->col_mask = 0xff;
+
        /* NT fluid sim defaults */
        ob->fluidsimSettings = NULL;
 
@@ -875,7 +961,7 @@ Object *BKE_object_add(struct Scene *scene, int type)
        char name[MAX_ID_NAME];
 
        BLI_strncpy(name, get_obdata_defname(type), sizeof(name));
-       ob = BKE_object_add_only_object(type, name);
+       ob = BKE_object_add_only_object(G.main, type, name);
 
        ob->data = BKE_object_obdata_add_from_type(type);
 
@@ -1081,7 +1167,7 @@ static void copy_object_pose(Object *obn, Object *ob)
                }
                
                for (con = chan->constraints.first; con; con = con->next) {
-                       bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
+                       bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con);
                        ListBase targets = {NULL, NULL};
                        bConstraintTarget *ct;
                        
@@ -1141,13 +1227,13 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
        copy_v3_v3(ob_tar->size, ob_src->size);
 }
 
-static Object *object_copy_do(Object *ob, int copy_caches)
+Object *BKE_object_copy_ex(Main *bmain, Object *ob, int copy_caches)
 {
        Object *obn;
        ModifierData *md;
        int a;
 
-       obn = BKE_libblock_copy(&ob->id);
+       obn = BKE_libblock_copy_ex(bmain, &ob->id);
        
        if (ob->totcol) {
                obn->mat = MEM_dupallocN(ob->mat);
@@ -1181,7 +1267,7 @@ static Object *object_copy_do(Object *ob, int copy_caches)
                        BKE_pose_rebuild(obn, obn->data);
        }
        defgroup_copy_list(&obn->defbase, &ob->defbase);
-       copy_constraints(&obn->constraints, &ob->constraints, TRUE);
+       BKE_copy_constraints(&obn->constraints, &ob->constraints, TRUE);
 
        obn->mode = 0;
        obn->sculpt = NULL;
@@ -1204,6 +1290,8 @@ static Object *object_copy_do(Object *ob, int copy_caches)
        }
        obn->soft = copy_softbody(ob->soft, copy_caches);
        obn->bsoft = copy_bulletsoftbody(ob->bsoft);
+       obn->rigidbody_object = BKE_rigidbody_copy_object(ob);
+       obn->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob);
 
        BKE_object_copy_particlesystems(obn, ob);
        
@@ -1221,13 +1309,7 @@ static Object *object_copy_do(Object *ob, int copy_caches)
 /* copy objects, will re-initialize cached simulation data */
 Object *BKE_object_copy(Object *ob)
 {
-       return object_copy_do(ob, FALSE);
-}
-
-/* copy objects, will duplicate cached simulation data */
-Object *BKE_object_copy_with_caches(Object *ob)
-{
-       return object_copy_do(ob, TRUE);
+       return BKE_object_copy_ex(G.main, ob, FALSE);
 }
 
 static void extern_local_object(Object *ob)
@@ -1484,14 +1566,14 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
 
 /* *************** CALC ****************** */
 
-void BKE_object_scale_to_mat3(Object *ob, float mat[][3])
+void BKE_object_scale_to_mat3(Object *ob, float mat[3][3])
 {
        float vec[3];
        mul_v3_v3v3(vec, ob->size, ob->dscale);
        size_to_mat3(mat, vec);
 }
 
-void BKE_object_rot_to_mat3(Object *ob, float mat[][3])
+void BKE_object_rot_to_mat3(Object *ob, float mat[3][3], short use_drot)
 {
        float rmat[3][3], dmat[3][3];
        
@@ -1522,10 +1604,13 @@ void BKE_object_rot_to_mat3(Object *ob, float mat[][3])
        }
        
        /* combine these rotations */
-       mul_m3_m3m3(mat, dmat, rmat);
+       if (use_drot)
+               mul_m3_m3m3(mat, dmat, rmat);
+       else
+               copy_m3_m3(mat, rmat);
 }
 
-void BKE_object_mat3_to_rot(Object *ob, float mat[][3], short use_compat)
+void BKE_object_mat3_to_rot(Object *ob, float mat[3][3], short use_compat)
 {
        switch (ob->rotmode) {
                case ROT_MODE_QUAT:
@@ -1628,7 +1713,7 @@ void BKE_object_tfm_protected_restore(Object *ob,
 }
 
 /* see BKE_pchan_apply_mat4() for the equivalent 'pchan' function */
-void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, const short use_parent)
+void BKE_object_apply_mat4(Object *ob, float mat[4][4], const short use_compat, const short use_parent)
 {
        float rot[3][3];
 
@@ -1657,7 +1742,7 @@ void BKE_object_apply_mat4(Object *ob, float mat[][4], const short use_compat, c
        /* BKE_object_mat3_to_rot handles delta rotations */
 }
 
-void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */
+void BKE_object_to_mat3(Object *ob, float mat[3][3]) /* no parent */
 {
        float smat[3][3];
        float rmat[3][3];
@@ -1667,11 +1752,11 @@ void BKE_object_to_mat3(Object *ob, float mat[][3]) /* no parent */
        BKE_object_scale_to_mat3(ob, smat);
 
        /* rot */
-       BKE_object_rot_to_mat3(ob, rmat);
+       BKE_object_rot_to_mat3(ob, rmat, TRUE);
        mul_m3_m3m3(mat, rmat, smat);
 }
 
-void BKE_object_to_mat4(Object *ob, float mat[][4])
+void BKE_object_to_mat4(Object *ob, float mat[4][4])
 {
        float tmat[3][3];
        
@@ -1685,7 +1770,7 @@ void BKE_object_to_mat4(Object *ob, float mat[][4])
 /* extern */
 int enable_cu_speed = 1;
 
-static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
+static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[4][4])
 {
        Curve *cu;
        float vec[4], dir[3], quat[4], radius, ctime;
@@ -1718,7 +1803,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
                CLAMP(ctime, 0.0f, 1.0f);
        }
        else {
-               ctime = scene->r.cfra;
+               ctime = BKE_scene_frame_get(scene);
                if (IS_EQF(cu->pathlen, 0.0f) == 0)
                        ctime /= cu->pathlen;
                
@@ -1769,7 +1854,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
        }
 }
 
-static void ob_parbone(Object *ob, Object *par, float mat[][4])
+static void ob_parbone(Object *ob, Object *par, float mat[4][4])
 {      
        bPoseChannel *pchan;
        float vec[3];
@@ -1781,19 +1866,26 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4])
        
        /* Make sure the bone is still valid */
        pchan = BKE_pose_channel_find_name(par->pose, ob->parsubstr);
-       if (!pchan) {
+       if (!pchan || !pchan->bone) {
                printf("Object %s with Bone parent: bone %s doesn't exist\n", ob->id.name + 2, ob->parsubstr);
                unit_m4(mat);
                return;
        }
 
        /* get bone transform */
-       copy_m4_m4(mat, pchan->pose_mat);
+       if (pchan->bone->flag & BONE_RELATIVE_PARENTING) {
+               /* the new option uses the root - expected bahaviour, but differs from old... */
+               /* XXX check on version patching? */
+               copy_m4_m4(mat, pchan->chan_mat);
+       }
+       else {
+               copy_m4_m4(mat, pchan->pose_mat);
 
-       /* but for backwards compatibility, the child has to move to the tail */
-       copy_v3_v3(vec, mat[1]);
-       mul_v3_fl(vec, pchan->bone->length);
-       add_v3_v3(mat[3], vec);
+               /* but for backwards compatibility, the child has to move to the tail */
+               copy_v3_v3(vec, mat[1]);
+               mul_v3_fl(vec, pchan->bone->length);
+               add_v3_v3(mat[3], vec);
+       }
 }
 
 static void give_parvert(Object *par, int nr, float vec[3])
@@ -1871,7 +1963,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
        }
        else if (ELEM(par->type, OB_CURVE, OB_SURF)) {
                Curve *cu       = par->data;
-               ListBase *nurb  = BKE_curve_nurbs_get(cu);;
+               ListBase *nurb  = BKE_curve_nurbs_get(cu);
 
                BKE_nurbList_index_get_co(nurb, nr, vec);
        }
@@ -1899,7 +1991,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
        }
 }
 
-static void ob_parvert3(Object *ob, Object *par, float mat[][4])
+static void ob_parvert3(Object *ob, Object *par, float mat[4][4])
 {
        float cmat[3][3], v1[3], v2[3], v3[3], q[4];
 
@@ -1922,12 +2014,12 @@ static void ob_parvert3(Object *ob, Object *par, float mat[][4])
                else {
                        add_v3_v3v3(mat[3], v1, v2);
                        add_v3_v3(mat[3], v3);
-                       mul_v3_fl(mat[3], 0.3333333f);
+                       mul_v3_fl(mat[3], 1.0f / 3.0f);
                }
        }
 }
 
-static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul)
+static void solve_parenting(Scene *scene, Object *ob, Object *par, float obmat[4][4], float slowmat[4][4], int simul)
 {
        float totmat[4][4];
        float tmat[4][4];
@@ -2025,7 +2117,9 @@ static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[
        return 1;
 }
 
-void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
+/* note, scene is the active scene while actual_scene is the scene the object resides in */
+void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
+                                      RigidBodyWorld *rbw)
 {
        if (ob == NULL) return;
        
@@ -2050,14 +2144,17 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
        else {
                BKE_object_to_mat4(ob, ob->obmat);
        }
+
+       /* read values pushed into RBO from sim/cache... */
+       BKE_rigidbody_sync_transforms(rbw, ob, ctime);
        
        /* solve constraints */
        if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
                bConstraintOb *cob;
                
-               cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
-               solve_constraints(&ob->constraints, cob, ctime);
-               constraints_clear_evalob(cob);
+               cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+               BKE_solve_constraints(&ob->constraints, cob, ctime);
+               BKE_constraints_clear_evalob(cob);
        }
        
        /* set negative scale flag in object */
@@ -2065,6 +2162,11 @@ void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
        else ob->transflag &= ~OB_NEG_SCALE;
 }
 
+void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
+{
+       BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL);
+}
+
 /* get object transformation matrix without recalculating dependencies and
  * constraints -- assume dependencies are already solved by depsgraph.
  * no changes to object and it's parent would be done.
@@ -2086,15 +2188,19 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
        }
 }
 
-void BKE_object_where_is_calc(struct Scene *scene, Object *ob)
+void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
 {
-       BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra);
+       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw);
+}
+void BKE_object_where_is_calc(Scene *scene, Object *ob)
+{
+       BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL);
 }
 
-void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
 /* was written for the old game engine (until 2.04) */
 /* It seems that this function is only called
  * for a lamp that is the child of another object */
+void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
 {
        Object *par;
        float *fp1, *fp2;
@@ -2126,9 +2232,9 @@ void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
        if (ob->constraints.first) {
                bConstraintOb *cob;
                
-               cob = constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
-               solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
-               constraints_clear_evalob(cob);
+               cob = BKE_constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
+               BKE_solve_constraints(&ob->constraints, cob, BKE_scene_frame_get(scene));
+               BKE_constraints_clear_evalob(cob);
        }
 }
 
@@ -2300,11 +2406,9 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u
                                bPoseChannel *pchan;
 
                                for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
-
-                                       if ((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE)) {
-                                               /* pass */
-                                       }
-                                       else {
+                                       /* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment
+                                        *     (editarmature.c:2592)... Skip in this case too! */
+                                       if (pchan->bone && !((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE))) {
                                                mul_v3_m4v3(vec, ob->obmat, pchan->pose_head);
                                                minmax_v3v3_v3(min_r, max_r, vec);
                                                mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail);
@@ -2362,7 +2466,7 @@ int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_ma
                ListBase *lb;
                DupliObject *dob;
                
-               lb = object_duplilist(scene, ob);
+               lb = object_duplilist(scene, ob, FALSE);
                for (dob = lb->first; dob; dob = dob->next) {
                        if ((use_hidden == FALSE) && (dob->no_draw != 0)) {
                                /* pass */
@@ -2439,7 +2543,7 @@ void BKE_scene_foreach_display_point(
                                ListBase *lb;
                                DupliObject *dob;
 
-                               lb = object_duplilist(scene, ob);
+                               lb = object_duplilist(scene, ob, FALSE);
                                for (dob = lb->first; dob; dob = dob->next) {
                                        if (dob->no_draw == 0) {
                                                BKE_object_foreach_display_point(dob->ob, dob->mat, func_cb, user_data);
@@ -2526,7 +2630,8 @@ int BKE_object_parent_loop_check(const Object *par, const Object *ob)
 
 /* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
 /* requires flags to be set! */
-void BKE_object_handle_update(Scene *scene, Object *ob)
+/* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
+void BKE_object_handle_update_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
 {
        if (ob->recalc & OB_RECALC_ALL) {
                /* speed optimization for animation lookups */
@@ -2567,15 +2672,13 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
                                        copy_m4_m4(ob->obmat, ob->proxy_from->obmat);
                        }
                        else
-                               BKE_object_where_is_calc(scene, ob);
+                               BKE_object_where_is_calc_ex(scene, rbw, ob);
                }
                
                if (ob->recalc & OB_RECALC_DATA) {
                        ID *data_id = (ID *)ob->data;
                        AnimData *adt = BKE_animdata_from_id(data_id);
-                       float ctime = (float)scene->r.cfra; // XXX this is bad...
-                       ListBase pidlist;
-                       PTCacheID *pid;
+                       float ctime = BKE_scene_frame_get(scene);
                        
                        if (G.debug & G_DEBUG)
                                printf("recalcdata %s\n", ob->id.name + 2);
@@ -2616,8 +2719,10 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
 
                                case OB_ARMATURE:
                                        if (ob->id.lib && ob->proxy_from) {
-                                               // printf("pose proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name);
-                                               BKE_pose_copy_result(ob->pose, ob->proxy_from->pose);
+                                               if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
+                                                       printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
+                                                              ob->id.name + 2, ob->proxy_from->id.name + 2);
+                                               }
                                        }
                                        else {
                                                BKE_pose_where_is(scene, ob);
@@ -2656,6 +2761,8 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
                                        }
                                }
                        }
+                       else if (ob->type == OB_LAMP)
+                               lamp_drivers_update(scene, ob->data, ctime);
                        
                        /* particles */
                        if (ob->particlesystem.first) {
@@ -2698,26 +2805,8 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
                                                psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
                                }
                        }
-
-                       /* check if quick cache is needed */
-                       BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
-
-                       for (pid = pidlist.first; pid; pid = pid->next) {
-                               if ((pid->cache->flag & PTCACHE_BAKED) ||
-                                   (pid->cache->flag & PTCACHE_QUICK_CACHE) == 0)
-                               {
-                                       continue;
-                               }
-
-                               if (pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID) == 0) {
-                                       scene->physics_settings.quick_cache_step =
-                                               scene->physics_settings.quick_cache_step ?
-                                               mini(scene->physics_settings.quick_cache_step, pid->cache->step) :
-                                               pid->cache->step;
-                               }
-                       }
-
-                       BLI_freelistN(&pidlist);
+                       
+                       /* quick cache removed */
                }
 
                /* the no-group proxy case, we call update */
@@ -2737,6 +2826,15 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
                // printf("set proxy pointer for later group stuff %s\n", ob->id.name);
        }
 }
+/* WARNING: "scene" here may not be the scene object actually resides in. 
+ * When dealing with background-sets, "scene" is actually the active scene.
+ * e.g. "scene" <-- set 1 <-- set 2 ("ob" lives here) <-- set 3 <-- ... <-- set n
+ * rigid bodies depend on their world so use BKE_object_handle_update_ex() to also pass along the corrent rigid body world
+ */
+void BKE_object_handle_update(Scene *scene, Object *ob)
+{
+       BKE_object_handle_update_ex(scene, NULL, ob);
+}
 
 void BKE_object_sculpt_modifiers_changed(Object *ob)
 {
@@ -2747,7 +2845,7 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
                 * changing PVBH node organization, we hope topology does not change in
                 * the meantime .. weak */
                if (ss->pbvh) {
-                       BLI_pbvh_free(ss->pbvh);
+                       BKE_pbvh_free(ss->pbvh);
                        ss->pbvh = NULL;
                }
 
@@ -2757,10 +2855,10 @@ void BKE_object_sculpt_modifiers_changed(Object *ob)
                PBVHNode **nodes;
                int n, totnode;
 
-               BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+               BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
 
                for (n = 0; n < totnode; n++)
-                       BLI_pbvh_node_mark_update(nodes[n]);
+                       BKE_pbvh_node_mark_update(nodes[n]);
 
                MEM_freeN(nodes);
        }
@@ -2913,12 +3011,13 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, int
        }
        else {
                /* copy from current values */
-               float *data = do_ob_key(scene, ob);
+               int totelem;
+               float *data = BKE_key_evaluate_object(scene, ob, &totelem);
 
                /* create new block with prepared data */
                kb = BKE_keyblock_add_ctime(key, name, FALSE);
                kb->data = data;
-               kb->totelem = me->totvert;
+               kb->totelem = totelem;
        }
 
        return kb;
@@ -2950,11 +3049,12 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int
        }
        else {
                /* copy from current values */
-               float *data = do_ob_key(scene, ob);
+               int totelem;
+               float *data = BKE_key_evaluate_object(scene, ob, &totelem);
 
                /* create new block with prepared data */
                kb = BKE_keyblock_add_ctime(key, name, FALSE);
-               kb->totelem = lt->pntsu * lt->pntsv * lt->pntsw;
+               kb->totelem = totelem;
                kb->data = data;
        }
 
@@ -2989,11 +3089,12 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int
        }
        else {
                /* copy from current values */
-               float *data = do_ob_key(scene, ob);
+               int totelem;
+               float *data = BKE_key_evaluate_object(scene, ob, &totelem);
 
                /* create new block with prepared data */
                kb = BKE_keyblock_add_ctime(key, name, FALSE);
-               kb->totelem = BKE_nurbList_verts_count(lb);
+               kb->totelem = totelem;
                kb->data = data;
        }
 
@@ -3096,17 +3197,20 @@ void BKE_object_relink(Object *ob)
        if (ob->id.lib)
                return;
 
-       relink_constraints(&ob->constraints);
+       BKE_relink_constraints(&ob->constraints);
        if (ob->pose) {
                bPoseChannel *chan;
                for (chan = ob->pose->chanbase.first; chan; chan = chan->next) {
-                       relink_constraints(&chan->constraints);
+                       BKE_relink_constraints(&chan->constraints);
                }
        }
        modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL);
 
        if (ob->adt)
                BKE_relink_animdata(ob->adt);
+       
+       if (ob->rigidbody_constraint)
+               BKE_rigidbody_relink_constraint(ob->rigidbody_constraint);
 
        ID_NEW(ob->parent);