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