Blender V2.61 - r43446

ipo.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): 2008,2009 Joshua Leung (IPO System cleanup, Animation System Recode)
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 /* NOTE:
00034  *
00035  * This file is no longer used to provide tools for the depreceated IPO system. Instead, it
00036  * is only used to house the conversion code to the new system.
00037  *
00038  * -- Joshua Leung, Jan 2009
00039  */
00040  
00041 #include <math.h>
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include <stddef.h>
00045 
00046 /* since we have versioning code here */
00047 #define DNA_DEPRECATED_ALLOW
00048 
00049 #include "DNA_anim_types.h"
00050 #include "DNA_constraint_types.h"
00051 #include "DNA_camera_types.h"
00052 #include "DNA_lamp_types.h"
00053 #include "DNA_ipo_types.h"
00054 #include "DNA_key_types.h"
00055 #include "DNA_material_types.h"
00056 #include "DNA_nla_types.h"
00057 #include "DNA_sequence_types.h"
00058 #include "DNA_scene_types.h"
00059 #include "DNA_world_types.h"
00060 #include "DNA_object_types.h"
00061 
00062 #include "BLI_math.h" /* windows needs for M_PI */
00063 #include "BLI_blenlib.h"
00064 #include "BLI_dynstr.h"
00065 #include "BLI_utildefines.h"
00066 
00067 
00068 #include "BKE_ipo.h"
00069 #include "BKE_animsys.h"
00070 #include "BKE_action.h"
00071 #include "BKE_fcurve.h"
00072 #include "BKE_global.h"
00073 #include "BKE_main.h"
00074 #include "BKE_nla.h"
00075 #include "BKE_sequencer.h"
00076 
00077 #include "MEM_guardedalloc.h"
00078 
00079 /* *************************************************** */
00080 /* Old-Data Freeing Tools */
00081 
00082 /* Free data from old IPO-Blocks (those which haven't been converted), but not IPO block itself */
00083 // XXX this shouldn't be necessary anymore, but may occur while not all data is converted yet
00084 void free_ipo (Ipo *ipo)
00085 {
00086     IpoCurve *icu, *icn;
00087     int n= 0;
00088     
00089     for (icu= ipo->curve.first; icu; icu= icn) {
00090         icn= icu->next;
00091         n++;
00092         
00093         if (icu->bezt) MEM_freeN(icu->bezt);
00094         if (icu->bp) MEM_freeN(icu->bp);
00095         if (icu->driver) MEM_freeN(icu->driver);
00096         
00097         BLI_freelinkN(&ipo->curve, icu);
00098     }
00099     
00100     if (G.f & G_DEBUG)
00101         printf("Freed %d (Unconverted) Ipo-Curves from IPO '%s' \n", n, ipo->id.name+2);
00102 }
00103 
00104 /* *************************************************** */
00105 /* ADRCODE to RNA-Path Conversion Code  - Special (Bitflags) */
00106 
00107 /* Mapping Table for bitflag <-> RNA path */
00108 typedef struct AdrBit2Path {
00109     int bit;
00110     const char *path;
00111     int array_index;
00112 } AdrBit2Path;
00113 
00114 /* ----------------- */
00115 /* Mapping Tables to use bits <-> RNA paths */
00116 
00117 /* Object layers */
00118 static AdrBit2Path ob_layer_bits[]= {
00119     {(1<<0), "layers", 0},
00120     {(1<<1), "layers", 1},
00121     {(1<<2), "layers", 2},
00122     {(1<<3), "layers", 3},
00123     {(1<<4), "layers", 4},
00124     {(1<<5), "layers", 5},
00125     {(1<<6), "layers", 6},
00126     {(1<<7), "layers", 7},
00127     {(1<<8), "layers", 8},
00128     {(1<<9), "layers", 9},
00129     {(1<<10), "layers", 10},
00130     {(1<<11), "layers", 11},
00131     {(1<<12), "layers", 12},
00132     {(1<<13), "layers", 13},
00133     {(1<<14), "layers", 14},
00134     {(1<<15), "layers", 15},
00135     {(1<<16), "layers", 16},
00136     {(1<<17), "layers", 17},
00137     {(1<<18), "layers", 18},
00138     {(1<<19), "layers", 19}
00139 };
00140 
00141 /* Material mode */
00142 static AdrBit2Path ma_mode_bits[]= {
00143 //  {MA_TRACEBLE, "traceable", 0},
00144 //  {MA_SHADOW, "shadow", 0},
00145 //  {MA_SHLESS, "shadeless", 0},
00146 //  ...
00147     {MA_RAYTRANSP, "transparency", 0},
00148     {MA_RAYMIRROR, "raytrace_mirror.enabled", 0},
00149 //  {MA_HALO, "type", MA_TYPE_HALO}
00150 };
00151 
00152 /* ----------------- */
00153 
00154 /* quick macro for returning the appropriate array for adrcode_bitmaps_to_paths() */
00155 #define RET_ABP(items) \
00156     { \
00157         *tot= sizeof(items)/sizeof(AdrBit2Path); \
00158         return items; \
00159     }
00160 
00161 /* This function checks if a Blocktype+Adrcode combo, returning a mapping table */
00162 static AdrBit2Path *adrcode_bitmaps_to_paths (int blocktype, int adrcode, int *tot)
00163 {
00164     /* Object layers */
00165     if ((blocktype == ID_OB) && (adrcode == OB_LAY)) 
00166         RET_ABP(ob_layer_bits)
00167     else if ((blocktype == ID_MA) && (adrcode == MA_MODE))
00168         RET_ABP(ma_mode_bits)
00169     // XXX TODO: add other types...
00170     
00171     /* Normal curve */
00172     return NULL;
00173 }
00174 
00175 /* *************************************************** */
00176 /* ADRCODE to RNA-Path Conversion Code  - Standard */
00177 
00178 /* Object types */
00179 static const char *ob_adrcodes_to_paths (int adrcode, int *array_index)
00180 {
00181     /* set array index like this in-case nothing sets it correctly  */
00182     *array_index= 0;
00183     
00184     /* result depends on adrcode */
00185     switch (adrcode) {
00186         case OB_LOC_X:
00187             *array_index= 0; return "location";
00188         case OB_LOC_Y:
00189             *array_index= 1; return "location";
00190         case OB_LOC_Z:
00191             *array_index= 2; return "location";
00192         case OB_DLOC_X:
00193             *array_index= 0; return "delta_location";
00194         case OB_DLOC_Y:
00195             *array_index= 1; return "delta_location";
00196         case OB_DLOC_Z:
00197             *array_index= 2; return "delta_location";
00198         
00199         case OB_ROT_X:
00200             *array_index= 0; return "rotation_euler";
00201         case OB_ROT_Y:
00202             *array_index= 1; return "rotation_euler";
00203         case OB_ROT_Z:
00204             *array_index= 2; return "rotation_euler";
00205         case OB_DROT_X:
00206             *array_index= 0; return "delta_rotation_euler";
00207         case OB_DROT_Y:
00208             *array_index= 1; return "delta_rotation_euler";
00209         case OB_DROT_Z:
00210             *array_index= 2; return "delta_rotation_euler";
00211             
00212         case OB_SIZE_X:
00213             *array_index= 0; return "scale";
00214         case OB_SIZE_Y:
00215             *array_index= 1; return "scale";
00216         case OB_SIZE_Z:
00217             *array_index= 2; return "scale";
00218         case OB_DSIZE_X:
00219             *array_index= 0; return "delta_scale";
00220         case OB_DSIZE_Y:
00221             *array_index= 1; return "delta_scale";
00222         case OB_DSIZE_Z:
00223             *array_index= 2; return "delta_scale";
00224         case OB_COL_R:
00225             *array_index= 0; return "color";
00226         case OB_COL_G:
00227             *array_index= 1; return "color";
00228         case OB_COL_B:
00229             *array_index= 2; return "color";
00230         case OB_COL_A:
00231             *array_index= 3; return "color";
00232 #if 0
00233         case OB_PD_FSTR:
00234             if (ob->pd) poin= &(ob->pd->f_strength);
00235             break;
00236         case OB_PD_FFALL:
00237             if (ob->pd) poin= &(ob->pd->f_power);
00238             break;
00239         case OB_PD_SDAMP:
00240             if (ob->pd) poin= &(ob->pd->pdef_damp);
00241             break;
00242         case OB_PD_RDAMP:
00243             if (ob->pd) poin= &(ob->pd->pdef_rdamp);
00244             break;
00245         case OB_PD_PERM:
00246             if (ob->pd) poin= &(ob->pd->pdef_perm);
00247             break;
00248         case OB_PD_FMAXD:
00249             if (ob->pd) poin= &(ob->pd->maxdist);
00250             break;
00251 #endif
00252     }
00253     
00254     return NULL;
00255 }
00256 
00257 /* PoseChannel types 
00258  * NOTE: pchan name comes from 'actname' added earlier... 
00259  */
00260 static const char *pchan_adrcodes_to_paths (int adrcode, int *array_index)
00261 {
00262     /* set array index like this in-case nothing sets it correctly  */
00263     *array_index= 0;
00264     
00265     /* result depends on adrcode */
00266     switch (adrcode) {
00267         case AC_QUAT_W:
00268             *array_index= 0; return "rotation_quaternion";
00269         case AC_QUAT_X:
00270             *array_index= 1; return "rotation_quaternion";
00271         case AC_QUAT_Y:
00272             *array_index= 2; return "rotation_quaternion";
00273         case AC_QUAT_Z:
00274             *array_index= 3; return "rotation_quaternion";
00275             
00276         case AC_EUL_X:
00277             *array_index= 0; return "rotation_euler";
00278         case AC_EUL_Y:
00279             *array_index= 1; return "rotation_euler";
00280         case AC_EUL_Z:
00281             *array_index= 2; return "rotation_euler";
00282         
00283         case AC_LOC_X:
00284             *array_index= 0; return "location";
00285         case AC_LOC_Y:
00286             *array_index= 1; return "location";
00287         case AC_LOC_Z:
00288             *array_index= 2; return "location";
00289         
00290         case AC_SIZE_X:
00291             *array_index= 0; return "scale";
00292         case AC_SIZE_Y:
00293             *array_index= 1; return "scale";
00294         case AC_SIZE_Z:
00295             *array_index= 2; return "scale";
00296     }
00297     
00298     /* for debugging only */
00299     printf("ERROR: unmatched PoseChannel setting (code %d) \n", adrcode);
00300     return NULL;
00301 }
00302 
00303 /* Constraint types */
00304 static const char *constraint_adrcodes_to_paths (int adrcode, int *array_index)
00305 {
00306     /* set array index like this in-case nothing sets it correctly  */
00307     *array_index= 0;
00308     
00309     /* result depends on adrcode */
00310     switch (adrcode) {
00311         case CO_ENFORCE:
00312             return "influence";
00313         case CO_HEADTAIL:   // XXX this needs to be wrapped in RNA.. probably then this path will be invalid
00314             return "data.head_tail";
00315     }
00316     
00317     return NULL;
00318 }
00319 
00320 /* ShapeKey types 
00321  * NOTE: as we don't have access to the keyblock where the data comes from (for now), 
00322  *       we'll just use numerical indices for now...
00323  */
00324 static char *shapekey_adrcodes_to_paths (int adrcode, int *UNUSED(array_index))
00325 {
00326     static char buf[128];
00327     
00328     /* block will be attached to ID_KE block, and setting that we alter is the 'value' (which sets keyblock.curval) */
00329     // XXX adrcode 0 was dummy 'speed' curve 
00330     if (adrcode == 0) 
00331         strcpy(buf, "speed");
00332     else
00333         BLI_snprintf(buf, sizeof(buf), "key_blocks[%d].value", adrcode);
00334     return buf;
00335 }
00336 
00337 /* MTex (Texture Slot) types */
00338 static const char *mtex_adrcodes_to_paths (int adrcode, int *UNUSED(array_index))
00339 {
00340     const char *base=NULL, *prop=NULL;
00341     static char buf[128];
00342     
00343     /* base part of path */
00344     if (adrcode & MA_MAP1) base= "textures[0]";
00345     else if (adrcode & MA_MAP2) base= "textures[1]";
00346     else if (adrcode & MA_MAP3) base= "textures[2]";
00347     else if (adrcode & MA_MAP4) base= "textures[3]";
00348     else if (adrcode & MA_MAP5) base= "textures[4]";
00349     else if (adrcode & MA_MAP6) base= "textures[5]";
00350     else if (adrcode & MA_MAP7) base= "textures[6]";
00351     else if (adrcode & MA_MAP8) base= "textures[7]";
00352     else if (adrcode & MA_MAP9) base= "textures[8]";
00353     else if (adrcode & MA_MAP10) base= "textures[9]";
00354     else if (adrcode & MA_MAP11) base= "textures[10]";
00355     else if (adrcode & MA_MAP12) base= "textures[11]";
00356     else if (adrcode & MA_MAP13) base= "textures[12]";
00357     else if (adrcode & MA_MAP14) base= "textures[13]";
00358     else if (adrcode & MA_MAP15) base= "textures[14]";
00359     else if (adrcode & MA_MAP16) base= "textures[15]";
00360     else if (adrcode & MA_MAP17) base= "textures[16]";
00361     else if (adrcode & MA_MAP18) base= "textures[17]";
00362         
00363     /* property identifier for path */
00364     adrcode= (adrcode & (MA_MAP1-1));
00365     switch (adrcode) {
00366 #if 0 // XXX these are not wrapped in RNA yet!
00367         case MAP_OFS_X:
00368             poin= &(mtex->ofs[0]); break;
00369         case MAP_OFS_Y:
00370             poin= &(mtex->ofs[1]); break;
00371         case MAP_OFS_Z:
00372             poin= &(mtex->ofs[2]); break;
00373         case MAP_SIZE_X:
00374             poin= &(mtex->size[0]); break;
00375         case MAP_SIZE_Y:
00376             poin= &(mtex->size[1]); break;
00377         case MAP_SIZE_Z:
00378             poin= &(mtex->size[2]); break;
00379         case MAP_R:
00380             poin= &(mtex->r); break;
00381         case MAP_G:
00382             poin= &(mtex->g); break;
00383         case MAP_B:
00384             poin= &(mtex->b); break;
00385         case MAP_DVAR:
00386             poin= &(mtex->def_var); break;
00387         case MAP_COLF:
00388             poin= &(mtex->colfac); break;
00389         case MAP_NORF:
00390             poin= &(mtex->norfac); break;
00391         case MAP_VARF:
00392             poin= &(mtex->varfac); break;
00393 #endif
00394         case MAP_DISP:
00395             prop= "warp_factor"; break;
00396     }
00397     
00398     /* only build and return path if there's a property */
00399     if (prop) {
00400         BLI_snprintf(buf, 128, "%s.%s", base, prop);
00401         return buf;
00402     }
00403     else
00404         return NULL;
00405 }
00406 
00407 /* Texture types */
00408 static const char *texture_adrcodes_to_paths (int adrcode, int *array_index)
00409 {
00410     /* set array index like this in-case nothing sets it correctly  */
00411     *array_index= 0;
00412     
00413     /* result depends on adrcode */
00414     switch (adrcode) {
00415         case TE_NSIZE:
00416             return "noise_size";
00417         case TE_TURB:
00418             return "turbulence";
00419             
00420         case TE_NDEPTH: // XXX texture RNA undefined
00421             //poin= &(tex->noisedepth); *type= IPO_SHORT; break;
00422             break;
00423         case TE_NTYPE: // XXX texture RNA undefined
00424             //poin= &(tex->noisetype); *type= IPO_SHORT; break;
00425             break;
00426             
00427         case TE_N_BAS1:
00428             return "noise_basis";
00429         case TE_N_BAS2:
00430             return "noise_basis"; // XXX this is not yet defined in RNA...
00431         
00432             /* voronoi */
00433         case TE_VNW1:
00434             *array_index= 0; return "feature_weights";
00435         case TE_VNW2:
00436             *array_index= 1; return "feature_weights";
00437         case TE_VNW3:
00438             *array_index= 2; return "feature_weights";
00439         case TE_VNW4:
00440             *array_index= 3; return "feature_weights";
00441         case TE_VNMEXP:
00442             return "minkovsky_exponent";
00443         case TE_VN_DISTM:
00444             return "distance_metric";
00445         case TE_VN_COLT:
00446             return "color_type";
00447         
00448             /* distorted noise / voronoi */
00449         case TE_ISCA:
00450             return "noise_intensity";
00451             
00452             /* distorted noise */
00453         case TE_DISTA:
00454             return "distortion_amount";
00455         
00456             /* musgrave */
00457         case TE_MG_TYP: // XXX texture RNA undefined
00458         //  poin= &(tex->stype); *type= IPO_SHORT; break;
00459             break;
00460         case TE_MGH:
00461             return "highest_dimension";
00462         case TE_MG_LAC:
00463             return "lacunarity";
00464         case TE_MG_OCT:
00465             return "octaves";
00466         case TE_MG_OFF:
00467             return "offset";
00468         case TE_MG_GAIN:
00469             return "gain";
00470             
00471         case TE_COL_R:
00472             *array_index= 0; return "rgb_factor";
00473         case TE_COL_G:
00474             *array_index= 1; return "rgb_factor";
00475         case TE_COL_B:
00476             *array_index= 2; return "rgb_factor";
00477             
00478         case TE_BRIGHT:
00479             return "brightness";
00480         case TE_CONTRA:
00481             return "constrast";
00482     }
00483     
00484     return NULL;
00485 }
00486 
00487 /* Material Types */
00488 static const char *material_adrcodes_to_paths (int adrcode, int *array_index)
00489 {
00490     /* set array index like this in-case nothing sets it correctly  */
00491     *array_index= 0;
00492     
00493     /* result depends on adrcode */
00494     switch (adrcode) {
00495         case MA_COL_R:
00496             *array_index= 0; return "diffuse_color";
00497         case MA_COL_G:
00498             *array_index= 1; return "diffuse_color";
00499         case MA_COL_B:
00500             *array_index= 2; return "diffuse_color";
00501             
00502         case MA_SPEC_R:
00503             *array_index= 0; return "specular_color";
00504         case MA_SPEC_G:
00505             *array_index= 1; return "specular_color";
00506         case MA_SPEC_B:
00507             *array_index= 2; return "specular_color";
00508             
00509         case MA_MIR_R:
00510             *array_index= 0; return "mirror_color";
00511         case MA_MIR_G:
00512             *array_index= 1; return "mirror_color";
00513         case MA_MIR_B:
00514             *array_index= 2; return "mirror_color";
00515             
00516         case MA_ALPHA:
00517             return "alpha";
00518             
00519         case MA_REF:
00520             return "diffuse_intensity";
00521         
00522         case MA_EMIT:
00523             return "emit";
00524         
00525         case MA_AMB:
00526             return "ambient";
00527         
00528         case MA_SPEC:
00529             return "specular_intensity";
00530         
00531         case MA_HARD:
00532             return "specular_hardness";
00533             
00534         case MA_SPTR:
00535             return "specular_opacity";
00536             
00537         case MA_IOR:
00538             return "ior";
00539             
00540         case MA_HASIZE:
00541             return "halo.size";
00542             
00543         case MA_TRANSLU:
00544             return "translucency";
00545             
00546         case MA_RAYM:
00547             return "raytrace_mirror.reflect";
00548             
00549         case MA_FRESMIR:
00550             return "raytrace_mirror.fresnel";
00551             
00552         case MA_FRESMIRI:
00553             return "raytrace_mirror.fresnel_factor";
00554             
00555         case MA_FRESTRA:
00556             return "raytrace_transparency.fresnel";
00557             
00558         case MA_FRESTRAI:
00559             return "raytrace_transparency.fresnel_factor";
00560             
00561         case MA_ADD:
00562             return "halo.add";
00563         
00564         default: /* for now, we assume that the others were MTex channels */
00565             return mtex_adrcodes_to_paths(adrcode, array_index);
00566     }
00567     
00568     return NULL;    
00569 }
00570 
00571 /* Camera Types */
00572 static const char *camera_adrcodes_to_paths (int adrcode, int *array_index)
00573 {
00574     /* set array index like this in-case nothing sets it correctly  */
00575     *array_index= 0;
00576     
00577     /* result depends on adrcode */
00578     switch (adrcode) {
00579         case CAM_LENS:
00580 #if 0 // XXX this cannot be resolved easily... perhaps we assume camera is perspective (works for most cases...
00581             if (ca->type == CAM_ORTHO)
00582                 return "ortho_scale";
00583             else
00584                 return "lens"; 
00585 #else // XXX lazy hack for now...
00586             return "lens";
00587 #endif // XXX this cannot be resolved easily
00588             
00589         case CAM_STA:
00590             return "clip_start";
00591         case CAM_END:
00592             return "clip_end";
00593             
00594 #if 0 // XXX these are not defined in RNA
00595         case CAM_YF_APERT:
00596             poin= &(ca->YF_aperture); break;
00597         case CAM_YF_FDIST:
00598             poin= &(ca->YF_dofdist); break;
00599 #endif // XXX these are not defined in RNA
00600             
00601         case CAM_SHIFT_X:
00602             return "shift_x";
00603         case CAM_SHIFT_Y:
00604             return "shift_y";
00605     }
00606     
00607     /* unrecognised adrcode, or not-yet-handled ones! */
00608     return NULL;
00609 }
00610 
00611 /* Lamp Types */
00612 static const char *lamp_adrcodes_to_paths (int adrcode, int *array_index)
00613 {
00614     /* set array index like this in-case nothing sets it correctly  */
00615     *array_index= 0;
00616     
00617     /* result depends on adrcode */
00618     switch (adrcode) {
00619         case LA_ENERGY:
00620             return "energy";
00621             
00622         case LA_COL_R:
00623             *array_index= 0;  return "color";
00624         case LA_COL_G:
00625             *array_index= 1;  return "color";
00626         case LA_COL_B:
00627             *array_index= 2;  return "color";
00628             
00629         case LA_DIST:
00630             return "distance";
00631         
00632         case LA_SPOTSI:
00633             return "spot_size";
00634         case LA_SPOTBL:
00635             return "spot_blend";
00636             
00637         case LA_QUAD1:
00638             return "linear_attenuation";
00639         case LA_QUAD2:
00640             return "quadratic_attenuation";
00641             
00642         case LA_HALOINT:
00643             return "halo_intensity";
00644             
00645         default: /* for now, we assume that the others were MTex channels */
00646             return mtex_adrcodes_to_paths(adrcode, array_index);
00647     }
00648     
00649     /* unrecognised adrcode, or not-yet-handled ones! */
00650     return NULL;
00651 }
00652 
00653 /* Sound Types */
00654 static const char *sound_adrcodes_to_paths (int adrcode, int *array_index)
00655 {
00656     /* set array index like this in-case nothing sets it correctly  */
00657     *array_index= 0;
00658     
00659     /* result depends on adrcode */
00660     switch (adrcode) {
00661         case SND_VOLUME:
00662             return "volume";
00663         case SND_PITCH:
00664             return "pitch";
00665     /* XXX Joshua -- I had wrapped panning in rna, but someone commented out, calling it "unused" */
00666     /*  case SND_PANNING:
00667             return "panning"; */
00668         case SND_ATTEN:
00669             return "attenuation";
00670     }
00671     
00672     /* unrecognised adrcode, or not-yet-handled ones! */
00673     return NULL;
00674 }
00675 
00676 /* World Types */
00677 static const char *world_adrcodes_to_paths (int adrcode, int *array_index)
00678 {
00679     /* set array index like this in-case nothing sets it correctly  */
00680     *array_index= 0;
00681     
00682     /* result depends on adrcode */
00683     switch (adrcode) {
00684         case WO_HOR_R:
00685             *array_index= 0; return "horizon_color";
00686         case WO_HOR_G:
00687             *array_index= 1; return "horizon_color";
00688         case WO_HOR_B:
00689             *array_index= 2; return "horizon_color";
00690         case WO_ZEN_R:
00691             *array_index= 0; return "zenith_color";
00692         case WO_ZEN_G:
00693             *array_index= 1; return "zenith_color";
00694         case WO_ZEN_B:
00695             *array_index= 2; return "zenith_color";
00696         
00697         case WO_EXPOS:
00698             return "exposure";
00699         
00700         case WO_MISI:
00701             return "mist.intensity";
00702         case WO_MISTDI:
00703             return "mist.depth";
00704         case WO_MISTSTA:
00705             return "mist.start";
00706         case WO_MISTHI:
00707             return "mist.height";
00708 
00709         case WO_STAR_R:
00710         case WO_STAR_G:
00711         case WO_STAR_B:
00712             printf("WARNING: WO_STAR_R/G/B deprecated\n");
00713             return NULL;
00714         
00715         case WO_STARDIST:
00716             return "stars.min_distance";
00717         case WO_STARSIZE:
00718             return "stars.size";
00719         
00720         default: /* for now, we assume that the others were MTex channels */
00721             return mtex_adrcodes_to_paths(adrcode, array_index);
00722         }
00723         
00724     return NULL;    
00725 }
00726 
00727 /* Particle Types */
00728 static const char *particle_adrcodes_to_paths (int adrcode, int *array_index)
00729 {
00730     /* set array index like this in-case nothing sets it correctly  */
00731     *array_index= 0;
00732     
00733     /* result depends on adrcode */
00734     switch (adrcode) {
00735         case PART_CLUMP:
00736             return "settings.clump_factor";
00737         case PART_AVE:
00738             return "settings.angular_velocity_factor";
00739         case PART_SIZE:
00740             return "settings.particle_size";
00741         case PART_DRAG:
00742             return "settings.drag_factor";
00743         case PART_BROWN:
00744             return "settings.brownian_factor";
00745         case PART_DAMP:
00746             return "settings.damp_factor";
00747         case PART_LENGTH:
00748             return "settings.length";
00749         case PART_GRAV_X:
00750             *array_index= 0; return "settings.acceleration";
00751         case PART_GRAV_Y:
00752             *array_index= 1; return "settings.acceleration";
00753         case PART_GRAV_Z:
00754             *array_index= 2; return "settings.acceleration";
00755         case PART_KINK_AMP:
00756             return "settings.kink_amplitude";
00757         case PART_KINK_FREQ:
00758             return "settings.kink_frequency";
00759         case PART_KINK_SHAPE:
00760             return "settings.kink_shape";
00761         case PART_BB_TILT:
00762             return "settings.billboard_tilt";
00763         
00764         /* PartDeflect needs to be sorted out properly in rna_object_force;
00765            If anyone else works on this, but is unfamiliar, these particular
00766             settings reference the particles of the system themselves
00767             being used as forces -- it will use the same rna structure
00768             as the similar object forces                */
00769         /*case PART_PD_FSTR:
00770             if (part->pd) poin= &(part->pd->f_strength);
00771             break;
00772         case PART_PD_FFALL:
00773             if (part->pd) poin= &(part->pd->f_power);
00774             break;
00775         case PART_PD_FMAXD:
00776             if (part->pd) poin= &(part->pd->maxdist);
00777             break;
00778         case PART_PD2_FSTR:
00779             if (part->pd2) poin= &(part->pd2->f_strength);
00780             break;
00781         case PART_PD2_FFALL:
00782             if (part->pd2) poin= &(part->pd2->f_power);
00783             break;
00784         case PART_PD2_FMAXD:
00785             if (part->pd2) poin= &(part->pd2->maxdist);
00786             break;*/
00787 
00788         }
00789         
00790     return NULL;    
00791 }
00792 
00793 /* ------- */
00794 
00795 /* Allocate memory for RNA-path for some property given a blocktype, adrcode, and 'root' parts of path
00796  *  Input:
00797  *      - blocktype, adrcode    - determines setting to get
00798  *      - actname, constname,seq - used to build path
00799  *  Output:
00800  *      - array_index           - index in property's array (if applicable) to use
00801  *      - return                - the allocated path...
00802  */
00803 static char *get_rna_access (int blocktype, int adrcode, char actname[], char constname[], Sequence *seq, int *array_index)
00804 {
00805     DynStr *path= BLI_dynstr_new();
00806     const char *propname=NULL;
00807     char *rpath=NULL;
00808     char buf[512];
00809     int dummy_index= 0;
00810     
00811     /* hack: if constname is set, we can only be dealing with an Constraint curve */
00812     if (constname)
00813         blocktype= ID_CO;
00814     
00815     /* get property name based on blocktype */
00816     switch (blocktype) {
00817         case ID_OB: /* object */
00818             propname= ob_adrcodes_to_paths(adrcode, &dummy_index);
00819             break;
00820         
00821         case ID_PO: /* pose channel */
00822             propname= pchan_adrcodes_to_paths(adrcode, &dummy_index);
00823             break;
00824             
00825         case ID_KE: /* shapekeys */
00826             propname= shapekey_adrcodes_to_paths(adrcode, &dummy_index);
00827             break;
00828             
00829         case ID_CO: /* constraint */
00830             propname= constraint_adrcodes_to_paths(adrcode, &dummy_index);  
00831             break;
00832             
00833         case ID_TE: /* texture */
00834             propname= texture_adrcodes_to_paths(adrcode, &dummy_index);
00835             break;
00836             
00837         case ID_MA: /* material */
00838             propname= material_adrcodes_to_paths(adrcode, &dummy_index);
00839             break;
00840             
00841         case ID_CA: /* camera */
00842             propname= camera_adrcodes_to_paths(adrcode, &dummy_index);
00843             break;
00844             
00845         case ID_LA: /* lamp */
00846             propname= lamp_adrcodes_to_paths(adrcode, &dummy_index);
00847             break;
00848         
00849         case ID_SO: /* sound */
00850             propname= sound_adrcodes_to_paths(adrcode, &dummy_index);
00851             break;
00852         
00853         case ID_WO: /* world */
00854             propname= world_adrcodes_to_paths(adrcode, &dummy_index);
00855             break;
00856         
00857         case ID_PA: /* particle */
00858             propname= particle_adrcodes_to_paths(adrcode, &dummy_index);
00859             break;
00860             
00861         case ID_CU: /* curve */
00862             /* this used to be a 'dummy' curve which got evaluated on the fly... 
00863              * now we've got real var for this!
00864              */
00865             propname= "eval_time";
00866             break;
00867         
00868         /* XXX problematic blocktypes */        
00869         case ID_SEQ: /* sequencer strip */
00870             //SEQ_FAC1:
00871             switch (adrcode) {
00872             case SEQ_FAC1:
00873                 propname= "effect_fader";
00874                 break;
00875             case SEQ_FAC_SPEED:
00876                 propname= "speed_fader";
00877                 break;
00878             case SEQ_FAC_OPACITY:
00879                 propname= "blend_opacity";
00880                 break;
00881             }
00882             //  poin= &(seq->facf0); // XXX this doesn't seem to be included anywhere in sequencer RNA...
00883             break;
00884             
00885         /* special hacks */
00886         case -1:
00887             /* special case for rotdiff drivers... we don't need a property for this... */
00888             break;
00889             
00890         // TODO... add other blocktypes...
00891         default:
00892             printf("IPO2ANIMATO WARNING: No path for blocktype %d, adrcode %d yet \n", blocktype, adrcode);
00893             break;
00894     }
00895     
00896     /* check if any property found 
00897      *  - blocktype < 0 is special case for a specific type of driver, where we don't need a property name...
00898      */
00899     if ((propname == NULL) && (blocktype > 0)) {
00900         /* nothing was found, so exit */
00901         if (array_index) 
00902             *array_index= 0;
00903             
00904         BLI_dynstr_free(path);
00905         
00906         return NULL;
00907     }
00908     else {
00909         if (array_index)
00910             *array_index= dummy_index;
00911     }
00912 
00913     /* 'buf' _must_ be initialized in this block */
00914     /* append preceding bits to path */
00915     /* note, strings are not escapted and they should be! */
00916     if ((actname && actname[0]) && (constname && constname[0])) {
00917         /* Constraint in Pose-Channel */
00918         BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"].constraints[\"%s\"]", actname, constname);
00919     }
00920     else if (actname && actname[0]) {
00921         if ((blocktype == ID_OB) && strcmp(actname, "Object")==0) {
00922             /* Actionified "Object" IPO's... no extra path stuff needed */
00923             buf[0]= '\0'; /* empty string */
00924         }
00925         else if ((blocktype == ID_KE) && strcmp(actname, "Shape")==0) {
00926             /* Actionified "Shape" IPO's - these are forced onto object level via the action container there... */
00927             strcpy(buf, "data.shape_keys");
00928         }
00929         else {
00930             /* Pose-Channel */
00931             BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"]", actname);
00932         }
00933     }
00934     else if (constname && constname[0]) {
00935         /* Constraint in Object */
00936         BLI_snprintf(buf, sizeof(buf), "constraints[\"%s\"]", constname);
00937     }
00938     else if (seq) {
00939         /* Sequence names in Scene */
00940         BLI_snprintf(buf, sizeof(buf), "sequence_editor.sequences_all[\"%s\"]", seq->name+2);
00941     }
00942     else {
00943         buf[0]= '\0'; /* empty string */
00944     }
00945 
00946     BLI_dynstr_append(path, buf);
00947     
00948     /* need to add dot before property if there was anything precceding this */
00949     if (buf[0])
00950         BLI_dynstr_append(path, ".");
00951     
00952     /* now write name of property */
00953     BLI_dynstr_append(path, propname);
00954     
00955     /* if there was no array index pointer provided, add it to the path */
00956     if (array_index == NULL) {
00957         BLI_snprintf(buf, sizeof(buf), "[\"%d\"]", dummy_index);
00958         BLI_dynstr_append(path, buf);
00959     }
00960     
00961     /* convert to normal MEM_malloc'd string */
00962     rpath= BLI_dynstr_get_cstring(path);
00963     BLI_dynstr_free(path);
00964     
00965     /* return path... */
00966     return rpath;
00967 }
00968 
00969 /* *************************************************** */
00970 /* Conversion Utilities */
00971 
00972 /* Convert adrcodes to driver target transform channel types */
00973 static short adrcode_to_dtar_transchan (short adrcode)
00974 {
00975     switch (adrcode) {
00976         case OB_LOC_X:  
00977             return DTAR_TRANSCHAN_LOCX;
00978         case OB_LOC_Y:
00979             return DTAR_TRANSCHAN_LOCY;
00980         case OB_LOC_Z:
00981             return DTAR_TRANSCHAN_LOCZ;
00982         
00983         case OB_ROT_X:  
00984             return DTAR_TRANSCHAN_ROTX;
00985         case OB_ROT_Y:
00986             return DTAR_TRANSCHAN_ROTY;
00987         case OB_ROT_Z:
00988             return DTAR_TRANSCHAN_ROTZ;
00989         
00990         case OB_SIZE_X: 
00991             return DTAR_TRANSCHAN_SCALEX;
00992         case OB_SIZE_Y:
00993             return DTAR_TRANSCHAN_SCALEX;
00994         case OB_SIZE_Z:
00995             return DTAR_TRANSCHAN_SCALEX;
00996             
00997         default:
00998             return 0;
00999     }
01000 }
01001 
01002 /* Convert IpoDriver to ChannelDriver - will free the old data (i.e. the old driver) */
01003 static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
01004 {
01005     ChannelDriver *cdriver;
01006     
01007     /* allocate memory for new driver */
01008     cdriver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
01009     
01010     /* if 'pydriver', just copy data across */
01011     if (idriver->type == IPO_DRIVER_TYPE_PYTHON) {
01012         /* PyDriver only requires the expression to be copied */
01013         // FIXME: expression will be useless due to API changes, but at least not totally lost
01014         cdriver->type = DRIVER_TYPE_PYTHON;
01015         if (idriver->name[0])
01016             BLI_strncpy(cdriver->expression, idriver->name, sizeof(cdriver->expression));
01017     }
01018     else {
01019         DriverVar *dvar = NULL;
01020         DriverTarget *dtar = NULL;
01021         
01022         /* this should be ok for all types here... */
01023         cdriver->type= DRIVER_TYPE_AVERAGE;
01024         
01025         /* what to store depends on the 'blocktype' - object or posechannel */
01026         if (idriver->blocktype == ID_AR) { /* PoseChannel */
01027             if (idriver->adrcode == OB_ROT_DIFF) {
01028                 /* Rotational Difference requires a special type of variable */
01029                 dvar= driver_add_new_variable(cdriver);
01030                 driver_change_variable_type(dvar, DVAR_TYPE_ROT_DIFF);
01031                 
01032                     /* first bone target */
01033                 dtar= &dvar->targets[0];
01034                 dtar->id= (ID *)idriver->ob;
01035                 dtar->idtype= ID_OB;
01036                 if (idriver->name[0])
01037                     BLI_strncpy(dtar->pchan_name, idriver->name, sizeof(dtar->pchan_name));
01038                 
01039                     /* second bone target (name was stored in same var as the first one) */
01040                 dtar= &dvar->targets[1];
01041                 dtar->id= (ID *)idriver->ob;
01042                 dtar->idtype= ID_OB;
01043                 if (idriver->name[0]) // xxx... for safety
01044                     BLI_strncpy(dtar->pchan_name, idriver->name+DRIVER_NAME_OFFS, sizeof(dtar->pchan_name));
01045             }
01046             else {
01047                 /* only a single variable, of type 'transform channel' */
01048                 dvar= driver_add_new_variable(cdriver);
01049                 driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
01050                 
01051                 /* only requires a single target */
01052                 dtar= &dvar->targets[0];
01053                 dtar->id= (ID *)idriver->ob;
01054                 dtar->idtype= ID_OB;
01055                 if (idriver->name[0])
01056                     BLI_strncpy(dtar->pchan_name, idriver->name, sizeof(dtar->pchan_name));
01057                 dtar->transChan= adrcode_to_dtar_transchan(idriver->adrcode);
01058                 dtar->flag |= DTAR_FLAG_LOCALSPACE; /* old drivers took local space */
01059             }
01060         }
01061         else { /* Object */
01062             /* only a single variable, of type 'transform channel' */
01063             dvar= driver_add_new_variable(cdriver);
01064             driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
01065             
01066                 /* only requires single target */
01067             dtar= &dvar->targets[0];
01068             dtar->id= (ID *)idriver->ob;
01069             dtar->idtype= ID_OB;
01070             dtar->transChan= adrcode_to_dtar_transchan(idriver->adrcode);
01071         }
01072     }
01073     
01074     /* return the new one */
01075     return cdriver;
01076 }
01077 
01078 /* Add F-Curve to the correct list 
01079  *  - grpname is needed to be used as group name where relevant, and is usually derived from actname
01080  */
01081 static void fcurve_add_to_list (ListBase *groups, ListBase *list, FCurve *fcu, char *grpname, int muteipo)
01082 {
01083     /* If we're adding to an action, we will have groups to write to... */
01084     if (groups && grpname) {
01085         /* wrap the pointers given into a dummy action that we pass to the API func
01086          * and extract the resultant lists...
01087          */
01088         bAction tmp_act;
01089         bActionGroup *agrp= NULL;
01090         
01091         /* init the temp action */
01092         memset(&tmp_act, 0, sizeof(bAction)); // XXX only enable this line if we get errors
01093         tmp_act.groups.first= groups->first;
01094         tmp_act.groups.last= groups->last;
01095         tmp_act.curves.first= list->first;
01096         tmp_act.curves.last= list->last;
01097         /* ... xxx, the other vars don't need to be filled in */
01098         
01099         /* get the group to use */
01100         agrp= action_groups_find_named(&tmp_act, grpname);
01101         if (agrp == NULL) {
01102             /* no matching group, so add one */
01103             if (agrp == NULL) {
01104                 /* Add a new group, and make it active */
01105                 agrp= MEM_callocN(sizeof(bActionGroup), "bActionGroup");
01106                 
01107                 agrp->flag = AGRP_SELECTED;
01108                 if (muteipo) agrp->flag |= AGRP_MUTED;
01109                 
01110                 BLI_strncpy(agrp->name, grpname, sizeof(agrp->name));
01111                 
01112                 BLI_addtail(&tmp_act.groups, agrp);
01113                 BLI_uniquename(&tmp_act.groups, agrp, "Group", '.', offsetof(bActionGroup, name), sizeof(agrp->name));
01114             }
01115         }
01116         
01117         /* add F-Curve to group */
01118         /* WARNING: this func should only need to look at the stuff we initialised, if not, things may crash */
01119         action_groups_add_channel(&tmp_act, agrp, fcu);
01120         
01121         if (agrp->flag & AGRP_MUTED) /* flush down */
01122             fcu->flag |= FCURVE_MUTED;
01123         
01124         /* set the output lists based on the ones in the temp action */
01125         groups->first= tmp_act.groups.first;
01126         groups->last= tmp_act.groups.last;
01127         list->first= tmp_act.curves.first;
01128         list->last= tmp_act.curves.last;
01129     }
01130     else {
01131         /* simply add the F-Curve to the end of the given list */
01132         BLI_addtail(list, fcu);
01133     }
01134 }
01135 
01136 /* Convert IPO-Curve to F-Curve (including Driver data), and free any of the old data that 
01137  * is not relevant, BUT do not free the IPO-Curve itself...
01138  *  actname: name of Action-Channel (if applicable) that IPO-Curve's IPO-block belonged to
01139  *  constname: name of Constraint-Channel (if applicable) that IPO-Curve's IPO-block belonged to
01140  *      seq: sequencer-strip (if applicable) that IPO-Curve's IPO-block belonged to
01141  */
01142 static void icu_to_fcurves (ID *id, ListBase *groups, ListBase *list, IpoCurve *icu, char *actname, char *constname, Sequence * seq, int muteipo)
01143 {
01144     AdrBit2Path *abp;
01145     FCurve *fcu;
01146     int totbits;
01147     
01148     /* allocate memory for a new F-Curve */
01149     fcu= MEM_callocN(sizeof(FCurve), "FCurve");
01150     
01151     /* convert driver */
01152     if (icu->driver)
01153         fcu->driver= idriver_to_cdriver(icu->driver);
01154     
01155     /* copy flags */
01156     if (icu->flag & IPO_VISIBLE) fcu->flag |= FCURVE_VISIBLE;
01157     if (icu->flag & IPO_SELECT) fcu->flag |= FCURVE_SELECTED;
01158     if (icu->flag & IPO_ACTIVE) fcu->flag |= FCURVE_ACTIVE;
01159     if (icu->flag & IPO_MUTE) fcu->flag |= FCURVE_MUTED;
01160     if (icu->flag & IPO_PROTECT) fcu->flag |= FCURVE_PROTECTED;
01161     
01162     /* set extrapolation */
01163     switch (icu->extrap) {
01164         case IPO_HORIZ: /* constant extrapolation */
01165         case IPO_DIR: /* linear extrapolation */
01166         {
01167             /* just copy, as the new defines match the old ones... */
01168             fcu->extend= icu->extrap;
01169         }
01170             break;
01171             
01172         case IPO_CYCL: /* cyclic extrapolation */
01173         case IPO_CYCLX: /* cyclic extrapolation + offset */
01174         {
01175             /* Add a new FModifier (Cyclic) instead of setting extend value 
01176              * as that's the new equivilant of that option. 
01177              */
01178             FModifier *fcm= add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES);
01179             FMod_Cycles *data= (FMod_Cycles *)fcm->data;
01180             
01181             /* if 'offset' one is in use, set appropriate settings */
01182             if (icu->extrap == IPO_CYCLX)
01183                 data->before_mode= data->after_mode= FCM_EXTRAPOLATE_CYCLIC_OFFSET;
01184             else
01185                 data->before_mode= data->after_mode= FCM_EXTRAPOLATE_CYCLIC;
01186         }
01187             break;
01188     }
01189     
01190     /* -------- */
01191     
01192     /* get adrcode <-> bitflags mapping to handle nasty bitflag curves? */
01193     abp= adrcode_bitmaps_to_paths(icu->blocktype, icu->adrcode, &totbits);
01194     if (abp && totbits) {
01195         FCurve *fcurve;
01196         int b;
01197         
01198         if (G.f & G_DEBUG) printf("\tconvert bitflag ipocurve, totbits = %d \n", totbits);
01199         
01200         /* add the 'only int values' flag */
01201         fcu->flag |= (FCURVE_INT_VALUES|FCURVE_DISCRETE_VALUES);        
01202         
01203         /* for each bit we have to remap + check for:
01204          * 1) we need to make copy the existing F-Curve data (fcu -> fcurve),
01205          *    except for the last one which will use the original 
01206          * 2) copy the relevant path info across
01207          * 3) filter the keyframes for the flag of interest
01208          */
01209         for (b=0; b < totbits; b++, abp++) {
01210             unsigned int i=0;
01211             
01212             /* make a copy of existing base-data if not the last curve */
01213             if (b < (totbits-1))
01214                 fcurve= copy_fcurve(fcu);
01215             else
01216                 fcurve= fcu;
01217                 
01218             /* set path */
01219             fcurve->rna_path= BLI_strdup(abp->path);
01220             fcurve->array_index= abp->array_index;
01221             
01222             /* convert keyframes 
01223              *  - beztriples and bpoints are mutually exclusive, so we won't have both at the same time
01224              *  - beztriples are more likely to be encountered as they are keyframes (the other type wasn't used yet)
01225              */
01226             fcurve->totvert= icu->totvert;
01227             
01228             if (icu->bezt) {
01229                 BezTriple *dst, *src;
01230                 
01231                 /* allocate new array for keyframes/beztriples */
01232                 fcurve->bezt= MEM_callocN(sizeof(BezTriple)*fcurve->totvert, "BezTriples");
01233                 
01234                 /* loop through copying all BezTriples individually, as we need to modify a few things */
01235                 for (dst=fcurve->bezt, src=icu->bezt, i=0; i < fcurve->totvert; i++, dst++, src++) {
01236                     /* firstly, copy BezTriple data */
01237                     *dst= *src;
01238                     
01239                     /* interpolation can only be constant... */
01240                     dst->ipo= BEZT_IPO_CONST;
01241                     
01242                     /* 'hide' flag is now used for keytype - only 'keyframes' existed before */
01243                     dst->hide= BEZT_KEYTYPE_KEYFRAME;
01244                     
01245                     /* auto-handles - per curve to per handle */
01246                     if (icu->flag & IPO_AUTO_HORIZ) {
01247                         if (dst->h1 == HD_AUTO) dst->h1 = HD_AUTO_ANIM;
01248                         if (dst->h2 == HD_AUTO) dst->h2 = HD_AUTO_ANIM;
01249                     }
01250                     
01251                     /* correct values, by checking if the flag of interest is set */
01252                     if ( ((int)(dst->vec[1][1])) & (abp->bit) )
01253                         dst->vec[0][1]= dst->vec[1][1]= dst->vec[2][1] = 1.0f;
01254                     else
01255                         dst->vec[0][1]= dst->vec[1][1]= dst->vec[2][1] = 0.0f;
01256                 }
01257             }
01258             else if (icu->bp) {
01259                 /* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */
01260                 //BPoint *bp;
01261                 //FPoint *fpt;
01262             }
01263             
01264             /* add new F-Curve to list */
01265             fcurve_add_to_list(groups, list, fcurve, actname, muteipo);
01266         }
01267     }
01268     else {
01269         unsigned int i=0;
01270         
01271         /* get rna-path
01272          *  - we will need to set the 'disabled' flag if no path is able to be made (for now)
01273          */
01274         fcu->rna_path= get_rna_access(icu->blocktype, icu->adrcode, actname, constname, seq, &fcu->array_index);
01275         if (fcu->rna_path == NULL)
01276             fcu->flag |= FCURVE_DISABLED;
01277         
01278         /* convert keyframes 
01279          *  - beztriples and bpoints are mutually exclusive, so we won't have both at the same time
01280          *  - beztriples are more likely to be encountered as they are keyframes (the other type wasn't used yet)
01281          */
01282         fcu->totvert= icu->totvert;
01283         
01284         if (icu->bezt) {
01285             BezTriple *dst, *src;
01286             
01287             /* allocate new array for keyframes/beztriples */
01288             fcu->bezt= MEM_callocN(sizeof(BezTriple)*fcu->totvert, "BezTriples");
01289             
01290             /* loop through copying all BezTriples individually, as we need to modify a few things */
01291             for (dst=fcu->bezt, src=icu->bezt, i=0; i < fcu->totvert; i++, dst++, src++) {
01292                 /* firstly, copy BezTriple data */
01293                 *dst= *src;
01294                 
01295                 /* now copy interpolation from curve (if not already set) */
01296                 if (icu->ipo != IPO_MIXED)
01297                     dst->ipo= icu->ipo;
01298                     
01299                 /* 'hide' flag is now used for keytype - only 'keyframes' existed before */
01300                 dst->hide= BEZT_KEYTYPE_KEYFRAME;
01301                 
01302                 /* auto-handles - per curve to per handle */
01303                 if (icu->flag & IPO_AUTO_HORIZ) {
01304                     if (dst->h1 == HD_AUTO) dst->h1 = HD_AUTO_ANIM;
01305                     if (dst->h2 == HD_AUTO) dst->h2 = HD_AUTO_ANIM;
01306                 }
01307                     
01308                 /* correct values for euler rotation curves 
01309                  *  - they were degrees/10 
01310                  *  - we need radians for RNA to do the right thing
01311                  */
01312                 if ( ((icu->blocktype == ID_OB) && ELEM3(icu->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) ||
01313                      ((icu->blocktype == ID_PO) && ELEM3(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z)) )
01314                 {
01315                     const float fac= (float)M_PI / 18.0f; //10.0f * M_PI/180.0f;
01316                     
01317                     dst->vec[0][1] *= fac;
01318                     dst->vec[1][1] *= fac;
01319                     dst->vec[2][1] *= fac;
01320                 }
01321                 
01322                 /* correct values for path speed curves 
01323                  *  - their values were 0-1
01324                  *  - we now need as 'frames'
01325                  */
01326                 if ( (id) && (icu->blocktype == GS(id->name)) && 
01327                      (fcu->rna_path && strcmp(fcu->rna_path, "eval_time")==0) )
01328                 {
01329                     Curve *cu = (Curve *)id;
01330                     
01331                     dst->vec[0][1] *= cu->pathlen;
01332                     dst->vec[1][1] *= cu->pathlen;
01333                     dst->vec[2][1] *= cu->pathlen;
01334                 }
01335                 
01336                 /* correct times for rotation drivers 
01337                  *  - need to go from degrees to radians...
01338                  *  - there's only really 1 target to worry about 
01339                  *  - were also degrees/10
01340                  */
01341                 if (fcu->driver && fcu->driver->variables.first) {
01342                     DriverVar *dvar= fcu->driver->variables.first;
01343                     DriverTarget *dtar= &dvar->targets[0];
01344                     
01345                     if (ELEM3(dtar->transChan, DTAR_TRANSCHAN_ROTX, DTAR_TRANSCHAN_ROTY, DTAR_TRANSCHAN_ROTZ)) {
01346                         const float fac= (float)M_PI / 18.0f;
01347                         
01348                         dst->vec[0][0] *= fac;
01349                         dst->vec[1][0] *= fac;
01350                         dst->vec[2][0] *= fac;
01351                     }
01352                 }
01353                 
01354                 /* correct values for sequencer curves, that were not locked to frame */
01355                 if (seq && (seq->flag & SEQ_IPO_FRAME_LOCKED) == 0) {
01356                     double mul= (seq->enddisp-seq->startdisp)/100.0f;
01357                     double offset= seq->startdisp;
01358                     
01359                     dst->vec[0][0] *= mul;
01360                     dst->vec[0][0] += offset;
01361                     
01362                     dst->vec[1][0] *= mul;
01363                     dst->vec[1][0] += offset;
01364                     
01365                     dst->vec[2][0] *= mul;
01366                     dst->vec[2][0] += offset;
01367                 }
01368             }
01369         }
01370         else if (icu->bp) {
01371             /* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */
01372             //BPoint *bp;
01373             //FPoint *fpt;
01374         }
01375         
01376         /* add new F-Curve to list */
01377         fcurve_add_to_list(groups, list, fcu, actname, muteipo);
01378     }
01379 }
01380 
01381 /* ------------------------- */
01382 
01383 /* Convert IPO-block (i.e. all its IpoCurves) to the new system.
01384  * This does not assume that any ID or AnimData uses it, but does assume that
01385  * it is given two lists, which it will perform driver/animation-data separation.
01386  */
01387 static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], Sequence *seq, ListBase *animgroups, ListBase *anim, ListBase *drivers)
01388 {
01389     IpoCurve *icu;
01390     
01391     /* sanity check */
01392     if (ELEM3(NULL, ipo, anim, drivers))
01393         return;
01394         
01395     if (G.f & G_DEBUG) printf("ipo_to_animato \n");
01396         
01397     /* validate actname and constname 
01398      *  - clear actname if it was one of the generic <builtin> ones (i.e. 'Object', or 'Shapes')
01399      *  - actname can then be used to assign F-Curves in Action to Action Groups 
01400      *    (i.e. thus keeping the benefits that used to be provided by Action Channels for grouping
01401      *      F-Curves for bones). This may be added later... for now let's just dump without them...
01402      */
01403     if (actname) {
01404         if ((ipo->blocktype == ID_OB) && (strcmp(actname, "Object") == 0))
01405             actname= NULL;
01406         else if ((ipo->blocktype == ID_OB) && (strcmp(actname, "Shape") == 0))
01407             actname= NULL;
01408     }
01409     
01410     /* loop over IPO-Curves, freeing as we progress */
01411     for (icu= ipo->curve.first; icu; icu= icu->next) {
01412         /* Since an IPO-Curve may end up being made into many F-Curves (i.e. bitflag curves), 
01413          * we figure out the best place to put the channel, then tell the curve-converter to just dump there
01414          */
01415         if (icu->driver) {
01416             /* Blender 2.4x allowed empty drivers, but we don't now, since they cause more trouble than they're worth */
01417             if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) {
01418                 icu_to_fcurves(id, NULL, drivers, icu, actname, constname, seq, ipo->muteipo);
01419             }
01420             else {
01421                 MEM_freeN(icu->driver);
01422                 icu->driver= NULL;
01423             }
01424         }
01425         else
01426             icu_to_fcurves(id, animgroups, anim, icu, actname, constname, seq, ipo->muteipo);
01427     }
01428     
01429     /* if this IPO block doesn't have any users after this one, free... */
01430     ipo->id.us--;
01431     if (ID_REAL_USERS(ipo) <= 0) {
01432         IpoCurve *icn;
01433         
01434         for (icu= ipo->curve.first; icu; icu= icn) {
01435             icn= icu->next;
01436             
01437             /* free driver */
01438             if (icu->driver)
01439                 MEM_freeN(icu->driver);
01440                 
01441             /* free old data of curve now that it's no longer needed for converting any more curves */
01442             if (icu->bezt) MEM_freeN(icu->bezt);
01443             if (icu->bp) MEM_freeN(icu->bezt);
01444             
01445             /* free this IPO-Curve */
01446             BLI_freelinkN(&ipo->curve, icu);
01447         }
01448     }
01449 }
01450 
01451 /* Convert Action-block to new system, separating animation and drivers
01452  * New curves may not be converted directly into the given Action (i.e. for Actions linked
01453  * to Objects, where ob->ipo and ob->action need to be combined).
01454  * NOTE: we need to be careful here, as same data-structs are used for new system too!
01455  */
01456 static void action_to_animato (ID *id, bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers)
01457 {
01458     bActionChannel *achan, *achann;
01459     bConstraintChannel *conchan, *conchann;
01460     
01461     /* only continue if there are Action Channels (indicating unconverted data) */
01462     if (act->chanbase.first == NULL)
01463         return;
01464         
01465     /* get rid of all Action Groups */
01466     // XXX this is risky if there's some old + some new data in the Action...
01467     if (act->groups.first) 
01468         BLI_freelistN(&act->groups);
01469     
01470     /* loop through Action-Channels, converting data, freeing as we go */
01471     for (achan= act->chanbase.first; achan; achan= achann) {
01472         /* get pointer to next Action Channel */
01473         achann= achan->next;
01474         
01475         /* convert Action Channel's IPO data */
01476         if (achan->ipo) {
01477             ipo_to_animato(id, achan->ipo, achan->name, NULL, NULL, groups, curves, drivers);
01478             achan->ipo->id.us--;
01479             achan->ipo= NULL;
01480         }
01481         
01482         /* convert constraint channel IPO-data */
01483         for (conchan= achan->constraintChannels.first; conchan; conchan= conchann) {
01484             /* get pointer to next Constraint Channel */
01485             conchann= conchan->next;
01486             
01487             /* convert Constraint Channel's IPO data */
01488             if (conchan->ipo) {
01489                 ipo_to_animato(id, conchan->ipo, achan->name, conchan->name, NULL, groups, curves, drivers);
01490                 conchan->ipo->id.us--;
01491                 conchan->ipo= NULL;
01492             }
01493             
01494             /* free Constraint Channel */
01495             BLI_freelinkN(&achan->constraintChannels, conchan);
01496         }
01497         
01498         /* free Action Channel */
01499         BLI_freelinkN(&act->chanbase, achan);
01500     }
01501 }
01502 
01503 
01504 /* ------------------------- */
01505 
01506 /* Convert IPO-block (i.e. all its IpoCurves) for some ID to the new system
01507  * This assumes that AnimData has been added already. Separation of drivers
01508  * from animation data is accomplished here too...
01509  */
01510 static void ipo_to_animdata (ID *id, Ipo *ipo, char actname[], char constname[], Sequence *seq)
01511 {
01512     AnimData *adt= BKE_animdata_from_id(id);
01513     ListBase anim = {NULL, NULL};
01514     ListBase drivers = {NULL, NULL};
01515     
01516     /* sanity check */
01517     if ELEM(NULL, id, ipo)
01518         return;
01519     if (adt == NULL) {
01520         printf("ERROR ipo_to_animdata(): adt invalid \n");
01521         return;
01522     }
01523     
01524     if (G.f & G_DEBUG) {
01525         printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s seqname:%s  curves:%d \n", 
01526                id->name+2, ipo->id.name+2, (actname)?actname:"<None>", (constname)?constname:"<None>", (seq)?(seq->name+2):"<None>",
01527             BLI_countlist(&ipo->curve));
01528     }
01529     
01530     /* Convert curves to animato system (separated into separate lists of F-Curves for animation and drivers),
01531      * and the try to put these lists in the right places, but do not free the lists here
01532      */
01533     // XXX there shouldn't be any need for the groups, so don't supply pointer for that now... 
01534     ipo_to_animato(id, ipo, actname, constname, seq, NULL, &anim, &drivers);
01535     
01536     /* deal with animation first */
01537     if (anim.first) {
01538         if (G.f & G_DEBUG) printf("\thas anim \n");
01539         /* try to get action */
01540         if (adt->action == NULL) {
01541             char nameBuf[MAX_ID_NAME];
01542             
01543             BLI_snprintf(nameBuf, sizeof(nameBuf), "CDA:%s", ipo->id.name+2);
01544             
01545             adt->action= add_empty_action(nameBuf);
01546             if (G.f & G_DEBUG) printf("\t\tadded new action - '%s' \n", nameBuf);
01547         }
01548         
01549         /* add F-Curves to action */
01550         BLI_movelisttolist(&adt->action->curves, &anim);
01551     }
01552     
01553     /* deal with drivers */
01554     if (drivers.first) {
01555         if (G.f & G_DEBUG) printf("\thas drivers \n");
01556         /* add drivers to end of driver stack */
01557         BLI_movelisttolist(&adt->drivers, &drivers);
01558     }
01559 }
01560 
01561 /* Convert Action-block to new system
01562  * NOTE: we need to be careful here, as same data-structs are used for new system too!
01563  */
01564 static void action_to_animdata (ID *id, bAction *act)
01565 {
01566     AnimData *adt= BKE_animdata_from_id(id);
01567     
01568     /* only continue if there are Action Channels (indicating unconverted data) */
01569     if (ELEM(NULL, adt, act->chanbase.first))
01570         return;
01571     
01572     /* check if we need to set this Action as the AnimData's action */
01573     if (adt->action == NULL) {
01574         /* set this Action as AnimData's Action */
01575         if (G.f & G_DEBUG) printf("act_to_adt - set adt action to act \n");
01576         adt->action= act;
01577     }
01578     
01579     /* convert Action data */
01580     action_to_animato(id, act, &adt->action->groups, &adt->action->curves, &adt->drivers);
01581 }
01582 
01583 /* ------------------------- */
01584 
01585 // TODO:
01586 //  - NLA group duplicators info
01587 //  - NLA curve/stride modifiers...
01588 
01589 /* Convert NLA-Strip to new system */
01590 static void nlastrips_to_animdata (ID *id, ListBase *strips)
01591 {
01592     AnimData *adt= BKE_animdata_from_id(id);
01593     NlaTrack *nlt = NULL;
01594     NlaStrip *strip;
01595     bActionStrip *as, *asn;
01596     
01597     /* for each one of the original strips, convert to a new strip and free the old... */
01598     for (as= strips->first; as; as= asn) {
01599         asn= as->next;
01600         
01601         /* this old strip is only worth something if it had an action... */
01602         if (as->act) {
01603             /* convert Action data (if not yet converted), storing the results in the same Action */
01604             action_to_animato(id, as->act, &as->act->groups, &as->act->curves, &adt->drivers);
01605             
01606             /* create a new-style NLA-strip which references this Action, then copy over relevant settings */
01607             {
01608                 /* init a new strip, and assign the action to it 
01609                  *  - no need to muck around with the user-counts, since this is just 
01610                  *    passing over the ref to the new owner, not creating an additional ref
01611                  */
01612                 strip= MEM_callocN(sizeof(NlaStrip), "NlaStrip");
01613                 strip->act= as->act;
01614                 
01615                     /* endpoints */
01616                 strip->start= as->start;
01617                 strip->end= as->end;
01618                 strip->actstart= as->actstart;
01619                 strip->actend= as->actend;
01620                 
01621                     /* action reuse */
01622                 strip->repeat= as->repeat;
01623                 strip->scale= as->scale;
01624                 if (as->flag & ACTSTRIP_LOCK_ACTION)    strip->flag |= NLASTRIP_FLAG_SYNC_LENGTH;
01625                 
01626                     /* blending */
01627                 strip->blendin= as->blendin;
01628                 strip->blendout= as->blendout;
01629                 strip->blendmode= (as->mode==ACTSTRIPMODE_ADD) ? NLASTRIP_MODE_ADD : NLASTRIP_MODE_REPLACE;
01630                 if (as->flag & ACTSTRIP_AUTO_BLENDS)    strip->flag |= NLASTRIP_FLAG_AUTO_BLENDS;
01631                     
01632                     /* assorted setting flags */
01633                 if (as->flag & ACTSTRIP_SELECT)         strip->flag |= NLASTRIP_FLAG_SELECT;
01634                 if (as->flag & ACTSTRIP_ACTIVE)         strip->flag |= NLASTRIP_FLAG_ACTIVE;
01635                 
01636                 if (as->flag & ACTSTRIP_MUTE)           strip->flag |= NLASTRIP_FLAG_MUTED;
01637                 if (as->flag & ACTSTRIP_REVERSE)        strip->flag |= NLASTRIP_FLAG_REVERSE;
01638                 
01639                     /* by default, we now always extrapolate, while in the past this was optional */
01640                 if ((as->flag & ACTSTRIP_HOLDLASTFRAME)==0) 
01641                     strip->extendmode= NLASTRIP_EXTEND_NOTHING;
01642             }   
01643             
01644             /* try to add this strip to the current NLA-Track (i.e. the 'last' one on the stack atm) */
01645             if (BKE_nlatrack_add_strip(nlt, strip) == 0) {
01646                 /* trying to add to the current failed (no space), 
01647                  * so add a new track to the stack, and add to that...
01648                  */
01649                 nlt= add_nlatrack(adt, NULL);
01650                 BKE_nlatrack_add_strip(nlt, strip);
01651             }
01652         }
01653         
01654         /* modifiers */
01655         // FIXME: for now, we just free them...
01656         if (as->modifiers.first)
01657             BLI_freelistN(&as->modifiers);
01658         
01659         /* free the old strip */
01660         BLI_freelinkN(strips, as);
01661     }
01662 }
01663 
01664 /* *************************************************** */
01665 /* External API - Only Called from do_versions() */
01666 
01667 /* Called from do_versions() in readfile.c to convert the old 'IPO/adrcode' system
01668  * to the new 'Animato/RNA' system.
01669  *
01670  * The basic method used here, is to loop over datablocks which have IPO-data, and 
01671  * add those IPO's to new AnimData blocks as Actions. 
01672  * Action/NLA data only works well for Objects, so these only need to be checked for there.
01673  *  
01674  * Data that has been converted should be freed immediately, which means that it is immediately
01675  * clear which datablocks have yet to be converted, and also prevent freeing errors when we exit.
01676  */
01677 // XXX currently done after all file reading... 
01678 void do_versions_ipos_to_animato(Main *main)
01679 {
01680     ListBase drivers = {NULL, NULL};
01681     ID *id;
01682     
01683     if (main == NULL) {
01684         printf("Argh! Main is NULL in do_versions_ipos_to_animato() \n");
01685         return;
01686     }
01687         
01688     /* only convert if version is right */
01689     if (main->versionfile >= 250) {
01690         printf("WARNING: Animation data too new to convert (Version %d) \n", main->versionfile);
01691         return;
01692     }
01693     else if (G.f & G_DEBUG)
01694         printf("INFO: Converting to Animato... \n");
01695         
01696     /* ----------- Animation Attached to Data -------------- */
01697     
01698     /* objects */
01699     for (id= main->object.first; id; id= id->next) {
01700         Object *ob= (Object *)id;
01701         bPoseChannel *pchan;
01702         bConstraint *con;
01703         bConstraintChannel *conchan, *conchann;
01704         
01705         if (G.f & G_DEBUG) printf("\tconverting ob %s \n", id->name+2);
01706         
01707         /* check if object has any animation data */
01708         if (ob->nlastrips.first) {
01709             /* Add AnimData block */
01710             BKE_id_add_animdata(id);
01711             
01712             /* IPO first to take into any non-NLA'd Object Animation */
01713             if (ob->ipo) {
01714                 ipo_to_animdata(id, ob->ipo, NULL, NULL, NULL);
01715                 
01716                 ob->ipo->id.us--;
01717                 ob->ipo= NULL;
01718             }
01719             
01720             /* Action is skipped since it'll be used by some strip in the NLA anyway, 
01721              * causing errors with evaluation in the new evaluation pipeline
01722              */
01723             if (ob->action) {
01724                 ob->action->id.us--;
01725                 ob->action= NULL;
01726             }
01727             
01728             /* finally NLA */
01729             nlastrips_to_animdata(id, &ob->nlastrips);
01730         }
01731         else if ((ob->ipo) || (ob->action)) {
01732             /* Add AnimData block */
01733             AnimData *adt= BKE_id_add_animdata(id);
01734             
01735             /* Action first - so that Action name get conserved */
01736             if (ob->action) {
01737                 action_to_animdata(id, ob->action);
01738                 
01739                 /* only decrease usercount if this Action isn't now being used by AnimData */
01740                 if (ob->action != adt->action) {
01741                     ob->action->id.us--;
01742                     ob->action= NULL;
01743                 }
01744             }
01745             
01746             /* IPO second... */
01747             if (ob->ipo) {
01748                 ipo_to_animdata(id, ob->ipo, NULL, NULL, NULL);
01749                 ob->ipo->id.us--;
01750                 ob->ipo= NULL;
01751             }
01752         }
01753         
01754         /* check PoseChannels for constraints with local data */
01755         if (ob->pose) {
01756             /* Verify if there's AnimData block */
01757             BKE_id_add_animdata(id);
01758             
01759             for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
01760                 for (con= pchan->constraints.first; con; con= con->next) {
01761                     /* if constraint has own IPO, convert add these to Object 
01762                      * (NOTE: they're most likely to be drivers too) 
01763                      */
01764                     if (con->ipo) {
01765                         /* although this was the constraint's local IPO, we still need to provide pchan + con 
01766                          * so that drivers can be added properly...
01767                          */
01768                         ipo_to_animdata(id, con->ipo, pchan->name, con->name, NULL);
01769                         con->ipo->id.us--;
01770                         con->ipo= NULL;
01771                     }
01772                 }
01773             }
01774         }
01775         
01776         /* check constraints for local IPO's */
01777         for (con= ob->constraints.first; con; con= con->next) {
01778             /* if constraint has own IPO, convert add these to Object 
01779              * (NOTE: they're most likely to be drivers too) 
01780              */
01781             if (con->ipo) {
01782                 /* Verify if there's AnimData block, just in case */
01783                 BKE_id_add_animdata(id);
01784                 
01785                 /* although this was the constraint's local IPO, we still need to provide con 
01786                  * so that drivers can be added properly...
01787                  */
01788                 ipo_to_animdata(id, con->ipo, NULL, con->name, NULL);
01789                 con->ipo->id.us--;
01790                 con->ipo= NULL;
01791             }
01792              
01793             /* check for Action Constraint */
01794             // XXX do we really want to do this here?
01795         }
01796         
01797         /* check constraint channels - we need to remove them anyway... */
01798         if (ob->constraintChannels.first) {
01799             /* Verify if there's AnimData block */
01800             BKE_id_add_animdata(id);
01801             
01802             for (conchan= ob->constraintChannels.first; conchan; conchan= conchann) {
01803                 /* get pointer to next Constraint Channel */
01804                 conchann= conchan->next;
01805                 
01806                 /* convert Constraint Channel's IPO data */
01807                 if (conchan->ipo) {
01808                     ipo_to_animdata(id, conchan->ipo, NULL, conchan->name, NULL);
01809                     conchan->ipo->id.us--;
01810                     conchan->ipo= NULL;
01811                 }
01812                 
01813                 /* free Constraint Channel */
01814                 BLI_freelinkN(&ob->constraintChannels, conchan);
01815             }
01816         }
01817         
01818         /* object's action will always be object-rooted */
01819         {
01820             AnimData *adt= BKE_animdata_from_id(id);
01821             if (adt && adt->action)
01822                 adt->action->idroot = ID_OB;
01823         }
01824     }
01825     
01826     /* shapekeys */
01827     for (id= main->key.first; id; id= id->next) {
01828         Key *key= (Key *)id;
01829         
01830         if (G.f & G_DEBUG) printf("\tconverting key %s \n", id->name+2);
01831         
01832         /* we're only interested in the IPO 
01833          * NOTE: for later, it might be good to port these over to Object instead, as many of these
01834          * are likely to be drivers, but it's hard to trace that from here, so move this to Ob loop?
01835          */
01836         if (key->ipo) {
01837             /* Add AnimData block */
01838             AnimData *adt= BKE_id_add_animdata(id);
01839             
01840             /* Convert Shapekey data... */
01841             ipo_to_animdata(id, key->ipo, NULL, NULL, NULL);
01842             
01843             if (adt->action)
01844                 adt->action->idroot = key->ipo->blocktype;
01845             
01846             key->ipo->id.us--;
01847             key->ipo= NULL;
01848         }
01849     }
01850     
01851     /* materials */
01852     for (id= main->mat.first; id; id= id->next) {
01853         Material *ma= (Material *)id;
01854         
01855         if (G.f & G_DEBUG) printf("\tconverting material %s \n", id->name+2);
01856         
01857         /* we're only interested in the IPO */
01858         if (ma->ipo) {
01859             /* Add AnimData block */
01860             AnimData *adt= BKE_id_add_animdata(id);
01861             
01862             /* Convert Material data... */
01863             ipo_to_animdata(id, ma->ipo, NULL, NULL, NULL);
01864             
01865             if (adt->action)
01866                 adt->action->idroot = ma->ipo->blocktype;
01867             
01868             ma->ipo->id.us--;
01869             ma->ipo= NULL;
01870         }
01871     }
01872     
01873     /* worlds */
01874     for (id= main->world.first; id; id= id->next) {
01875         World *wo= (World *)id;
01876         
01877         if (G.f & G_DEBUG) printf("\tconverting world %s \n", id->name+2);
01878         
01879         /* we're only interested in the IPO */
01880         if (wo->ipo) {
01881             /* Add AnimData block */
01882             AnimData *adt= BKE_id_add_animdata(id);
01883             
01884             /* Convert World data... */
01885             ipo_to_animdata(id, wo->ipo, NULL, NULL, NULL);
01886             
01887             if (adt->action)
01888                 adt->action->idroot = wo->ipo->blocktype;
01889             
01890             wo->ipo->id.us--;
01891             wo->ipo= NULL;
01892         }
01893     }
01894     
01895     /* sequence strips */
01896     for (id= main->scene.first; id; id= id->next) {
01897         Scene *scene = (Scene *)id;
01898         Editing * ed = scene->ed;
01899         if (ed && ed->seqbasep) {
01900             Sequence * seq;
01901             
01902             AnimData *adt= BKE_id_add_animdata(id);
01903             
01904             SEQ_BEGIN(ed, seq) {
01905                 IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL;
01906                 short adrcode = SEQ_FAC1;
01907                 
01908                 if (G.f & G_DEBUG) 
01909                     printf("\tconverting sequence strip %s \n", seq->name+2);
01910                 
01911                 if (ELEM(NULL, seq->ipo, icu)) {
01912                     seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;
01913                     continue;
01914                 }
01915                 
01916                 /* patch adrcode, so that we can map
01917                    to different DNA variables later 
01918                    (semi-hack (tm) )
01919                 */
01920                 switch (seq->type) {
01921                     case SEQ_IMAGE:
01922                     case SEQ_META:
01923                     case SEQ_SCENE:
01924                     case SEQ_MOVIE:
01925                     case SEQ_COLOR:
01926                         adrcode = SEQ_FAC_OPACITY;
01927                         break;
01928                     case SEQ_SPEED:
01929                         adrcode = SEQ_FAC_SPEED;
01930                         break;
01931                 }
01932                 icu->adrcode = adrcode;
01933                 
01934                 /* convert IPO */
01935                 ipo_to_animdata((ID *)scene, seq->ipo, NULL, NULL, seq);
01936                 
01937                 if (adt->action)
01938                     adt->action->idroot = ID_SCE; /* scene-rooted */
01939                 
01940                 seq->ipo->id.us--;
01941                 seq->ipo = NULL;
01942             }
01943             SEQ_END
01944         }
01945     }
01946 
01947 
01948     /* textures */
01949     for (id= main->tex.first; id; id= id->next) {
01950         Tex *te= (Tex *)id;
01951         
01952         if (G.f & G_DEBUG) printf("\tconverting texture %s \n", id->name+2);
01953         
01954         /* we're only interested in the IPO */
01955         if (te->ipo) {
01956             /* Add AnimData block */
01957             AnimData *adt= BKE_id_add_animdata(id);
01958             
01959             /* Convert Texture data... */
01960             ipo_to_animdata(id, te->ipo, NULL, NULL, NULL);
01961             
01962             if (adt->action)
01963                 adt->action->idroot = te->ipo->blocktype;
01964             
01965             te->ipo->id.us--;
01966             te->ipo= NULL;
01967         }
01968     }
01969     
01970     /* cameras */
01971     for (id= main->camera.first; id; id= id->next) {
01972         Camera *ca= (Camera *)id;
01973         
01974         if (G.f & G_DEBUG) printf("\tconverting camera %s \n", id->name+2);
01975         
01976         /* we're only interested in the IPO */
01977         if (ca->ipo) {
01978             /* Add AnimData block */
01979             AnimData *adt= BKE_id_add_animdata(id);
01980             
01981             /* Convert Camera data... */
01982             ipo_to_animdata(id, ca->ipo, NULL, NULL, NULL);
01983             
01984             if (adt->action)
01985                 adt->action->idroot = ca->ipo->blocktype;
01986             
01987             ca->ipo->id.us--;
01988             ca->ipo= NULL;
01989         }
01990     }
01991     
01992     /* lamps */
01993     for (id= main->lamp.first; id; id= id->next) {
01994         Lamp *la= (Lamp *)id;
01995         
01996         if (G.f & G_DEBUG) printf("\tconverting lamp %s \n", id->name+2);
01997         
01998         /* we're only interested in the IPO */
01999         if (la->ipo) {
02000             /* Add AnimData block */
02001             AnimData *adt= BKE_id_add_animdata(id);
02002             
02003             /* Convert Lamp data... */
02004             ipo_to_animdata(id, la->ipo, NULL, NULL, NULL);
02005             
02006             if (adt->action)
02007                 adt->action->idroot = la->ipo->blocktype;
02008             
02009             la->ipo->id.us--;
02010             la->ipo= NULL;
02011         }
02012     }
02013     
02014     /* curves */
02015     for (id= main->curve.first; id; id= id->next) {
02016         Curve *cu= (Curve *)id;
02017         
02018         if (G.f & G_DEBUG) printf("\tconverting curve %s \n", id->name+2);
02019         
02020         /* we're only interested in the IPO */
02021         if (cu->ipo) {
02022             /* Add AnimData block */
02023             AnimData *adt= BKE_id_add_animdata(id);
02024             
02025             /* Convert Curve data... */
02026             ipo_to_animdata(id, cu->ipo, NULL, NULL, NULL);
02027             
02028             if (adt->action)
02029                 adt->action->idroot = cu->ipo->blocktype;
02030             
02031             cu->ipo->id.us--;
02032             cu->ipo= NULL;
02033         }
02034     }
02035     
02036     /* --------- Unconverted Animation Data ------------------ */
02037     /* For Animation data which may not be directly connected (i.e. not linked) to any other 
02038      * data, we need to perform a separate pass to make sure that they are converted to standalone
02039      * Actions which may then be able to be reused. This does mean that we will be going over data that's
02040      * already been converted, but there are no problems with that.
02041      *
02042      * The most common case for this will be Action Constraints, or IPO's with Fake-Users. 
02043      * We collect all drivers that were found into a temporary collection, and free them in one go, as they're 
02044      * impossible to resolve.
02045      */
02046     
02047     /* actions */
02048     for (id= main->action.first; id; id= id->next) {
02049         bAction *act= (bAction *)id;
02050         
02051         if (G.f & G_DEBUG) printf("\tconverting action %s \n", id->name+2);
02052         
02053         /* if old action, it will be object-only... */
02054         if (act->chanbase.first)
02055             act->idroot = ID_OB;
02056         
02057         /* be careful! some of the actions we encounter will be converted ones... */
02058         action_to_animato(NULL, act, &act->groups, &act->curves, &drivers);
02059     }
02060     
02061     /* ipo's */
02062     for (id= main->ipo.first; id; id= id->next) {
02063         Ipo *ipo= (Ipo *)id;
02064         
02065         if (G.f & G_DEBUG) printf("\tconverting ipo %s \n", id->name+2);
02066         
02067         /* most likely this IPO has already been processed, so check if any curves left to convert */
02068         if (ipo->curve.first) {
02069             bAction *new_act;
02070             
02071             /* add a new action for this, and convert all data into that action */
02072             new_act= add_empty_action("ConvIPO_Action"); // XXX need a better name...
02073             ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers);
02074             new_act->idroot = ipo->blocktype;
02075         }
02076         
02077         /* clear fake-users, and set user-count to zero to make sure it is cleared on file-save */
02078         ipo->id.us= 0;
02079         ipo->id.flag &= ~LIB_FAKEUSER;
02080     }
02081     
02082     /* free unused drivers from actions + ipos */
02083     free_fcurves(&drivers);
02084     
02085     if (G.f & G_DEBUG)
02086         printf("INFO: Animato convert done \n");
02087 }
02088