Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): ton roosendaal 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <stdio.h> 00034 #include <stdlib.h> 00035 #include <stddef.h> 00036 #include <string.h> 00037 #include <ctype.h> 00038 00039 #include "MEM_guardedalloc.h" 00040 00041 #include "DNA_property_types.h" 00042 #include "DNA_object_types.h" 00043 00044 #include "BLI_blenlib.h" 00045 00046 #include "BKE_property.h" 00047 00048 void free_property(bProperty *prop) 00049 { 00050 00051 if(prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin); 00052 MEM_freeN(prop); 00053 00054 } 00055 00056 void free_properties(ListBase *lb) 00057 { 00058 bProperty *prop; 00059 00060 while( (prop= lb->first) ) { 00061 BLI_remlink(lb, prop); 00062 free_property(prop); 00063 } 00064 } 00065 00066 bProperty *copy_property(bProperty *prop) 00067 { 00068 bProperty *propn; 00069 00070 propn= MEM_dupallocN(prop); 00071 if(prop->poin && prop->poin != &prop->data) { 00072 propn->poin= MEM_dupallocN(prop->poin); 00073 } 00074 else propn->poin= &propn->data; 00075 00076 return propn; 00077 } 00078 00079 void copy_properties(ListBase *lbn, ListBase *lbo) 00080 { 00081 bProperty *prop, *propn; 00082 free_properties( lbn ); /* incase we are copying to an object with props */ 00083 prop= lbo->first; 00084 while(prop) { 00085 propn= copy_property(prop); 00086 BLI_addtail(lbn, propn); 00087 prop= prop->next; 00088 } 00089 00090 00091 } 00092 00093 void init_property(bProperty *prop) 00094 { 00095 /* also use when property changes type */ 00096 00097 if(prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin); 00098 prop->poin= NULL; 00099 00100 prop->data= 0; 00101 00102 switch(prop->type) { 00103 case GPROP_BOOL: 00104 case GPROP_INT: 00105 case GPROP_FLOAT: 00106 case GPROP_TIME: 00107 prop->poin= &prop->data; 00108 break; 00109 case GPROP_STRING: 00110 prop->poin= MEM_callocN(MAX_PROPSTRING, "property string"); 00111 break; 00112 } 00113 } 00114 00115 00116 bProperty *new_property(int type) 00117 { 00118 bProperty *prop; 00119 00120 prop= MEM_callocN(sizeof(bProperty), "property"); 00121 prop->type= type; 00122 00123 init_property(prop); 00124 00125 strcpy(prop->name, "prop"); 00126 00127 return prop; 00128 } 00129 00130 /* used by unique_property() only */ 00131 static bProperty *get_property__internal(bProperty *first, bProperty *self, const char *name) 00132 { 00133 bProperty *p; 00134 for(p= first; p; p= p->next) { 00135 if (p!=self && (strcmp(p->name, name)==0)) 00136 return p; 00137 } 00138 return NULL; 00139 } 00140 void unique_property(bProperty *first, bProperty *prop, int force) 00141 { 00142 bProperty *p; 00143 00144 /* set the first if its not set */ 00145 if(first==NULL) { 00146 first= prop; 00147 while(first->prev) { 00148 first= first->prev; 00149 } 00150 } 00151 00152 if(force) { 00153 /* change other names to make them unique */ 00154 while((p = get_property__internal(first, prop, prop->name))) { 00155 unique_property(first, p, 0); 00156 } 00157 }else { 00158 /* change our own name until its unique */ 00159 if(get_property__internal(first, prop, prop->name)) { 00160 /* there is a collision */ 00161 char new_name[sizeof(prop->name)]; 00162 char base_name[sizeof(prop->name)]; 00163 char num[sizeof(prop->name)]; 00164 int i= 0; 00165 00166 /* strip numbers */ 00167 BLI_strncpy(base_name, prop->name, sizeof(base_name)); 00168 for(i= strlen(base_name)-1; (i>=0 && isdigit(base_name[i])); i--) { 00169 base_name[i]= '\0'; 00170 } 00171 i= 0; 00172 00173 do { /* ensure we have enough chars for the new number in the name */ 00174 BLI_snprintf(num, sizeof(num), "%d", i++); 00175 BLI_strncpy(new_name, base_name, sizeof(prop->name) - strlen(num)); 00176 strcat(new_name, num); 00177 } while(get_property__internal(first, prop, new_name)); 00178 00179 BLI_strncpy(prop->name, new_name, sizeof(prop->name)); 00180 } 00181 } 00182 } 00183 00184 bProperty *get_ob_property(Object *ob, const char *name) 00185 { 00186 return BLI_findstring(&ob->prop, name, offsetof(bProperty, name)); 00187 } 00188 00189 void set_ob_property(Object *ob, bProperty *propc) 00190 { 00191 bProperty *prop; 00192 prop= get_ob_property(ob, propc->name); 00193 if(prop) { 00194 free_property(prop); 00195 BLI_remlink(&ob->prop, prop); 00196 } 00197 BLI_addtail(&ob->prop, copy_property(propc)); 00198 } 00199 00200 /* negative: prop is smaller 00201 * positive: prop is larger 00202 */ 00203 int compare_property(bProperty *prop, const char *str) 00204 { 00205 // extern int Gdfra; /* sector.c */ 00206 float fvalue, ftest; 00207 00208 switch(prop->type) { 00209 case GPROP_BOOL: 00210 if(BLI_strcasecmp(str, "true")==0) { 00211 if(prop->data==1) return 0; 00212 else return 1; 00213 } 00214 else if(BLI_strcasecmp(str, "false")==0) { 00215 if(prop->data==0) return 0; 00216 else return 1; 00217 } 00218 /* no break, do GPROP_int too! */ 00219 00220 case GPROP_INT: 00221 return prop->data - atoi(str); 00222 00223 case GPROP_FLOAT: 00224 case GPROP_TIME: 00225 // WARNING: untested for GPROP_TIME 00226 // function isn't used currently 00227 fvalue= *((float *)&prop->data); 00228 ftest= (float)atof(str); 00229 if( fvalue > ftest) return 1; 00230 else if( fvalue < ftest) return -1; 00231 return 0; 00232 00233 case GPROP_STRING: 00234 return strcmp(prop->poin, str); 00235 } 00236 00237 return 0; 00238 } 00239 00240 void set_property(bProperty *prop, const char *str) 00241 { 00242 // extern int Gdfra; /* sector.c */ 00243 00244 switch(prop->type) { 00245 case GPROP_BOOL: 00246 if(BLI_strcasecmp(str, "true")==0) prop->data= 1; 00247 else if(BLI_strcasecmp(str, "false")==0) prop->data= 0; 00248 else prop->data= (atoi(str)!=0); 00249 break; 00250 case GPROP_INT: 00251 prop->data= atoi(str); 00252 break; 00253 case GPROP_FLOAT: 00254 case GPROP_TIME: 00255 *((float *)&prop->data)= (float)atof(str); 00256 break; 00257 case GPROP_STRING: 00258 strcpy(prop->poin, str); /* TODO - check size? */ 00259 break; 00260 } 00261 00262 } 00263 00264 void add_property(bProperty *prop, const char *str) 00265 { 00266 // extern int Gdfra; /* sector.c */ 00267 00268 switch(prop->type) { 00269 case GPROP_BOOL: 00270 case GPROP_INT: 00271 prop->data+= atoi(str); 00272 break; 00273 case GPROP_FLOAT: 00274 case GPROP_TIME: 00275 *((float *)&prop->data)+= (float)atof(str); 00276 break; 00277 case GPROP_STRING: 00278 /* strcpy(prop->poin, str); */ 00279 break; 00280 } 00281 } 00282 00283 /* reads value of property, sets it in chars in str */ 00284 void set_property_valstr(bProperty *prop, char *str) 00285 { 00286 // extern int Gdfra; /* sector.c */ 00287 00288 if(str == NULL) return; 00289 00290 switch(prop->type) { 00291 case GPROP_BOOL: 00292 case GPROP_INT: 00293 sprintf(str, "%d", prop->data); 00294 break; 00295 case GPROP_FLOAT: 00296 case GPROP_TIME: 00297 sprintf(str, "%f", *((float *)&prop->data)); 00298 break; 00299 case GPROP_STRING: 00300 BLI_strncpy(str, prop->poin, MAX_PROPSTRING); 00301 break; 00302 } 00303 } 00304 00305 void cp_property(bProperty *prop1, bProperty *prop2) 00306 { 00307 char str[128]; 00308 00309 set_property_valstr(prop2, str); 00310 00311 set_property(prop1, str); 00312 }