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