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