aa013a5b3aa574eaa25e2d5bb92a94cc5035de57
[blender.git] / intern / elbeem / intern / attributes.cpp
1 /******************************************************************************
2  *
3  * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
4  * Copyright 2003,2004 Nils Thuerey
5  *
6  * configuration attribute storage class and attribute class
7  *
8  *****************************************************************************/
9
10 #include "attributes.h"
11 #include <sstream>
12
13
14 //! output attribute values? on=1/off=0
15 #define DEBUG_ATTRIBUTES 0
16
17
18 /******************************************************************************
19  * attribute conversion functions
20  *****************************************************************************/
21
22 // get value as string 
23 string Attribute::getAsString()
24 {
25         if(mValue.size()!=1) {
26                 //errMsg("Attribute::getAsString", "Attribute \"" << mName << "\" used as string has invalid value '"<< getCompleteString() <<"' ");
27                 // for directories etc. , this might be valid! cutoff "..." first
28                 string comp = getCompleteString();
29                 if(comp.size()<2) return string("");
30                 return comp.substr(1, comp.size()-2);
31         }
32         return mValue[0];
33 }
34
35 // get value as integer value
36 int Attribute::getAsInt()
37 {
38         bool success = true;
39         int ret = 0;
40         if(mValue.size()!=1) success = false;
41         else {
42                 const char *str = mValue[0].c_str();
43                 char *endptr;
44                 ret = strtol(str, &endptr, 10);
45                 if( (str==endptr) ||
46                                 ((str!=endptr) && (*endptr != '\0')) )success = false;
47         }
48
49         if(!success) {
50                 errMsg("Attribute::getAsString", "Attribute \"" << mName << "\" used as int has invalid value '"<< getCompleteString() <<"' ");
51                 errMsg("Attribute::getAsString", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
52                 errMsg("Attribute::getAsString", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
53                 return 0;
54         }
55         return ret;
56 }
57
58
59 // get value as integer value
60 bool Attribute::getAsBool() 
61 {
62         int val = getAsInt();
63         if(val==0) return false;
64         else                     return true;
65 }
66
67
68 // get value as double value
69 double Attribute::getAsFloat()
70 {
71         bool success = true;
72         double ret = 0.0;
73         if(mValue.size()!=1) success = false;
74         else {
75                 const char *str = mValue[0].c_str();
76                 char *endptr;
77                 ret = strtod(str, &endptr);
78                 if((str!=endptr) && (*endptr != '\0')) success = false;
79         }
80
81         if(!success) {
82                 errMsg("Attribute::getAsFloat", "Attribute \"" << mName << "\" used as double has invalid value '"<< getCompleteString() <<"' ");
83                 errMsg("Attribute::getAsFloat", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
84                 errMsg("Attribute::getAsFloat", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
85                 return 0.0;
86         }
87         return ret;
88 }
89
90 // get value as 3d vector 
91 ntlVec3d Attribute::getAsVec3d()
92 {
93         bool success = true;
94         ntlVec3d ret(0.0);
95         if(mValue.size()==1) {
96                 const char *str = mValue[0].c_str();
97                 char *endptr;
98                 double rval = strtod(str, &endptr);
99                 if( (str==endptr) ||
100                                 ((str!=endptr) && (*endptr != '\0')) )success = false;
101                 if(success) ret = ntlVec3d( rval );
102         } else if(mValue.size()==3) {
103                 char *endptr;
104                 const char *str = NULL;
105
106                 str = mValue[0].c_str();
107                 double rval1 = strtod(str, &endptr);
108                 if( (str==endptr) ||
109                                 ((str!=endptr) && (*endptr != '\0')) )success = false;
110
111                 str = mValue[1].c_str();
112                 double rval2 = strtod(str, &endptr);
113                 if( (str==endptr) ||
114                                 ((str!=endptr) && (*endptr != '\0')) )success = false;
115
116                 str = mValue[2].c_str();
117                 double rval3 = strtod(str, &endptr);
118                 if( (str==endptr) ||
119                                 ((str!=endptr) && (*endptr != '\0')) )success = false;
120
121                 if(success) ret = ntlVec3d( rval1, rval2, rval3 );
122         } else {
123                 success = false;
124         }
125
126         if(!success) {
127                 errMsg("Attribute::getAsVec3d", "Attribute \"" << mName << "\" used as Vec3d has invalid value '"<< getCompleteString() <<"' ");
128                 errMsg("Attribute::getAsVec3d", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
129                 errMsg("Attribute::getAsVec3d", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
130                 return ntlVec3d(0.0);
131         }
132         return ret;
133 }
134                 
135 // get value as 4x4 matrix 
136 ntlMat4Gfx Attribute::getAsMat4Gfx()
137 {
138         bool success = true;
139         ntlMat4Gfx ret(0.0);
140         char *endptr;
141         const char *str = NULL;
142
143         if(mValue.size()==1) {
144                 const char *str = mValue[0].c_str();
145                 char *endptr;
146                 double rval = strtod(str, &endptr);
147                 if( (str==endptr) ||
148                                 ((str!=endptr) && (*endptr != '\0')) )success = false;
149                 if(success) {
150                         ret = ntlMat4Gfx( 0.0 );
151                         ret.value[0][0] = rval;
152                         ret.value[1][1] = rval;
153                         ret.value[2][2] = rval;
154                         ret.value[3][3] = 1.0;
155                 }
156         } else if(mValue.size()==9) {
157                 // 3x3
158                 for(int i=0; i<3;i++) {
159                         for(int j=0; j<3;j++) {
160                                 str = mValue[i*3+j].c_str();
161                                 ret.value[i][j] = strtod(str, &endptr);
162                                 if( (str==endptr) ||
163                                                 ((str!=endptr) && (*endptr != '\0')) ) success = false;
164                         }
165                 }
166         } else if(mValue.size()==16) {
167                 // 4x4
168                 for(int i=0; i<4;i++) {
169                         for(int j=0; j<4;j++) {
170                                 str = mValue[i*4+j].c_str();
171                                 ret.value[i][j] = strtod(str, &endptr);
172                                 if( (str==endptr) ||
173                                                 ((str!=endptr) && (*endptr != '\0')) ) success = false;
174                         }
175                 }
176
177         } else {
178                 success = false;
179         }
180
181         if(!success) {
182                 errMsg("Attribute::getAsMat4Gfx", "Attribute \"" << mName << "\" used as Mat4x4 has invalid value '"<< getCompleteString() <<"' ");
183                 errMsg("Attribute::getAsMat4Gfx", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
184                 errMsg("Attribute::getAsMat4Gfx", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
185                 return ntlMat4Gfx(0.0);
186         }
187         return ret;
188 }
189                 
190
191 // get the concatenated string of all value string
192 string Attribute::getCompleteString()
193 {
194         string ret;
195         for(size_t i=0;i<mValue.size();i++) {
196                 ret += mValue[i];
197                 if(i<mValue.size()-1) ret += " ";
198         }
199         return ret;
200 }
201
202
203 /******************************************************************************
204  * check if there were unknown params
205  *****************************************************************************/
206 bool AttributeList::checkUnusedParams()
207 {
208         bool found = false;
209         for(map<string, Attribute*>::iterator i=mAttrs.begin();
210                         i != mAttrs.end(); i++) {
211                 if((*i).second) {
212                         if(!(*i).second->getUsed()) {
213                                 errorOut("Attribute "<<mName<<" has unknown parameter '"<<(*i).first<<"' = '"<< mAttrs[(*i).first]->getAsString() <<"' ");
214                                 found = true;
215                         }
216                 }
217         }
218         return found;
219 }
220 //! set all params to used, for invisible objects
221 void AttributeList::setAllUsed() {
222         for(map<string, Attribute*>::iterator i=mAttrs.begin();
223                         i != mAttrs.end(); i++) {
224                 if((*i).second) {
225                         (*i).second->setUsed(true);
226                 }
227         }
228 }
229
230 /******************************************************************************
231  * Attribute list read functions
232  *****************************************************************************/
233 int AttributeList::readInt(string name, int defaultValue, string source,string target, bool needed) {
234         if(!exists(name)) {
235                 if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
236                 return defaultValue;
237         } 
238         if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
239         find(name)->setUsed(true);
240         return find(name)->getAsInt(); 
241 }
242 bool AttributeList::readBool(string name, bool defaultValue, string source,string target, bool needed) {
243         if(!exists(name)) {
244                 if(needed) { errorOut("AttributeList::readBool error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
245                 return defaultValue;
246         } 
247         if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
248         find(name)->setUsed(true);
249         return find(name)->getAsBool(); 
250 }
251 double AttributeList::readFloat(string name, double defaultValue, string source,string target, bool needed) {
252         if(!exists(name)) {
253                 if(needed) { errorOut("AttributeList::readFloat error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
254                 return defaultValue;
255         } 
256         if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
257         find(name)->setUsed(true);
258         return find(name)->getAsFloat(); 
259 }
260 string AttributeList::readString(string name, string defaultValue, string source,string target, bool needed) {
261         if(!exists(name)) {
262                 if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
263                 return defaultValue;
264         } 
265         if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
266         find(name)->setUsed(true);
267         return find(name)->getAsString(); 
268 }
269 ntlVec3d AttributeList::readVec3d(string name, ntlVec3d defaultValue, string source,string target, bool needed) {
270         if(!exists(name)) {
271                 if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
272                 return defaultValue;
273         } 
274         if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
275         find(name)->setUsed(true);
276         return find(name)->getAsVec3d(); 
277 }
278
279 ntlMat4Gfx AttributeList::readMat4Gfx(string name, ntlMat4Gfx defaultValue, string source,string target, bool needed) {
280         if(!exists(name)) {
281                 if(needed) { errorOut("AttributeList::readInt error: Required attribute '"<<name<<"' for "<< source <<"  not set! "); exit(1); }
282                 return defaultValue;
283         } 
284         if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Var '"<< target <<"' set to '"<< find(name)->getCompleteString() <<"' as type int " , 3); }
285         find(name)->setUsed(true);
286         return find(name)->getAsMat4Gfx(); 
287 }
288
289 // set that a parameter can be given, and will be ignored...
290 bool AttributeList::ignoreParameter(string name, string source) {
291         if(!exists(name)) return false;
292         find(name)->setUsed(true);
293         if(DEBUG_ATTRIBUTES==1) { debugOut( source << " Param '"<< name <<"' set but ignored... " , 3); }
294         return true;
295 }
296                 
297 /******************************************************************************
298  * destructor
299  *****************************************************************************/
300 AttributeList::~AttributeList() { 
301         for(map<string, Attribute*>::iterator i=mAttrs.begin();
302                         i != mAttrs.end(); i++) {
303                 if((*i).second) {
304                         delete (*i).second;
305                         (*i).second = NULL;
306                 }
307         }
308 };
309
310
311 /******************************************************************************
312  * debugging
313  *****************************************************************************/
314
315 //! debug function, prints value 
316 void Attribute::print()
317 {
318         std::ostringstream ostr;
319         ostr << "  "<< mName <<"= ";
320         for(size_t i=0;i<mValue.size();i++) {
321                 ostr <<"'"<< mValue[i]<<"' ";
322         }
323         ostr <<" (at line "<<mLine<<") "; //<< std::endl;
324         debugOut( ostr.str(), 10);
325 }
326                 
327 //! debug function, prints all attribs 
328 void AttributeList::print()
329 {
330         debugOut("Attribute "<<mName<<" values:", 10);
331         for(map<string, Attribute*>::iterator i=mAttrs.begin();
332                         i != mAttrs.end(); i++) {
333                 if((*i).second) {
334                         (*i).second->print();
335                 }
336         }
337 }
338
339
340
341 /******************************************************************************
342  * import attributes from other attribute list
343  *****************************************************************************/
344 void AttributeList::import(AttributeList *oal)
345 {
346         for(map<string, Attribute*>::iterator i=oal->mAttrs.begin();
347                         i !=oal->mAttrs.end(); i++) {
348                 // FIXME - check freeing of copyied attributes
349                 if((*i).second) {
350                         Attribute *newAttr = new Attribute( *(*i).second );
351                         mAttrs[ (*i).first ] = newAttr;
352                 }
353         }
354 }
355
356
357
358