Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation, 2005. Full recode 00022 * Joshua Leung 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 /* This file contains code for presenting F-Curves and other animation data 00033 * in the UI (especially for use in the Animation Editors). 00034 * 00035 * -- Joshua Leung, Dec 2008 00036 */ 00037 00038 00039 #include "MEM_guardedalloc.h" 00040 00041 #include "BLI_blenlib.h" 00042 #include "BLI_math.h" 00043 #include "BLI_utildefines.h" 00044 00045 #include "DNA_anim_types.h" 00046 00047 #include "RNA_access.h" 00048 00049 #include "ED_anim_api.h" 00050 00051 /* ----------------------- Getter functions ----------------------- */ 00052 00053 /* Write into "name" buffer, the name of the property (retrieved using RNA from the curve's settings), 00054 * and return the icon used for the struct that this property refers to 00055 * WARNING: name buffer we're writing to cannot exceed 256 chars (check anim_channels_defines.c for details) 00056 */ 00057 int getname_anim_fcurve(char *name, ID *id, FCurve *fcu) 00058 { 00059 int icon = 0; 00060 00061 /* sanity checks */ 00062 if (name == NULL) 00063 return icon; 00064 else if ELEM3(NULL, id, fcu, fcu->rna_path) { 00065 if (fcu == NULL) 00066 strcpy(name, "<invalid>"); 00067 else if (fcu->rna_path == NULL) 00068 strcpy(name, "<no path>"); 00069 else /* id == NULL */ 00070 BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index); 00071 } 00072 else { 00073 PointerRNA id_ptr, ptr; 00074 PropertyRNA *prop; 00075 00076 /* get RNA pointer, and resolve the path */ 00077 RNA_id_pointer_create(id, &id_ptr); 00078 00079 /* try to resolve the path */ 00080 if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) { 00081 const char *structname=NULL, *propname=NULL; 00082 char arrayindbuf[16]; 00083 const char *arrayname=NULL; 00084 short free_structname = 0; 00085 00086 /* For now, name will consist of 3 parts: struct-name, property name, array index 00087 * There are several options possible: 00088 * 1) <struct-name>.<property-name>.<array-index> 00089 * i.e. Bone1.Location.X, or Object.Location.X 00090 * 2) <array-index> <property-name> (<struct name>) 00091 * i.e. X Location (Bone1), or X Location (Object) 00092 * 00093 * Currently, option 2 is in use, to try and make it easier to quickly identify F-Curves (it does have 00094 * problems with looking rather odd though). Option 1 is better in terms of revealing a consistent sense of 00095 * hierarchy though, which isn't so clear with option 2. 00096 */ 00097 00098 /* for structname 00099 * - as base, we use a custom name from the structs if one is available 00100 * - however, if we're showing subdata of bones (probably there will be other exceptions later) 00101 * need to include that info too since it gets confusing otherwise 00102 * - if a pointer just refers to the ID-block, then don't repeat this info 00103 * since this just introduces clutter 00104 */ 00105 if (strstr(fcu->rna_path, "bones") && strstr(fcu->rna_path, "constraints")) { 00106 /* perform string 'chopping' to get "Bone Name : Constraint Name" */ 00107 char *pchanName= BLI_getQuotedStr(fcu->rna_path, "bones["); 00108 char *constName= BLI_getQuotedStr(fcu->rna_path, "constraints["); 00109 00110 /* assemble the string to display in the UI... */ 00111 structname= BLI_sprintfN("%s : %s", pchanName, constName); 00112 free_structname= 1; 00113 00114 /* free the temp names */ 00115 if (pchanName) MEM_freeN(pchanName); 00116 if (constName) MEM_freeN(constName); 00117 } 00118 else if (ptr.data != ptr.id.data) { 00119 PropertyRNA *nameprop= RNA_struct_name_property(ptr.type); 00120 if (nameprop) { 00121 /* this gets a string which will need to be freed */ 00122 structname= RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0, NULL); 00123 free_structname= 1; 00124 } 00125 else 00126 structname= RNA_struct_ui_name(ptr.type); 00127 } 00128 00129 /* Property Name is straightforward */ 00130 propname= RNA_property_ui_name(prop); 00131 00132 /* Array Index - only if applicable */ 00133 if (RNA_property_array_length(&ptr, prop)) { 00134 char c= RNA_property_array_item_char(prop, fcu->array_index); 00135 00136 /* we need to write the index to a temp buffer (in py syntax) */ 00137 if (c) BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "%c ", c); 00138 else BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "[%d]", fcu->array_index); 00139 00140 arrayname= &arrayindbuf[0]; 00141 } 00142 else { 00143 /* no array index */ 00144 arrayname= ""; 00145 } 00146 00147 /* putting this all together into the buffer */ 00148 // XXX we need to check for invalid names... 00149 // XXX the name length limit needs to be passed in or as some define 00150 if (structname) 00151 BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname); 00152 else 00153 BLI_snprintf(name, 256, "%s%s", arrayname, propname); 00154 00155 /* free temp name if nameprop is set */ 00156 if (free_structname) 00157 MEM_freeN((void *)structname); 00158 00159 00160 /* Icon for this property's owner: 00161 * use the struct's icon if it is set 00162 */ 00163 icon= RNA_struct_ui_icon(ptr.type); 00164 00165 /* valid path - remove the invalid tag since we now know how to use it saving 00166 * users manual effort to reenable using "Revive Disabled FCurves" [#29629] 00167 */ 00168 fcu->flag &= ~FCURVE_DISABLED; 00169 } 00170 else { 00171 /* invalid path */ 00172 BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index); 00173 00174 /* icon for this should be the icon for the base ID */ 00175 // TODO: or should we just use the error icon? 00176 icon= RNA_struct_ui_icon(id_ptr.type); 00177 00178 /* tag F-Curve as disabled - as not usable path */ 00179 fcu->flag |= FCURVE_DISABLED; 00180 } 00181 } 00182 00183 /* return the icon that the active data had */ 00184 return icon; 00185 } 00186 00187 /* ------------------------------- Color Codes for F-Curve Channels ---------------------------- */ 00188 00189 /* step between the major distinguishable color bands of the primary colors */ 00190 #define HSV_BANDWIDTH 0.3f 00191 00192 /* used to determine the color of F-Curves with FCURVE_COLOR_AUTO_RAINBOW set */ 00193 //void fcurve_rainbow (unsigned int cur, unsigned int tot, float *out) 00194 void getcolor_fcurve_rainbow (int cur, int tot, float *out) 00195 { 00196 float hue, val, sat, fac; 00197 int grouping; 00198 00199 /* we try to divide the color into groupings of n colors, 00200 * where n is: 00201 * 3 - for 'odd' numbers of curves - there should be a majority of triplets of curves 00202 * 4 - for 'even' numbers of curves - there should be a majority of quartets of curves 00203 * so the base color is simply one of the three primary colors 00204 */ 00205 grouping= (4 - (tot % 2)); 00206 hue= HSV_BANDWIDTH * (float)(cur % grouping); 00207 00208 /* 'Value' (i.e. darkness) needs to vary so that larger sets of three will be 00209 * 'darker' (i.e. smaller value), so that they don't look that similar to previous ones. 00210 * However, only a range of 0.3 to 1.0 is really usable to avoid clashing 00211 * with some other stuff 00212 */ 00213 fac = ((float)cur / (float)tot) * 0.7f; 00214 00215 /* the base color can get offset a bit so that the colors aren't so identical */ 00216 hue += fac * HSV_BANDWIDTH; 00217 if (hue > 1.0f) hue= fmod(hue, 1.0f); 00218 00219 /* saturation adjustments for more visible range */ 00220 if ((hue > 0.5f) && (hue < 0.8f)) sat= 0.5f; 00221 else sat= 0.6f; 00222 00223 /* value is fixed at 1.0f, otherwise we cannot clearly see the curves... */ 00224 val= 1.0f; 00225 00226 /* finally, conver this to RGB colors */ 00227 hsv_to_rgb(hue, sat, val, out, out+1, out+2); 00228 }