Blender V2.61 - r43446

object.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): none yet.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <string.h>
00034 #include <math.h>
00035 #include <stdio.h>          
00036 
00037 #include "MEM_guardedalloc.h"
00038 
00039 #include "DNA_anim_types.h"
00040 #include "DNA_armature_types.h"
00041 #include "DNA_camera_types.h"
00042 #include "DNA_constraint_types.h"
00043 #include "DNA_group_types.h"
00044 #include "DNA_key_types.h"
00045 #include "DNA_lattice_types.h"
00046 #include "DNA_material_types.h"
00047 #include "DNA_meta_types.h"
00048 #include "DNA_meshdata_types.h"
00049 #include "DNA_movieclip_types.h"
00050 #include "DNA_scene_types.h"
00051 #include "DNA_screen_types.h"
00052 #include "DNA_sequence_types.h"
00053 #include "DNA_smoke_types.h"
00054 #include "DNA_sound_types.h"
00055 #include "DNA_space_types.h"
00056 #include "DNA_view3d_types.h"
00057 #include "DNA_world_types.h"
00058 
00059 #include "BLI_blenlib.h"
00060 #include "BLI_bpath.h"
00061 #include "BLI_editVert.h"
00062 #include "BLI_math.h"
00063 #include "BLI_pbvh.h"
00064 #include "BLI_utildefines.h"
00065 
00066 #include "BKE_main.h"
00067 #include "BKE_global.h"
00068 #include "BKE_idprop.h"
00069 #include "BKE_armature.h"
00070 #include "BKE_action.h"
00071 #include "BKE_bullet.h"
00072 #include "BKE_colortools.h"
00073 #include "BKE_deform.h"
00074 #include "BKE_DerivedMesh.h"
00075 #include "BKE_animsys.h"
00076 #include "BKE_anim.h"
00077 #include "BKE_constraint.h"
00078 #include "BKE_curve.h"
00079 #include "BKE_displist.h"
00080 #include "BKE_effect.h"
00081 #include "BKE_fcurve.h"
00082 #include "BKE_group.h"
00083 #include "BKE_icons.h"
00084 #include "BKE_key.h"
00085 #include "BKE_lamp.h"
00086 #include "BKE_lattice.h"
00087 #include "BKE_library.h"
00088 #include "BKE_mesh.h"
00089 #include "BKE_mball.h"
00090 #include "BKE_modifier.h"
00091 #include "BKE_node.h"
00092 #include "BKE_object.h"
00093 #include "BKE_paint.h"
00094 #include "BKE_particle.h"
00095 #include "BKE_pointcache.h"
00096 #include "BKE_property.h"
00097 #include "BKE_sca.h"
00098 #include "BKE_scene.h"
00099 #include "BKE_sequencer.h"
00100 #include "BKE_speaker.h"
00101 #include "BKE_softbody.h"
00102 #include "BKE_material.h"
00103 #include "BKE_camera.h"
00104 
00105 #include "LBM_fluidsim.h"
00106 
00107 #ifdef WITH_PYTHON
00108 #include "BPY_extern.h"
00109 #endif
00110 
00111 #include "GPU_material.h"
00112 
00113 /* Local function protos */
00114 static void solve_parenting (Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul);
00115 
00116 float originmat[3][3];  /* after where_is_object(), can be used in other functions (bad!) */
00117 
00118 void clear_workob(Object *workob)
00119 {
00120     memset(workob, 0, sizeof(Object));
00121     
00122     workob->size[0]= workob->size[1]= workob->size[2]= 1.0f;
00123     workob->dscale[0]= workob->dscale[1]= workob->dscale[2]= 1.0f;
00124     workob->rotmode= ROT_MODE_EUL;
00125 }
00126 
00127 void copy_baseflags(struct Scene *scene)
00128 {
00129     Base *base= scene->base.first;
00130     
00131     while(base) {
00132         base->object->flag= base->flag;
00133         base= base->next;
00134     }
00135 }
00136 
00137 void copy_objectflags(struct Scene *scene)
00138 {
00139     Base *base= scene->base.first;
00140     
00141     while(base) {
00142         base->flag= base->object->flag;
00143         base= base->next;
00144     }
00145 }
00146 
00147 void update_base_layer(struct Scene *scene, Object *ob)
00148 {
00149     Base *base= scene->base.first;
00150 
00151     while (base) {
00152         if (base->object == ob) base->lay= ob->lay;
00153         base= base->next;
00154     }
00155 }
00156 
00157 void object_free_particlesystems(Object *ob)
00158 {
00159     while(ob->particlesystem.first){
00160         ParticleSystem *psys = ob->particlesystem.first;
00161         
00162         BLI_remlink(&ob->particlesystem,psys);
00163         
00164         psys_free(ob,psys);
00165     }
00166 }
00167 
00168 void object_free_softbody(Object *ob)
00169 {
00170     if(ob->soft) {
00171         sbFree(ob->soft);
00172         ob->soft= NULL;
00173     }
00174 }
00175 
00176 void object_free_bulletsoftbody(Object *ob)
00177 {
00178     if(ob->bsoft) {
00179         bsbFree(ob->bsoft);
00180         ob->bsoft= NULL;
00181     }
00182 }
00183 
00184 void object_free_modifiers(Object *ob)
00185 {
00186     while (ob->modifiers.first) {
00187         ModifierData *md = ob->modifiers.first;
00188         
00189         BLI_remlink(&ob->modifiers, md);
00190         
00191         modifier_free(md);
00192     }
00193 
00194     /* particle modifiers were freed, so free the particlesystems as well */
00195     object_free_particlesystems(ob);
00196 
00197     /* same for softbody */
00198     object_free_softbody(ob);
00199 }
00200 
00201 void object_link_modifiers(struct Object *ob, struct Object *from)
00202 {
00203     ModifierData *md;
00204     object_free_modifiers(ob);
00205 
00206     for (md=from->modifiers.first; md; md=md->next) {
00207         ModifierData *nmd = NULL;
00208 
00209         if(ELEM4(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance, eModifierType_Collision)) continue;
00210 
00211         nmd = modifier_new(md->type);
00212         modifier_copyData(md, nmd);
00213         BLI_addtail(&ob->modifiers, nmd);
00214     }
00215 
00216     copy_object_particlesystems(ob, from);
00217     copy_object_softbody(ob, from);
00218 
00219     // TODO: smoke?, cloth?
00220 }
00221 
00222 /* here we will collect all local displist stuff */
00223 /* also (ab)used in depsgraph */
00224 void object_free_display(Object *ob)
00225 {
00226     if(ob->derivedDeform) {
00227         ob->derivedDeform->needsFree = 1;
00228         ob->derivedDeform->release(ob->derivedDeform);
00229         ob->derivedDeform= NULL;
00230     }
00231     if(ob->derivedFinal) {
00232         ob->derivedFinal->needsFree = 1;
00233         ob->derivedFinal->release(ob->derivedFinal);
00234         ob->derivedFinal= NULL;
00235     }
00236     
00237     freedisplist(&ob->disp);
00238 }
00239 
00240 void free_sculptsession_deformMats(SculptSession *ss)
00241 {
00242     if(ss->orig_cos) MEM_freeN(ss->orig_cos);
00243     if(ss->deform_cos) MEM_freeN(ss->deform_cos);
00244     if(ss->deform_imats) MEM_freeN(ss->deform_imats);
00245 
00246     ss->orig_cos = NULL;
00247     ss->deform_cos = NULL;
00248     ss->deform_imats = NULL;
00249 }
00250 
00251 void free_sculptsession(Object *ob)
00252 {
00253     if(ob && ob->sculpt) {
00254         SculptSession *ss = ob->sculpt;
00255         DerivedMesh *dm= ob->derivedFinal;
00256 
00257         if(ss->pbvh)
00258             BLI_pbvh_free(ss->pbvh);
00259         if(dm && dm->getPBVH)
00260             dm->getPBVH(NULL, dm); /* signal to clear */
00261 
00262         if(ss->texcache)
00263             MEM_freeN(ss->texcache);
00264 
00265         if(ss->layer_co)
00266             MEM_freeN(ss->layer_co);
00267 
00268         if(ss->orig_cos)
00269             MEM_freeN(ss->orig_cos);
00270         if(ss->deform_cos)
00271             MEM_freeN(ss->deform_cos);
00272         if(ss->deform_imats)
00273             MEM_freeN(ss->deform_imats);
00274 
00275         MEM_freeN(ss);
00276 
00277         ob->sculpt = NULL;
00278     }
00279 }
00280 
00281 
00282 /* do not free object itself */
00283 void free_object(Object *ob)
00284 {
00285     int a;
00286     
00287     object_free_display(ob);
00288     
00289     /* disconnect specific data */
00290     if(ob->data) {
00291         ID *id= ob->data;
00292         id->us--;
00293         if(id->us==0) {
00294             if(ob->type==OB_MESH) unlink_mesh(ob->data);
00295             else if(ob->type==OB_CURVE) unlink_curve(ob->data);
00296             else if(ob->type==OB_MBALL) unlink_mball(ob->data);
00297         }
00298         ob->data= NULL;
00299     }
00300     
00301     for(a=0; a<ob->totcol; a++) {
00302         if(ob->mat[a]) ob->mat[a]->id.us--;
00303     }
00304     if(ob->mat) MEM_freeN(ob->mat);
00305     if(ob->matbits) MEM_freeN(ob->matbits);
00306     ob->mat= NULL;
00307     ob->matbits= NULL;
00308     if(ob->bb) MEM_freeN(ob->bb); 
00309     ob->bb= NULL;
00310     if(ob->adt) BKE_free_animdata((ID *)ob);
00311     if(ob->poselib) ob->poselib->id.us--;
00312     if(ob->gpd) ((ID *)ob->gpd)->us--;
00313     if(ob->defbase.first)
00314         BLI_freelistN(&ob->defbase);
00315     if(ob->pose)
00316         free_pose(ob->pose);
00317     if(ob->mpath)
00318         animviz_free_motionpath(ob->mpath);
00319     free_properties(&ob->prop);
00320     object_free_modifiers(ob);
00321     
00322     free_sensors(&ob->sensors);
00323     free_controllers(&ob->controllers);
00324     free_actuators(&ob->actuators);
00325     
00326     free_constraints(&ob->constraints);
00327     
00328     free_partdeflect(ob->pd);
00329 
00330     if(ob->soft) sbFree(ob->soft);
00331     if(ob->bsoft) bsbFree(ob->bsoft);
00332     if(ob->gpulamp.first) GPU_lamp_free(ob);
00333 
00334     free_sculptsession(ob);
00335 
00336     if(ob->pc_ids.first) BLI_freelistN(&ob->pc_ids);
00337 }
00338 
00339 static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Object **obpoin)
00340 {
00341     Object *unlinkOb = userData;
00342 
00343     if (*obpoin==unlinkOb) {
00344         *obpoin = NULL;
00345         ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; // XXX: should this just be OB_RECALC_DATA?
00346     }
00347 }
00348 
00349 void unlink_object(Object *ob)
00350 {
00351     Main *bmain= G.main;
00352     Object *obt;
00353     Material *mat;
00354     World *wrld;
00355     bScreen *sc;
00356     Scene *sce;
00357     Curve *cu;
00358     Tex *tex;
00359     Group *group;
00360     Camera *camera;
00361     bConstraint *con;
00362     //bActionStrip *strip; // XXX animsys 
00363     ModifierData *md;
00364     ARegion *ar;
00365     RegionView3D *rv3d;
00366     int a, found;
00367     
00368     unlink_controllers(&ob->controllers);
00369     unlink_actuators(&ob->actuators);
00370     
00371     /* check all objects: parents en bevels and fields, also from libraries */
00372     // FIXME: need to check all animation blocks (drivers)
00373     obt= bmain->object.first;
00374     while(obt) {
00375         if(obt->proxy==ob)
00376             obt->proxy= NULL;
00377         if(obt->proxy_from==ob) {
00378             obt->proxy_from= NULL;
00379             obt->recalc |= OB_RECALC_OB;
00380         }
00381         if(obt->proxy_group==ob)
00382             obt->proxy_group= NULL;
00383         
00384         if(obt->parent==ob) {
00385             obt->parent= NULL;
00386             obt->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
00387         }
00388         
00389         modifiers_foreachObjectLink(obt, unlink_object__unlinkModifierLinks, ob);
00390         
00391         if ELEM(obt->type, OB_CURVE, OB_FONT) {
00392             cu= obt->data;
00393 
00394             if(cu->bevobj==ob) {
00395                 cu->bevobj= NULL;
00396                 obt->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
00397             }
00398             if(cu->taperobj==ob) {
00399                 cu->taperobj= NULL;
00400                 obt->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
00401             }
00402             if(cu->textoncurve==ob) {
00403                 cu->textoncurve= NULL;
00404                 obt->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
00405             }
00406         }
00407         else if(obt->type==OB_ARMATURE && obt->pose) {
00408             bPoseChannel *pchan;
00409             for(pchan= obt->pose->chanbase.first; pchan; pchan= pchan->next) {
00410                 for (con = pchan->constraints.first; con; con=con->next) {
00411                     bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
00412                     ListBase targets = {NULL, NULL};
00413                     bConstraintTarget *ct;
00414                     
00415                     if (cti && cti->get_constraint_targets) {
00416                         cti->get_constraint_targets(con, &targets);
00417                         
00418                         for (ct= targets.first; ct; ct= ct->next) {
00419                             if (ct->tar == ob) {
00420                                 ct->tar = NULL;
00421                                 ct->subtarget[0]= '\0';
00422                                 obt->recalc |= OB_RECALC_DATA;
00423                             }
00424                         }
00425                         
00426                         if (cti->flush_constraint_targets)
00427                             cti->flush_constraint_targets(con, &targets, 0);
00428                     }
00429                 }
00430                 if(pchan->custom==ob)
00431                     pchan->custom= NULL;
00432             }
00433         } 
00434         else if(ELEM(OB_MBALL, ob->type, obt->type)) {
00435             if(is_mball_basis_for(obt, ob))
00436                 obt->recalc|= OB_RECALC_DATA;
00437         }
00438         
00439         sca_remove_ob_poin(obt, ob);
00440         
00441         for (con = obt->constraints.first; con; con=con->next) {
00442             bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
00443             ListBase targets = {NULL, NULL};
00444             bConstraintTarget *ct;
00445             
00446             if (cti && cti->get_constraint_targets) {
00447                 cti->get_constraint_targets(con, &targets);
00448                 
00449                 for (ct= targets.first; ct; ct= ct->next) {
00450                     if (ct->tar == ob) {
00451                         ct->tar = NULL;
00452                         ct->subtarget[0]= '\0';
00453                         obt->recalc |= OB_RECALC_DATA;
00454                     }
00455                 }
00456                 
00457                 if (cti->flush_constraint_targets)
00458                     cti->flush_constraint_targets(con, &targets, 0);
00459             }
00460         }
00461         
00462         /* object is deflector or field */
00463         if(ob->pd) {
00464             if(obt->soft)
00465                 obt->recalc |= OB_RECALC_DATA;
00466 
00467             /* cloth */
00468             for(md=obt->modifiers.first; md; md=md->next)
00469                 if(md->type == eModifierType_Cloth)
00470                     obt->recalc |= OB_RECALC_DATA;
00471         }
00472         
00473         /* strips */
00474 #if 0 // XXX old animation system
00475         for(strip= obt->nlastrips.first; strip; strip= strip->next) {
00476             if(strip->object==ob)
00477                 strip->object= NULL;
00478             
00479             if(strip->modifiers.first) {
00480                 bActionModifier *amod;
00481                 for(amod= strip->modifiers.first; amod; amod= amod->next)
00482                     if(amod->ob==ob)
00483                         amod->ob= NULL;
00484             }
00485         }
00486 #endif // XXX old animation system
00487 
00488         /* particle systems */
00489         if(obt->particlesystem.first) {
00490             ParticleSystem *tpsys= obt->particlesystem.first;
00491             for(; tpsys; tpsys=tpsys->next) {
00492                 BoidState *state = NULL;
00493                 BoidRule *rule = NULL;
00494 
00495                 ParticleTarget *pt = tpsys->targets.first;
00496                 for(; pt; pt=pt->next) {
00497                     if(pt->ob==ob) {
00498                         pt->ob = NULL;
00499                         obt->recalc |= OB_RECALC_DATA;
00500                         break;
00501                     }
00502                 }
00503 
00504                 if(tpsys->target_ob==ob) {
00505                     tpsys->target_ob= NULL;
00506                     obt->recalc |= OB_RECALC_DATA;
00507                 }
00508 
00509                 if(tpsys->part->dup_ob==ob)
00510                     tpsys->part->dup_ob= NULL;
00511 
00512                 if(tpsys->part->phystype==PART_PHYS_BOIDS) {
00513                     ParticleData *pa;
00514                     BoidParticle *bpa;
00515                     int p;
00516 
00517                     for(p=0,pa=tpsys->particles; p<tpsys->totpart; p++,pa++) {
00518                         bpa = pa->boid;
00519                         if(bpa->ground == ob)
00520                             bpa->ground = NULL;
00521                     }
00522                 }
00523                 if(tpsys->part->boids) {
00524                     for(state = tpsys->part->boids->states.first; state; state=state->next) {
00525                         for(rule = state->rules.first; rule; rule=rule->next) {
00526                             if(rule->type==eBoidRuleType_Avoid) {
00527                                 BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid*)rule;
00528                                 if(gabr->ob==ob)
00529                                     gabr->ob= NULL;
00530                             }
00531                             else if(rule->type==eBoidRuleType_FollowLeader) {
00532                                 BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader*)rule;
00533                                 if(flbr->ob==ob)
00534                                     flbr->ob= NULL;
00535                             }
00536                         }
00537                     }
00538                 }
00539             }
00540             if(ob->pd)
00541                 obt->recalc |= OB_RECALC_DATA;
00542         }
00543 
00544         obt= obt->id.next;
00545     }
00546     
00547     /* materials */
00548     mat= bmain->mat.first;
00549     while(mat) {
00550     
00551         for(a=0; a<MAX_MTEX; a++) {
00552             if(mat->mtex[a] && ob==mat->mtex[a]->object) {
00553                 /* actually, test for lib here... to do */
00554                 mat->mtex[a]->object= NULL;
00555             }
00556         }
00557 
00558         mat= mat->id.next;
00559     }
00560     
00561     /* textures */
00562     for(tex= bmain->tex.first; tex; tex= tex->id.next) {
00563         if(tex->env && (ob==tex->env->object)) tex->env->object= NULL;
00564         if(tex->pd  && (ob==tex->pd->object))  tex->pd->object= NULL;
00565         if(tex->vd  && (ob==tex->vd->object))  tex->vd->object= NULL;
00566     }
00567 
00568     /* worlds */
00569     wrld= bmain->world.first;
00570     while(wrld) {
00571         if(wrld->id.lib==NULL) {
00572             for(a=0; a<MAX_MTEX; a++) {
00573                 if(wrld->mtex[a] && ob==wrld->mtex[a]->object)
00574                     wrld->mtex[a]->object= NULL;
00575             }
00576         }
00577         
00578         wrld= wrld->id.next;
00579     }
00580         
00581     /* scenes */
00582     sce= bmain->scene.first;
00583     while(sce) {
00584         if(sce->id.lib==NULL) {
00585             if(sce->camera==ob) sce->camera= NULL;
00586             if(sce->toolsettings->skgen_template==ob) sce->toolsettings->skgen_template = NULL;
00587             if(sce->toolsettings->particle.object==ob) sce->toolsettings->particle.object= NULL;
00588 
00589 #ifdef DURIAN_CAMERA_SWITCH
00590             {
00591                 TimeMarker *m;
00592 
00593                 for (m= sce->markers.first; m; m= m->next) {
00594                     if(m->camera==ob)
00595                         m->camera= NULL;
00596                 }
00597             }
00598 #endif
00599             if(sce->ed) {
00600                 Sequence *seq;
00601                 SEQ_BEGIN(sce->ed, seq)
00602                     if(seq->scene_camera==ob) {
00603                         seq->scene_camera= NULL;
00604                     }
00605                 SEQ_END
00606             }
00607         }
00608 
00609         sce= sce->id.next;
00610     }
00611     
00612     /* screens */
00613     sc= bmain->screen.first;
00614     while(sc) {
00615         ScrArea *sa= sc->areabase.first;
00616         while(sa) {
00617             SpaceLink *sl;
00618 
00619             for (sl= sa->spacedata.first; sl; sl= sl->next) {
00620                 if(sl->spacetype==SPACE_VIEW3D) {
00621                     View3D *v3d= (View3D*) sl;
00622 
00623                     found= 0;
00624                     if(v3d->camera==ob) {
00625                         v3d->camera= NULL;
00626                         found= 1;
00627                     }
00628                     if(v3d->localvd && v3d->localvd->camera==ob ) {
00629                         v3d->localvd->camera= NULL;
00630                         found += 2;
00631                     }
00632 
00633                     if (found) {
00634                         if (sa->spacetype == SPACE_VIEW3D) {
00635                             for (ar= sa->regionbase.first; ar; ar= ar->next) {
00636                                 if (ar->regiontype==RGN_TYPE_WINDOW) {
00637                                     rv3d= (RegionView3D *)ar->regiondata;
00638                                     if (found == 1 || found == 3) {
00639                                         if (rv3d->persp == RV3D_CAMOB)
00640                                             rv3d->persp= RV3D_PERSP;
00641                                     }
00642                                     if (found == 2 || found == 3) {
00643                                         if (rv3d->localvd && rv3d->localvd->persp == RV3D_CAMOB)
00644                                             rv3d->localvd->persp= RV3D_PERSP;
00645                                     }
00646                                 }
00647                             }
00648                         }
00649                     }
00650                 }
00651                 else if(sl->spacetype==SPACE_OUTLINER) {
00652                     SpaceOops *so= (SpaceOops *)sl;
00653 
00654                     if(so->treestore) {
00655                         TreeStoreElem *tselem= so->treestore->data;
00656                         int a;
00657                         for(a=0; a<so->treestore->usedelem; a++, tselem++) {
00658                             if(tselem->id==(ID *)ob) tselem->id= NULL;
00659                         }
00660                     }
00661                 }
00662                 else if(sl->spacetype==SPACE_BUTS) {
00663                     SpaceButs *sbuts= (SpaceButs *)sl;
00664 
00665                     if(sbuts->pinid==(ID *)ob) {
00666                         sbuts->flag&= ~SB_PIN_CONTEXT;
00667                         sbuts->pinid= NULL;
00668                     }
00669                 }
00670             }
00671 
00672             sa= sa->next;
00673         }
00674         sc= sc->id.next;
00675     }
00676 
00677     /* groups */
00678     group= bmain->group.first;
00679     while(group) {
00680         rem_from_group(group, ob, NULL, NULL);
00681         group= group->id.next;
00682     }
00683     
00684     /* cameras */
00685     camera= bmain->camera.first;
00686     while(camera) {
00687         if (camera->dof_ob==ob) {
00688             camera->dof_ob = NULL;
00689         }
00690         camera= camera->id.next;
00691     }
00692 }
00693 
00694 int exist_object(Object *obtest)
00695 {
00696     Object *ob;
00697     
00698     if(obtest==NULL) return 0;
00699     
00700     ob= G.main->object.first;
00701     while(ob) {
00702         if(ob==obtest) return 1;
00703         ob= ob->id.next;
00704     }
00705     return 0;
00706 }
00707 
00708 /* *************************************************** */
00709 
00710 static void *add_obdata_from_type(int type)
00711 {
00712     switch (type) {
00713     case OB_MESH: return add_mesh("Mesh");
00714     case OB_CURVE: return add_curve("Curve", OB_CURVE);
00715     case OB_SURF: return add_curve("Surf", OB_SURF);
00716     case OB_FONT: return add_curve("Text", OB_FONT);
00717     case OB_MBALL: return add_mball("Meta");
00718     case OB_CAMERA: return add_camera("Camera");
00719     case OB_LAMP: return add_lamp("Lamp");
00720     case OB_LATTICE: return add_lattice("Lattice");
00721     case OB_ARMATURE: return add_armature("Armature");
00722     case OB_SPEAKER: return add_speaker("Speaker");
00723     case OB_EMPTY: return NULL;
00724     default:
00725         printf("add_obdata_from_type: Internal error, bad type: %d\n", type);
00726         return NULL;
00727     }
00728 }
00729 
00730 static const char *get_obdata_defname(int type)
00731 {
00732     switch (type) {
00733     case OB_MESH: return "Mesh";
00734     case OB_CURVE: return "Curve";
00735     case OB_SURF: return "Surf";
00736     case OB_FONT: return "Text";
00737     case OB_MBALL: return "Mball";
00738     case OB_CAMERA: return "Camera";
00739     case OB_LAMP: return "Lamp";
00740     case OB_LATTICE: return "Lattice";
00741     case OB_ARMATURE: return "Armature";
00742     case OB_SPEAKER: return "Speaker";
00743     case OB_EMPTY: return "Empty";
00744     default:
00745         printf("get_obdata_defname: Internal error, bad type: %d\n", type);
00746         return "Empty";
00747     }
00748 }
00749 
00750 /* more general add: creates minimum required data, but without vertices etc. */
00751 Object *add_only_object(int type, const char *name)
00752 {
00753     Object *ob;
00754 
00755     ob= alloc_libblock(&G.main->object, ID_OB, name);
00756 
00757     /* default object vars */
00758     ob->type= type;
00759     
00760     ob->col[0]= ob->col[1]= ob->col[2]= 1.0;
00761     ob->col[3]= 1.0;
00762     
00763     ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
00764     ob->dscale[0]= ob->dscale[1]= ob->dscale[2]= 1.0;
00765     
00766     /* objects should default to having Euler XYZ rotations, 
00767      * but rotations default to quaternions 
00768      */
00769     ob->rotmode= ROT_MODE_EUL;
00770 
00771     unit_axis_angle(ob->rotAxis, &ob->rotAngle);
00772     unit_axis_angle(ob->drotAxis, &ob->drotAngle);
00773 
00774     unit_qt(ob->quat);
00775     unit_qt(ob->dquat);
00776 
00777     /* rotation locks should be 4D for 4 component rotations by default... */
00778     ob->protectflag = OB_LOCK_ROT4D;
00779     
00780     unit_m4(ob->constinv);
00781     unit_m4(ob->parentinv);
00782     unit_m4(ob->obmat);
00783     ob->dt= OB_TEXTURE;
00784     ob->empty_drawtype= OB_PLAINAXES;
00785     ob->empty_drawsize= 1.0;
00786 
00787     if(type==OB_CAMERA || type==OB_LAMP || type==OB_SPEAKER) {
00788         ob->trackflag= OB_NEGZ;
00789         ob->upflag= OB_POSY;
00790     }
00791     else {
00792         ob->trackflag= OB_POSY;
00793         ob->upflag= OB_POSZ;
00794     }
00795     
00796     ob->dupon= 1; ob->dupoff= 0;
00797     ob->dupsta= 1; ob->dupend= 100;
00798     ob->dupfacesca = 1.0;
00799 
00800     /* Game engine defaults*/
00801     ob->mass= ob->inertia= 1.0f;
00802     ob->formfactor= 0.4f;
00803     ob->damping= 0.04f;
00804     ob->rdamping= 0.1f;
00805     ob->anisotropicFriction[0] = 1.0f;
00806     ob->anisotropicFriction[1] = 1.0f;
00807     ob->anisotropicFriction[2] = 1.0f;
00808     ob->gameflag= OB_PROP|OB_COLLISION;
00809     ob->margin = 0.0;
00810     ob->init_state=1;
00811     ob->state=1;
00812     /* ob->pad3 == Contact Processing Threshold */
00813     ob->m_contactProcessingThreshold = 1.;
00814     ob->obstacleRad = 1.;
00815     
00816     /* NT fluid sim defaults */
00817     ob->fluidsimSettings = NULL;
00818 
00819     ob->pc_ids.first = ob->pc_ids.last = NULL;
00820     
00821     /* Animation Visualisation defaults */
00822     animviz_settings_init(&ob->avs);
00823 
00824     return ob;
00825 }
00826 
00827 /* general add: to scene, with layer from area and default name */
00828 /* creates minimum required data, but without vertices etc. */
00829 Object *add_object(struct Scene *scene, int type)
00830 {
00831     Object *ob;
00832     Base *base;
00833     char name[MAX_ID_NAME];
00834 
00835     BLI_strncpy(name, get_obdata_defname(type), sizeof(name));
00836     ob = add_only_object(type, name);
00837 
00838     ob->data= add_obdata_from_type(type);
00839 
00840     ob->lay= scene->lay;
00841     
00842     base= scene_add_base(scene, ob);
00843     scene_select_base(scene, base);
00844     ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
00845 
00846     return ob;
00847 }
00848 
00849 SoftBody *copy_softbody(SoftBody *sb)
00850 {
00851     SoftBody *sbn;
00852     
00853     if (sb==NULL) return(NULL);
00854     
00855     sbn= MEM_dupallocN(sb);
00856     sbn->totspring= sbn->totpoint= 0;
00857     sbn->bpoint= NULL;
00858     sbn->bspring= NULL;
00859     
00860     sbn->keys= NULL;
00861     sbn->totkey= sbn->totpointkey= 0;
00862     
00863     sbn->scratch= NULL;
00864 
00865     sbn->pointcache= BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches);
00866 
00867     if(sb->effector_weights)
00868         sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
00869 
00870     return sbn;
00871 }
00872 
00873 BulletSoftBody *copy_bulletsoftbody(BulletSoftBody *bsb)
00874 {
00875     BulletSoftBody *bsbn;
00876 
00877     if (bsb == NULL)
00878         return NULL;
00879     bsbn = MEM_dupallocN(bsb);
00880     /* no pointer in this structure yet */
00881     return bsbn;
00882 }
00883 
00884 static ParticleSystem *copy_particlesystem(ParticleSystem *psys)
00885 {
00886     ParticleSystem *psysn;
00887     ParticleData *pa;
00888     int p;
00889 
00890     psysn= MEM_dupallocN(psys);
00891     psysn->particles= MEM_dupallocN(psys->particles);
00892     psysn->child= MEM_dupallocN(psys->child);
00893 
00894     if(psys->part->type == PART_HAIR) {
00895         for(p=0, pa=psysn->particles; p<psysn->totpart; p++, pa++)
00896             pa->hair = MEM_dupallocN(pa->hair);
00897     }
00898 
00899     if(psysn->particles && (psysn->particles->keys || psysn->particles->boid)) {
00900         ParticleKey *key = psysn->particles->keys;
00901         BoidParticle *boid = psysn->particles->boid;
00902 
00903         if(key)
00904             key = MEM_dupallocN(key);
00905         
00906         if(boid)
00907             boid = MEM_dupallocN(boid);
00908         
00909         for(p=0, pa=psysn->particles; p<psysn->totpart; p++, pa++) {
00910             if(boid)
00911                 pa->boid = boid++;
00912             if(key) {
00913                 pa->keys = key;
00914                 key += pa->totkey;
00915             }
00916         }
00917     }
00918 
00919     if(psys->clmd) {
00920         psysn->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
00921         modifier_copyData((ModifierData*)psys->clmd, (ModifierData*)psysn->clmd);
00922         psys->hair_in_dm = psys->hair_out_dm = NULL;
00923     }
00924 
00925     BLI_duplicatelist(&psysn->targets, &psys->targets);
00926 
00927     psysn->pathcache= NULL;
00928     psysn->childcache= NULL;
00929     psysn->edit= NULL;
00930     psysn->frand= NULL;
00931     psysn->pdd= NULL;
00932     psysn->effectors= NULL;
00933     
00934     psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL;
00935     psysn->childcachebufs.first = psysn->childcachebufs.last = NULL;
00936     psysn->renderdata = NULL;
00937     
00938     psysn->pointcache= BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches);
00939 
00940     /* XXX - from reading existing code this seems correct but intended usage of
00941      * pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
00942     if(psysn->clmd) {
00943         psysn->clmd->point_cache= psysn->pointcache;
00944     }
00945 
00946     id_us_plus((ID *)psysn->part);
00947 
00948     return psysn;
00949 }
00950 
00951 void copy_object_particlesystems(Object *obn, Object *ob)
00952 {
00953     ParticleSystem *psys, *npsys;
00954     ModifierData *md;
00955 
00956     obn->particlesystem.first= obn->particlesystem.last= NULL;
00957     for(psys=ob->particlesystem.first; psys; psys=psys->next) {
00958         npsys= copy_particlesystem(psys);
00959 
00960         BLI_addtail(&obn->particlesystem, npsys);
00961 
00962         /* need to update particle modifiers too */
00963         for(md=obn->modifiers.first; md; md=md->next) {
00964             if(md->type==eModifierType_ParticleSystem) {
00965                 ParticleSystemModifierData *psmd= (ParticleSystemModifierData*)md;
00966                 if(psmd->psys==psys)
00967                     psmd->psys= npsys;
00968             }
00969             else if(md->type==eModifierType_DynamicPaint) {
00970                 DynamicPaintModifierData *pmd= (DynamicPaintModifierData*)md;
00971                 if (pmd->brush) {
00972                     if(pmd->brush->psys==psys) {
00973                         pmd->brush->psys= npsys;
00974                     }
00975                 }
00976             }
00977             else if (md->type==eModifierType_Smoke) {
00978                 SmokeModifierData *smd = (SmokeModifierData*) md;
00979                 
00980                 if(smd->type==MOD_SMOKE_TYPE_FLOW) {
00981                     if (smd->flow) {
00982                         if (smd->flow->psys == psys)
00983                             smd->flow->psys= npsys;
00984                     }
00985                 }
00986             }
00987         }
00988     }
00989 }
00990 
00991 void copy_object_softbody(Object *obn, Object *ob)
00992 {
00993     if(ob->soft)
00994         obn->soft= copy_softbody(ob->soft);
00995 }
00996 
00997 static void copy_object_pose(Object *obn, Object *ob)
00998 {
00999     bPoseChannel *chan;
01000     
01001     /* note: need to clear obn->pose pointer first, so that copy_pose works (otherwise there's a crash) */
01002     obn->pose= NULL;
01003     copy_pose(&obn->pose, ob->pose, 1); /* 1 = copy constraints */
01004 
01005     for (chan = obn->pose->chanbase.first; chan; chan=chan->next){
01006         bConstraint *con;
01007         
01008         chan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
01009         
01010         for (con= chan->constraints.first; con; con= con->next) {
01011             bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
01012             ListBase targets = {NULL, NULL};
01013             bConstraintTarget *ct;
01014             
01015             if (cti && cti->get_constraint_targets) {
01016                 cti->get_constraint_targets(con, &targets);
01017                 
01018                 for (ct= targets.first; ct; ct= ct->next) {
01019                     if (ct->tar == ob)
01020                         ct->tar = obn;
01021                 }
01022                 
01023                 if (cti->flush_constraint_targets)
01024                     cti->flush_constraint_targets(con, &targets, 0);
01025             }
01026         }
01027     }
01028 }
01029 
01030 static int object_pose_context(Object *ob)
01031 {
01032     if( (ob) &&
01033         (ob->type == OB_ARMATURE) &&
01034         (ob->pose) &&
01035         (ob->mode & OB_MODE_POSE)
01036     ) {
01037         return 1;
01038     }
01039     else {
01040         return 0;
01041     }
01042 }
01043 
01044 Object *object_pose_armature_get(Object *ob)
01045 {
01046     if(ob==NULL)
01047         return NULL;
01048 
01049     if(object_pose_context(ob))
01050         return ob;
01051 
01052     ob= modifiers_isDeformedByArmature(ob);
01053 
01054     if(object_pose_context(ob))
01055         return ob;
01056 
01057     return NULL;
01058 }
01059 
01060 static void copy_object_transform(Object *ob_tar, Object *ob_src)
01061 {
01062     copy_v3_v3(ob_tar->loc, ob_src->loc);
01063     copy_v3_v3(ob_tar->rot, ob_src->rot);
01064     copy_v3_v3(ob_tar->quat, ob_src->quat);
01065     copy_v3_v3(ob_tar->rotAxis, ob_src->rotAxis);
01066     ob_tar->rotAngle= ob_src->rotAngle;
01067     ob_tar->rotmode= ob_src->rotmode;
01068     copy_v3_v3(ob_tar->size, ob_src->size);
01069 }
01070 
01071 Object *copy_object(Object *ob)
01072 {
01073     Object *obn;
01074     ModifierData *md;
01075     int a;
01076 
01077     obn= copy_libblock(&ob->id);
01078     
01079     if(ob->totcol) {
01080         obn->mat= MEM_dupallocN(ob->mat);
01081         obn->matbits= MEM_dupallocN(ob->matbits);
01082         obn->totcol= ob->totcol;
01083     }
01084     
01085     if(ob->bb) obn->bb= MEM_dupallocN(ob->bb);
01086     obn->flag &= ~OB_FROMGROUP;
01087     
01088     obn->modifiers.first = obn->modifiers.last= NULL;
01089     
01090     for (md=ob->modifiers.first; md; md=md->next) {
01091         ModifierData *nmd = modifier_new(md->type);
01092         BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
01093         modifier_copyData(md, nmd);
01094         BLI_addtail(&obn->modifiers, nmd);
01095     }
01096 
01097     obn->prop.first = obn->prop.last = NULL;
01098     copy_properties(&obn->prop, &ob->prop);
01099     
01100     copy_sensors(&obn->sensors, &ob->sensors);
01101     copy_controllers(&obn->controllers, &ob->controllers);
01102     copy_actuators(&obn->actuators, &ob->actuators);
01103     
01104     if(ob->pose) {
01105         copy_object_pose(obn, ob);
01106         /* backwards compat... non-armatures can get poses in older files? */
01107         if(ob->type==OB_ARMATURE)
01108             armature_rebuild_pose(obn, obn->data);
01109     }
01110     defgroup_copy_list(&obn->defbase, &ob->defbase);
01111     copy_constraints(&obn->constraints, &ob->constraints, TRUE);
01112 
01113     obn->mode = 0;
01114     obn->sculpt = NULL;
01115 
01116     /* increase user numbers */
01117     id_us_plus((ID *)obn->data);
01118     id_us_plus((ID *)obn->gpd);
01119     id_lib_extern((ID *)obn->dup_group);
01120 
01121     for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
01122     
01123     obn->disp.first= obn->disp.last= NULL;
01124     
01125     if(ob->pd){
01126         obn->pd= MEM_dupallocN(ob->pd);
01127         if(obn->pd->tex)
01128             id_us_plus(&(obn->pd->tex->id));
01129         if(obn->pd->rng)
01130             obn->pd->rng = MEM_dupallocN(ob->pd->rng);
01131     }
01132     obn->soft= copy_softbody(ob->soft);
01133     obn->bsoft = copy_bulletsoftbody(ob->bsoft);
01134 
01135     copy_object_particlesystems(obn, ob);
01136     
01137     obn->derivedDeform = NULL;
01138     obn->derivedFinal = NULL;
01139 
01140     obn->gpulamp.first = obn->gpulamp.last = NULL;
01141     obn->pc_ids.first = obn->pc_ids.last = NULL;
01142 
01143     obn->mpath= NULL;
01144     
01145     return obn;
01146 }
01147 
01148 static void extern_local_object(Object *ob)
01149 {
01150     ParticleSystem *psys;
01151 
01152     id_lib_extern((ID *)ob->data);
01153     id_lib_extern((ID *)ob->dup_group);
01154     id_lib_extern((ID *)ob->poselib);
01155     id_lib_extern((ID *)ob->gpd);
01156 
01157     extern_local_matarar(ob->mat, ob->totcol);
01158 
01159     for(psys=ob->particlesystem.first; psys; psys=psys->next)
01160         id_lib_extern((ID *)psys->part);
01161 }
01162 
01163 void make_local_object(Object *ob)
01164 {
01165     Main *bmain= G.main;
01166     Scene *sce;
01167     Base *base;
01168     int is_local= FALSE, is_lib= FALSE;
01169 
01170     /* - only lib users: do nothing
01171      * - only local users: set flag
01172      * - mixed: make copy
01173      */
01174 
01175     if(ob->id.lib==NULL) return;
01176     
01177     ob->proxy= ob->proxy_from= NULL;
01178     
01179     if(ob->id.us==1) {
01180         id_clear_lib_data(bmain, &ob->id);
01181         extern_local_object(ob);
01182     }
01183     else {
01184         for(sce= bmain->scene.first; sce && ELEM(0, is_lib, is_local); sce= sce->id.next) {
01185             if(object_in_scene(ob, sce)) {
01186                 if(sce->id.lib) is_lib= TRUE;
01187                 else is_local= TRUE;
01188             }
01189         }
01190 
01191         if(is_local && is_lib == FALSE) {
01192             id_clear_lib_data(bmain, &ob->id);
01193             extern_local_object(ob);
01194         }
01195         else if(is_local && is_lib) {
01196             Object *ob_new= copy_object(ob);
01197 
01198             ob_new->id.us= 0;
01199             
01200             /* Remap paths of new ID using old library as base. */
01201             BKE_id_lib_local_paths(bmain, ob->id.lib, &ob_new->id);
01202 
01203             sce= bmain->scene.first;
01204             while(sce) {
01205                 if(sce->id.lib==NULL) {
01206                     base= sce->base.first;
01207                     while(base) {
01208                         if(base->object==ob) {
01209                             base->object= ob_new;
01210                             ob_new->id.us++;
01211                             ob->id.us--;
01212                         }
01213                         base= base->next;
01214                     }
01215                 }
01216                 sce= sce->id.next;
01217             }
01218         }
01219     }
01220 }
01221 
01222 /*
01223  * Returns true if the Object is a from an external blend file (libdata)
01224  */
01225 int object_is_libdata(Object *ob)
01226 {
01227     if (!ob) return 0;
01228     if (ob->proxy) return 0;
01229     if (ob->id.lib) return 1;
01230     return 0;
01231 }
01232 
01233 /* Returns true if the Object data is a from an external blend file (libdata) */
01234 int object_data_is_libdata(Object *ob)
01235 {
01236     if(!ob) return 0;
01237     if(ob->proxy && (ob->data==NULL || ((ID *)ob->data)->lib==NULL)) return 0;
01238     if(ob->id.lib) return 1;
01239     if(ob->data==NULL) return 0;
01240     if(((ID *)ob->data)->lib) return 1;
01241 
01242     return 0;
01243 }
01244 
01245 /* *************** PROXY **************** */
01246 
01247 /* when you make proxy, ensure the exposed layers are extern */
01248 static void armature_set_id_extern(Object *ob)
01249 {
01250     bArmature *arm= ob->data;
01251     bPoseChannel *pchan;
01252     unsigned int lay= arm->layer_protected;
01253     
01254     for (pchan = ob->pose->chanbase.first; pchan; pchan=pchan->next) {
01255         if(!(pchan->bone->layer & lay))
01256             id_lib_extern((ID *)pchan->custom);
01257     }
01258             
01259 }
01260 
01261 void object_copy_proxy_drivers(Object *ob, Object *target)
01262 {
01263     if ((target->adt) && (target->adt->drivers.first)) {
01264         FCurve *fcu;
01265         
01266         /* add new animdata block */
01267         if(!ob->adt)
01268             ob->adt= BKE_id_add_animdata(&ob->id);
01269         
01270         /* make a copy of all the drivers (for now), then correct any links that need fixing */
01271         free_fcurves(&ob->adt->drivers);
01272         copy_fcurves(&ob->adt->drivers, &target->adt->drivers);
01273         
01274         for (fcu= ob->adt->drivers.first; fcu; fcu= fcu->next) {
01275             ChannelDriver *driver= fcu->driver;
01276             DriverVar *dvar;
01277             
01278             for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
01279                 /* all drivers */
01280                 DRIVER_TARGETS_LOOPER(dvar) 
01281                 {
01282                     if(dtar->id) {
01283                         if ((Object *)dtar->id == target)
01284                             dtar->id= (ID *)ob;
01285                         else {
01286                             /* only on local objects because this causes indirect links a -> b -> c,blend to point directly to a.blend
01287                              * when a.blend has a proxy thats linked into c.blend  */
01288                             if(ob->id.lib==NULL)
01289                                 id_lib_extern((ID *)dtar->id);
01290                         }
01291                     }
01292                 }
01293                 DRIVER_TARGETS_LOOPER_END
01294             }
01295         }
01296     }
01297 }
01298 
01299 /* proxy rule: lib_object->proxy_from == the one we borrow from, set temporally while object_update */
01300 /*             local_object->proxy == pointer to library object, saved in files and read */
01301 /*             local_object->proxy_group == pointer to group dupli-object, saved in files and read */
01302 
01303 void object_make_proxy(Object *ob, Object *target, Object *gob)
01304 {
01305     /* paranoia checks */
01306     if(ob->id.lib || target->id.lib==NULL) {
01307         printf("cannot make proxy\n");
01308         return;
01309     }
01310     
01311     ob->proxy= target;
01312     ob->proxy_group= gob;
01313     id_lib_extern(&target->id);
01314     
01315     ob->recalc= target->recalc= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
01316     
01317     /* copy transform
01318      * - gob means this proxy comes from a group, just apply the matrix
01319      *   so the object wont move from its dupli-transform.
01320      *
01321      * - no gob means this is being made from a linked object,
01322      *   this is closer to making a copy of the object - in-place. */
01323     if(gob) {
01324         ob->rotmode= target->rotmode;
01325         mult_m4_m4m4(ob->obmat, gob->obmat, target->obmat);
01326         if(gob->dup_group) { /* should always be true */
01327             float tvec[3];
01328             copy_v3_v3(tvec, gob->dup_group->dupli_ofs);
01329             mul_mat3_m4_v3(ob->obmat, tvec);
01330             sub_v3_v3(ob->obmat[3], tvec);
01331         }
01332         object_apply_mat4(ob, ob->obmat, FALSE, TRUE);
01333     }
01334     else {
01335         copy_object_transform(ob, target);
01336         ob->parent= target->parent; /* libdata */
01337         copy_m4_m4(ob->parentinv, target->parentinv);
01338     }
01339     
01340     /* copy animdata stuff - drivers only for now... */
01341     object_copy_proxy_drivers(ob, target);
01342 
01343     /* skip constraints? */
01344     // FIXME: this is considered by many as a bug
01345     
01346     /* set object type and link to data */
01347     ob->type= target->type;
01348     ob->data= target->data;
01349     id_us_plus((ID *)ob->data);     /* ensures lib data becomes LIB_EXTERN */
01350     
01351     /* copy material and index information */
01352     ob->actcol= ob->totcol= 0;
01353     if(ob->mat) MEM_freeN(ob->mat);
01354     if(ob->matbits) MEM_freeN(ob->matbits);
01355     ob->mat = NULL;
01356     ob->matbits= NULL;
01357     if ((target->totcol) && (target->mat) && OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
01358         int i;
01359         
01360         ob->actcol= target->actcol;
01361         ob->totcol= target->totcol;
01362         
01363         ob->mat = MEM_dupallocN(target->mat);
01364         ob->matbits = MEM_dupallocN(target->matbits);
01365         for(i=0; i<target->totcol; i++) {
01366             /* dont need to run test_object_materials since we know this object is new and not used elsewhere */
01367             id_us_plus((ID *)ob->mat[i]); 
01368         }
01369     }
01370     
01371     /* type conversions */
01372     if(target->type == OB_ARMATURE) {
01373         copy_object_pose(ob, target);   /* data copy, object pointers in constraints */
01374         rest_pose(ob->pose);            /* clear all transforms in channels */
01375         armature_rebuild_pose(ob, ob->data);    /* set all internal links */
01376         
01377         armature_set_id_extern(ob);
01378     }
01379     else if (target->type == OB_EMPTY) {
01380         ob->empty_drawtype = target->empty_drawtype;
01381         ob->empty_drawsize = target->empty_drawsize;
01382     }
01383 
01384     /* copy IDProperties */
01385     if(ob->id.properties) {
01386         IDP_FreeProperty(ob->id.properties);
01387         MEM_freeN(ob->id.properties);
01388         ob->id.properties= NULL;
01389     }
01390     if(target->id.properties) {
01391         ob->id.properties= IDP_CopyProperty(target->id.properties);
01392     }
01393 
01394     /* copy drawtype info */
01395     ob->dt= target->dt;
01396 }
01397 
01398 
01399 /* *************** CALC ****************** */
01400 
01401 void object_scale_to_mat3(Object *ob, float mat[][3])
01402 {
01403     float vec[3];
01404     mul_v3_v3v3(vec, ob->size, ob->dscale);
01405     size_to_mat3( mat,vec);
01406 }
01407 
01408 void object_rot_to_mat3(Object *ob, float mat[][3])
01409 {
01410     float rmat[3][3], dmat[3][3];
01411     
01412     /* 'dmat' is the delta-rotation matrix, which will get (pre)multiplied
01413      * with the rotation matrix to yield the appropriate rotation
01414      */
01415 
01416     /* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
01417     if (ob->rotmode > 0) {
01418         /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
01419         eulO_to_mat3(rmat, ob->rot, ob->rotmode);
01420         eulO_to_mat3(dmat, ob->drot, ob->rotmode);
01421     }
01422     else if (ob->rotmode == ROT_MODE_AXISANGLE) {
01423         /* axis-angle -  not really that great for 3D-changing orientations */
01424         axis_angle_to_mat3(rmat, ob->rotAxis, ob->rotAngle);
01425         axis_angle_to_mat3(dmat, ob->drotAxis, ob->drotAngle);
01426     }
01427     else {
01428         /* quats are normalised before use to eliminate scaling issues */
01429         float tquat[4];
01430         
01431         normalize_qt_qt(tquat, ob->quat);
01432         quat_to_mat3(rmat, tquat);
01433         
01434         normalize_qt_qt(tquat, ob->dquat);
01435         quat_to_mat3(dmat, tquat);
01436     }
01437     
01438     /* combine these rotations */
01439     mul_m3_m3m3(mat, dmat, rmat);
01440 }
01441 
01442 void object_mat3_to_rot(Object *ob, float mat[][3], short use_compat)
01443 {
01444     switch(ob->rotmode) {
01445     case ROT_MODE_QUAT:
01446         {
01447             float dquat[4];
01448             mat3_to_quat(ob->quat, mat);
01449             normalize_qt_qt(dquat, ob->dquat);
01450             invert_qt(dquat);
01451             mul_qt_qtqt(ob->quat, dquat, ob->quat);
01452         }
01453         break;
01454     case ROT_MODE_AXISANGLE:
01455         mat3_to_axis_angle(ob->rotAxis, &ob->rotAngle, mat);
01456         sub_v3_v3(ob->rotAxis, ob->drotAxis);
01457         ob->rotAngle -= ob->drotAngle;
01458         break;
01459     default: /* euler */
01460         {
01461             float quat[4];
01462             float dquat[4];
01463             float tmat[3][3];
01464 
01465             /* without drot we could apply 'mat' directly */
01466             mat3_to_quat(quat, mat);
01467             eulO_to_quat(dquat, ob->drot, ob->rotmode);
01468             invert_qt(dquat);
01469             mul_qt_qtqt(quat, dquat, quat);
01470             quat_to_mat3(tmat, quat);
01471             /* end drot correction */
01472 
01473             if(use_compat)  mat3_to_compatible_eulO(ob->rot, ob->rot, ob->rotmode, tmat);
01474             else            mat3_to_eulO(ob->rot, ob->rotmode, tmat);
01475         }
01476     }
01477 }
01478 
01479 void object_tfm_protected_backup(const Object *ob,
01480                                  ObjectTfmProtectedChannels *obtfm)
01481 {
01482 
01483 #define TFMCPY(   _v) (obtfm->_v = ob->_v)
01484 #define TFMCPY3D( _v) copy_v3_v3(obtfm->_v, ob->_v)
01485 #define TFMCPY4D( _v) copy_v4_v4(obtfm->_v, ob->_v)
01486 
01487     TFMCPY3D(loc);
01488     TFMCPY3D(dloc);
01489     TFMCPY3D(size);
01490     TFMCPY3D(dscale);
01491     TFMCPY3D(rot);
01492     TFMCPY3D(drot);
01493     TFMCPY4D(quat);
01494     TFMCPY4D(dquat);
01495     TFMCPY3D(rotAxis);
01496     TFMCPY3D(drotAxis);
01497     TFMCPY(rotAngle);
01498     TFMCPY(drotAngle);
01499 
01500 #undef TFMCPY
01501 #undef TFMCPY3D
01502 #undef TFMCPY4D
01503 
01504 }
01505 
01506 void object_tfm_protected_restore(Object *ob,
01507                                   const ObjectTfmProtectedChannels *obtfm,
01508                                   const short protectflag)
01509 {
01510     unsigned int i;
01511 
01512     for (i= 0; i < 3; i++) {
01513         if (protectflag & (OB_LOCK_LOCX<<i)) {
01514             ob->loc[i]=  obtfm->loc[i];
01515             ob->dloc[i]= obtfm->dloc[i];
01516         }
01517 
01518         if (protectflag & (OB_LOCK_SCALEX<<i)) {
01519             ob->size[i]=  obtfm->size[i];
01520             ob->dscale[i]= obtfm->dscale[i];
01521         }
01522 
01523         if (protectflag & (OB_LOCK_ROTX<<i)) {
01524             ob->rot[i]=  obtfm->rot[i];
01525             ob->drot[i]= obtfm->drot[i];
01526 
01527             ob->quat[i + 1]=  obtfm->quat[i + 1];
01528             ob->dquat[i + 1]= obtfm->dquat[i + 1];
01529 
01530             ob->rotAxis[i]=  obtfm->rotAxis[i];
01531             ob->drotAxis[i]= obtfm->drotAxis[i];
01532         }
01533     }
01534 
01535     if ((protectflag & OB_LOCK_ROT4D) && (protectflag & OB_LOCK_ROTW)) {
01536         ob->quat[0]=  obtfm->quat[0];
01537         ob->dquat[0]= obtfm->dquat[0];
01538 
01539         ob->rotAngle=  obtfm->rotAngle;
01540         ob->drotAngle= obtfm->drotAngle;
01541     }
01542 }
01543 
01544 /* see pchan_apply_mat4() for the equivalent 'pchan' function */
01545 void object_apply_mat4(Object *ob, float mat[][4], const short use_compat, const short use_parent)
01546 {
01547     float rot[3][3];
01548 
01549     if(use_parent && ob->parent) {
01550         float rmat[4][4], diff_mat[4][4], imat[4][4];
01551         mult_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
01552         invert_m4_m4(imat, diff_mat);
01553         mult_m4_m4m4(rmat, imat, mat); /* get the parent relative matrix */
01554         object_apply_mat4(ob, rmat, use_compat, FALSE);
01555         
01556         /* same as below, use rmat rather than mat */
01557         mat4_to_loc_rot_size(ob->loc, rot, ob->size, rmat);
01558         object_mat3_to_rot(ob, rot, use_compat);
01559     }
01560     else {
01561         mat4_to_loc_rot_size(ob->loc, rot, ob->size, mat);
01562         object_mat3_to_rot(ob, rot, use_compat);
01563     }
01564     
01565     sub_v3_v3(ob->loc, ob->dloc);
01566 
01567     if (ob->dscale[0] != 0.0f) ob->size[0] /= ob->dscale[0];
01568     if (ob->dscale[1] != 0.0f) ob->size[1] /= ob->dscale[1];
01569     if (ob->dscale[2] != 0.0f) ob->size[2] /= ob->dscale[2];
01570 
01571     /* object_mat3_to_rot handles delta rotations */
01572 }
01573 
01574 void object_to_mat3(Object *ob, float mat[][3]) /* no parent */
01575 {
01576     float smat[3][3];
01577     float rmat[3][3];
01578     /*float q1[4];*/
01579     
01580     /* size */
01581     object_scale_to_mat3(ob, smat);
01582 
01583     /* rot */
01584     object_rot_to_mat3(ob, rmat);
01585     mul_m3_m3m3(mat, rmat, smat);
01586 }
01587 
01588 void object_to_mat4(Object *ob, float mat[][4])
01589 {
01590     float tmat[3][3];
01591     
01592     object_to_mat3(ob, tmat);
01593     
01594     copy_m4_m3(mat, tmat);
01595 
01596     add_v3_v3v3(mat[3], ob->loc, ob->dloc);
01597 }
01598 
01599 /* extern */
01600 int enable_cu_speed= 1;
01601 
01602 static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
01603 {
01604     Curve *cu;
01605     float vec[4], dir[3], quat[4], radius, ctime;
01606     float timeoffs = 0.0, sf_orig = 0.0;
01607     
01608     unit_m4(mat);
01609     
01610     cu= par->data;
01611     if(cu->path==NULL || cu->path->data==NULL) /* only happens on reload file, but violates depsgraph still... fix! */
01612         makeDispListCurveTypes(scene, par, 0);
01613     if(cu->path==NULL) return;
01614     
01615     /* catch exceptions: feature for nla stride editing */
01616     if(ob->ipoflag & OB_DISABLE_PATH) {
01617         ctime= 0.0f;
01618     }
01619     /* catch exceptions: curve paths used as a duplicator */
01620     else if(enable_cu_speed) {
01621         /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated,
01622          * but this will only work if it actually is animated... 
01623          *
01624          * we divide the curvetime calculated in the previous step by the length of the path, to get a time
01625          * factor, which then gets clamped to lie within 0.0 - 1.0 range
01626          */
01627         if (IS_EQF(cu->pathlen, 0.0f) == 0)
01628             ctime= cu->ctime / cu->pathlen;
01629         else
01630             ctime= cu->ctime;
01631 
01632         CLAMP(ctime, 0.0f, 1.0f);
01633     }
01634     else {
01635         ctime= scene->r.cfra;
01636         if (IS_EQF(cu->pathlen, 0.0f) == 0)
01637             ctime /= cu->pathlen;
01638         
01639         CLAMP(ctime, 0.0f, 1.0f);
01640     }
01641     
01642     /* time calculus is correct, now apply distance offset */
01643     if(cu->flag & CU_OFFS_PATHDIST) {
01644         ctime += timeoffs/cu->path->totdist;
01645 
01646         /* restore */
01647         SWAP(float, sf_orig, ob->sf);
01648     }
01649     
01650     
01651     /* vec: 4 items! */
01652     if( where_on_path(par, ctime, vec, dir, cu->flag & CU_FOLLOW ? quat:NULL, &radius, NULL) ) {
01653 
01654         if(cu->flag & CU_FOLLOW) {
01655 #if 0
01656             float x1, q[4];
01657             vec_to_quat( quat,dir, ob->trackflag, ob->upflag);
01658             
01659             /* the tilt */
01660             normalize_v3(dir);
01661             q[0]= (float)cos(0.5*vec[3]);
01662             x1= (float)sin(0.5*vec[3]);
01663             q[1]= -x1*dir[0];
01664             q[2]= -x1*dir[1];
01665             q[3]= -x1*dir[2];
01666             mul_qt_qtqt(quat, q, quat);
01667 #else
01668             quat_apply_track(quat, ob->trackflag, ob->upflag);
01669 #endif
01670             normalize_qt(quat);
01671             quat_to_mat4(mat, quat);
01672         }
01673         
01674         if(cu->flag & CU_PATH_RADIUS) {
01675             float tmat[4][4], rmat[4][4];
01676             scale_m4_fl(tmat, radius);
01677             mult_m4_m4m4(rmat, tmat, mat);
01678             copy_m4_m4(mat, rmat);
01679         }
01680 
01681         copy_v3_v3(mat[3], vec);
01682         
01683     }
01684 }
01685 
01686 static void ob_parbone(Object *ob, Object *par, float mat[][4])
01687 {   
01688     bPoseChannel *pchan;
01689     float vec[3];
01690     
01691     if (par->type!=OB_ARMATURE) {
01692         unit_m4(mat);
01693         return;
01694     }
01695     
01696     /* Make sure the bone is still valid */
01697     pchan= get_pose_channel(par->pose, ob->parsubstr);
01698     if (!pchan){
01699         printf ("Object %s with Bone parent: bone %s doesn't exist\n", ob->id.name+2, ob->parsubstr);
01700         unit_m4(mat);
01701         return;
01702     }
01703 
01704     /* get bone transform */
01705     copy_m4_m4(mat, pchan->pose_mat);
01706 
01707     /* but for backwards compatibility, the child has to move to the tail */
01708     copy_v3_v3(vec, mat[1]);
01709     mul_v3_fl(vec, pchan->bone->length);
01710     add_v3_v3(mat[3], vec);
01711 }
01712 
01713 static void give_parvert(Object *par, int nr, float *vec)
01714 {
01715     EditMesh *em;
01716     int a, count;
01717     
01718     vec[0]=vec[1]=vec[2]= 0.0f;
01719     
01720     if(par->type==OB_MESH) {
01721         Mesh *me= par->data;
01722         DerivedMesh *dm;
01723 
01724         em = BKE_mesh_get_editmesh(me);
01725         dm = (em)? em->derivedFinal: par->derivedFinal;
01726             
01727         if(dm) {
01728             MVert *mvert= dm->getVertArray(dm);
01729             int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
01730             int i, vindex, numVerts = dm->getNumVerts(dm);
01731 
01732             /* get the average of all verts with (original index == nr) */
01733             count= 0;
01734             for(i = 0; i < numVerts; i++) {
01735                 vindex= (index)? index[i]: i;
01736 
01737                 if(vindex == nr) {
01738                     add_v3_v3(vec, mvert[i].co);
01739                     count++;
01740                 }
01741             }
01742 
01743             if (count==0) {
01744                 /* keep as 0,0,0 */
01745             } else if(count > 0) {
01746                 mul_v3_fl(vec, 1.0f / count);
01747             } else {
01748                 /* use first index if its out of range */
01749                 dm->getVertCo(dm, 0, vec);
01750             }
01751         }
01752         else fprintf(stderr, "%s: DerivedMesh is needed to solve parenting, object position can be wrong now\n", __func__);
01753 
01754         if(em)
01755             BKE_mesh_end_editmesh(me, em);
01756     }
01757     else if (ELEM(par->type, OB_CURVE, OB_SURF)) {
01758         Nurb *nu;
01759         Curve *cu;
01760         BPoint *bp;
01761         BezTriple *bezt;
01762         int found= 0;
01763         ListBase *nurbs;
01764 
01765         cu= par->data;
01766         nurbs= BKE_curve_nurbs(cu);
01767         nu= nurbs->first;
01768 
01769         count= 0;
01770         while(nu && !found) {
01771             if(nu->type == CU_BEZIER) {
01772                 bezt= nu->bezt;
01773                 a= nu->pntsu;
01774                 while(a--) {
01775                     if(count==nr) {
01776                         found= 1;
01777                         copy_v3_v3(vec, bezt->vec[1]);
01778                         break;
01779                     }
01780                     count++;
01781                     bezt++;
01782                 }
01783             }
01784             else {
01785                 bp= nu->bp;
01786                 a= nu->pntsu*nu->pntsv;
01787                 while(a--) {
01788                     if(count==nr) {
01789                         found= 1;
01790                         memcpy(vec, bp->vec, sizeof(float)*3);
01791                         break;
01792                     }
01793                     count++;
01794                     bp++;
01795                 }
01796             }
01797             nu= nu->next;
01798         }
01799 
01800     }
01801     else if(par->type==OB_LATTICE) {
01802         Lattice *latt= par->data;
01803         BPoint *bp;
01804         DispList *dl = find_displist(&par->disp, DL_VERTS);
01805         float *co = dl?dl->verts:NULL;
01806         
01807         if(latt->editlatt) latt= latt->editlatt->latt;
01808         
01809         a= latt->pntsu*latt->pntsv*latt->pntsw;
01810         count= 0;
01811         bp= latt->def;
01812         while(a--) {
01813             if(count==nr) {
01814                 if(co)
01815                     memcpy(vec, co, 3*sizeof(float));
01816                 else
01817                     memcpy(vec, bp->vec, 3*sizeof(float));
01818                 break;
01819             }
01820             count++;
01821             if(co) co+= 3;
01822             else bp++;
01823         }
01824     }
01825 }
01826 
01827 static void ob_parvert3(Object *ob, Object *par, float mat[][4])
01828 {
01829     float cmat[3][3], v1[3], v2[3], v3[3], q[4];
01830 
01831     /* in local ob space */
01832     unit_m4(mat);
01833     
01834     if (ELEM4(par->type, OB_MESH, OB_SURF, OB_CURVE, OB_LATTICE)) {
01835         
01836         give_parvert(par, ob->par1, v1);
01837         give_parvert(par, ob->par2, v2);
01838         give_parvert(par, ob->par3, v3);
01839                 
01840         tri_to_quat( q,v1, v2, v3);
01841         quat_to_mat3( cmat,q);
01842         copy_m4_m3(mat, cmat);
01843         
01844         if(ob->type==OB_CURVE) {
01845             copy_v3_v3(mat[3], v1);
01846         }
01847         else {
01848             add_v3_v3v3(mat[3], v1, v2);
01849             add_v3_v3(mat[3], v3);
01850             mul_v3_fl(mat[3], 0.3333333f);
01851         }
01852     }
01853 }
01854 
01855 static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4])
01856 {
01857     float *fp1, *fp2;
01858     float fac1, fac2;
01859     int a;
01860 
01861     // include framerate
01862     fac1= ( 1.0f / (1.0f + fabsf(ob->sf)) );
01863     if(fac1 >= 1.0f) return 0;
01864     fac2= 1.0f-fac1;
01865 
01866     fp1= obmat[0];
01867     fp2= slowmat[0];
01868     for(a=0; a<16; a++, fp1++, fp2++) {
01869         fp1[0]= fac1*fp1[0] + fac2*fp2[0];
01870     }
01871 
01872     return 1;
01873 }
01874 
01875 void where_is_object_time(Scene *scene, Object *ob, float ctime)
01876 {
01877     float slowmat[4][4] = MAT4_UNITY;
01878     float stime=ctime;
01879     
01880     /* new version: correct parent+vertexparent and track+parent */
01881     /* this one only calculates direct attached parent and track */
01882     /* is faster, but should keep track of timeoffs */
01883     
01884     if(ob==NULL) return;
01885     
01886     /* execute drivers only, as animation has already been done */
01887     BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS);
01888     
01889     if(ob->parent) {
01890         Object *par= ob->parent;
01891         
01892         /* hurms, code below conflicts with depgraph... (ton) */
01893         /* and even worse, it gives bad effects for NLA stride too (try ctime != par->ctime, with MBlur) */
01894         if(stime != par->ctime) {
01895             // only for ipo systems? 
01896             Object tmp= *par;
01897             
01898             if(par->proxy_from);    // was a copied matrix, no where_is! bad...
01899             else where_is_object_time(scene, par, ctime);
01900             
01901             solve_parenting(scene, ob, par, ob->obmat, slowmat, 0);
01902             
01903             *par= tmp;
01904         }
01905         else
01906             solve_parenting(scene, ob, par, ob->obmat, slowmat, 0);
01907         
01908         /* "slow parent" is definitely not threadsafe, and may also give bad results jumping around 
01909          * An old-fashioned hack which probably doesn't really cut it anymore
01910          */
01911         if(ob->partype & PARSLOW) {
01912             if(!where_is_object_parslow(ob, ob->obmat, slowmat))
01913                 return;
01914         }
01915     }
01916     else {
01917         object_to_mat4(ob, ob->obmat);
01918     }
01919 
01920     /* solve constraints */
01921     if (ob->constraints.first && !(ob->transflag & OB_NO_CONSTRAINTS)) {
01922         bConstraintOb *cob;
01923         
01924         cob= constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
01925         
01926         /* constraints need ctime, not stime. Some call where_is_object_time and bsystem_time */
01927         solve_constraints (&ob->constraints, cob, ctime);
01928         
01929         constraints_clear_evalob(cob);
01930     }
01931     
01932     /* set negative scale flag in object */
01933     if(is_negative_m4(ob->obmat))   ob->transflag |= OB_NEG_SCALE;
01934     else                            ob->transflag &= ~OB_NEG_SCALE;
01935 }
01936 
01937 /* get object transformation matrix without recalculating dependencies and
01938    constraints -- assume dependencies are already solved by depsgraph.
01939    no changes to object and it's parent would be done.
01940    used for bundles orientation in 3d space relative to parented blender camera */
01941 void where_is_object_mat(Scene *scene, Object *ob, float obmat[4][4])
01942 {
01943     float slowmat[4][4] = MAT4_UNITY;
01944 
01945     if(ob->parent) {
01946         Object *par= ob->parent;
01947 
01948         solve_parenting(scene, ob, par, obmat, slowmat, 1);
01949 
01950         if(ob->partype & PARSLOW)
01951             where_is_object_parslow(ob, obmat, slowmat);
01952     }
01953     else {
01954         object_to_mat4(ob, obmat);
01955     }
01956 }
01957 
01958 static void solve_parenting (Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul)
01959 {
01960     float totmat[4][4];
01961     float tmat[4][4];
01962     float locmat[4][4];
01963     float vec[3];
01964     int ok;
01965     
01966     object_to_mat4(ob, locmat);
01967     
01968     if(ob->partype & PARSLOW) copy_m4_m4(slowmat, obmat);
01969 
01970     switch(ob->partype & PARTYPE) {
01971     case PAROBJECT:
01972         ok= 0;
01973         if(par->type==OB_CURVE) {
01974             if( ((Curve *)par->data)->flag & CU_PATH ) {
01975                 ob_parcurve(scene, ob, par, tmat);
01976                 ok= 1;
01977             }
01978         }
01979         
01980         if(ok) mul_serie_m4(totmat, par->obmat, tmat, 
01981             NULL, NULL, NULL, NULL, NULL, NULL);
01982         else copy_m4_m4(totmat, par->obmat);
01983         
01984         break;
01985     case PARBONE:
01986         ob_parbone(ob, par, tmat);
01987         mul_serie_m4(totmat, par->obmat, tmat,         
01988             NULL, NULL, NULL, NULL, NULL, NULL);
01989         break;
01990         
01991     case PARVERT1:
01992         unit_m4(totmat);
01993         if (simul){
01994             copy_v3_v3(totmat[3], par->obmat[3]);
01995         }
01996         else{
01997             give_parvert(par, ob->par1, vec);
01998             mul_v3_m4v3(totmat[3], par->obmat, vec);
01999         }
02000         break;
02001     case PARVERT3:
02002         ob_parvert3(ob, par, tmat);
02003         
02004         mul_serie_m4(totmat, par->obmat, tmat,         
02005             NULL, NULL, NULL, NULL, NULL, NULL);
02006         break;
02007         
02008     case PARSKEL:
02009         copy_m4_m4(totmat, par->obmat);
02010         break;
02011     }
02012     
02013     // total 
02014     mul_serie_m4(tmat, totmat, ob->parentinv,         
02015         NULL, NULL, NULL, NULL, NULL, NULL);
02016     mul_serie_m4(obmat, tmat, locmat,         
02017         NULL, NULL, NULL, NULL, NULL, NULL);
02018     
02019     if (simul) {
02020 
02021     }
02022     else{
02023         // external usable originmat 
02024         copy_m3_m4(originmat, tmat);
02025         
02026         // origin, voor help line
02027         if( (ob->partype & PARTYPE)==PARSKEL ) {
02028             copy_v3_v3(ob->orig, par->obmat[3]);
02029         }
02030         else {
02031             copy_v3_v3(ob->orig, totmat[3]);
02032         }
02033     }
02034 
02035 }
02036 
02037 void where_is_object(struct Scene *scene, Object *ob)
02038 {
02039     where_is_object_time(scene, ob, (float)scene->r.cfra);
02040 }
02041 
02042 
02043 void where_is_object_simul(Scene *scene, Object *ob)
02044 /* was written for the old game engine (until 2.04) */
02045 /* It seems that this function is only called
02046 for a lamp that is the child of another object */
02047 {
02048     Object *par;
02049     float *fp1, *fp2;
02050     float slowmat[4][4];
02051     float fac1, fac2;
02052     int a;
02053     
02054     /* NO TIMEOFFS */
02055     if(ob->parent) {
02056         par= ob->parent;
02057         
02058         solve_parenting(scene, ob, par, ob->obmat, slowmat, 1);
02059         
02060         if(ob->partype & PARSLOW) {
02061             fac1= (float)(1.0/(1.0+ fabs(ob->sf)));
02062             fac2= 1.0f-fac1;
02063             fp1= ob->obmat[0];
02064             fp2= slowmat[0];
02065             for(a=0; a<16; a++, fp1++, fp2++) {
02066                 fp1[0]= fac1*fp1[0] + fac2*fp2[0];
02067             }
02068         }
02069     }
02070     else {
02071         object_to_mat4(ob, ob->obmat);
02072     }
02073     
02074     /* solve constraints */
02075     if (ob->constraints.first) {
02076         bConstraintOb *cob;
02077         
02078         cob= constraints_make_evalob(scene, ob, NULL, CONSTRAINT_OBTYPE_OBJECT);
02079         solve_constraints(&ob->constraints, cob, (float)scene->r.cfra);
02080         constraints_clear_evalob(cob);
02081     }
02082 }
02083 
02084 /* for calculation of the inverse parent transform, only used for editor */
02085 void what_does_parent(Scene *scene, Object *ob, Object *workob)
02086 {
02087     clear_workob(workob);
02088     
02089     unit_m4(workob->obmat);
02090     unit_m4(workob->parentinv);
02091     unit_m4(workob->constinv);
02092     workob->parent= ob->parent;
02093 
02094     workob->trackflag= ob->trackflag;
02095     workob->upflag= ob->upflag;
02096     
02097     workob->partype= ob->partype;
02098     workob->par1= ob->par1;
02099     workob->par2= ob->par2;
02100     workob->par3= ob->par3;
02101 
02102     workob->constraints.first = ob->constraints.first;
02103     workob->constraints.last = ob->constraints.last;
02104 
02105     BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr));
02106 
02107     where_is_object(scene, workob);
02108 }
02109 
02110 BoundBox *unit_boundbox(void)
02111 {
02112     BoundBox *bb;
02113     float min[3] = {-1.0f,-1.0f,-1.0f}, max[3] = {-1.0f,-1.0f,-1.0f};
02114 
02115     bb= MEM_callocN(sizeof(BoundBox), "OB-BoundBox");
02116     boundbox_set_from_min_max(bb, min, max);
02117     
02118     return bb;
02119 }
02120 
02121 void boundbox_set_from_min_max(BoundBox *bb, float min[3], float max[3])
02122 {
02123     bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= min[0];
02124     bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= max[0];
02125     
02126     bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= min[1];
02127     bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= max[1];
02128 
02129     bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= min[2];
02130     bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= max[2];
02131 }
02132 
02133 BoundBox *object_get_boundbox(Object *ob)
02134 {
02135     BoundBox *bb= NULL;
02136     
02137     if(ob->type==OB_MESH) {
02138         bb = mesh_get_bb(ob);
02139     }
02140     else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
02141         bb= ob->bb ? ob->bb : ( (Curve *)ob->data )->bb;
02142     }
02143     else if(ob->type==OB_MBALL) {
02144         bb= ob->bb;
02145     }
02146     return bb;
02147 }
02148 
02149 /* used to temporally disable/enable boundbox */
02150 void object_boundbox_flag(Object *ob, int flag, int set)
02151 {
02152     BoundBox *bb= object_get_boundbox(ob);
02153     if(bb) {
02154         if(set) bb->flag |= flag;
02155         else bb->flag &= ~flag;
02156     }
02157 }
02158 
02159 void object_get_dimensions(Object *ob, float *value)
02160 {
02161     BoundBox *bb = NULL;
02162     
02163     bb= object_get_boundbox(ob);
02164     if (bb) {
02165         float scale[3];
02166         
02167         mat4_to_size( scale,ob->obmat);
02168         
02169         value[0] = fabsf(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
02170         value[1] = fabsf(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
02171         value[2] = fabsf(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
02172     } else {
02173         value[0] = value[1] = value[2] = 0.f;
02174     }
02175 }
02176 
02177 void object_set_dimensions(Object *ob, const float *value)
02178 {
02179     BoundBox *bb = NULL;
02180     
02181     bb= object_get_boundbox(ob);
02182     if (bb) {
02183         float scale[3], len[3];
02184         
02185         mat4_to_size( scale,ob->obmat);
02186         
02187         len[0] = bb->vec[4][0] - bb->vec[0][0];
02188         len[1] = bb->vec[2][1] - bb->vec[0][1];
02189         len[2] = bb->vec[1][2] - bb->vec[0][2];
02190         
02191         if (len[0] > 0.f) ob->size[0] = value[0] / len[0];
02192         if (len[1] > 0.f) ob->size[1] = value[1] / len[1];
02193         if (len[2] > 0.f) ob->size[2] = value[2] / len[2];
02194     }
02195 }
02196 
02197 void minmax_object(Object *ob, float min[3], float max[3])
02198 {
02199     BoundBox bb;
02200     float vec[3];
02201     int a;
02202     short change= FALSE;
02203     
02204     switch(ob->type) {
02205     case OB_CURVE:
02206     case OB_FONT:
02207     case OB_SURF:
02208         {
02209             Curve *cu= ob->data;
02210 
02211             if(cu->bb==NULL) tex_space_curve(cu);
02212             bb= *(cu->bb);
02213 
02214             for(a=0; a<8; a++) {
02215                 mul_m4_v3(ob->obmat, bb.vec[a]);
02216                 DO_MINMAX(bb.vec[a], min, max);
02217             }
02218             change= TRUE;
02219         }
02220         break;
02221     case OB_LATTICE:
02222         {
02223             Lattice *lt= ob->data;
02224             BPoint *bp= lt->def;
02225             int u, v, w;
02226 
02227             for(w=0; w<lt->pntsw; w++) {
02228                 for(v=0; v<lt->pntsv; v++) {
02229                     for(u=0; u<lt->pntsu; u++, bp++) {
02230                         mul_v3_m4v3(vec, ob->obmat, bp->vec);
02231                         DO_MINMAX(vec, min, max);
02232                     }
02233                 }
02234             }
02235             change= TRUE;
02236         }
02237         break;
02238     case OB_ARMATURE:
02239         if(ob->pose) {
02240             bPoseChannel *pchan;
02241             for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
02242                 mul_v3_m4v3(vec, ob->obmat, pchan->pose_head);
02243                 DO_MINMAX(vec, min, max);
02244                 mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail);
02245                 DO_MINMAX(vec, min, max);
02246             }
02247             change= TRUE;
02248         }
02249         break;
02250     case OB_MESH:
02251         {
02252             Mesh *me= get_mesh(ob);
02253 
02254             if(me) {
02255                 bb = *mesh_get_bb(ob);
02256 
02257                 for(a=0; a<8; a++) {
02258                     mul_m4_v3(ob->obmat, bb.vec[a]);
02259                     DO_MINMAX(bb.vec[a], min, max);
02260                 }
02261                 change= TRUE;
02262             }
02263         }
02264         break;
02265     }
02266 
02267     if(change == FALSE) {
02268         DO_MINMAX(ob->obmat[3], min, max);
02269 
02270         copy_v3_v3(vec, ob->obmat[3]);
02271         add_v3_v3(vec, ob->size);
02272         DO_MINMAX(vec, min, max);
02273 
02274         copy_v3_v3(vec, ob->obmat[3]);
02275         sub_v3_v3(vec, ob->size);
02276         DO_MINMAX(vec, min, max);
02277     }
02278 }
02279 
02280 int minmax_object_duplis(Scene *scene, Object *ob, float *min, float *max)
02281 {
02282     int ok= 0;
02283     if ((ob->transflag & OB_DUPLI)==0) {
02284         return ok;
02285     } else {
02286         ListBase *lb;
02287         DupliObject *dob;
02288         
02289         lb= object_duplilist(scene, ob);
02290         for(dob= lb->first; dob; dob= dob->next) {
02291             if(dob->no_draw == 0) {
02292                 BoundBox *bb= object_get_boundbox(dob->ob);
02293 
02294                 if(bb) {
02295                     int i;
02296                     for(i=0; i<8; i++) {
02297                         float vec[3];
02298                         mul_v3_m4v3(vec, dob->mat, bb->vec[i]);
02299                         DO_MINMAX(vec, min, max);
02300                     }
02301 
02302                     ok= 1;
02303                 }
02304             }
02305         }
02306         free_object_duplilist(lb);  /* does restore */
02307     }
02308 
02309     return ok;
02310 }
02311 
02312 void BKE_object_foreach_display_point(
02313         Object *ob, float obmat[4][4],
02314         void (*func_cb)(const float[3], void *), void *user_data)
02315 {
02316     float co[3];
02317 
02318     if (ob->derivedFinal) {
02319         DerivedMesh *dm= ob->derivedFinal;
02320         MVert *mv= dm->getVertArray(dm);
02321         int totvert= dm->getNumVerts(dm);
02322         int i;
02323 
02324         for (i= 0; i < totvert; i++, mv++) {
02325             mul_v3_m4v3(co, obmat, mv->co);
02326             func_cb(co, user_data);
02327         }
02328     }
02329     else if (ob->disp.first) {
02330         DispList *dl;
02331 
02332         for (dl=ob->disp.first; dl; dl=dl->next) {
02333             float *v3= dl->verts;
02334             int totvert= dl->nr;
02335             int i;
02336 
02337             for (i= 0; i < totvert; i++, v3+=3) {
02338                 mul_v3_m4v3(co, obmat, v3);
02339                 func_cb(co, user_data);
02340             }
02341         }
02342     }
02343 }
02344 
02345 void BKE_scene_foreach_display_point(
02346         Scene *scene, View3D *v3d, const short flag,
02347         void (*func_cb)(const float[3], void *), void *user_data)
02348 {
02349     Base *base;
02350     Object *ob;
02351 
02352     for(base= FIRSTBASE; base; base = base->next) {
02353         if(BASE_VISIBLE(v3d, base) && (base->flag & flag) == flag) {
02354             ob= base->object;
02355 
02356             if ((ob->transflag & OB_DUPLI)==0) {
02357                 BKE_object_foreach_display_point(ob, ob->obmat, func_cb, user_data);
02358             }
02359             else {
02360                 ListBase *lb;
02361                 DupliObject *dob;
02362 
02363                 lb= object_duplilist(scene, ob);
02364                 for(dob= lb->first; dob; dob= dob->next) {
02365                     if(dob->no_draw == 0) {
02366                         BKE_object_foreach_display_point(dob->ob, dob->mat, func_cb, user_data);
02367                     }
02368                 }
02369                 free_object_duplilist(lb);  /* does restore */
02370             }
02371         }
02372     }
02373 }
02374 
02375 /* copied from DNA_object_types.h */
02376 typedef struct ObTfmBack {
02377     float loc[3], dloc[3], orig[3];
02378     float size[3], dscale[3];   /* scale and delta scale */
02379     float rot[3], drot[3];      /* euler rotation */
02380     float quat[4], dquat[4];    /* quaternion rotation */
02381     float rotAxis[3], drotAxis[3];  /* axis angle rotation - axis part */
02382     float rotAngle, drotAngle;  /* axis angle rotation - angle part */
02383     float obmat[4][4];      /* final worldspace matrix with constraints & animsys applied */
02384     float parentinv[4][4]; /* inverse result of parent, so that object doesn't 'stick' to parent */
02385     float constinv[4][4]; /* inverse result of constraints. doesn't include effect of parent or object local transform */
02386     float imat[4][4];   /* inverse matrix of 'obmat' for during render, old game engine, temporally: ipokeys of transform  */
02387 } ObTfmBack;
02388 
02389 void *object_tfm_backup(Object *ob)
02390 {
02391     ObTfmBack *obtfm= MEM_mallocN(sizeof(ObTfmBack), "ObTfmBack");
02392     copy_v3_v3(obtfm->loc, ob->loc);
02393     copy_v3_v3(obtfm->dloc, ob->dloc);
02394     copy_v3_v3(obtfm->orig, ob->orig);
02395     copy_v3_v3(obtfm->size, ob->size);
02396     copy_v3_v3(obtfm->dscale, ob->dscale);
02397     copy_v3_v3(obtfm->rot, ob->rot);
02398     copy_v3_v3(obtfm->drot, ob->drot);
02399     copy_qt_qt(obtfm->quat, ob->quat);
02400     copy_qt_qt(obtfm->dquat, ob->dquat);
02401     copy_v3_v3(obtfm->rotAxis, ob->rotAxis);
02402     copy_v3_v3(obtfm->drotAxis, ob->drotAxis);
02403     obtfm->rotAngle= ob->rotAngle;
02404     obtfm->drotAngle= ob->drotAngle;
02405     copy_m4_m4(obtfm->obmat, ob->obmat);
02406     copy_m4_m4(obtfm->parentinv, ob->parentinv);
02407     copy_m4_m4(obtfm->constinv, ob->constinv);
02408     copy_m4_m4(obtfm->imat, ob->imat);
02409 
02410     return (void *)obtfm;
02411 }
02412 
02413 void object_tfm_restore(Object *ob, void *obtfm_pt)
02414 {
02415     ObTfmBack *obtfm= (ObTfmBack *)obtfm_pt;
02416     copy_v3_v3(ob->loc, obtfm->loc);
02417     copy_v3_v3(ob->dloc, obtfm->dloc);
02418     copy_v3_v3(ob->orig, obtfm->orig);
02419     copy_v3_v3(ob->size, obtfm->size);
02420     copy_v3_v3(ob->dscale, obtfm->dscale);
02421     copy_v3_v3(ob->rot, obtfm->rot);
02422     copy_v3_v3(ob->drot, obtfm->drot);
02423     copy_qt_qt(ob->quat, obtfm->quat);
02424     copy_qt_qt(ob->dquat, obtfm->dquat);
02425     copy_v3_v3(ob->rotAxis, obtfm->rotAxis);
02426     copy_v3_v3(ob->drotAxis, obtfm->drotAxis);
02427     ob->rotAngle= obtfm->rotAngle;
02428     ob->drotAngle= obtfm->drotAngle;
02429     copy_m4_m4(ob->obmat, obtfm->obmat);
02430     copy_m4_m4(ob->parentinv, obtfm->parentinv);
02431     copy_m4_m4(ob->constinv, obtfm->constinv);
02432     copy_m4_m4(ob->imat, obtfm->imat);
02433 }
02434 
02435 int BKE_object_parent_loop_check(const Object *par, const Object *ob)
02436 {
02437     /* test if 'ob' is a parent somewhere in par's parents */
02438     if(par == NULL) return 0;
02439     if(ob == par) return 1;
02440     return BKE_object_parent_loop_check(par->parent, ob);
02441 }
02442 
02443 /* proxy rule: lib_object->proxy_from == the one we borrow from, only set temporal and cleared here */
02444 /*           local_object->proxy      == pointer to library object, saved in files and read */
02445 
02446 /* function below is polluted with proxy exceptions, cleanup will follow! */
02447 
02448 /* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
02449 /* requires flags to be set! */
02450 void object_handle_update(Scene *scene, Object *ob)
02451 {
02452     if(ob->recalc & OB_RECALC_ALL) {
02453         /* speed optimization for animation lookups */
02454         if(ob->pose)
02455             make_pose_channels_hash(ob->pose);
02456 
02457         if(ob->recalc & OB_RECALC_DATA) {
02458             if(ob->type==OB_ARMATURE) {
02459                 /* this happens for reading old files and to match library armatures
02460                    with poses we do it ahead of where_is_object to ensure animation
02461                    is evaluated on the rebuilt pose, otherwise we get incorrect poses
02462                    on file load */
02463                 if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
02464                     armature_rebuild_pose(ob, ob->data);
02465             }
02466         }
02467 
02468         /* XXX new animsys warning: depsgraph tag OB_RECALC_DATA should not skip drivers, 
02469            which is only in where_is_object now */
02470         // XXX: should this case be OB_RECALC_OB instead?
02471         if(ob->recalc & OB_RECALC_ALL) {
02472             
02473             if (G.f & G_DEBUG)
02474                 printf("recalcob %s\n", ob->id.name+2);
02475             
02476             /* handle proxy copy for target */
02477             if(ob->id.lib && ob->proxy_from) {
02478                 // printf("ob proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name);
02479                 if(ob->proxy_from->proxy_group) {/* transform proxy into group space */
02480                     Object *obg= ob->proxy_from->proxy_group;
02481                     invert_m4_m4(obg->imat, obg->obmat);
02482                     mult_m4_m4m4(ob->obmat, obg->imat, ob->proxy_from->obmat);
02483                     if(obg->dup_group) { /* should always be true */
02484                         add_v3_v3(ob->obmat[3], obg->dup_group->dupli_ofs);
02485                     }
02486                 }
02487                 else
02488                     copy_m4_m4(ob->obmat, ob->proxy_from->obmat);
02489             }
02490             else
02491                 where_is_object(scene, ob);
02492         }
02493         
02494         if(ob->recalc & OB_RECALC_DATA) {
02495             ID *data_id= (ID *)ob->data;
02496             AnimData *adt= BKE_animdata_from_id(data_id);
02497             float ctime= (float)scene->r.cfra; // XXX this is bad...
02498             ListBase pidlist;
02499             PTCacheID *pid;
02500             
02501             if (G.f & G_DEBUG)
02502                 printf("recalcdata %s\n", ob->id.name+2);
02503 
02504             if(adt) {
02505                 /* evaluate drivers */
02506                 // XXX: for mesh types, should we push this to derivedmesh instead?
02507                 BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS);
02508             }
02509 
02510             /* includes all keys and modifiers */
02511             switch(ob->type) {
02512             case OB_MESH:
02513                 {
02514 #if 0               // XXX, comment for 2.56a release, background wont set 'scene->customdata_mask'
02515                     EditMesh *em = (ob == scene->obedit)? BKE_mesh_get_editmesh(ob->data): NULL;
02516                     BLI_assert((scene->customdata_mask & CD_MASK_BAREMESH) == CD_MASK_BAREMESH);
02517                     if(em) {
02518                         makeDerivedMesh(scene, ob, em,  scene->customdata_mask); /* was CD_MASK_BAREMESH */
02519                         BKE_mesh_end_editmesh(ob->data, em);
02520                     } else
02521                         makeDerivedMesh(scene, ob, NULL, scene->customdata_mask);
02522 
02523 #else               /* ensure CD_MASK_BAREMESH for now */
02524                     EditMesh *em = (ob == scene->obedit)? BKE_mesh_get_editmesh(ob->data): NULL;
02525                     uint64_t data_mask= scene->customdata_mask | ob->customdata_mask | CD_MASK_BAREMESH;
02526                     if(em) {
02527                         makeDerivedMesh(scene, ob, em,  data_mask); /* was CD_MASK_BAREMESH */
02528                         BKE_mesh_end_editmesh(ob->data, em);
02529                     } else
02530                         makeDerivedMesh(scene, ob, NULL, data_mask);
02531 #endif
02532 
02533                 }
02534                 break;
02535 
02536             case OB_ARMATURE:
02537                 if(ob->id.lib && ob->proxy_from) {
02538                     // printf("pose proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name);
02539                     copy_pose_result(ob->pose, ob->proxy_from->pose);
02540                 }
02541                 else {
02542                     where_is_pose(scene, ob);
02543                 }
02544                 break;
02545 
02546             case OB_MBALL:
02547                 makeDispListMBall(scene, ob);
02548                 break;
02549 
02550             case OB_CURVE:
02551             case OB_SURF:
02552             case OB_FONT:
02553                 makeDispListCurveTypes(scene, ob, 0);
02554                 break;
02555                 
02556             case OB_LATTICE:
02557                 lattice_calc_modifiers(scene, ob);
02558                 break;
02559             }
02560 
02561 
02562             if(ob->particlesystem.first) {
02563                 ParticleSystem *tpsys, *psys;
02564                 DerivedMesh *dm;
02565                 ob->transflag &= ~OB_DUPLIPARTS;
02566                 
02567                 psys= ob->particlesystem.first;
02568                 while(psys) {
02569                     if(psys_check_enabled(ob, psys)) {
02570                         /* check use of dupli objects here */
02571                         if(psys->part && (psys->part->draw_as == PART_DRAW_REND || G.rendering) &&
02572                             ((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob)
02573                             || (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group)))
02574                             ob->transflag |= OB_DUPLIPARTS;
02575 
02576                         particle_system_update(scene, ob, psys);
02577                         psys= psys->next;
02578                     }
02579                     else if(psys->flag & PSYS_DELETE) {
02580                         tpsys=psys->next;
02581                         BLI_remlink(&ob->particlesystem, psys);
02582                         psys_free(ob,psys);
02583                         psys= tpsys;
02584                     }
02585                     else
02586                         psys= psys->next;
02587                 }
02588 
02589                 if(G.rendering && ob->transflag & OB_DUPLIPARTS) {
02590                     /* this is to make sure we get render level duplis in groups:
02591                      * the derivedmesh must be created before init_render_mesh,
02592                      * since object_duplilist does dupliparticles before that */
02593                     dm = mesh_create_derived_render(scene, ob, CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
02594                     dm->release(dm);
02595 
02596                     for(psys=ob->particlesystem.first; psys; psys=psys->next)
02597                         psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
02598                 }
02599             }
02600 
02601             /* check if quick cache is needed */
02602             BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
02603 
02604             for(pid=pidlist.first; pid; pid=pid->next) {
02605                 if((pid->cache->flag & PTCACHE_BAKED)
02606                     || (pid->cache->flag & PTCACHE_QUICK_CACHE)==0)
02607                     continue;
02608 
02609                 if(pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID)==0) {
02610                     scene->physics_settings.quick_cache_step =
02611                         scene->physics_settings.quick_cache_step ?
02612                         MIN2(scene->physics_settings.quick_cache_step, pid->cache->step) :
02613                         pid->cache->step;
02614                 }
02615             }
02616 
02617             BLI_freelistN(&pidlist);
02618         }
02619 
02620         /* the no-group proxy case, we call update */
02621         if(ob->proxy && ob->proxy_group==NULL) {
02622             /* set pointer in library proxy target, for copying, but restore it */
02623             ob->proxy->proxy_from= ob;
02624             // printf("call update, lib ob %s proxy %s\n", ob->proxy->id.name, ob->id.name);
02625             object_handle_update(scene, ob->proxy);
02626         }
02627     
02628         ob->recalc &= ~OB_RECALC_ALL;
02629     }
02630 
02631     /* the case when this is a group proxy, object_update is called in group.c */
02632     if(ob->proxy) {
02633         ob->proxy->proxy_from= ob;
02634         // printf("set proxy pointer for later group stuff %s\n", ob->id.name);
02635     }
02636 }
02637 
02638 void object_sculpt_modifiers_changed(Object *ob)
02639 {
02640     SculptSession *ss= ob->sculpt;
02641 
02642     if(!ss->cache) {
02643         /* we free pbvh on changes, except during sculpt since it can't deal with
02644            changing PVBH node organization, we hope topology does not change in
02645            the meantime .. weak */
02646         if(ss->pbvh) {
02647                 BLI_pbvh_free(ss->pbvh);
02648                 ss->pbvh= NULL;
02649         }
02650 
02651         free_sculptsession_deformMats(ob->sculpt);
02652     } else {
02653         PBVHNode **nodes;
02654         int n, totnode;
02655 
02656         BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
02657 
02658         for(n = 0; n < totnode; n++)
02659             BLI_pbvh_node_mark_update(nodes[n]);
02660 
02661         MEM_freeN(nodes);
02662     }
02663 }
02664 
02665 int give_obdata_texspace(Object *ob, short **texflag, float **loc, float **size, float **rot)
02666 {
02667     
02668     if (ob->data==NULL)
02669         return 0;
02670     
02671     switch (GS(((ID *)ob->data)->name)) {
02672     case ID_ME:
02673     {
02674         Mesh *me= ob->data;
02675         if (texflag)    *texflag = &me->texflag;
02676         if (loc)        *loc = me->loc;
02677         if (size)       *size = me->size;
02678         if (rot)        *rot = me->rot;
02679         break;
02680     }
02681     case ID_CU:
02682     {
02683         Curve *cu= ob->data;
02684         if (texflag)    *texflag = &cu->texflag;
02685         if (loc)        *loc = cu->loc;
02686         if (size)       *size = cu->size;
02687         if (rot)        *rot = cu->rot;
02688         break;
02689     }
02690     case ID_MB:
02691     {
02692         MetaBall *mb= ob->data;
02693         if (texflag)    *texflag = &mb->texflag;
02694         if (loc)        *loc = mb->loc;
02695         if (size)       *size = mb->size;
02696         if (rot)        *rot = mb->rot;
02697         break;
02698     }
02699     default:
02700         return 0;
02701     }
02702     return 1;
02703 }
02704 
02705 /*
02706  * Test a bounding box for ray intersection
02707  * assumes the ray is already local to the boundbox space
02708  */
02709 int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3])
02710 {
02711     static int triangle_indexes[12][3] = {{0, 1, 2}, {0, 2, 3},
02712                                           {3, 2, 6}, {3, 6, 7},
02713                                           {1, 2, 6}, {1, 6, 5}, 
02714                                           {5, 6, 7}, {4, 5, 7},
02715                                           {0, 3, 7}, {0, 4, 7},
02716                                           {0, 1, 5}, {0, 4, 5}};
02717     int result = 0;
02718     int i;
02719     
02720     for (i = 0; i < 12 && result == 0; i++)
02721     {
02722         float lambda;
02723         int v1, v2, v3;
02724         v1 = triangle_indexes[i][0];
02725         v2 = triangle_indexes[i][1];
02726         v3 = triangle_indexes[i][2];
02727         result = isect_ray_tri_v3(ray_start, ray_normal, bb->vec[v1], bb->vec[v2], bb->vec[v3], &lambda, NULL);
02728     }
02729     
02730     return result;
02731 }
02732 
02733 static int pc_cmp(void *a, void *b)
02734 {
02735     LinkData *ad = a, *bd = b;
02736     if(GET_INT_FROM_POINTER(ad->data) > GET_INT_FROM_POINTER(bd->data))
02737         return 1;
02738     else return 0;
02739 }
02740 
02741 int object_insert_ptcache(Object *ob) 
02742 {
02743     LinkData *link = NULL;
02744     int i = 0;
02745 
02746     BLI_sortlist(&ob->pc_ids, pc_cmp);
02747 
02748     for(link=ob->pc_ids.first, i = 0; link; link=link->next, i++) 
02749     {
02750         int index = GET_INT_FROM_POINTER(link->data);
02751 
02752         if(i < index)
02753             break;
02754     }
02755 
02756     link = MEM_callocN(sizeof(LinkData), "PCLink");
02757     link->data = SET_INT_IN_POINTER(i);
02758     BLI_addtail(&ob->pc_ids, link);
02759 
02760     return i;
02761 }
02762 
02763 #if 0
02764 static int pc_findindex(ListBase *listbase, int index)
02765 {
02766     LinkData *link= NULL;
02767     int number= 0;
02768     
02769     if (listbase == NULL) return -1;
02770     
02771     link= listbase->first;
02772     while (link) {
02773         if ((int)link->data == index)
02774             return number;
02775         
02776         number++;
02777         link= link->next;
02778     }
02779     
02780     return -1;
02781 }
02782 
02783 void object_delete_ptcache(Object *ob, int index) 
02784 {
02785     int list_index = pc_findindex(&ob->pc_ids, index);
02786     LinkData *link = BLI_findlink(&ob->pc_ids, list_index);
02787     BLI_freelinkN(&ob->pc_ids, link);
02788 }
02789 #endif
02790 
02791 /* shape key utility function */
02792 
02793 /************************* Mesh ************************/
02794 static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, int from_mix)
02795 {
02796     Mesh *me= ob->data;
02797     Key *key= me->key;
02798     KeyBlock *kb;
02799     int newkey= 0;
02800 
02801     if(key == NULL) {
02802         key= me->key= add_key((ID *)me);
02803         key->type= KEY_RELATIVE;
02804         newkey= 1;
02805     }
02806 
02807     if(newkey || from_mix==FALSE) {
02808         /* create from mesh */
02809         kb= add_keyblock(key, name);
02810         mesh_to_key(me, kb);
02811     }
02812     else {
02813         /* copy from current values */
02814         float *data= do_ob_key(scene, ob);
02815 
02816         /* create new block with prepared data */
02817         kb= add_keyblock(key, name);
02818         kb->data= data;
02819         kb->totelem= me->totvert;
02820     }
02821 
02822     return kb;
02823 }
02824 /************************* Lattice ************************/
02825 static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int from_mix)
02826 {
02827     Lattice *lt= ob->data;
02828     Key *key= lt->key;
02829     KeyBlock *kb;
02830     int newkey= 0;
02831 
02832     if(key==NULL) {
02833         key= lt->key= add_key( (ID *)lt);
02834         key->type= KEY_RELATIVE;
02835         newkey= 1;
02836     }
02837 
02838     if(newkey || from_mix==FALSE) {
02839         kb= add_keyblock(key, name);
02840         if (!newkey) {
02841             KeyBlock *basekb= (KeyBlock *)key->block.first;
02842             kb->data= MEM_dupallocN(basekb->data);
02843             kb->totelem= basekb->totelem;
02844         }
02845         else {
02846             latt_to_key(lt, kb);
02847         }
02848     }
02849     else {
02850         /* copy from current values */
02851         float *data= do_ob_key(scene, ob);
02852 
02853         /* create new block with prepared data */
02854         kb= add_keyblock(key, name);
02855         kb->totelem= lt->pntsu*lt->pntsv*lt->pntsw;
02856         kb->data= data;
02857     }
02858 
02859     return kb;
02860 }
02861 /************************* Curve ************************/
02862 static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int from_mix)
02863 {
02864     Curve *cu= ob->data;
02865     Key *key= cu->key;
02866     KeyBlock *kb;
02867     ListBase *lb= BKE_curve_nurbs(cu);
02868     int newkey= 0;
02869 
02870     if(key==NULL) {
02871         key= cu->key= add_key( (ID *)cu);
02872         key->type = KEY_RELATIVE;
02873         newkey= 1;
02874     }
02875 
02876     if(newkey || from_mix==FALSE) {
02877         /* create from curve */
02878         kb= add_keyblock(key, name);
02879         if (!newkey) {
02880             KeyBlock *basekb= (KeyBlock *)key->block.first;
02881             kb->data= MEM_dupallocN(basekb->data);
02882             kb->totelem= basekb->totelem;
02883         }
02884         else {
02885             curve_to_key(cu, kb, lb);
02886         }
02887     }
02888     else {
02889         /* copy from current values */
02890         float *data= do_ob_key(scene, ob);
02891 
02892         /* create new block with prepared data */
02893         kb= add_keyblock(key, name);
02894         kb->totelem= count_curveverts(lb);
02895         kb->data= data;
02896     }
02897 
02898     return kb;
02899 }
02900 
02901 KeyBlock *object_insert_shape_key(Scene *scene, Object *ob, const char *name, int from_mix)
02902 {
02903     if(ob->type==OB_MESH)                    return insert_meshkey(scene, ob, name, from_mix);
02904     else if ELEM(ob->type, OB_CURVE, OB_SURF)return insert_curvekey(scene, ob, name, from_mix);
02905     else if(ob->type==OB_LATTICE)            return insert_lattkey(scene, ob, name, from_mix);
02906     else                                     return NULL;
02907 }
02908 
02909 /* most important if this is modified it should _always_ return True, in certain
02910  * cases false positives are hard to avoid (shape keys for eg)
02911  */
02912 int object_is_modified(Scene *scene, Object *ob)
02913 {
02914     int flag= 0;
02915 
02916     if(ob_get_key(ob)) {
02917         flag |= eModifierMode_Render;
02918     }
02919     else {
02920         ModifierData *md;
02921         /* cloth */
02922         for(md=modifiers_getVirtualModifierList(ob); md && (flag != (eModifierMode_Render | eModifierMode_Realtime)); md=md->next) {
02923             if((flag & eModifierMode_Render) == 0   && modifier_isEnabled(scene, md, eModifierMode_Render))     flag |= eModifierMode_Render;
02924             if((flag & eModifierMode_Realtime) == 0 && modifier_isEnabled(scene, md, eModifierMode_Realtime))   flag |= eModifierMode_Realtime;
02925         }
02926     }
02927 
02928     return flag;
02929 }
02930 
02931 static void copy_object__forwardModifierLinks(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin)
02932 {
02933     /* this is copied from ID_NEW; it might be better to have a macro */
02934     if(*idpoin && (*idpoin)->newid) *idpoin = (*idpoin)->newid;
02935 }
02936 
02937 void object_relink(Object *ob)
02938 {
02939     if(ob->id.lib)
02940         return;
02941 
02942     relink_constraints(&ob->constraints);
02943     if (ob->pose){
02944         bPoseChannel *chan;
02945         for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
02946             relink_constraints(&chan->constraints);
02947         }
02948     }
02949     modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL);
02950 
02951     if(ob->adt)
02952         BKE_relink_animdata(ob->adt);
02953 
02954     ID_NEW(ob->parent);
02955 
02956     ID_NEW(ob->proxy);
02957     ID_NEW(ob->proxy_group);
02958 }
02959 
02960 MovieClip *object_get_movieclip(Scene *scene, Object *ob, int use_default)
02961 {
02962     MovieClip *clip= use_default ? scene->clip : NULL;
02963     bConstraint *con= ob->constraints.first, *scon= NULL;
02964 
02965     while(con){
02966         if(con->type==CONSTRAINT_TYPE_CAMERASOLVER){
02967             if(scon==NULL || (scon->flag&CONSTRAINT_OFF))
02968                 scon= con;
02969         }
02970 
02971         con= con->next;
02972     }
02973 
02974     if(scon) {
02975         bCameraSolverConstraint *solver= scon->data;
02976         if((solver->flag&CAMERASOLVER_ACTIVECLIP)==0)
02977             clip= solver->clip;
02978         else
02979             clip= scene->clip;
02980     }
02981 
02982     return clip;
02983 }