|
Blender
V2.59
|
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 }