Testing for the need to quick cache was causing slowdowns on files with many duplis.
[blender.git] / source / blender / blenkernel / intern / object.c
index 4d4ede8a59d002990a7598373e4375911a163186..ef630a18ab4c4c39c90a44a47de0060aa404d28c 100644 (file)
 #include "MEM_guardedalloc.h"
 
 #include "DNA_anim_types.h"
-#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
-#include "DNA_boid_types.h"
 #include "DNA_camera_types.h"
 #include "DNA_constraint_types.h"
-#include "DNA_curve_types.h"
 #include "DNA_group_types.h"
 #include "DNA_key_types.h"
 #include "DNA_lamp_types.h"
 #include "DNA_lattice_types.h"
 #include "DNA_material_types.h"
-#include "DNA_mesh_types.h"
 #include "DNA_meta_types.h"
-#include "DNA_curve_types.h"
 #include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_nla_types.h"
-#include "DNA_object_types.h"
-#include "DNA_object_force.h"
-#include "DNA_object_fluidsim.h"
-#include "DNA_outliner_types.h"
-#include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_sequence_types.h"
 #include "DNA_space_types.h"
-#include "DNA_texture_types.h"
-#include "DNA_userdef_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_world_types.h"
 
 #include "BLI_blenlib.h"
-#include "BLI_math.h"
 #include "BLI_editVert.h"
+#include "BLI_math.h"
+#include "BLI_pbvh.h"
 
 #include "BKE_utildefines.h"
 
 #include "BKE_colortools.h"
 #include "BKE_deform.h"
 #include "BKE_DerivedMesh.h"
-#include "BKE_nla.h"
 #include "BKE_animsys.h"
 #include "BKE_anim.h"
-#include "BKE_blender.h"
 #include "BKE_constraint.h"
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 #include "BKE_property.h"
 #include "BKE_sca.h"
 #include "BKE_scene.h"
-#include "BKE_screen.h"
+#include "BKE_sequencer.h"
 #include "BKE_softbody.h"
 
 #include "LBM_fluidsim.h"
@@ -246,23 +232,26 @@ void object_free_display(Object *ob)
        freedisplist(&ob->disp);
 }
 
-void free_sculptsession(SculptSession **ssp)
+void free_sculptsession(Object *ob)
 {
-       if(ssp && *ssp) {
-               SculptSession *ss = *ssp;
+       if(ob && ob->sculpt) {
+               SculptSession *ss = ob->sculpt;
+               DerivedMesh *dm= ob->derivedFinal;
+
+               if(ss->pbvh)
+                       BLI_pbvh_free(ss->pbvh);
+               if(dm && dm->getPBVH)
+                       dm->getPBVH(NULL, dm); /* signal to clear */
 
                if(ss->texcache)
                        MEM_freeN(ss->texcache);
 
-               if(ss->layer_disps)
-                       MEM_freeN(ss->layer_disps);
-
                if(ss->layer_co)
                        MEM_freeN(ss->layer_co);
 
                MEM_freeN(ss);
 
-               *ssp = NULL;
+               ob->sculpt = NULL;
        }
 }
 
@@ -321,7 +310,7 @@ void free_object(Object *ob)
        if(ob->bsoft) bsbFree(ob->bsoft);
        if(ob->gpulamp.first) GPU_lamp_free(ob);
 
-       free_sculptsession(&ob->sculpt);
+       free_sculptsession(ob);
 
        if(ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
 }
@@ -372,11 +361,6 @@ void unlink_object(Scene *scene, Object *ob)
                        obt->recalc |= OB_RECALC;
                }
                
-               if(obt->track==ob) {
-                       obt->track= NULL;
-                       obt->recalc |= OB_RECALC_OB;
-               }
-               
                modifiers_foreachObjectLink(obt, unlink_object__unlinkModifierLinks, ob);
                
                if ELEM(obt->type, OB_CURVE, OB_FONT) {
@@ -591,7 +575,16 @@ void unlink_object(Scene *scene, Object *ob)
                                }
                        }
 #endif
+                       if(sce->ed) {
+                               Sequence *seq;
+                               SEQ_BEGIN(sce->ed, seq)
+                                       if(seq->scene_camera==ob) {
+                                               seq->scene_camera= NULL;
+                                       }
+                               SEQ_END
+                       }
                }
+
                sce= sce->id.next;
        }
        
@@ -716,9 +709,9 @@ void make_local_camera(Camera *cam)
        int local=0, lib=0;
 
        /* - only lib users: do nothing
-           * - only local users: set flag
-           * - mixed: make copy
-           */
+               * - only local users: set flag
+               * - mixed: make copy
+               */
        
        if(cam->id.lib==0) return;
        if(cam->id.us==1) {
@@ -864,9 +857,9 @@ void make_local_lamp(Lamp *la)
        int local=0, lib=0;
 
        /* - only lib users: do nothing
-           * - only local users: set flag
-           * - mixed: make copy
-           */
+               * - only local users: set flag
+               * - mixed: make copy
+               */
        
        if(la->id.lib==0) return;
        if(la->id.us==1) {
@@ -1362,9 +1355,9 @@ void make_local_object(Object *ob)
        int local=0, lib=0;
 
        /* - only lib users: do nothing
-           * - only local users: set flag
-           * - mixed: make copy
-           */
+               * - only local users: set flag
+               * - mixed: make copy
+               */
        
        if(ob->id.lib==NULL) return;
        
@@ -1772,7 +1765,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
        
        
        /* vec: 4 items! */
-       if( where_on_path(par, ctime, vec, dir, NULL, &radius) ) {
+        if( where_on_path(par, ctime, vec, dir, NULL, &radius) ) {
 
                if(cu->flag & CU_FOLLOW) {
                        vec_to_quat( quat,dir, ob->trackflag, ob->upflag);
@@ -2039,12 +2032,6 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
                object_to_mat4(ob, ob->obmat);
        }
 
-       /* Handle tracking */
-       if(ob->track) {
-               if( ctime != ob->track->ctime) where_is_object_time(scene, ob->track, ctime);
-               solve_tracking (ob, ob->track->obmat);
-       }
-
        /* solve constraints */
        if (ob->constraints.first && !(ob->flag & OB_NO_CONSTRAINTS)) {
                bConstraintOb *cob;
@@ -2139,33 +2126,6 @@ static void solve_parenting (Scene *scene, Object *ob, Object *par, float obmat[
                }
        }
 
-}
-void solve_tracking (Object *ob, float targetmat[][4])
-{
-       float quat[4];
-       float vec[3];
-       float totmat[3][3];
-       float tmat[4][4];
-       
-       sub_v3_v3v3(vec, ob->obmat[3], targetmat[3]);
-       vec_to_quat( quat,vec, ob->trackflag, ob->upflag);
-       quat_to_mat3( totmat,quat);
-       
-       if(ob->parent && (ob->transflag & OB_POWERTRACK)) {
-               /* 'temporal' : clear parent info */
-               object_to_mat4(ob, tmat);
-               tmat[0][3]= ob->obmat[0][3];
-               tmat[1][3]= ob->obmat[1][3];
-               tmat[2][3]= ob->obmat[2][3];
-               tmat[3][0]= ob->obmat[3][0];
-               tmat[3][1]= ob->obmat[3][1];
-               tmat[3][2]= ob->obmat[3][2];
-               tmat[3][3]= ob->obmat[3][3];
-       }
-       else copy_m4_m4(tmat, ob->obmat);
-       
-       mul_m4_m3m4(ob->obmat, totmat, tmat);
-
 }
 
 void where_is_object(struct Scene *scene, Object *ob)
@@ -2187,12 +2147,6 @@ for a lamp that is the child of another object */
        int a;
        
        /* NO TIMEOFFS */
-       
-       /* no ipo! (because of dloc and realtime-ipos) */
-               // XXX old animation system
-       //ipo= ob->ipo;
-       //ob->ipo= NULL;
-
        if(ob->parent) {
                par= ob->parent;
                
@@ -2214,9 +2168,6 @@ for a lamp that is the child of another object */
                object_to_mat4(ob, ob->obmat);
        }
        
-       if(ob->track) 
-               solve_tracking(ob, ob->track->obmat);
-
        /* solve constraints */
        if (ob->constraints.first) {
                bConstraintOb *cob;
@@ -2225,10 +2176,6 @@ for a lamp that is the child of another object */
                solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
                constraints_clear_evalob(cob);
        }
-       
-       /*  WATCH IT!!! */
-               // XXX old animation system
-       //ob->ipo= ipo;
 }
 
 /* for calculation of the inverse parent transform, only used for editor */
@@ -2240,7 +2187,6 @@ void what_does_parent(Scene *scene, Object *ob, Object *workob)
        unit_m4(workob->parentinv);
        unit_m4(workob->constinv);
        workob->parent= ob->parent;
-       workob->track= ob->track;
 
        workob->trackflag= ob->trackflag;
        workob->upflag= ob->upflag;
@@ -2307,6 +2253,44 @@ void object_boundbox_flag(Object *ob, int flag, int set)
        }
 }
 
+void object_get_dimensions(Object *ob, float *value)
+{
+       BoundBox *bb = NULL;
+       
+       bb= object_get_boundbox(ob);
+       if (bb) {
+               float scale[3];
+               
+               mat4_to_size( scale,ob->obmat);
+               
+               value[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
+               value[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
+               value[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
+       } else {
+               value[0] = value[1] = value[2] = 0.f;
+       }
+}
+
+void object_set_dimensions(Object *ob, const float *value)
+{
+       BoundBox *bb = NULL;
+       
+       bb= object_get_boundbox(ob);
+       if (bb) {
+               float scale[3], len[3];
+               
+               mat4_to_size( scale,ob->obmat);
+               
+               len[0] = bb->vec[4][0] - bb->vec[0][0];
+               len[1] = bb->vec[2][1] - bb->vec[0][1];
+               len[2] = bb->vec[1][2] - bb->vec[0][2];
+               
+               if (len[0] > 0.f) ob->size[0] = value[0] / len[0];
+               if (len[1] > 0.f) ob->size[1] = value[1] / len[1];
+               if (len[2] > 0.f) ob->size[2] = value[2] / len[2];
+       }
+}
+
 void minmax_object(Object *ob, float *min, float *max)
 {
        BoundBox bb;
@@ -2475,7 +2459,10 @@ void object_tfm_restore(Object *ob, void *obtfm_pt)
 void object_handle_update(Scene *scene, Object *ob)
 {
        if(ob->recalc & OB_RECALC) {
-               
+               /* speed optimization for animation lookups */
+               if(ob->pose)
+                       make_pose_channels_hash(ob->pose);
+
                /* XXX new animsys warning: depsgraph tag OB_RECALC_DATA should not skip drivers, 
                   which is only in where_is_object now */
                if(ob->recalc & OB_RECALC) {
@@ -2502,6 +2489,8 @@ void object_handle_update(Scene *scene, Object *ob)
                        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;
                        
                        if (G.f & G_DEBUG)
                                printf("recalcdata %s\n", ob->id.name+2);
@@ -2515,7 +2504,7 @@ void object_handle_update(Scene *scene, Object *ob)
                                BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS);
                                
                                        // here was vieweditdatamask? XXX
-                               if(ob->mode & OB_MODE_EDIT) {
+                               if(em) {
                                        makeDerivedMesh(scene, ob, em, CD_MASK_BAREMESH);
                                        BKE_mesh_end_editmesh(ob->data, em);
                                } else
@@ -2590,6 +2579,24 @@ void 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 ?
+                                               MIN2(scene->physics_settings.quick_cache_step, pid->cache->step) :
+                                               pid->cache->step;
+                               }
+                       }
+
+                       BLI_freelistN(&pidlist);
                }
 
                /* the no-group proxy case, we call update */
@@ -2787,8 +2794,8 @@ void object_camera_matrix(
                pixsize= cam->ortho_scale/viewfac;
        }
        else {
-               if(rd->xasp*winx >= rd->yasp*winy)      viewfac= (winx*(*lens))/32.0;
-               else                                                            viewfac= (*ycor) * (winy*(*lens))/32.0;
+               if(rd->xasp*winx >= rd->yasp*winy)      viewfac= ((*lens) * winx)/32.0;
+               else                                                            viewfac= (*ycor) * ((*lens) * winy)/32.0;
                pixsize= (*clipsta) / viewfac;
        }
 
@@ -2801,20 +2808,20 @@ void object_camera_matrix(
 
        if(field_second) {
                if(rd->mode & R_ODDFIELD) {
-                       viewplane->ymin-= .5 * (*ycor);
-                       viewplane->ymax-= .5 * (*ycor);
+                       viewplane->ymin-= 0.5 * (*ycor);
+                       viewplane->ymax-= 0.5 * (*ycor);
                }
                else {
-                       viewplane->ymin+= .5* (*ycor);
-                       viewplane->ymax+= .5* (*ycor);
+                       viewplane->ymin+= 0.5 * (*ycor);
+                       viewplane->ymax+= 0.5 * (*ycor);
                }
        }
        /* the window matrix is used for clipping, and not changed during OSA steps */
        /* using an offset of +0.5 here would give clip errors on edges */
-       viewplane->xmin= pixsize*(viewplane->xmin);
-       viewplane->xmax= pixsize*(viewplane->xmax);
-       viewplane->ymin= pixsize*(viewplane->ymin);
-       viewplane->ymax= pixsize*(viewplane->ymax);
+       viewplane->xmin *= pixsize;
+       viewplane->xmax *= pixsize;
+       viewplane->ymin *= pixsize;
+       viewplane->ymax *= pixsize;
 
        (*viewdx)= pixsize;
        (*viewdy)= (*ycor) * pixsize;