diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/blenkernel/intern/ipo.c | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/blenkernel/intern/ipo.c')
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 3709 |
1 files changed, 1924 insertions, 1785 deletions
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 954026ea560..8f3b1fed692 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -21,7 +21,6 @@ * \ingroup bke */ - /* NOTE: * * This file is no longer used to provide tools for the deprecated IPO system. Instead, it @@ -74,7 +73,7 @@ #include "MEM_guardedalloc.h" #ifdef WIN32 -# include "BLI_math_base.h" /* M_PI */ +# include "BLI_math_base.h" /* M_PI */ #endif static CLG_LogRef LOG = {"bke.ipo"}; @@ -86,22 +85,25 @@ static CLG_LogRef LOG = {"bke.ipo"}; // XXX this shouldn't be necessary anymore, but may occur while not all data is converted yet void BKE_ipo_free(Ipo *ipo) { - IpoCurve *icu, *icn; - int n = 0; + IpoCurve *icu, *icn; + int n = 0; - for (icu = ipo->curve.first; icu; icu = icn) { - icn = icu->next; - n++; + for (icu = ipo->curve.first; icu; icu = icn) { + icn = icu->next; + n++; - if (icu->bezt) MEM_freeN(icu->bezt); - if (icu->bp) MEM_freeN(icu->bp); - if (icu->driver) MEM_freeN(icu->driver); + if (icu->bezt) + MEM_freeN(icu->bezt); + if (icu->bp) + MEM_freeN(icu->bp); + if (icu->driver) + MEM_freeN(icu->driver); - BLI_freelinkN(&ipo->curve, icu); - } + BLI_freelinkN(&ipo->curve, icu); + } - if (G.debug & G_DEBUG) - printf("Freed %d (Unconverted) Ipo-Curves from IPO '%s'\n", n, ipo->id.name + 2); + if (G.debug & G_DEBUG) + printf("Freed %d (Unconverted) Ipo-Curves from IPO '%s'\n", n, ipo->id.name + 2); } /* *************************************************** */ @@ -109,9 +111,9 @@ void BKE_ipo_free(Ipo *ipo) /* Mapping Table for bitflag <-> RNA path */ typedef struct AdrBit2Path { - int bit; - const char *path; - int array_index; + int bit; + const char *path; + int array_index; } AdrBit2Path; /* ----------------- */ @@ -119,48 +121,36 @@ typedef struct AdrBit2Path { /* Object layers */ static AdrBit2Path ob_layer_bits[] = { - {(1 << 0), "layers", 0}, - {(1 << 1), "layers", 1}, - {(1 << 2), "layers", 2}, - {(1 << 3), "layers", 3}, - {(1 << 4), "layers", 4}, - {(1 << 5), "layers", 5}, - {(1 << 6), "layers", 6}, - {(1 << 7), "layers", 7}, - {(1 << 8), "layers", 8}, - {(1 << 9), "layers", 9}, - {(1 << 10), "layers", 10}, - {(1 << 11), "layers", 11}, - {(1 << 12), "layers", 12}, - {(1 << 13), "layers", 13}, - {(1 << 14), "layers", 14}, - {(1 << 15), "layers", 15}, - {(1 << 16), "layers", 16}, - {(1 << 17), "layers", 17}, - {(1 << 18), "layers", 18}, - {(1 << 19), "layers", 19}, + {(1 << 0), "layers", 0}, {(1 << 1), "layers", 1}, {(1 << 2), "layers", 2}, + {(1 << 3), "layers", 3}, {(1 << 4), "layers", 4}, {(1 << 5), "layers", 5}, + {(1 << 6), "layers", 6}, {(1 << 7), "layers", 7}, {(1 << 8), "layers", 8}, + {(1 << 9), "layers", 9}, {(1 << 10), "layers", 10}, {(1 << 11), "layers", 11}, + {(1 << 12), "layers", 12}, {(1 << 13), "layers", 13}, {(1 << 14), "layers", 14}, + {(1 << 15), "layers", 15}, {(1 << 16), "layers", 16}, {(1 << 17), "layers", 17}, + {(1 << 18), "layers", 18}, {(1 << 19), "layers", 19}, }; /* ----------------- */ /* quick macro for returning the appropriate array for adrcode_bitmaps_to_paths() */ #define RET_ABP(items) \ - { \ - *tot = sizeof(items) / sizeof(AdrBit2Path); \ - return items; \ - } (void)0 + { \ + *tot = sizeof(items) / sizeof(AdrBit2Path); \ + return items; \ + } \ + (void)0 /* This function checks if a Blocktype+Adrcode combo, returning a mapping table */ static AdrBit2Path *adrcode_bitmaps_to_paths(int blocktype, int adrcode, int *tot) { - /* Object layers */ - if ((blocktype == ID_OB) && (adrcode == OB_LAY)) { - RET_ABP(ob_layer_bits); - } - // XXX TODO: add other types... - - /* Normal curve */ - return NULL; + /* Object layers */ + if ((blocktype == ID_OB) && (adrcode == OB_LAY)) { + RET_ABP(ob_layer_bits); + } + // XXX TODO: add other types... + + /* Normal curve */ + return NULL; } #undef RET_ABP @@ -170,80 +160,102 @@ static AdrBit2Path *adrcode_bitmaps_to_paths(int blocktype, int adrcode, int *to /* Object types */ static const char *ob_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case OB_LOC_X: - *array_index = 0; return "location"; - case OB_LOC_Y: - *array_index = 1; return "location"; - case OB_LOC_Z: - *array_index = 2; return "location"; - case OB_DLOC_X: - *array_index = 0; return "delta_location"; - case OB_DLOC_Y: - *array_index = 1; return "delta_location"; - case OB_DLOC_Z: - *array_index = 2; return "delta_location"; - - case OB_ROT_X: - *array_index = 0; return "rotation_euler"; - case OB_ROT_Y: - *array_index = 1; return "rotation_euler"; - case OB_ROT_Z: - *array_index = 2; return "rotation_euler"; - case OB_DROT_X: - *array_index = 0; return "delta_rotation_euler"; - case OB_DROT_Y: - *array_index = 1; return "delta_rotation_euler"; - case OB_DROT_Z: - *array_index = 2; return "delta_rotation_euler"; - - case OB_SIZE_X: - *array_index = 0; return "scale"; - case OB_SIZE_Y: - *array_index = 1; return "scale"; - case OB_SIZE_Z: - *array_index = 2; return "scale"; - case OB_DSIZE_X: - *array_index = 0; return "delta_scale"; - case OB_DSIZE_Y: - *array_index = 1; return "delta_scale"; - case OB_DSIZE_Z: - *array_index = 2; return "delta_scale"; - case OB_COL_R: - *array_index = 0; return "color"; - case OB_COL_G: - *array_index = 1; return "color"; - case OB_COL_B: - *array_index = 2; return "color"; - case OB_COL_A: - *array_index = 3; return "color"; + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case OB_LOC_X: + *array_index = 0; + return "location"; + case OB_LOC_Y: + *array_index = 1; + return "location"; + case OB_LOC_Z: + *array_index = 2; + return "location"; + case OB_DLOC_X: + *array_index = 0; + return "delta_location"; + case OB_DLOC_Y: + *array_index = 1; + return "delta_location"; + case OB_DLOC_Z: + *array_index = 2; + return "delta_location"; + + case OB_ROT_X: + *array_index = 0; + return "rotation_euler"; + case OB_ROT_Y: + *array_index = 1; + return "rotation_euler"; + case OB_ROT_Z: + *array_index = 2; + return "rotation_euler"; + case OB_DROT_X: + *array_index = 0; + return "delta_rotation_euler"; + case OB_DROT_Y: + *array_index = 1; + return "delta_rotation_euler"; + case OB_DROT_Z: + *array_index = 2; + return "delta_rotation_euler"; + + case OB_SIZE_X: + *array_index = 0; + return "scale"; + case OB_SIZE_Y: + *array_index = 1; + return "scale"; + case OB_SIZE_Z: + *array_index = 2; + return "scale"; + case OB_DSIZE_X: + *array_index = 0; + return "delta_scale"; + case OB_DSIZE_Y: + *array_index = 1; + return "delta_scale"; + case OB_DSIZE_Z: + *array_index = 2; + return "delta_scale"; + case OB_COL_R: + *array_index = 0; + return "color"; + case OB_COL_G: + *array_index = 1; + return "color"; + case OB_COL_B: + *array_index = 2; + return "color"; + case OB_COL_A: + *array_index = 3; + return "color"; #if 0 - case OB_PD_FSTR: - if (ob->pd) poin = &(ob->pd->f_strength); - break; - case OB_PD_FFALL: - if (ob->pd) poin = &(ob->pd->f_power); - break; - case OB_PD_SDAMP: - if (ob->pd) poin = &(ob->pd->pdef_damp); - break; - case OB_PD_RDAMP: - if (ob->pd) poin = &(ob->pd->pdef_rdamp); - break; - case OB_PD_PERM: - if (ob->pd) poin = &(ob->pd->pdef_perm); - break; - case OB_PD_FMAXD: - if (ob->pd) poin = &(ob->pd->maxdist); - break; + case OB_PD_FSTR: + if (ob->pd) poin = &(ob->pd->f_strength); + break; + case OB_PD_FFALL: + if (ob->pd) poin = &(ob->pd->f_power); + break; + case OB_PD_SDAMP: + if (ob->pd) poin = &(ob->pd->pdef_damp); + break; + case OB_PD_RDAMP: + if (ob->pd) poin = &(ob->pd->pdef_rdamp); + break; + case OB_PD_PERM: + if (ob->pd) poin = &(ob->pd->pdef_perm); + break; + case OB_PD_FMAXD: + if (ob->pd) poin = &(ob->pd->maxdist); + break; #endif - } + } - return NULL; + return NULL; } /* PoseChannel types @@ -251,62 +263,75 @@ static const char *ob_adrcodes_to_paths(int adrcode, int *array_index) */ static const char *pchan_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case AC_QUAT_W: - *array_index = 0; return "rotation_quaternion"; - case AC_QUAT_X: - *array_index = 1; return "rotation_quaternion"; - case AC_QUAT_Y: - *array_index = 2; return "rotation_quaternion"; - case AC_QUAT_Z: - *array_index = 3; return "rotation_quaternion"; - - case AC_EUL_X: - *array_index = 0; return "rotation_euler"; - case AC_EUL_Y: - *array_index = 1; return "rotation_euler"; - case AC_EUL_Z: - *array_index = 2; return "rotation_euler"; - - case AC_LOC_X: - *array_index = 0; return "location"; - case AC_LOC_Y: - *array_index = 1; return "location"; - case AC_LOC_Z: - *array_index = 2; return "location"; - - case AC_SIZE_X: - *array_index = 0; return "scale"; - case AC_SIZE_Y: - *array_index = 1; return "scale"; - case AC_SIZE_Z: - *array_index = 2; return "scale"; - } - - /* for debugging only */ - CLOG_ERROR(&LOG, "unmatched PoseChannel setting (code %d)", adrcode); - return NULL; + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case AC_QUAT_W: + *array_index = 0; + return "rotation_quaternion"; + case AC_QUAT_X: + *array_index = 1; + return "rotation_quaternion"; + case AC_QUAT_Y: + *array_index = 2; + return "rotation_quaternion"; + case AC_QUAT_Z: + *array_index = 3; + return "rotation_quaternion"; + + case AC_EUL_X: + *array_index = 0; + return "rotation_euler"; + case AC_EUL_Y: + *array_index = 1; + return "rotation_euler"; + case AC_EUL_Z: + *array_index = 2; + return "rotation_euler"; + + case AC_LOC_X: + *array_index = 0; + return "location"; + case AC_LOC_Y: + *array_index = 1; + return "location"; + case AC_LOC_Z: + *array_index = 2; + return "location"; + + case AC_SIZE_X: + *array_index = 0; + return "scale"; + case AC_SIZE_Y: + *array_index = 1; + return "scale"; + case AC_SIZE_Z: + *array_index = 2; + return "scale"; + } + + /* for debugging only */ + CLOG_ERROR(&LOG, "unmatched PoseChannel setting (code %d)", adrcode); + return NULL; } /* Constraint types */ static const char *constraint_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case CO_ENFORCE: - return "influence"; - case CO_HEADTAIL: // XXX this needs to be wrapped in RNA.. probably then this path will be invalid - return "data.head_tail"; - } - - return NULL; + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case CO_ENFORCE: + return "influence"; + case CO_HEADTAIL: // XXX this needs to be wrapped in RNA.. probably then this path will be invalid + return "data.head_tail"; + } + + return NULL; } /* ShapeKey types @@ -315,478 +340,524 @@ static const char *constraint_adrcodes_to_paths(int adrcode, int *array_index) */ static char *shapekey_adrcodes_to_paths(ID *id, int adrcode, int *UNUSED(array_index)) { - static char buf[128]; - - /* block will be attached to ID_KE block... */ - if (adrcode == 0) { - /* adrcode=0 was the misnamed "speed" curve (now "evaluation time") */ - BLI_strncpy(buf, "eval_time", sizeof(buf)); - } - else { - /* Find the name of the ShapeKey (i.e. KeyBlock) to look for */ - Key *key = (Key *)id; - KeyBlock *kb = BKE_keyblock_from_key(key, adrcode); - - /* setting that we alter is the "value" (i.e. keyblock.curval) */ - if (kb) { - /* Use the keyblock name, escaped, so that path lookups for this will work */ - BLI_snprintf(buf, sizeof(buf), "key_blocks[\"%s\"].value", kb->name); - } - else { - /* Fallback - Use the adrcode as index directly, so that this can be manually fixed */ - BLI_snprintf(buf, sizeof(buf), "key_blocks[%d].value", adrcode); - } - } - return buf; + static char buf[128]; + + /* block will be attached to ID_KE block... */ + if (adrcode == 0) { + /* adrcode=0 was the misnamed "speed" curve (now "evaluation time") */ + BLI_strncpy(buf, "eval_time", sizeof(buf)); + } + else { + /* Find the name of the ShapeKey (i.e. KeyBlock) to look for */ + Key *key = (Key *)id; + KeyBlock *kb = BKE_keyblock_from_key(key, adrcode); + + /* setting that we alter is the "value" (i.e. keyblock.curval) */ + if (kb) { + /* Use the keyblock name, escaped, so that path lookups for this will work */ + BLI_snprintf(buf, sizeof(buf), "key_blocks[\"%s\"].value", kb->name); + } + else { + /* Fallback - Use the adrcode as index directly, so that this can be manually fixed */ + BLI_snprintf(buf, sizeof(buf), "key_blocks[%d].value", adrcode); + } + } + return buf; } /* MTex (Texture Slot) types */ static const char *mtex_adrcodes_to_paths(int adrcode, int *UNUSED(array_index)) { - const char *base = NULL, *prop = NULL; - static char buf[128]; - - /* base part of path */ - if (adrcode & MA_MAP1) base = "textures[0]"; - else if (adrcode & MA_MAP2) base = "textures[1]"; - else if (adrcode & MA_MAP3) base = "textures[2]"; - else if (adrcode & MA_MAP4) base = "textures[3]"; - else if (adrcode & MA_MAP5) base = "textures[4]"; - else if (adrcode & MA_MAP6) base = "textures[5]"; - else if (adrcode & MA_MAP7) base = "textures[6]"; - else if (adrcode & MA_MAP8) base = "textures[7]"; - else if (adrcode & MA_MAP9) base = "textures[8]"; - else if (adrcode & MA_MAP10) base = "textures[9]"; - else if (adrcode & MA_MAP11) base = "textures[10]"; - else if (adrcode & MA_MAP12) base = "textures[11]"; - else if (adrcode & MA_MAP13) base = "textures[12]"; - else if (adrcode & MA_MAP14) base = "textures[13]"; - else if (adrcode & MA_MAP15) base = "textures[14]"; - else if (adrcode & MA_MAP16) base = "textures[15]"; - else if (adrcode & MA_MAP17) base = "textures[16]"; - else if (adrcode & MA_MAP18) base = "textures[17]"; - - /* property identifier for path */ - adrcode = (adrcode & (MA_MAP1 - 1)); - switch (adrcode) { -#if 0 // XXX these are not wrapped in RNA yet! - case MAP_OFS_X: - poin = &(mtex->ofs[0]); break; - case MAP_OFS_Y: - poin = &(mtex->ofs[1]); break; - case MAP_OFS_Z: - poin = &(mtex->ofs[2]); break; - case MAP_SIZE_X: - poin = &(mtex->size[0]); break; - case MAP_SIZE_Y: - poin = &(mtex->size[1]); break; - case MAP_SIZE_Z: - poin = &(mtex->size[2]); break; - case MAP_R: - poin = &(mtex->r); break; - case MAP_G: - poin = &(mtex->g); break; - case MAP_B: - poin = &(mtex->b); break; - case MAP_DVAR: - poin = &(mtex->def_var); break; - case MAP_COLF: - poin = &(mtex->colfac); break; - case MAP_NORF: - poin = &(mtex->norfac); break; - case MAP_VARF: - poin = &(mtex->varfac); break; + const char *base = NULL, *prop = NULL; + static char buf[128]; + + /* base part of path */ + if (adrcode & MA_MAP1) + base = "textures[0]"; + else if (adrcode & MA_MAP2) + base = "textures[1]"; + else if (adrcode & MA_MAP3) + base = "textures[2]"; + else if (adrcode & MA_MAP4) + base = "textures[3]"; + else if (adrcode & MA_MAP5) + base = "textures[4]"; + else if (adrcode & MA_MAP6) + base = "textures[5]"; + else if (adrcode & MA_MAP7) + base = "textures[6]"; + else if (adrcode & MA_MAP8) + base = "textures[7]"; + else if (adrcode & MA_MAP9) + base = "textures[8]"; + else if (adrcode & MA_MAP10) + base = "textures[9]"; + else if (adrcode & MA_MAP11) + base = "textures[10]"; + else if (adrcode & MA_MAP12) + base = "textures[11]"; + else if (adrcode & MA_MAP13) + base = "textures[12]"; + else if (adrcode & MA_MAP14) + base = "textures[13]"; + else if (adrcode & MA_MAP15) + base = "textures[14]"; + else if (adrcode & MA_MAP16) + base = "textures[15]"; + else if (adrcode & MA_MAP17) + base = "textures[16]"; + else if (adrcode & MA_MAP18) + base = "textures[17]"; + + /* property identifier for path */ + adrcode = (adrcode & (MA_MAP1 - 1)); + switch (adrcode) { +#if 0 // XXX these are not wrapped in RNA yet! + case MAP_OFS_X: + poin = &(mtex->ofs[0]); break; + case MAP_OFS_Y: + poin = &(mtex->ofs[1]); break; + case MAP_OFS_Z: + poin = &(mtex->ofs[2]); break; + case MAP_SIZE_X: + poin = &(mtex->size[0]); break; + case MAP_SIZE_Y: + poin = &(mtex->size[1]); break; + case MAP_SIZE_Z: + poin = &(mtex->size[2]); break; + case MAP_R: + poin = &(mtex->r); break; + case MAP_G: + poin = &(mtex->g); break; + case MAP_B: + poin = &(mtex->b); break; + case MAP_DVAR: + poin = &(mtex->def_var); break; + case MAP_COLF: + poin = &(mtex->colfac); break; + case MAP_NORF: + poin = &(mtex->norfac); break; + case MAP_VARF: + poin = &(mtex->varfac); break; #endif - case MAP_DISP: - prop = "warp_factor"; break; - } - - /* only build and return path if there's a property */ - if (prop) { - BLI_snprintf(buf, 128, "%s.%s", base, prop); - return buf; - } - else - return NULL; + case MAP_DISP: + prop = "warp_factor"; + break; + } + + /* only build and return path if there's a property */ + if (prop) { + BLI_snprintf(buf, 128, "%s.%s", base, prop); + return buf; + } + else + return NULL; } /* Texture types */ static const char *texture_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case TE_NSIZE: - return "noise_size"; - case TE_TURB: - return "turbulence"; - - case TE_NDEPTH: // XXX texture RNA undefined - //poin= &(tex->noisedepth); *type= IPO_SHORT; break; - break; - case TE_NTYPE: // XXX texture RNA undefined - //poin= &(tex->noisetype); *type= IPO_SHORT; break; - break; - - case TE_N_BAS1: - return "noise_basis"; - case TE_N_BAS2: - return "noise_basis"; // XXX this is not yet defined in RNA... - - /* voronoi */ - case TE_VNW1: - *array_index = 0; return "feature_weights"; - case TE_VNW2: - *array_index = 1; return "feature_weights"; - case TE_VNW3: - *array_index = 2; return "feature_weights"; - case TE_VNW4: - *array_index = 3; return "feature_weights"; - case TE_VNMEXP: - return "minkovsky_exponent"; - case TE_VN_DISTM: - return "distance_metric"; - case TE_VN_COLT: - return "color_type"; - - /* distorted noise / voronoi */ - case TE_ISCA: - return "noise_intensity"; - - /* distorted noise */ - case TE_DISTA: - return "distortion_amount"; - - /* musgrave */ - case TE_MG_TYP: // XXX texture RNA undefined - // poin= &(tex->stype); *type= IPO_SHORT; break; - break; - case TE_MGH: - return "highest_dimension"; - case TE_MG_LAC: - return "lacunarity"; - case TE_MG_OCT: - return "octaves"; - case TE_MG_OFF: - return "offset"; - case TE_MG_GAIN: - return "gain"; - - case TE_COL_R: - *array_index = 0; return "rgb_factor"; - case TE_COL_G: - *array_index = 1; return "rgb_factor"; - case TE_COL_B: - *array_index = 2; return "rgb_factor"; - - case TE_BRIGHT: - return "brightness"; - case TE_CONTRA: - return "contrast"; - } - - return NULL; + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case TE_NSIZE: + return "noise_size"; + case TE_TURB: + return "turbulence"; + + case TE_NDEPTH: // XXX texture RNA undefined + //poin= &(tex->noisedepth); *type= IPO_SHORT; break; + break; + case TE_NTYPE: // XXX texture RNA undefined + //poin= &(tex->noisetype); *type= IPO_SHORT; break; + break; + + case TE_N_BAS1: + return "noise_basis"; + case TE_N_BAS2: + return "noise_basis"; // XXX this is not yet defined in RNA... + + /* voronoi */ + case TE_VNW1: + *array_index = 0; + return "feature_weights"; + case TE_VNW2: + *array_index = 1; + return "feature_weights"; + case TE_VNW3: + *array_index = 2; + return "feature_weights"; + case TE_VNW4: + *array_index = 3; + return "feature_weights"; + case TE_VNMEXP: + return "minkovsky_exponent"; + case TE_VN_DISTM: + return "distance_metric"; + case TE_VN_COLT: + return "color_type"; + + /* distorted noise / voronoi */ + case TE_ISCA: + return "noise_intensity"; + + /* distorted noise */ + case TE_DISTA: + return "distortion_amount"; + + /* musgrave */ + case TE_MG_TYP: // XXX texture RNA undefined + // poin= &(tex->stype); *type= IPO_SHORT; break; + break; + case TE_MGH: + return "highest_dimension"; + case TE_MG_LAC: + return "lacunarity"; + case TE_MG_OCT: + return "octaves"; + case TE_MG_OFF: + return "offset"; + case TE_MG_GAIN: + return "gain"; + + case TE_COL_R: + *array_index = 0; + return "rgb_factor"; + case TE_COL_G: + *array_index = 1; + return "rgb_factor"; + case TE_COL_B: + *array_index = 2; + return "rgb_factor"; + + case TE_BRIGHT: + return "brightness"; + case TE_CONTRA: + return "contrast"; + } + + return NULL; } /* Material Types */ static const char *material_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case MA_COL_R: - *array_index = 0; return "diffuse_color"; - case MA_COL_G: - *array_index = 1; return "diffuse_color"; - case MA_COL_B: - *array_index = 2; return "diffuse_color"; - - case MA_SPEC_R: - *array_index = 0; return "specular_color"; - case MA_SPEC_G: - *array_index = 1; return "specular_color"; - case MA_SPEC_B: - *array_index = 2; return "specular_color"; - - case MA_MIR_R: - *array_index = 0; return "mirror_color"; - case MA_MIR_G: - *array_index = 1; return "mirror_color"; - case MA_MIR_B: - *array_index = 2; return "mirror_color"; - - case MA_ALPHA: - return "alpha"; - - case MA_REF: - return "diffuse_intensity"; - - case MA_EMIT: - return "emit"; - - case MA_AMB: - return "ambient"; - - case MA_SPEC: - return "specular_intensity"; - - case MA_HARD: - return "specular_hardness"; - - case MA_SPTR: - return "specular_opacity"; - - case MA_IOR: - return "ior"; - - case MA_HASIZE: - return "halo.size"; - - case MA_TRANSLU: - return "translucency"; - - case MA_RAYM: - return "raytrace_mirror.reflect"; - - case MA_FRESMIR: - return "raytrace_mirror.fresnel"; - - case MA_FRESMIRI: - return "raytrace_mirror.fresnel_factor"; - - case MA_FRESTRA: - return "raytrace_transparency.fresnel"; - - case MA_FRESTRAI: - return "raytrace_transparency.fresnel_factor"; - - case MA_ADD: - return "halo.add"; - - default: /* for now, we assume that the others were MTex channels */ - return mtex_adrcodes_to_paths(adrcode, array_index); - } - - return NULL; + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case MA_COL_R: + *array_index = 0; + return "diffuse_color"; + case MA_COL_G: + *array_index = 1; + return "diffuse_color"; + case MA_COL_B: + *array_index = 2; + return "diffuse_color"; + + case MA_SPEC_R: + *array_index = 0; + return "specular_color"; + case MA_SPEC_G: + *array_index = 1; + return "specular_color"; + case MA_SPEC_B: + *array_index = 2; + return "specular_color"; + + case MA_MIR_R: + *array_index = 0; + return "mirror_color"; + case MA_MIR_G: + *array_index = 1; + return "mirror_color"; + case MA_MIR_B: + *array_index = 2; + return "mirror_color"; + + case MA_ALPHA: + return "alpha"; + + case MA_REF: + return "diffuse_intensity"; + + case MA_EMIT: + return "emit"; + + case MA_AMB: + return "ambient"; + + case MA_SPEC: + return "specular_intensity"; + + case MA_HARD: + return "specular_hardness"; + + case MA_SPTR: + return "specular_opacity"; + + case MA_IOR: + return "ior"; + + case MA_HASIZE: + return "halo.size"; + + case MA_TRANSLU: + return "translucency"; + + case MA_RAYM: + return "raytrace_mirror.reflect"; + + case MA_FRESMIR: + return "raytrace_mirror.fresnel"; + + case MA_FRESMIRI: + return "raytrace_mirror.fresnel_factor"; + + case MA_FRESTRA: + return "raytrace_transparency.fresnel"; + + case MA_FRESTRAI: + return "raytrace_transparency.fresnel_factor"; + + case MA_ADD: + return "halo.add"; + + default: /* for now, we assume that the others were MTex channels */ + return mtex_adrcodes_to_paths(adrcode, array_index); + } + + return NULL; } /* Camera Types */ static const char *camera_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case CAM_LENS: -#if 0 // XXX this cannot be resolved easily... perhaps we assume camera is perspective (works for most cases... - if (ca->type == CAM_ORTHO) - return "ortho_scale"; - else - return "lens"; -#else // XXX lazy hack for now... - return "lens"; -#endif // XXX this cannot be resolved easily - - case CAM_STA: - return "clip_start"; - case CAM_END: - return "clip_end"; - -#if 0 // XXX these are not defined in RNA - case CAM_YF_APERT: - poin = &(ca->YF_aperture); break; - case CAM_YF_FDIST: - poin = &(ca->dof_distance); break; -#endif // XXX these are not defined in RNA - - case CAM_SHIFT_X: - return "shift_x"; - case CAM_SHIFT_Y: - return "shift_y"; - } - - /* unrecognized adrcode, or not-yet-handled ones! */ - return NULL; + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case CAM_LENS: +#if 0 // XXX this cannot be resolved easily... perhaps we assume camera is perspective (works for most cases... + if (ca->type == CAM_ORTHO) + return "ortho_scale"; + else + return "lens"; +#else // XXX lazy hack for now... + return "lens"; +#endif // XXX this cannot be resolved easily + + case CAM_STA: + return "clip_start"; + case CAM_END: + return "clip_end"; + +#if 0 // XXX these are not defined in RNA + case CAM_YF_APERT: + poin = &(ca->YF_aperture); break; + case CAM_YF_FDIST: + poin = &(ca->dof_distance); break; +#endif // XXX these are not defined in RNA + + case CAM_SHIFT_X: + return "shift_x"; + case CAM_SHIFT_Y: + return "shift_y"; + } + + /* unrecognized adrcode, or not-yet-handled ones! */ + return NULL; } /* Light Types */ static const char *light_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case LA_ENERGY: - return "energy"; - - case LA_COL_R: - *array_index = 0; return "color"; - case LA_COL_G: - *array_index = 1; return "color"; - case LA_COL_B: - *array_index = 2; return "color"; - - case LA_DIST: - return "distance"; - - case LA_SPOTSI: - return "spot_size"; - case LA_SPOTBL: - return "spot_blend"; - - case LA_QUAD1: - return "linear_attenuation"; - case LA_QUAD2: - return "quadratic_attenuation"; - - case LA_HALOINT: - return "halo_intensity"; - - default: /* for now, we assume that the others were MTex channels */ - return mtex_adrcodes_to_paths(adrcode, array_index); - } - - /* unrecognized adrcode, or not-yet-handled ones! */ - return NULL; + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case LA_ENERGY: + return "energy"; + + case LA_COL_R: + *array_index = 0; + return "color"; + case LA_COL_G: + *array_index = 1; + return "color"; + case LA_COL_B: + *array_index = 2; + return "color"; + + case LA_DIST: + return "distance"; + + case LA_SPOTSI: + return "spot_size"; + case LA_SPOTBL: + return "spot_blend"; + + case LA_QUAD1: + return "linear_attenuation"; + case LA_QUAD2: + return "quadratic_attenuation"; + + case LA_HALOINT: + return "halo_intensity"; + + default: /* for now, we assume that the others were MTex channels */ + return mtex_adrcodes_to_paths(adrcode, array_index); + } + + /* unrecognized adrcode, or not-yet-handled ones! */ + return NULL; } /* Sound Types */ static const char *sound_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case SND_VOLUME: - return "volume"; - case SND_PITCH: - return "pitch"; - /* XXX Joshua -- I had wrapped panning in rna, but someone commented out, calling it "unused" */ + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case SND_VOLUME: + return "volume"; + case SND_PITCH: + return "pitch"; + /* XXX Joshua -- I had wrapped panning in rna, but someone commented out, calling it "unused" */ #if 0 - case SND_PANNING: - return "panning"; + case SND_PANNING: + return "panning"; #endif - case SND_ATTEN: - return "attenuation"; - } + case SND_ATTEN: + return "attenuation"; + } - /* unrecognized adrcode, or not-yet-handled ones! */ - return NULL; + /* unrecognized adrcode, or not-yet-handled ones! */ + return NULL; } /* World Types */ static const char *world_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case WO_HOR_R: - *array_index = 0; return "horizon_color"; - case WO_HOR_G: - *array_index = 1; return "horizon_color"; - case WO_HOR_B: - *array_index = 2; return "horizon_color"; - case WO_ZEN_R: - *array_index = 0; return "zenith_color"; - case WO_ZEN_G: - *array_index = 1; return "zenith_color"; - case WO_ZEN_B: - *array_index = 2; return "zenith_color"; - - case WO_EXPOS: - return "exposure"; - - case WO_MISI: - return "mist.intensity"; - case WO_MISTDI: - return "mist.depth"; - case WO_MISTSTA: - return "mist.start"; - case WO_MISTHI: - return "mist.height"; - - default: /* for now, we assume that the others were MTex channels */ - return mtex_adrcodes_to_paths(adrcode, array_index); - } - - return NULL; + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case WO_HOR_R: + *array_index = 0; + return "horizon_color"; + case WO_HOR_G: + *array_index = 1; + return "horizon_color"; + case WO_HOR_B: + *array_index = 2; + return "horizon_color"; + case WO_ZEN_R: + *array_index = 0; + return "zenith_color"; + case WO_ZEN_G: + *array_index = 1; + return "zenith_color"; + case WO_ZEN_B: + *array_index = 2; + return "zenith_color"; + + case WO_EXPOS: + return "exposure"; + + case WO_MISI: + return "mist.intensity"; + case WO_MISTDI: + return "mist.depth"; + case WO_MISTSTA: + return "mist.start"; + case WO_MISTHI: + return "mist.height"; + + default: /* for now, we assume that the others were MTex channels */ + return mtex_adrcodes_to_paths(adrcode, array_index); + } + + return NULL; } /* Particle Types */ static const char *particle_adrcodes_to_paths(int adrcode, int *array_index) { - /* set array index like this in-case nothing sets it correctly */ - *array_index = 0; - - /* result depends on adrcode */ - switch (adrcode) { - case PART_CLUMP: - return "settings.clump_factor"; - case PART_AVE: - return "settings.angular_velocity_factor"; - case PART_SIZE: - return "settings.particle_size"; - case PART_DRAG: - return "settings.drag_factor"; - case PART_BROWN: - return "settings.brownian_factor"; - case PART_DAMP: - return "settings.damp_factor"; - case PART_LENGTH: - return "settings.length"; - case PART_GRAV_X: - *array_index = 0; return "settings.acceleration"; - case PART_GRAV_Y: - *array_index = 1; return "settings.acceleration"; - case PART_GRAV_Z: - *array_index = 2; return "settings.acceleration"; - case PART_KINK_AMP: - return "settings.kink_amplitude"; - case PART_KINK_FREQ: - return "settings.kink_frequency"; - case PART_KINK_SHAPE: - return "settings.kink_shape"; - case PART_BB_TILT: - return "settings.billboard_tilt"; - - /* PartDeflect needs to be sorted out properly in rna_object_force; - * If anyone else works on this, but is unfamiliar, these particular - * settings reference the particles of the system themselves - * being used as forces -- it will use the same rna structure - * as the similar object forces */ + /* set array index like this in-case nothing sets it correctly */ + *array_index = 0; + + /* result depends on adrcode */ + switch (adrcode) { + case PART_CLUMP: + return "settings.clump_factor"; + case PART_AVE: + return "settings.angular_velocity_factor"; + case PART_SIZE: + return "settings.particle_size"; + case PART_DRAG: + return "settings.drag_factor"; + case PART_BROWN: + return "settings.brownian_factor"; + case PART_DAMP: + return "settings.damp_factor"; + case PART_LENGTH: + return "settings.length"; + case PART_GRAV_X: + *array_index = 0; + return "settings.acceleration"; + case PART_GRAV_Y: + *array_index = 1; + return "settings.acceleration"; + case PART_GRAV_Z: + *array_index = 2; + return "settings.acceleration"; + case PART_KINK_AMP: + return "settings.kink_amplitude"; + case PART_KINK_FREQ: + return "settings.kink_frequency"; + case PART_KINK_SHAPE: + return "settings.kink_shape"; + case PART_BB_TILT: + return "settings.billboard_tilt"; + + /* PartDeflect needs to be sorted out properly in rna_object_force; + * If anyone else works on this, but is unfamiliar, these particular + * settings reference the particles of the system themselves + * being used as forces -- it will use the same rna structure + * as the similar object forces */ #if 0 - case PART_PD_FSTR: - if (part->pd) poin = &(part->pd->f_strength); - break; - case PART_PD_FFALL: - if (part->pd) poin = &(part->pd->f_power); - break; - case PART_PD_FMAXD: - if (part->pd) poin = &(part->pd->maxdist); - break; - case PART_PD2_FSTR: - if (part->pd2) poin = &(part->pd2->f_strength); - break; - case PART_PD2_FFALL: - if (part->pd2) poin = &(part->pd2->f_power); - break; - case PART_PD2_FMAXD: - if (part->pd2) poin = &(part->pd2->maxdist); - break; + case PART_PD_FSTR: + if (part->pd) poin = &(part->pd->f_strength); + break; + case PART_PD_FFALL: + if (part->pd) poin = &(part->pd->f_power); + break; + case PART_PD_FMAXD: + if (part->pd) poin = &(part->pd->maxdist); + break; + case PART_PD2_FSTR: + if (part->pd2) poin = &(part->pd2->f_strength); + break; + case PART_PD2_FFALL: + if (part->pd2) poin = &(part->pd2->f_power); + break; + case PART_PD2_FMAXD: + if (part->pd2) poin = &(part->pd2->maxdist); + break; #endif + } - } - - return NULL; + return NULL; } /* ------- */ @@ -800,170 +871,176 @@ static const char *particle_adrcodes_to_paths(int adrcode, int *array_index) * - array_index - index in property's array (if applicable) to use * - return - the allocated path... */ -static char *get_rna_access(ID *id, int blocktype, int adrcode, char actname[], char constname[], Sequence *seq, int *array_index) +static char *get_rna_access(ID *id, + int blocktype, + int adrcode, + char actname[], + char constname[], + Sequence *seq, + int *array_index) { - DynStr *path = BLI_dynstr_new(); - const char *propname = NULL; - char *rpath = NULL; - char buf[512]; - int dummy_index = 0; - - /* hack: if constname is set, we can only be dealing with an Constraint curve */ - if (constname) - blocktype = ID_CO; - - /* get property name based on blocktype */ - switch (blocktype) { - case ID_OB: /* object */ - propname = ob_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_PO: /* pose channel */ - propname = pchan_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_KE: /* shapekeys */ - propname = shapekey_adrcodes_to_paths(id, adrcode, &dummy_index); - break; - - case ID_CO: /* constraint */ - propname = constraint_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_TE: /* texture */ - propname = texture_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_MA: /* material */ - propname = material_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_CA: /* camera */ - propname = camera_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_LA: /* light */ - propname = light_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_SO: /* sound */ - propname = sound_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_WO: /* world */ - propname = world_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_PA: /* particle */ - propname = particle_adrcodes_to_paths(adrcode, &dummy_index); - break; - - case ID_CU: /* curve */ - /* this used to be a 'dummy' curve which got evaluated on the fly... - * now we've got real var for this! - */ - propname = "eval_time"; - break; - - /* XXX problematic blocktypes */ - case ID_SEQ: /* sequencer strip */ - //SEQ_FAC1: - switch (adrcode) { - case SEQ_FAC1: - propname = "effect_fader"; - break; - case SEQ_FAC_SPEED: - propname = "speed_fader"; - break; - case SEQ_FAC_OPACITY: - propname = "blend_opacity"; - break; - } - // poin= &(seq->facf0); // XXX this doesn't seem to be included anywhere in sequencer RNA... - break; - - /* special hacks */ - case -1: - /* special case for rotdiff drivers... we don't need a property for this... */ - break; - - /* TODO... add other blocktypes... */ - default: - CLOG_WARN(&LOG, "No path for blocktype %d, adrcode %d yet", blocktype, adrcode); - break; - } - - /* check if any property found - * - blocktype < 0 is special case for a specific type of driver, where we don't need a property name... - */ - if ((propname == NULL) && (blocktype > 0)) { - /* nothing was found, so exit */ - if (array_index) - *array_index = 0; - - BLI_dynstr_free(path); - - return NULL; - } - else { - if (array_index) - *array_index = dummy_index; - } - - /* 'buf' _must_ be initialized in this block */ - /* append preceding bits to path */ - /* note, strings are not escapted and they should be! */ - if ((actname && actname[0]) && (constname && constname[0])) { - /* Constraint in Pose-Channel */ - BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"].constraints[\"%s\"]", actname, constname); - } - else if (actname && actname[0]) { - if ((blocktype == ID_OB) && STREQ(actname, "Object")) { - /* Actionified "Object" IPO's... no extra path stuff needed */ - buf[0] = '\0'; /* empty string */ - } - else if ((blocktype == ID_KE) && STREQ(actname, "Shape")) { - /* Actionified "Shape" IPO's - these are forced onto object level via the action container there... */ - strcpy(buf, "data.shape_keys"); - } - else { - /* Pose-Channel */ - BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"]", actname); - } - } - else if (constname && constname[0]) { - /* Constraint in Object */ - BLI_snprintf(buf, sizeof(buf), "constraints[\"%s\"]", constname); - } - else if (seq) { - /* Sequence names in Scene */ - BLI_snprintf(buf, sizeof(buf), "sequence_editor.sequences_all[\"%s\"]", seq->name + 2); - } - else { - buf[0] = '\0'; /* empty string */ - } - - BLI_dynstr_append(path, buf); - - /* need to add dot before property if there was anything precceding this */ - if (buf[0]) - BLI_dynstr_append(path, "."); - - /* now write name of property */ - BLI_dynstr_append(path, propname); - - /* if there was no array index pointer provided, add it to the path */ - if (array_index == NULL) { - BLI_snprintf(buf, sizeof(buf), "[\"%d\"]", dummy_index); - BLI_dynstr_append(path, buf); - } - - /* convert to normal MEM_malloc'd string */ - rpath = BLI_dynstr_get_cstring(path); - BLI_dynstr_free(path); - - /* return path... */ - return rpath; + DynStr *path = BLI_dynstr_new(); + const char *propname = NULL; + char *rpath = NULL; + char buf[512]; + int dummy_index = 0; + + /* hack: if constname is set, we can only be dealing with an Constraint curve */ + if (constname) + blocktype = ID_CO; + + /* get property name based on blocktype */ + switch (blocktype) { + case ID_OB: /* object */ + propname = ob_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_PO: /* pose channel */ + propname = pchan_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_KE: /* shapekeys */ + propname = shapekey_adrcodes_to_paths(id, adrcode, &dummy_index); + break; + + case ID_CO: /* constraint */ + propname = constraint_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_TE: /* texture */ + propname = texture_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_MA: /* material */ + propname = material_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_CA: /* camera */ + propname = camera_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_LA: /* light */ + propname = light_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_SO: /* sound */ + propname = sound_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_WO: /* world */ + propname = world_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_PA: /* particle */ + propname = particle_adrcodes_to_paths(adrcode, &dummy_index); + break; + + case ID_CU: /* curve */ + /* this used to be a 'dummy' curve which got evaluated on the fly... + * now we've got real var for this! + */ + propname = "eval_time"; + break; + + /* XXX problematic blocktypes */ + case ID_SEQ: /* sequencer strip */ + //SEQ_FAC1: + switch (adrcode) { + case SEQ_FAC1: + propname = "effect_fader"; + break; + case SEQ_FAC_SPEED: + propname = "speed_fader"; + break; + case SEQ_FAC_OPACITY: + propname = "blend_opacity"; + break; + } + // poin= &(seq->facf0); // XXX this doesn't seem to be included anywhere in sequencer RNA... + break; + + /* special hacks */ + case -1: + /* special case for rotdiff drivers... we don't need a property for this... */ + break; + + /* TODO... add other blocktypes... */ + default: + CLOG_WARN(&LOG, "No path for blocktype %d, adrcode %d yet", blocktype, adrcode); + break; + } + + /* check if any property found + * - blocktype < 0 is special case for a specific type of driver, where we don't need a property name... + */ + if ((propname == NULL) && (blocktype > 0)) { + /* nothing was found, so exit */ + if (array_index) + *array_index = 0; + + BLI_dynstr_free(path); + + return NULL; + } + else { + if (array_index) + *array_index = dummy_index; + } + + /* 'buf' _must_ be initialized in this block */ + /* append preceding bits to path */ + /* note, strings are not escapted and they should be! */ + if ((actname && actname[0]) && (constname && constname[0])) { + /* Constraint in Pose-Channel */ + BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"].constraints[\"%s\"]", actname, constname); + } + else if (actname && actname[0]) { + if ((blocktype == ID_OB) && STREQ(actname, "Object")) { + /* Actionified "Object" IPO's... no extra path stuff needed */ + buf[0] = '\0'; /* empty string */ + } + else if ((blocktype == ID_KE) && STREQ(actname, "Shape")) { + /* Actionified "Shape" IPO's - these are forced onto object level via the action container there... */ + strcpy(buf, "data.shape_keys"); + } + else { + /* Pose-Channel */ + BLI_snprintf(buf, sizeof(buf), "pose.bones[\"%s\"]", actname); + } + } + else if (constname && constname[0]) { + /* Constraint in Object */ + BLI_snprintf(buf, sizeof(buf), "constraints[\"%s\"]", constname); + } + else if (seq) { + /* Sequence names in Scene */ + BLI_snprintf(buf, sizeof(buf), "sequence_editor.sequences_all[\"%s\"]", seq->name + 2); + } + else { + buf[0] = '\0'; /* empty string */ + } + + BLI_dynstr_append(path, buf); + + /* need to add dot before property if there was anything precceding this */ + if (buf[0]) + BLI_dynstr_append(path, "."); + + /* now write name of property */ + BLI_dynstr_append(path, propname); + + /* if there was no array index pointer provided, add it to the path */ + if (array_index == NULL) { + BLI_snprintf(buf, sizeof(buf), "[\"%d\"]", dummy_index); + BLI_dynstr_append(path, buf); + } + + /* convert to normal MEM_malloc'd string */ + rpath = BLI_dynstr_get_cstring(path); + BLI_dynstr_free(path); + + /* return path... */ + return rpath; } /* *************************************************** */ @@ -972,164 +1049,171 @@ static char *get_rna_access(ID *id, int blocktype, int adrcode, char actname[], /* Convert adrcodes to driver target transform channel types */ static short adrcode_to_dtar_transchan(short adrcode) { - switch (adrcode) { - case OB_LOC_X: - return DTAR_TRANSCHAN_LOCX; - case OB_LOC_Y: - return DTAR_TRANSCHAN_LOCY; - case OB_LOC_Z: - return DTAR_TRANSCHAN_LOCZ; - - case OB_ROT_X: - return DTAR_TRANSCHAN_ROTX; - case OB_ROT_Y: - return DTAR_TRANSCHAN_ROTY; - case OB_ROT_Z: - return DTAR_TRANSCHAN_ROTZ; - - case OB_SIZE_X: - return DTAR_TRANSCHAN_SCALEX; - case OB_SIZE_Y: - return DTAR_TRANSCHAN_SCALEX; - case OB_SIZE_Z: - return DTAR_TRANSCHAN_SCALEX; - - default: - return 0; - } + switch (adrcode) { + case OB_LOC_X: + return DTAR_TRANSCHAN_LOCX; + case OB_LOC_Y: + return DTAR_TRANSCHAN_LOCY; + case OB_LOC_Z: + return DTAR_TRANSCHAN_LOCZ; + + case OB_ROT_X: + return DTAR_TRANSCHAN_ROTX; + case OB_ROT_Y: + return DTAR_TRANSCHAN_ROTY; + case OB_ROT_Z: + return DTAR_TRANSCHAN_ROTZ; + + case OB_SIZE_X: + return DTAR_TRANSCHAN_SCALEX; + case OB_SIZE_Y: + return DTAR_TRANSCHAN_SCALEX; + case OB_SIZE_Z: + return DTAR_TRANSCHAN_SCALEX; + + default: + return 0; + } } /* Convert IpoDriver to ChannelDriver - will free the old data (i.e. the old driver) */ static ChannelDriver *idriver_to_cdriver(IpoDriver *idriver) { - ChannelDriver *cdriver; - - /* allocate memory for new driver */ - cdriver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver"); - - /* if 'pydriver', just copy data across */ - if (idriver->type == IPO_DRIVER_TYPE_PYTHON) { - /* PyDriver only requires the expression to be copied */ - // FIXME: expression will be useless due to API changes, but at least not totally lost - cdriver->type = DRIVER_TYPE_PYTHON; - if (idriver->name[0]) - BLI_strncpy(cdriver->expression, idriver->name, sizeof(cdriver->expression)); - } - else { - DriverVar *dvar = NULL; - DriverTarget *dtar = NULL; - - /* this should be ok for all types here... */ - cdriver->type = DRIVER_TYPE_AVERAGE; - - /* what to store depends on the 'blocktype' - object or posechannel */ - if (idriver->blocktype == ID_AR) { /* PoseChannel */ - if (idriver->adrcode == OB_ROT_DIFF) { - /* Rotational Difference requires a special type of variable */ - dvar = driver_add_new_variable(cdriver); - driver_change_variable_type(dvar, DVAR_TYPE_ROT_DIFF); - - /* first bone target */ - dtar = &dvar->targets[0]; - dtar->id = (ID *)idriver->ob; - dtar->idtype = ID_OB; - if (idriver->name[0]) - BLI_strncpy(dtar->pchan_name, idriver->name, sizeof(dtar->pchan_name)); - - /* second bone target (name was stored in same var as the first one) */ - dtar = &dvar->targets[1]; - dtar->id = (ID *)idriver->ob; - dtar->idtype = ID_OB; - if (idriver->name[0]) // xxx... for safety - BLI_strncpy(dtar->pchan_name, idriver->name + DRIVER_NAME_OFFS, sizeof(dtar->pchan_name)); - } - else { - /* only a single variable, of type 'transform channel' */ - dvar = driver_add_new_variable(cdriver); - driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN); - - /* only requires a single target */ - dtar = &dvar->targets[0]; - dtar->id = (ID *)idriver->ob; - dtar->idtype = ID_OB; - if (idriver->name[0]) - BLI_strncpy(dtar->pchan_name, idriver->name, sizeof(dtar->pchan_name)); - dtar->transChan = adrcode_to_dtar_transchan(idriver->adrcode); - dtar->flag |= DTAR_FLAG_LOCALSPACE; /* old drivers took local space */ - } - } - else { /* Object */ - /* only a single variable, of type 'transform channel' */ - dvar = driver_add_new_variable(cdriver); - driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN); - - /* only requires single target */ - dtar = &dvar->targets[0]; - dtar->id = (ID *)idriver->ob; - dtar->idtype = ID_OB; - dtar->transChan = adrcode_to_dtar_transchan(idriver->adrcode); - } - } - - /* return the new one */ - return cdriver; + ChannelDriver *cdriver; + + /* allocate memory for new driver */ + cdriver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver"); + + /* if 'pydriver', just copy data across */ + if (idriver->type == IPO_DRIVER_TYPE_PYTHON) { + /* PyDriver only requires the expression to be copied */ + // FIXME: expression will be useless due to API changes, but at least not totally lost + cdriver->type = DRIVER_TYPE_PYTHON; + if (idriver->name[0]) + BLI_strncpy(cdriver->expression, idriver->name, sizeof(cdriver->expression)); + } + else { + DriverVar *dvar = NULL; + DriverTarget *dtar = NULL; + + /* this should be ok for all types here... */ + cdriver->type = DRIVER_TYPE_AVERAGE; + + /* what to store depends on the 'blocktype' - object or posechannel */ + if (idriver->blocktype == ID_AR) { /* PoseChannel */ + if (idriver->adrcode == OB_ROT_DIFF) { + /* Rotational Difference requires a special type of variable */ + dvar = driver_add_new_variable(cdriver); + driver_change_variable_type(dvar, DVAR_TYPE_ROT_DIFF); + + /* first bone target */ + dtar = &dvar->targets[0]; + dtar->id = (ID *)idriver->ob; + dtar->idtype = ID_OB; + if (idriver->name[0]) + BLI_strncpy(dtar->pchan_name, idriver->name, sizeof(dtar->pchan_name)); + + /* second bone target (name was stored in same var as the first one) */ + dtar = &dvar->targets[1]; + dtar->id = (ID *)idriver->ob; + dtar->idtype = ID_OB; + if (idriver->name[0]) // xxx... for safety + BLI_strncpy( + dtar->pchan_name, idriver->name + DRIVER_NAME_OFFS, sizeof(dtar->pchan_name)); + } + else { + /* only a single variable, of type 'transform channel' */ + dvar = driver_add_new_variable(cdriver); + driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN); + + /* only requires a single target */ + dtar = &dvar->targets[0]; + dtar->id = (ID *)idriver->ob; + dtar->idtype = ID_OB; + if (idriver->name[0]) + BLI_strncpy(dtar->pchan_name, idriver->name, sizeof(dtar->pchan_name)); + dtar->transChan = adrcode_to_dtar_transchan(idriver->adrcode); + dtar->flag |= DTAR_FLAG_LOCALSPACE; /* old drivers took local space */ + } + } + else { /* Object */ + /* only a single variable, of type 'transform channel' */ + dvar = driver_add_new_variable(cdriver); + driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN); + + /* only requires single target */ + dtar = &dvar->targets[0]; + dtar->id = (ID *)idriver->ob; + dtar->idtype = ID_OB; + dtar->transChan = adrcode_to_dtar_transchan(idriver->adrcode); + } + } + + /* return the new one */ + return cdriver; } /* Add F-Curve to the correct list * - grpname is needed to be used as group name where relevant, and is usually derived from actname */ -static void fcurve_add_to_list(ListBase *groups, ListBase *list, FCurve *fcu, char *grpname, int muteipo) +static void fcurve_add_to_list( + ListBase *groups, ListBase *list, FCurve *fcu, char *grpname, int muteipo) { - /* If we're adding to an action, we will have groups to write to... */ - if (groups && grpname) { - /* wrap the pointers given into a dummy action that we pass to the API func - * and extract the resultant lists... - */ - bAction tmp_act; - bActionGroup *agrp = NULL; - - /* init the temp action */ - memset(&tmp_act, 0, sizeof(bAction)); // XXX only enable this line if we get errors - tmp_act.groups.first = groups->first; - tmp_act.groups.last = groups->last; - tmp_act.curves.first = list->first; - tmp_act.curves.last = list->last; - /* ... xxx, the other vars don't need to be filled in */ - - /* get the group to use */ - agrp = BKE_action_group_find_name(&tmp_act, grpname); - /* no matching group, so add one */ - if (agrp == NULL) { - /* Add a new group, and make it active */ - agrp = MEM_callocN(sizeof(bActionGroup), "bActionGroup"); - - agrp->flag = AGRP_SELECTED; - if (muteipo) agrp->flag |= AGRP_MUTED; - - BLI_strncpy(agrp->name, grpname, sizeof(agrp->name)); - - BLI_addtail(&tmp_act.groups, agrp); - BLI_uniquename(&tmp_act.groups, agrp, DATA_("Group"), '.', offsetof(bActionGroup, name), - sizeof(agrp->name)); - } - - /* add F-Curve to group */ - /* WARNING: this func should only need to look at the stuff we initialized, if not, things may crash */ - action_groups_add_channel(&tmp_act, agrp, fcu); - - if (agrp->flag & AGRP_MUTED) /* flush down */ - fcu->flag |= FCURVE_MUTED; - - /* set the output lists based on the ones in the temp action */ - groups->first = tmp_act.groups.first; - groups->last = tmp_act.groups.last; - list->first = tmp_act.curves.first; - list->last = tmp_act.curves.last; - } - else { - /* simply add the F-Curve to the end of the given list */ - BLI_addtail(list, fcu); - } + /* If we're adding to an action, we will have groups to write to... */ + if (groups && grpname) { + /* wrap the pointers given into a dummy action that we pass to the API func + * and extract the resultant lists... + */ + bAction tmp_act; + bActionGroup *agrp = NULL; + + /* init the temp action */ + memset(&tmp_act, 0, sizeof(bAction)); // XXX only enable this line if we get errors + tmp_act.groups.first = groups->first; + tmp_act.groups.last = groups->last; + tmp_act.curves.first = list->first; + tmp_act.curves.last = list->last; + /* ... xxx, the other vars don't need to be filled in */ + + /* get the group to use */ + agrp = BKE_action_group_find_name(&tmp_act, grpname); + /* no matching group, so add one */ + if (agrp == NULL) { + /* Add a new group, and make it active */ + agrp = MEM_callocN(sizeof(bActionGroup), "bActionGroup"); + + agrp->flag = AGRP_SELECTED; + if (muteipo) + agrp->flag |= AGRP_MUTED; + + BLI_strncpy(agrp->name, grpname, sizeof(agrp->name)); + + BLI_addtail(&tmp_act.groups, agrp); + BLI_uniquename(&tmp_act.groups, + agrp, + DATA_("Group"), + '.', + offsetof(bActionGroup, name), + sizeof(agrp->name)); + } + + /* add F-Curve to group */ + /* WARNING: this func should only need to look at the stuff we initialized, if not, things may crash */ + action_groups_add_channel(&tmp_act, agrp, fcu); + + if (agrp->flag & AGRP_MUTED) /* flush down */ + fcu->flag |= FCURVE_MUTED; + + /* set the output lists based on the ones in the temp action */ + groups->first = tmp_act.groups.first; + groups->last = tmp_act.groups.last; + list->first = tmp_act.curves.first; + list->last = tmp_act.curves.last; + } + else { + /* simply add the F-Curve to the end of the given list */ + BLI_addtail(list, fcu); + } } /* Convert IPO-Curve to F-Curve (including Driver data), and free any of the old data that @@ -1138,242 +1222,261 @@ static void fcurve_add_to_list(ListBase *groups, ListBase *list, FCurve *fcu, ch * constname: name of Constraint-Channel (if applicable) that IPO-Curve's IPO-block belonged to * seq: sequencer-strip (if applicable) that IPO-Curve's IPO-block belonged to */ -static void icu_to_fcurves(ID *id, ListBase *groups, ListBase *list, IpoCurve *icu, char *actname, char *constname, Sequence *seq, int muteipo) +static void icu_to_fcurves(ID *id, + ListBase *groups, + ListBase *list, + IpoCurve *icu, + char *actname, + char *constname, + Sequence *seq, + int muteipo) { - AdrBit2Path *abp; - FCurve *fcu; - int totbits; - - /* allocate memory for a new F-Curve */ - fcu = MEM_callocN(sizeof(FCurve), "FCurve"); - - /* convert driver */ - if (icu->driver) - fcu->driver = idriver_to_cdriver(icu->driver); - - /* copy flags */ - if (icu->flag & IPO_VISIBLE) fcu->flag |= FCURVE_VISIBLE; - if (icu->flag & IPO_SELECT) fcu->flag |= FCURVE_SELECTED; - if (icu->flag & IPO_ACTIVE) fcu->flag |= FCURVE_ACTIVE; - if (icu->flag & IPO_MUTE) fcu->flag |= FCURVE_MUTED; - if (icu->flag & IPO_PROTECT) fcu->flag |= FCURVE_PROTECTED; - - /* set extrapolation */ - switch (icu->extrap) { - case IPO_HORIZ: /* constant extrapolation */ - case IPO_DIR: /* linear extrapolation */ - { - /* just copy, as the new defines match the old ones... */ - fcu->extend = icu->extrap; - break; - } - case IPO_CYCL: /* cyclic extrapolation */ - case IPO_CYCLX: /* cyclic extrapolation + offset */ - { - /* Add a new FModifier (Cyclic) instead of setting extend value - * as that's the new equivalent of that option. - */ - FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu); - FMod_Cycles *data = (FMod_Cycles *)fcm->data; - - /* if 'offset' one is in use, set appropriate settings */ - if (icu->extrap == IPO_CYCLX) - data->before_mode = data->after_mode = FCM_EXTRAPOLATE_CYCLIC_OFFSET; - else - data->before_mode = data->after_mode = FCM_EXTRAPOLATE_CYCLIC; - break; - } - } - - /* -------- */ - - /* get adrcode <-> bitflags mapping to handle nasty bitflag curves? */ - abp = adrcode_bitmaps_to_paths(icu->blocktype, icu->adrcode, &totbits); - if (abp && totbits) { - FCurve *fcurve; - int b; - - if (G.debug & G_DEBUG) printf("\tconvert bitflag ipocurve, totbits = %d\n", totbits); - - /* add the 'only int values' flag */ - fcu->flag |= (FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES); - - /* for each bit we have to remap + check for: - * 1) we need to make copy the existing F-Curve data (fcu -> fcurve), - * except for the last one which will use the original - * 2) copy the relevant path info across - * 3) filter the keyframes for the flag of interest - */ - for (b = 0; b < totbits; b++, abp++) { - unsigned int i = 0; - - /* make a copy of existing base-data if not the last curve */ - if (b < (totbits - 1)) - fcurve = copy_fcurve(fcu); - else - fcurve = fcu; - - /* set path */ - fcurve->rna_path = BLI_strdup(abp->path); - fcurve->array_index = abp->array_index; - - /* convert keyframes - * - beztriples and bpoints are mutually exclusive, so we won't have both at the same time - * - beztriples are more likely to be encountered as they are keyframes (the other type wasn't used yet) - */ - fcurve->totvert = icu->totvert; - - if (icu->bezt) { - BezTriple *dst, *src; - - /* allocate new array for keyframes/beztriples */ - fcurve->bezt = MEM_callocN(sizeof(BezTriple) * fcurve->totvert, "BezTriples"); - - /* loop through copying all BezTriples individually, as we need to modify a few things */ - for (dst = fcurve->bezt, src = icu->bezt, i = 0; i < fcurve->totvert; i++, dst++, src++) { - /* firstly, copy BezTriple data */ - *dst = *src; - - /* interpolation can only be constant... */ - dst->ipo = BEZT_IPO_CONST; - - /* 'hide' flag is now used for keytype - only 'keyframes' existed before */ - dst->hide = BEZT_KEYTYPE_KEYFRAME; - - /* auto-handles - per curve to per handle */ - if (icu->flag & IPO_AUTO_HORIZ) { - if (dst->h1 == HD_AUTO) dst->h1 = HD_AUTO_ANIM; - if (dst->h2 == HD_AUTO) dst->h2 = HD_AUTO_ANIM; - } - - /* correct values, by checking if the flag of interest is set */ - if ( ((int)(dst->vec[1][1])) & (abp->bit) ) - dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 1.0f; - else - dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 0.0f; - } - } - else if (icu->bp) { - /* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */ - //BPoint *bp; - //FPoint *fpt; - } - - /* add new F-Curve to list */ - fcurve_add_to_list(groups, list, fcurve, actname, muteipo); - } - } - else { - unsigned int i = 0; - - /* get rna-path - * - we will need to set the 'disabled' flag if no path is able to be made (for now) - */ - fcu->rna_path = get_rna_access(id, icu->blocktype, icu->adrcode, actname, constname, seq, &fcu->array_index); - if (fcu->rna_path == NULL) - fcu->flag |= FCURVE_DISABLED; - - /* convert keyframes - * - beztriples and bpoints are mutually exclusive, so we won't have both at the same time - * - beztriples are more likely to be encountered as they are keyframes (the other type wasn't used yet) - */ - fcu->totvert = icu->totvert; - - if (icu->bezt) { - BezTriple *dst, *src; - - /* allocate new array for keyframes/beztriples */ - fcu->bezt = MEM_callocN(sizeof(BezTriple) * fcu->totvert, "BezTriples"); - - /* loop through copying all BezTriples individually, as we need to modify a few things */ - for (dst = fcu->bezt, src = icu->bezt, i = 0; i < fcu->totvert; i++, dst++, src++) { - /* firstly, copy BezTriple data */ - *dst = *src; - - /* now copy interpolation from curve (if not already set) */ - if (icu->ipo != IPO_MIXED) - dst->ipo = icu->ipo; - - /* 'hide' flag is now used for keytype - only 'keyframes' existed before */ - dst->hide = BEZT_KEYTYPE_KEYFRAME; - - /* auto-handles - per curve to per handle */ - if (icu->flag & IPO_AUTO_HORIZ) { - if (dst->h1 == HD_AUTO) dst->h1 = HD_AUTO_ANIM; - if (dst->h2 == HD_AUTO) dst->h2 = HD_AUTO_ANIM; - } - - /* correct values for euler rotation curves - * - they were degrees/10 - * - we need radians for RNA to do the right thing - */ - if ( ((icu->blocktype == ID_OB) && ELEM(icu->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) || - ((icu->blocktype == ID_PO) && ELEM(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z)) ) - { - const float fac = (float)M_PI / 18.0f; //10.0f * M_PI/180.0f; - - dst->vec[0][1] *= fac; - dst->vec[1][1] *= fac; - dst->vec[2][1] *= fac; - } - - /* correct values for path speed curves - * - their values were 0-1 - * - we now need as 'frames' - */ - if ( (id) && (icu->blocktype == GS(id->name)) && - (fcu->rna_path && STREQ(fcu->rna_path, "eval_time")) ) - { - Curve *cu = (Curve *)id; - - dst->vec[0][1] *= cu->pathlen; - dst->vec[1][1] *= cu->pathlen; - dst->vec[2][1] *= cu->pathlen; - } - - /* correct times for rotation drivers - * - need to go from degrees to radians... - * - there's only really 1 target to worry about - * - were also degrees/10 - */ - if (fcu->driver && fcu->driver->variables.first) { - DriverVar *dvar = fcu->driver->variables.first; - DriverTarget *dtar = &dvar->targets[0]; - - if (ELEM(dtar->transChan, DTAR_TRANSCHAN_ROTX, DTAR_TRANSCHAN_ROTY, DTAR_TRANSCHAN_ROTZ)) { - const float fac = (float)M_PI / 18.0f; - - dst->vec[0][0] *= fac; - dst->vec[1][0] *= fac; - dst->vec[2][0] *= fac; - } - } - - /* correct values for sequencer curves, that were not locked to frame */ - if (seq && (seq->flag & SEQ_IPO_FRAME_LOCKED) == 0) { - const float mul = (seq->enddisp - seq->startdisp) / 100.0f; - const float offset = seq->startdisp; - - dst->vec[0][0] *= mul; - dst->vec[0][0] += offset; - - dst->vec[1][0] *= mul; - dst->vec[1][0] += offset; - - dst->vec[2][0] *= mul; - dst->vec[2][0] += offset; - } - } - } - else if (icu->bp) { - /* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */ - //BPoint *bp; - //FPoint *fpt; - } - - /* add new F-Curve to list */ - fcurve_add_to_list(groups, list, fcu, actname, muteipo); - } + AdrBit2Path *abp; + FCurve *fcu; + int totbits; + + /* allocate memory for a new F-Curve */ + fcu = MEM_callocN(sizeof(FCurve), "FCurve"); + + /* convert driver */ + if (icu->driver) + fcu->driver = idriver_to_cdriver(icu->driver); + + /* copy flags */ + if (icu->flag & IPO_VISIBLE) + fcu->flag |= FCURVE_VISIBLE; + if (icu->flag & IPO_SELECT) + fcu->flag |= FCURVE_SELECTED; + if (icu->flag & IPO_ACTIVE) + fcu->flag |= FCURVE_ACTIVE; + if (icu->flag & IPO_MUTE) + fcu->flag |= FCURVE_MUTED; + if (icu->flag & IPO_PROTECT) + fcu->flag |= FCURVE_PROTECTED; + + /* set extrapolation */ + switch (icu->extrap) { + case IPO_HORIZ: /* constant extrapolation */ + case IPO_DIR: /* linear extrapolation */ + { + /* just copy, as the new defines match the old ones... */ + fcu->extend = icu->extrap; + break; + } + case IPO_CYCL: /* cyclic extrapolation */ + case IPO_CYCLX: /* cyclic extrapolation + offset */ + { + /* Add a new FModifier (Cyclic) instead of setting extend value + * as that's the new equivalent of that option. + */ + FModifier *fcm = add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu); + FMod_Cycles *data = (FMod_Cycles *)fcm->data; + + /* if 'offset' one is in use, set appropriate settings */ + if (icu->extrap == IPO_CYCLX) + data->before_mode = data->after_mode = FCM_EXTRAPOLATE_CYCLIC_OFFSET; + else + data->before_mode = data->after_mode = FCM_EXTRAPOLATE_CYCLIC; + break; + } + } + + /* -------- */ + + /* get adrcode <-> bitflags mapping to handle nasty bitflag curves? */ + abp = adrcode_bitmaps_to_paths(icu->blocktype, icu->adrcode, &totbits); + if (abp && totbits) { + FCurve *fcurve; + int b; + + if (G.debug & G_DEBUG) + printf("\tconvert bitflag ipocurve, totbits = %d\n", totbits); + + /* add the 'only int values' flag */ + fcu->flag |= (FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES); + + /* for each bit we have to remap + check for: + * 1) we need to make copy the existing F-Curve data (fcu -> fcurve), + * except for the last one which will use the original + * 2) copy the relevant path info across + * 3) filter the keyframes for the flag of interest + */ + for (b = 0; b < totbits; b++, abp++) { + unsigned int i = 0; + + /* make a copy of existing base-data if not the last curve */ + if (b < (totbits - 1)) + fcurve = copy_fcurve(fcu); + else + fcurve = fcu; + + /* set path */ + fcurve->rna_path = BLI_strdup(abp->path); + fcurve->array_index = abp->array_index; + + /* convert keyframes + * - beztriples and bpoints are mutually exclusive, so we won't have both at the same time + * - beztriples are more likely to be encountered as they are keyframes (the other type wasn't used yet) + */ + fcurve->totvert = icu->totvert; + + if (icu->bezt) { + BezTriple *dst, *src; + + /* allocate new array for keyframes/beztriples */ + fcurve->bezt = MEM_callocN(sizeof(BezTriple) * fcurve->totvert, "BezTriples"); + + /* loop through copying all BezTriples individually, as we need to modify a few things */ + for (dst = fcurve->bezt, src = icu->bezt, i = 0; i < fcurve->totvert; i++, dst++, src++) { + /* firstly, copy BezTriple data */ + *dst = *src; + + /* interpolation can only be constant... */ + dst->ipo = BEZT_IPO_CONST; + + /* 'hide' flag is now used for keytype - only 'keyframes' existed before */ + dst->hide = BEZT_KEYTYPE_KEYFRAME; + + /* auto-handles - per curve to per handle */ + if (icu->flag & IPO_AUTO_HORIZ) { + if (dst->h1 == HD_AUTO) + dst->h1 = HD_AUTO_ANIM; + if (dst->h2 == HD_AUTO) + dst->h2 = HD_AUTO_ANIM; + } + + /* correct values, by checking if the flag of interest is set */ + if (((int)(dst->vec[1][1])) & (abp->bit)) + dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 1.0f; + else + dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 0.0f; + } + } + else if (icu->bp) { + /* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */ + //BPoint *bp; + //FPoint *fpt; + } + + /* add new F-Curve to list */ + fcurve_add_to_list(groups, list, fcurve, actname, muteipo); + } + } + else { + unsigned int i = 0; + + /* get rna-path + * - we will need to set the 'disabled' flag if no path is able to be made (for now) + */ + fcu->rna_path = get_rna_access( + id, icu->blocktype, icu->adrcode, actname, constname, seq, &fcu->array_index); + if (fcu->rna_path == NULL) + fcu->flag |= FCURVE_DISABLED; + + /* convert keyframes + * - beztriples and bpoints are mutually exclusive, so we won't have both at the same time + * - beztriples are more likely to be encountered as they are keyframes (the other type wasn't used yet) + */ + fcu->totvert = icu->totvert; + + if (icu->bezt) { + BezTriple *dst, *src; + + /* allocate new array for keyframes/beztriples */ + fcu->bezt = MEM_callocN(sizeof(BezTriple) * fcu->totvert, "BezTriples"); + + /* loop through copying all BezTriples individually, as we need to modify a few things */ + for (dst = fcu->bezt, src = icu->bezt, i = 0; i < fcu->totvert; i++, dst++, src++) { + /* firstly, copy BezTriple data */ + *dst = *src; + + /* now copy interpolation from curve (if not already set) */ + if (icu->ipo != IPO_MIXED) + dst->ipo = icu->ipo; + + /* 'hide' flag is now used for keytype - only 'keyframes' existed before */ + dst->hide = BEZT_KEYTYPE_KEYFRAME; + + /* auto-handles - per curve to per handle */ + if (icu->flag & IPO_AUTO_HORIZ) { + if (dst->h1 == HD_AUTO) + dst->h1 = HD_AUTO_ANIM; + if (dst->h2 == HD_AUTO) + dst->h2 = HD_AUTO_ANIM; + } + + /* correct values for euler rotation curves + * - they were degrees/10 + * - we need radians for RNA to do the right thing + */ + if (((icu->blocktype == ID_OB) && ELEM(icu->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) || + ((icu->blocktype == ID_PO) && ELEM(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z))) { + const float fac = (float)M_PI / 18.0f; //10.0f * M_PI/180.0f; + + dst->vec[0][1] *= fac; + dst->vec[1][1] *= fac; + dst->vec[2][1] *= fac; + } + + /* correct values for path speed curves + * - their values were 0-1 + * - we now need as 'frames' + */ + if ((id) && (icu->blocktype == GS(id->name)) && + (fcu->rna_path && STREQ(fcu->rna_path, "eval_time"))) { + Curve *cu = (Curve *)id; + + dst->vec[0][1] *= cu->pathlen; + dst->vec[1][1] *= cu->pathlen; + dst->vec[2][1] *= cu->pathlen; + } + + /* correct times for rotation drivers + * - need to go from degrees to radians... + * - there's only really 1 target to worry about + * - were also degrees/10 + */ + if (fcu->driver && fcu->driver->variables.first) { + DriverVar *dvar = fcu->driver->variables.first; + DriverTarget *dtar = &dvar->targets[0]; + + if (ELEM(dtar->transChan, + DTAR_TRANSCHAN_ROTX, + DTAR_TRANSCHAN_ROTY, + DTAR_TRANSCHAN_ROTZ)) { + const float fac = (float)M_PI / 18.0f; + + dst->vec[0][0] *= fac; + dst->vec[1][0] *= fac; + dst->vec[2][0] *= fac; + } + } + + /* correct values for sequencer curves, that were not locked to frame */ + if (seq && (seq->flag & SEQ_IPO_FRAME_LOCKED) == 0) { + const float mul = (seq->enddisp - seq->startdisp) / 100.0f; + const float offset = seq->startdisp; + + dst->vec[0][0] *= mul; + dst->vec[0][0] += offset; + + dst->vec[1][0] *= mul; + dst->vec[1][0] += offset; + + dst->vec[2][0] *= mul; + dst->vec[2][0] += offset; + } + } + } + else if (icu->bp) { + /* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */ + //BPoint *bp; + //FPoint *fpt; + } + + /* add new F-Curve to list */ + fcurve_add_to_list(groups, list, fcu, actname, muteipo); + } } /* ------------------------- */ @@ -1382,68 +1485,78 @@ static void icu_to_fcurves(ID *id, ListBase *groups, ListBase *list, IpoCurve *i * This does not assume that any ID or AnimData uses it, but does assume that * it is given two lists, which it will perform driver/animation-data separation. */ -static void ipo_to_animato(ID *id, Ipo *ipo, char actname[], char constname[], Sequence *seq, ListBase *animgroups, ListBase *anim, ListBase *drivers) +static void ipo_to_animato(ID *id, + Ipo *ipo, + char actname[], + char constname[], + Sequence *seq, + ListBase *animgroups, + ListBase *anim, + ListBase *drivers) { - IpoCurve *icu; - - /* sanity check */ - if (ELEM(NULL, ipo, anim, drivers)) - return; - - if (G.debug & G_DEBUG) printf("ipo_to_animato\n"); - - /* validate actname and constname - * - clear actname if it was one of the generic <builtin> ones (i.e. 'Object', or 'Shapes') - * - actname can then be used to assign F-Curves in Action to Action Groups - * (i.e. thus keeping the benefits that used to be provided by Action Channels for grouping - * F-Curves for bones). This may be added later... for now let's just dump without them... - */ - if (actname) { - if ((ipo->blocktype == ID_OB) && STREQ(actname, "Object")) - actname = NULL; - else if ((ipo->blocktype == ID_OB) && STREQ(actname, "Shape")) - actname = NULL; - } - - /* loop over IPO-Curves, freeing as we progress */ - for (icu = ipo->curve.first; icu; icu = icu->next) { - /* Since an IPO-Curve may end up being made into many F-Curves (i.e. bitflag curves), - * we figure out the best place to put the channel, then tell the curve-converter to just dump there - */ - if (icu->driver) { - /* Blender 2.4x allowed empty drivers, but we don't now, since they cause more trouble than they're worth */ - if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) { - icu_to_fcurves(id, NULL, drivers, icu, actname, constname, seq, ipo->muteipo); - } - else { - MEM_freeN(icu->driver); - icu->driver = NULL; - } - } - else - icu_to_fcurves(id, animgroups, anim, icu, actname, constname, seq, ipo->muteipo); - } - - /* if this IPO block doesn't have any users after this one, free... */ - id_us_min(&ipo->id); - if (ID_REAL_USERS(ipo) <= 0) { - IpoCurve *icn; - - for (icu = ipo->curve.first; icu; icu = icn) { - icn = icu->next; - - /* free driver */ - if (icu->driver) - MEM_freeN(icu->driver); - - /* free old data of curve now that it's no longer needed for converting any more curves */ - if (icu->bezt) MEM_freeN(icu->bezt); - if (icu->bp) MEM_freeN(icu->bezt); - - /* free this IPO-Curve */ - BLI_freelinkN(&ipo->curve, icu); - } - } + IpoCurve *icu; + + /* sanity check */ + if (ELEM(NULL, ipo, anim, drivers)) + return; + + if (G.debug & G_DEBUG) + printf("ipo_to_animato\n"); + + /* validate actname and constname + * - clear actname if it was one of the generic <builtin> ones (i.e. 'Object', or 'Shapes') + * - actname can then be used to assign F-Curves in Action to Action Groups + * (i.e. thus keeping the benefits that used to be provided by Action Channels for grouping + * F-Curves for bones). This may be added later... for now let's just dump without them... + */ + if (actname) { + if ((ipo->blocktype == ID_OB) && STREQ(actname, "Object")) + actname = NULL; + else if ((ipo->blocktype == ID_OB) && STREQ(actname, "Shape")) + actname = NULL; + } + + /* loop over IPO-Curves, freeing as we progress */ + for (icu = ipo->curve.first; icu; icu = icu->next) { + /* Since an IPO-Curve may end up being made into many F-Curves (i.e. bitflag curves), + * we figure out the best place to put the channel, then tell the curve-converter to just dump there + */ + if (icu->driver) { + /* Blender 2.4x allowed empty drivers, but we don't now, since they cause more trouble than they're worth */ + if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) { + icu_to_fcurves(id, NULL, drivers, icu, actname, constname, seq, ipo->muteipo); + } + else { + MEM_freeN(icu->driver); + icu->driver = NULL; + } + } + else + icu_to_fcurves(id, animgroups, anim, icu, actname, constname, seq, ipo->muteipo); + } + + /* if this IPO block doesn't have any users after this one, free... */ + id_us_min(&ipo->id); + if (ID_REAL_USERS(ipo) <= 0) { + IpoCurve *icn; + + for (icu = ipo->curve.first; icu; icu = icn) { + icn = icu->next; + + /* free driver */ + if (icu->driver) + MEM_freeN(icu->driver); + + /* free old data of curve now that it's no longer needed for converting any more curves */ + if (icu->bezt) + MEM_freeN(icu->bezt); + if (icu->bp) + MEM_freeN(icu->bezt); + + /* free this IPO-Curve */ + BLI_freelinkN(&ipo->curve, icu); + } + } } /* Convert Action-block to new system, separating animation and drivers @@ -1451,109 +1564,118 @@ static void ipo_to_animato(ID *id, Ipo *ipo, char actname[], char constname[], S * to Objects, where ob->ipo and ob->action need to be combined). * NOTE: we need to be careful here, as same data-structs are used for new system too! */ -static void action_to_animato(ID *id, bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers) +static void action_to_animato( + ID *id, bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers) { - bActionChannel *achan, *achann; - bConstraintChannel *conchan, *conchann; - - /* only continue if there are Action Channels (indicating unconverted data) */ - if (BLI_listbase_is_empty(&act->chanbase)) - return; - - /* get rid of all Action Groups */ - // XXX this is risky if there's some old + some new data in the Action... - if (act->groups.first) - BLI_freelistN(&act->groups); - - /* loop through Action-Channels, converting data, freeing as we go */ - for (achan = act->chanbase.first; achan; achan = achann) { - /* get pointer to next Action Channel */ - achann = achan->next; - - /* convert Action Channel's IPO data */ - if (achan->ipo) { - ipo_to_animato(id, achan->ipo, achan->name, NULL, NULL, groups, curves, drivers); - id_us_min(&achan->ipo->id); - achan->ipo = NULL; - } - - /* convert constraint channel IPO-data */ - for (conchan = achan->constraintChannels.first; conchan; conchan = conchann) { - /* get pointer to next Constraint Channel */ - conchann = conchan->next; - - /* convert Constraint Channel's IPO data */ - if (conchan->ipo) { - ipo_to_animato(id, conchan->ipo, achan->name, conchan->name, NULL, groups, curves, drivers); - id_us_min(&conchan->ipo->id); - conchan->ipo = NULL; - } - - /* free Constraint Channel */ - BLI_freelinkN(&achan->constraintChannels, conchan); - } - - /* free Action Channel */ - BLI_freelinkN(&act->chanbase, achan); - } + bActionChannel *achan, *achann; + bConstraintChannel *conchan, *conchann; + + /* only continue if there are Action Channels (indicating unconverted data) */ + if (BLI_listbase_is_empty(&act->chanbase)) + return; + + /* get rid of all Action Groups */ + // XXX this is risky if there's some old + some new data in the Action... + if (act->groups.first) + BLI_freelistN(&act->groups); + + /* loop through Action-Channels, converting data, freeing as we go */ + for (achan = act->chanbase.first; achan; achan = achann) { + /* get pointer to next Action Channel */ + achann = achan->next; + + /* convert Action Channel's IPO data */ + if (achan->ipo) { + ipo_to_animato(id, achan->ipo, achan->name, NULL, NULL, groups, curves, drivers); + id_us_min(&achan->ipo->id); + achan->ipo = NULL; + } + + /* convert constraint channel IPO-data */ + for (conchan = achan->constraintChannels.first; conchan; conchan = conchann) { + /* get pointer to next Constraint Channel */ + conchann = conchan->next; + + /* convert Constraint Channel's IPO data */ + if (conchan->ipo) { + ipo_to_animato( + id, conchan->ipo, achan->name, conchan->name, NULL, groups, curves, drivers); + id_us_min(&conchan->ipo->id); + conchan->ipo = NULL; + } + + /* free Constraint Channel */ + BLI_freelinkN(&achan->constraintChannels, conchan); + } + + /* free Action Channel */ + BLI_freelinkN(&act->chanbase, achan); + } } - /* ------------------------- */ /* Convert IPO-block (i.e. all its IpoCurves) for some ID to the new system * This assumes that AnimData has been added already. Separation of drivers * from animation data is accomplished here too... */ -static void ipo_to_animdata(Main *bmain, ID *id, Ipo *ipo, char actname[], char constname[], Sequence *seq) +static void ipo_to_animdata( + Main *bmain, ID *id, Ipo *ipo, char actname[], char constname[], Sequence *seq) { - AnimData *adt = BKE_animdata_from_id(id); - ListBase anim = {NULL, NULL}; - ListBase drivers = {NULL, NULL}; - - /* sanity check */ - if (ELEM(NULL, id, ipo)) - return; - if (adt == NULL) { - CLOG_ERROR(&LOG, "adt invalid"); - return; - } - - if (G.debug & G_DEBUG) { - printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s seqname:%s curves:%d\n", - id->name + 2, ipo->id.name + 2, (actname) ? actname : "<None>", (constname) ? constname : "<None>", (seq) ? (seq->name + 2) : "<None>", - BLI_listbase_count(&ipo->curve)); - } - - /* Convert curves to animato system (separated into separate lists of F-Curves for animation and drivers), - * and the try to put these lists in the right places, but do not free the lists here - */ - // XXX there shouldn't be any need for the groups, so don't supply pointer for that now... - ipo_to_animato(id, ipo, actname, constname, seq, NULL, &anim, &drivers); - - /* deal with animation first */ - if (anim.first) { - if (G.debug & G_DEBUG) printf("\thas anim\n"); - /* try to get action */ - if (adt->action == NULL) { - char nameBuf[MAX_ID_NAME]; - - BLI_snprintf(nameBuf, sizeof(nameBuf), "CDA:%s", ipo->id.name + 2); - - adt->action = BKE_action_add(bmain, nameBuf); - if (G.debug & G_DEBUG) printf("\t\tadded new action - '%s'\n", nameBuf); - } - - /* add F-Curves to action */ - BLI_movelisttolist(&adt->action->curves, &anim); - } - - /* deal with drivers */ - if (drivers.first) { - if (G.debug & G_DEBUG) printf("\thas drivers\n"); - /* add drivers to end of driver stack */ - BLI_movelisttolist(&adt->drivers, &drivers); - } + AnimData *adt = BKE_animdata_from_id(id); + ListBase anim = {NULL, NULL}; + ListBase drivers = {NULL, NULL}; + + /* sanity check */ + if (ELEM(NULL, id, ipo)) + return; + if (adt == NULL) { + CLOG_ERROR(&LOG, "adt invalid"); + return; + } + + if (G.debug & G_DEBUG) { + printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s seqname:%s curves:%d\n", + id->name + 2, + ipo->id.name + 2, + (actname) ? actname : "<None>", + (constname) ? constname : "<None>", + (seq) ? (seq->name + 2) : "<None>", + BLI_listbase_count(&ipo->curve)); + } + + /* Convert curves to animato system (separated into separate lists of F-Curves for animation and drivers), + * and the try to put these lists in the right places, but do not free the lists here + */ + // XXX there shouldn't be any need for the groups, so don't supply pointer for that now... + ipo_to_animato(id, ipo, actname, constname, seq, NULL, &anim, &drivers); + + /* deal with animation first */ + if (anim.first) { + if (G.debug & G_DEBUG) + printf("\thas anim\n"); + /* try to get action */ + if (adt->action == NULL) { + char nameBuf[MAX_ID_NAME]; + + BLI_snprintf(nameBuf, sizeof(nameBuf), "CDA:%s", ipo->id.name + 2); + + adt->action = BKE_action_add(bmain, nameBuf); + if (G.debug & G_DEBUG) + printf("\t\tadded new action - '%s'\n", nameBuf); + } + + /* add F-Curves to action */ + BLI_movelisttolist(&adt->action->curves, &anim); + } + + /* deal with drivers */ + if (drivers.first) { + if (G.debug & G_DEBUG) + printf("\thas drivers\n"); + /* add drivers to end of driver stack */ + BLI_movelisttolist(&adt->drivers, &drivers); + } } /* Convert Action-block to new system @@ -1561,21 +1683,22 @@ static void ipo_to_animdata(Main *bmain, ID *id, Ipo *ipo, char actname[], char */ static void action_to_animdata(ID *id, bAction *act) { - AnimData *adt = BKE_animdata_from_id(id); - - /* only continue if there are Action Channels (indicating unconverted data) */ - if (ELEM(NULL, adt, act->chanbase.first)) - return; - - /* check if we need to set this Action as the AnimData's action */ - if (adt->action == NULL) { - /* set this Action as AnimData's Action */ - if (G.debug & G_DEBUG) printf("act_to_adt - set adt action to act\n"); - adt->action = act; - } - - /* convert Action data */ - action_to_animato(id, act, &adt->action->groups, &adt->action->curves, &adt->drivers); + AnimData *adt = BKE_animdata_from_id(id); + + /* only continue if there are Action Channels (indicating unconverted data) */ + if (ELEM(NULL, adt, act->chanbase.first)) + return; + + /* check if we need to set this Action as the AnimData's action */ + if (adt->action == NULL) { + /* set this Action as AnimData's Action */ + if (G.debug & G_DEBUG) + printf("act_to_adt - set adt action to act\n"); + adt->action = act; + } + + /* convert Action data */ + action_to_animato(id, act, &adt->action->groups, &adt->action->curves, &adt->drivers); } /* ------------------------- */ @@ -1587,79 +1710,86 @@ static void action_to_animdata(ID *id, bAction *act) /* Convert NLA-Strip to new system */ static void nlastrips_to_animdata(ID *id, ListBase *strips) { - AnimData *adt = BKE_animdata_from_id(id); - NlaTrack *nlt = NULL; - NlaStrip *strip; - bActionStrip *as, *asn; - - /* for each one of the original strips, convert to a new strip and free the old... */ - for (as = strips->first; as; as = asn) { - asn = as->next; - - /* this old strip is only worth something if it had an action... */ - if (as->act) { - /* convert Action data (if not yet converted), storing the results in the same Action */ - action_to_animato(id, as->act, &as->act->groups, &as->act->curves, &adt->drivers); - - /* create a new-style NLA-strip which references this Action, then copy over relevant settings */ - { - /* init a new strip, and assign the action to it - * - no need to muck around with the user-counts, since this is just - * passing over the ref to the new owner, not creating an additional ref - */ - strip = MEM_callocN(sizeof(NlaStrip), "NlaStrip"); - strip->act = as->act; - - /* endpoints */ - strip->start = as->start; - strip->end = as->end; - strip->actstart = as->actstart; - strip->actend = as->actend; - - /* action reuse */ - strip->repeat = as->repeat; - strip->scale = as->scale; - if (as->flag & ACTSTRIP_LOCK_ACTION) strip->flag |= NLASTRIP_FLAG_SYNC_LENGTH; - - /* blending */ - strip->blendin = as->blendin; - strip->blendout = as->blendout; - strip->blendmode = (as->mode == ACTSTRIPMODE_ADD) ? NLASTRIP_MODE_ADD : NLASTRIP_MODE_REPLACE; - if (as->flag & ACTSTRIP_AUTO_BLENDS) strip->flag |= NLASTRIP_FLAG_AUTO_BLENDS; - - /* assorted setting flags */ - if (as->flag & ACTSTRIP_SELECT) strip->flag |= NLASTRIP_FLAG_SELECT; - if (as->flag & ACTSTRIP_ACTIVE) strip->flag |= NLASTRIP_FLAG_ACTIVE; - - if (as->flag & ACTSTRIP_MUTE) strip->flag |= NLASTRIP_FLAG_MUTED; - if (as->flag & ACTSTRIP_REVERSE) strip->flag |= NLASTRIP_FLAG_REVERSE; - - /* by default, we now always extrapolate, while in the past this was optional */ - if ((as->flag & ACTSTRIP_HOLDLASTFRAME) == 0) - strip->extendmode = NLASTRIP_EXTEND_NOTHING; - } - - /* try to add this strip to the current NLA-Track (i.e. the 'last' one on the stack atm) */ - if (BKE_nlatrack_add_strip(nlt, strip) == 0) { - /* trying to add to the current failed (no space), - * so add a new track to the stack, and add to that... - */ - nlt = BKE_nlatrack_add(adt, NULL); - BKE_nlatrack_add_strip(nlt, strip); - } - - /* ensure that strip has a name */ - BKE_nlastrip_validate_name(adt, strip); - } - - /* modifiers */ - // FIXME: for now, we just free them... - if (as->modifiers.first) - BLI_freelistN(&as->modifiers); - - /* free the old strip */ - BLI_freelinkN(strips, as); - } + AnimData *adt = BKE_animdata_from_id(id); + NlaTrack *nlt = NULL; + NlaStrip *strip; + bActionStrip *as, *asn; + + /* for each one of the original strips, convert to a new strip and free the old... */ + for (as = strips->first; as; as = asn) { + asn = as->next; + + /* this old strip is only worth something if it had an action... */ + if (as->act) { + /* convert Action data (if not yet converted), storing the results in the same Action */ + action_to_animato(id, as->act, &as->act->groups, &as->act->curves, &adt->drivers); + + /* create a new-style NLA-strip which references this Action, then copy over relevant settings */ + { + /* init a new strip, and assign the action to it + * - no need to muck around with the user-counts, since this is just + * passing over the ref to the new owner, not creating an additional ref + */ + strip = MEM_callocN(sizeof(NlaStrip), "NlaStrip"); + strip->act = as->act; + + /* endpoints */ + strip->start = as->start; + strip->end = as->end; + strip->actstart = as->actstart; + strip->actend = as->actend; + + /* action reuse */ + strip->repeat = as->repeat; + strip->scale = as->scale; + if (as->flag & ACTSTRIP_LOCK_ACTION) + strip->flag |= NLASTRIP_FLAG_SYNC_LENGTH; + + /* blending */ + strip->blendin = as->blendin; + strip->blendout = as->blendout; + strip->blendmode = (as->mode == ACTSTRIPMODE_ADD) ? NLASTRIP_MODE_ADD : + NLASTRIP_MODE_REPLACE; + if (as->flag & ACTSTRIP_AUTO_BLENDS) + strip->flag |= NLASTRIP_FLAG_AUTO_BLENDS; + + /* assorted setting flags */ + if (as->flag & ACTSTRIP_SELECT) + strip->flag |= NLASTRIP_FLAG_SELECT; + if (as->flag & ACTSTRIP_ACTIVE) + strip->flag |= NLASTRIP_FLAG_ACTIVE; + + if (as->flag & ACTSTRIP_MUTE) + strip->flag |= NLASTRIP_FLAG_MUTED; + if (as->flag & ACTSTRIP_REVERSE) + strip->flag |= NLASTRIP_FLAG_REVERSE; + + /* by default, we now always extrapolate, while in the past this was optional */ + if ((as->flag & ACTSTRIP_HOLDLASTFRAME) == 0) + strip->extendmode = NLASTRIP_EXTEND_NOTHING; + } + + /* try to add this strip to the current NLA-Track (i.e. the 'last' one on the stack atm) */ + if (BKE_nlatrack_add_strip(nlt, strip) == 0) { + /* trying to add to the current failed (no space), + * so add a new track to the stack, and add to that... + */ + nlt = BKE_nlatrack_add(adt, NULL); + BKE_nlatrack_add_strip(nlt, strip); + } + + /* ensure that strip has a name */ + BKE_nlastrip_validate_name(adt, strip); + } + + /* modifiers */ + // FIXME: for now, we just free them... + if (as->modifiers.first) + BLI_freelistN(&as->modifiers); + + /* free the old strip */ + BLI_freelinkN(strips, as); + } } /* *************************************************** */ @@ -1678,410 +1808,419 @@ static void nlastrips_to_animdata(ID *id, ListBase *strips) // XXX currently done after all file reading... void do_versions_ipos_to_animato(Main *bmain) { - ListBase drivers = {NULL, NULL}; - ID *id; - - if (bmain == NULL) { - CLOG_ERROR(&LOG, "Argh! Main is NULL"); - return; - } - - /* only convert if version is right */ - if (bmain->versionfile >= 250) { - CLOG_WARN(&LOG, "Animation data too new to convert (Version %d)", bmain->versionfile); - return; - } - else if (G.debug & G_DEBUG) - printf("INFO: Converting to Animato...\n"); - - /* ----------- Animation Attached to Data -------------- */ - - /* objects */ - for (id = bmain->objects.first; id; id = id->next) { - Object *ob = (Object *)id; - bPoseChannel *pchan; - bConstraint *con; - bConstraintChannel *conchan, *conchann; - - if (G.debug & G_DEBUG) printf("\tconverting ob %s\n", id->name + 2); - - /* check if object has any animation data */ - if (ob->nlastrips.first) { - /* Add AnimData block */ - BKE_animdata_add_id(id); - - /* IPO first to take into any non-NLA'd Object Animation */ - if (ob->ipo) { - ipo_to_animdata(bmain, id, ob->ipo, NULL, NULL, NULL); - /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */ - ob->ipo = NULL; - } - - /* Action is skipped since it'll be used by some strip in the NLA anyway, - * causing errors with evaluation in the new evaluation pipeline - */ - if (ob->action) { - id_us_min(&ob->action->id); - ob->action = NULL; - } - - /* finally NLA */ - nlastrips_to_animdata(id, &ob->nlastrips); - } - else if ((ob->ipo) || (ob->action)) { - /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); - - /* Action first - so that Action name get conserved */ - if (ob->action) { - action_to_animdata(id, ob->action); - - /* only decrease usercount if this Action isn't now being used by AnimData */ - if (ob->action != adt->action) { - id_us_min(&ob->action->id); - ob->action = NULL; - } - } - - /* IPO second... */ - if (ob->ipo) { - ipo_to_animdata(bmain, id, ob->ipo, NULL, NULL, NULL); - /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */ - ob->ipo = NULL; - } - } - - /* check PoseChannels for constraints with local data */ - if (ob->pose) { - /* Verify if there's AnimData block */ - BKE_animdata_add_id(id); - - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - for (con = pchan->constraints.first; con; con = con->next) { - /* if constraint has own IPO, convert add these to Object - * (NOTE: they're most likely to be drivers too) - */ - if (con->ipo) { - /* although this was the constraint's local IPO, we still need to provide pchan + con - * so that drivers can be added properly... - */ - ipo_to_animdata(bmain, id, con->ipo, pchan->name, con->name, NULL); - id_us_min(&con->ipo->id); - con->ipo = NULL; - } - } - } - } - - /* check constraints for local IPO's */ - for (con = ob->constraints.first; con; con = con->next) { - /* if constraint has own IPO, convert add these to Object - * (NOTE: they're most likely to be drivers too) - */ - if (con->ipo) { - /* Verify if there's AnimData block, just in case */ - BKE_animdata_add_id(id); - - /* although this was the constraint's local IPO, we still need to provide con - * so that drivers can be added properly... - */ - ipo_to_animdata(bmain, id, con->ipo, NULL, con->name, NULL); - id_us_min(&con->ipo->id); - con->ipo = NULL; - } - - /* check for Action Constraint */ - // XXX do we really want to do this here? - } - - /* check constraint channels - we need to remove them anyway... */ - if (ob->constraintChannels.first) { - /* Verify if there's AnimData block */ - BKE_animdata_add_id(id); - - for (conchan = ob->constraintChannels.first; conchan; conchan = conchann) { - /* get pointer to next Constraint Channel */ - conchann = conchan->next; - - /* convert Constraint Channel's IPO data */ - if (conchan->ipo) { - ipo_to_animdata(bmain, id, conchan->ipo, NULL, conchan->name, NULL); - id_us_min(&conchan->ipo->id); - conchan->ipo = NULL; - } - - /* free Constraint Channel */ - BLI_freelinkN(&ob->constraintChannels, conchan); - } - } - - /* object's action will always be object-rooted */ - { - AnimData *adt = BKE_animdata_from_id(id); - if (adt && adt->action) - adt->action->idroot = ID_OB; - } - } - - /* shapekeys */ - for (id = bmain->shapekeys.first; id; id = id->next) { - Key *key = (Key *)id; - - if (G.debug & G_DEBUG) printf("\tconverting key %s\n", id->name + 2); - - /* we're only interested in the IPO - * NOTE: for later, it might be good to port these over to Object instead, as many of these - * are likely to be drivers, but it's hard to trace that from here, so move this to Ob loop? - */ - if (key->ipo) { - /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); - - /* Convert Shapekey data... */ - ipo_to_animdata(bmain, id, key->ipo, NULL, NULL, NULL); - - if (adt->action) - adt->action->idroot = key->ipo->blocktype; - - id_us_min(&key->ipo->id); - key->ipo = NULL; - } - } - - /* materials */ - for (id = bmain->materials.first; id; id = id->next) { - Material *ma = (Material *)id; - - if (G.debug & G_DEBUG) printf("\tconverting material %s\n", id->name + 2); - - /* we're only interested in the IPO */ - if (ma->ipo) { - /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); - - /* Convert Material data... */ - ipo_to_animdata(bmain, id, ma->ipo, NULL, NULL, NULL); - - if (adt->action) - adt->action->idroot = ma->ipo->blocktype; - - id_us_min(&ma->ipo->id); - ma->ipo = NULL; - } - } - - /* worlds */ - for (id = bmain->worlds.first; id; id = id->next) { - World *wo = (World *)id; - - if (G.debug & G_DEBUG) printf("\tconverting world %s\n", id->name + 2); - - /* we're only interested in the IPO */ - if (wo->ipo) { - /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); - - /* Convert World data... */ - ipo_to_animdata(bmain, id, wo->ipo, NULL, NULL, NULL); - - if (adt->action) - adt->action->idroot = wo->ipo->blocktype; - - id_us_min(&wo->ipo->id); - wo->ipo = NULL; - } - } - - /* sequence strips */ - for (id = bmain->scenes.first; id; id = id->next) { - Scene *scene = (Scene *)id; - Editing *ed = scene->ed; - if (ed && ed->seqbasep) { - Sequence *seq; - - AnimData *adt = BKE_animdata_add_id(id); - - SEQ_BEGIN(ed, seq) - { - IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL; - short adrcode = SEQ_FAC1; - - if (G.debug & G_DEBUG) - printf("\tconverting sequence strip %s\n", seq->name + 2); - - if (ELEM(NULL, seq->ipo, icu)) { - seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; - continue; - } - - /* patch adrcode, so that we can map - * to different DNA variables later - * (semi-hack (tm) ) - */ - switch (seq->type) { - case SEQ_TYPE_IMAGE: - case SEQ_TYPE_META: - case SEQ_TYPE_SCENE: - case SEQ_TYPE_MOVIE: - case SEQ_TYPE_COLOR: - adrcode = SEQ_FAC_OPACITY; - break; - case SEQ_TYPE_SPEED: - adrcode = SEQ_FAC_SPEED; - break; - } - icu->adrcode = adrcode; - - /* convert IPO */ - ipo_to_animdata(bmain, (ID *)scene, seq->ipo, NULL, NULL, seq); - - if (adt->action) - adt->action->idroot = ID_SCE; /* scene-rooted */ - - id_us_min(&seq->ipo->id); - seq->ipo = NULL; - } SEQ_END; - } - } - - - /* textures */ - for (id = bmain->textures.first; id; id = id->next) { - Tex *te = (Tex *)id; - - if (G.debug & G_DEBUG) printf("\tconverting texture %s\n", id->name + 2); - - /* we're only interested in the IPO */ - if (te->ipo) { - /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); - - /* Convert Texture data... */ - ipo_to_animdata(bmain, id, te->ipo, NULL, NULL, NULL); - - if (adt->action) - adt->action->idroot = te->ipo->blocktype; - - id_us_min(&te->ipo->id); - te->ipo = NULL; - } - } - - /* cameras */ - for (id = bmain->cameras.first; id; id = id->next) { - Camera *ca = (Camera *)id; - - if (G.debug & G_DEBUG) printf("\tconverting camera %s\n", id->name + 2); - - /* we're only interested in the IPO */ - if (ca->ipo) { - /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); - - /* Convert Camera data... */ - ipo_to_animdata(bmain, id, ca->ipo, NULL, NULL, NULL); - - if (adt->action) - adt->action->idroot = ca->ipo->blocktype; - - id_us_min(&ca->ipo->id); - ca->ipo = NULL; - } - } - - /* lights */ - for (id = bmain->lights.first; id; id = id->next) { - Light *la = (Light *)id; - - if (G.debug & G_DEBUG) printf("\tconverting light %s\n", id->name + 2); - - /* we're only interested in the IPO */ - if (la->ipo) { - /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); - - /* Convert Light data... */ - ipo_to_animdata(bmain, id, la->ipo, NULL, NULL, NULL); - - if (adt->action) - adt->action->idroot = la->ipo->blocktype; - - id_us_min(&la->ipo->id); - la->ipo = NULL; - } - } - - /* curves */ - for (id = bmain->curves.first; id; id = id->next) { - Curve *cu = (Curve *)id; - - if (G.debug & G_DEBUG) printf("\tconverting curve %s\n", id->name + 2); - - /* we're only interested in the IPO */ - if (cu->ipo) { - /* Add AnimData block */ - AnimData *adt = BKE_animdata_add_id(id); - - /* Convert Curve data... */ - ipo_to_animdata(bmain, id, cu->ipo, NULL, NULL, NULL); - - if (adt->action) - adt->action->idroot = cu->ipo->blocktype; - - id_us_min(&cu->ipo->id); - cu->ipo = NULL; - } - } - - /* --------- Unconverted Animation Data ------------------ */ - /* For Animation data which may not be directly connected (i.e. not linked) to any other - * data, we need to perform a separate pass to make sure that they are converted to standalone - * Actions which may then be able to be reused. This does mean that we will be going over data that's - * already been converted, but there are no problems with that. - * - * The most common case for this will be Action Constraints, or IPO's with Fake-Users. - * We collect all drivers that were found into a temporary collection, and free them in one go, as they're - * impossible to resolve. - */ - - /* actions */ - for (id = bmain->actions.first; id; id = id->next) { - bAction *act = (bAction *)id; - - if (G.debug & G_DEBUG) printf("\tconverting action %s\n", id->name + 2); - - /* if old action, it will be object-only... */ - if (act->chanbase.first) - act->idroot = ID_OB; - - /* be careful! some of the actions we encounter will be converted ones... */ - action_to_animato(NULL, act, &act->groups, &act->curves, &drivers); - } - - /* ipo's */ - for (id = bmain->ipo.first; id; id = id->next) { - Ipo *ipo = (Ipo *)id; - - if (G.debug & G_DEBUG) printf("\tconverting ipo %s\n", id->name + 2); - - /* most likely this IPO has already been processed, so check if any curves left to convert */ - if (ipo->curve.first) { - bAction *new_act; + ListBase drivers = {NULL, NULL}; + ID *id; + + if (bmain == NULL) { + CLOG_ERROR(&LOG, "Argh! Main is NULL"); + return; + } + + /* only convert if version is right */ + if (bmain->versionfile >= 250) { + CLOG_WARN(&LOG, "Animation data too new to convert (Version %d)", bmain->versionfile); + return; + } + else if (G.debug & G_DEBUG) + printf("INFO: Converting to Animato...\n"); + + /* ----------- Animation Attached to Data -------------- */ + + /* objects */ + for (id = bmain->objects.first; id; id = id->next) { + Object *ob = (Object *)id; + bPoseChannel *pchan; + bConstraint *con; + bConstraintChannel *conchan, *conchann; + + if (G.debug & G_DEBUG) + printf("\tconverting ob %s\n", id->name + 2); + + /* check if object has any animation data */ + if (ob->nlastrips.first) { + /* Add AnimData block */ + BKE_animdata_add_id(id); + + /* IPO first to take into any non-NLA'd Object Animation */ + if (ob->ipo) { + ipo_to_animdata(bmain, id, ob->ipo, NULL, NULL, NULL); + /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */ + ob->ipo = NULL; + } + + /* Action is skipped since it'll be used by some strip in the NLA anyway, + * causing errors with evaluation in the new evaluation pipeline + */ + if (ob->action) { + id_us_min(&ob->action->id); + ob->action = NULL; + } + + /* finally NLA */ + nlastrips_to_animdata(id, &ob->nlastrips); + } + else if ((ob->ipo) || (ob->action)) { + /* Add AnimData block */ + AnimData *adt = BKE_animdata_add_id(id); + + /* Action first - so that Action name get conserved */ + if (ob->action) { + action_to_animdata(id, ob->action); + + /* only decrease usercount if this Action isn't now being used by AnimData */ + if (ob->action != adt->action) { + id_us_min(&ob->action->id); + ob->action = NULL; + } + } + + /* IPO second... */ + if (ob->ipo) { + ipo_to_animdata(bmain, id, ob->ipo, NULL, NULL, NULL); + /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */ + ob->ipo = NULL; + } + } + + /* check PoseChannels for constraints with local data */ + if (ob->pose) { + /* Verify if there's AnimData block */ + BKE_animdata_add_id(id); + + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + for (con = pchan->constraints.first; con; con = con->next) { + /* if constraint has own IPO, convert add these to Object + * (NOTE: they're most likely to be drivers too) + */ + if (con->ipo) { + /* although this was the constraint's local IPO, we still need to provide pchan + con + * so that drivers can be added properly... + */ + ipo_to_animdata(bmain, id, con->ipo, pchan->name, con->name, NULL); + id_us_min(&con->ipo->id); + con->ipo = NULL; + } + } + } + } + + /* check constraints for local IPO's */ + for (con = ob->constraints.first; con; con = con->next) { + /* if constraint has own IPO, convert add these to Object + * (NOTE: they're most likely to be drivers too) + */ + if (con->ipo) { + /* Verify if there's AnimData block, just in case */ + BKE_animdata_add_id(id); + + /* although this was the constraint's local IPO, we still need to provide con + * so that drivers can be added properly... + */ + ipo_to_animdata(bmain, id, con->ipo, NULL, con->name, NULL); + id_us_min(&con->ipo->id); + con->ipo = NULL; + } + + /* check for Action Constraint */ + // XXX do we really want to do this here? + } + + /* check constraint channels - we need to remove them anyway... */ + if (ob->constraintChannels.first) { + /* Verify if there's AnimData block */ + BKE_animdata_add_id(id); + + for (conchan = ob->constraintChannels.first; conchan; conchan = conchann) { + /* get pointer to next Constraint Channel */ + conchann = conchan->next; + + /* convert Constraint Channel's IPO data */ + if (conchan->ipo) { + ipo_to_animdata(bmain, id, conchan->ipo, NULL, conchan->name, NULL); + id_us_min(&conchan->ipo->id); + conchan->ipo = NULL; + } + + /* free Constraint Channel */ + BLI_freelinkN(&ob->constraintChannels, conchan); + } + } + + /* object's action will always be object-rooted */ + { + AnimData *adt = BKE_animdata_from_id(id); + if (adt && adt->action) + adt->action->idroot = ID_OB; + } + } + + /* shapekeys */ + for (id = bmain->shapekeys.first; id; id = id->next) { + Key *key = (Key *)id; + + if (G.debug & G_DEBUG) + printf("\tconverting key %s\n", id->name + 2); + + /* we're only interested in the IPO + * NOTE: for later, it might be good to port these over to Object instead, as many of these + * are likely to be drivers, but it's hard to trace that from here, so move this to Ob loop? + */ + if (key->ipo) { + /* Add AnimData block */ + AnimData *adt = BKE_animdata_add_id(id); + + /* Convert Shapekey data... */ + ipo_to_animdata(bmain, id, key->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = key->ipo->blocktype; + + id_us_min(&key->ipo->id); + key->ipo = NULL; + } + } + + /* materials */ + for (id = bmain->materials.first; id; id = id->next) { + Material *ma = (Material *)id; + + if (G.debug & G_DEBUG) + printf("\tconverting material %s\n", id->name + 2); + + /* we're only interested in the IPO */ + if (ma->ipo) { + /* Add AnimData block */ + AnimData *adt = BKE_animdata_add_id(id); + + /* Convert Material data... */ + ipo_to_animdata(bmain, id, ma->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = ma->ipo->blocktype; + + id_us_min(&ma->ipo->id); + ma->ipo = NULL; + } + } + + /* worlds */ + for (id = bmain->worlds.first; id; id = id->next) { + World *wo = (World *)id; + + if (G.debug & G_DEBUG) + printf("\tconverting world %s\n", id->name + 2); + + /* we're only interested in the IPO */ + if (wo->ipo) { + /* Add AnimData block */ + AnimData *adt = BKE_animdata_add_id(id); + + /* Convert World data... */ + ipo_to_animdata(bmain, id, wo->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = wo->ipo->blocktype; + + id_us_min(&wo->ipo->id); + wo->ipo = NULL; + } + } + + /* sequence strips */ + for (id = bmain->scenes.first; id; id = id->next) { + Scene *scene = (Scene *)id; + Editing *ed = scene->ed; + if (ed && ed->seqbasep) { + Sequence *seq; + + AnimData *adt = BKE_animdata_add_id(id); + + SEQ_BEGIN (ed, seq) { + IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL; + short adrcode = SEQ_FAC1; + + if (G.debug & G_DEBUG) + printf("\tconverting sequence strip %s\n", seq->name + 2); + + if (ELEM(NULL, seq->ipo, icu)) { + seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE; + continue; + } + + /* patch adrcode, so that we can map + * to different DNA variables later + * (semi-hack (tm) ) + */ + switch (seq->type) { + case SEQ_TYPE_IMAGE: + case SEQ_TYPE_META: + case SEQ_TYPE_SCENE: + case SEQ_TYPE_MOVIE: + case SEQ_TYPE_COLOR: + adrcode = SEQ_FAC_OPACITY; + break; + case SEQ_TYPE_SPEED: + adrcode = SEQ_FAC_SPEED; + break; + } + icu->adrcode = adrcode; + + /* convert IPO */ + ipo_to_animdata(bmain, (ID *)scene, seq->ipo, NULL, NULL, seq); + + if (adt->action) + adt->action->idroot = ID_SCE; /* scene-rooted */ + + id_us_min(&seq->ipo->id); + seq->ipo = NULL; + } + SEQ_END; + } + } + + /* textures */ + for (id = bmain->textures.first; id; id = id->next) { + Tex *te = (Tex *)id; + + if (G.debug & G_DEBUG) + printf("\tconverting texture %s\n", id->name + 2); + + /* we're only interested in the IPO */ + if (te->ipo) { + /* Add AnimData block */ + AnimData *adt = BKE_animdata_add_id(id); + + /* Convert Texture data... */ + ipo_to_animdata(bmain, id, te->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = te->ipo->blocktype; + + id_us_min(&te->ipo->id); + te->ipo = NULL; + } + } + + /* cameras */ + for (id = bmain->cameras.first; id; id = id->next) { + Camera *ca = (Camera *)id; + + if (G.debug & G_DEBUG) + printf("\tconverting camera %s\n", id->name + 2); + + /* we're only interested in the IPO */ + if (ca->ipo) { + /* Add AnimData block */ + AnimData *adt = BKE_animdata_add_id(id); + + /* Convert Camera data... */ + ipo_to_animdata(bmain, id, ca->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = ca->ipo->blocktype; + + id_us_min(&ca->ipo->id); + ca->ipo = NULL; + } + } + + /* lights */ + for (id = bmain->lights.first; id; id = id->next) { + Light *la = (Light *)id; + + if (G.debug & G_DEBUG) + printf("\tconverting light %s\n", id->name + 2); + + /* we're only interested in the IPO */ + if (la->ipo) { + /* Add AnimData block */ + AnimData *adt = BKE_animdata_add_id(id); + + /* Convert Light data... */ + ipo_to_animdata(bmain, id, la->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = la->ipo->blocktype; + + id_us_min(&la->ipo->id); + la->ipo = NULL; + } + } + + /* curves */ + for (id = bmain->curves.first; id; id = id->next) { + Curve *cu = (Curve *)id; + + if (G.debug & G_DEBUG) + printf("\tconverting curve %s\n", id->name + 2); + + /* we're only interested in the IPO */ + if (cu->ipo) { + /* Add AnimData block */ + AnimData *adt = BKE_animdata_add_id(id); + + /* Convert Curve data... */ + ipo_to_animdata(bmain, id, cu->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = cu->ipo->blocktype; - /* add a new action for this, and convert all data into that action */ - new_act = BKE_action_add(bmain, id->name + 2); - ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers); - new_act->idroot = ipo->blocktype; - } + id_us_min(&cu->ipo->id); + cu->ipo = NULL; + } + } + + /* --------- Unconverted Animation Data ------------------ */ + /* For Animation data which may not be directly connected (i.e. not linked) to any other + * data, we need to perform a separate pass to make sure that they are converted to standalone + * Actions which may then be able to be reused. This does mean that we will be going over data that's + * already been converted, but there are no problems with that. + * + * The most common case for this will be Action Constraints, or IPO's with Fake-Users. + * We collect all drivers that were found into a temporary collection, and free them in one go, as they're + * impossible to resolve. + */ - /* clear fake-users, and set user-count to zero to make sure it is cleared on file-save */ - ipo->id.us = 0; - ipo->id.flag &= ~LIB_FAKEUSER; - } + /* actions */ + for (id = bmain->actions.first; id; id = id->next) { + bAction *act = (bAction *)id; - /* free unused drivers from actions + ipos */ - free_fcurves(&drivers); + if (G.debug & G_DEBUG) + printf("\tconverting action %s\n", id->name + 2); + + /* if old action, it will be object-only... */ + if (act->chanbase.first) + act->idroot = ID_OB; + + /* be careful! some of the actions we encounter will be converted ones... */ + action_to_animato(NULL, act, &act->groups, &act->curves, &drivers); + } + + /* ipo's */ + for (id = bmain->ipo.first; id; id = id->next) { + Ipo *ipo = (Ipo *)id; + + if (G.debug & G_DEBUG) + printf("\tconverting ipo %s\n", id->name + 2); + + /* most likely this IPO has already been processed, so check if any curves left to convert */ + if (ipo->curve.first) { + bAction *new_act; + + /* add a new action for this, and convert all data into that action */ + new_act = BKE_action_add(bmain, id->name + 2); + ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers); + new_act->idroot = ipo->blocktype; + } - if (G.debug & G_DEBUG) - printf("INFO: Animato convert done\n"); + /* clear fake-users, and set user-count to zero to make sure it is cleared on file-save */ + ipo->id.us = 0; + ipo->id.flag &= ~LIB_FAKEUSER; + } + + /* free unused drivers from actions + ipos */ + free_fcurves(&drivers); + + if (G.debug & G_DEBUG) + printf("INFO: Animato convert done\n"); } |