ReAntTweakBar.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. #include "ReAntTweakBar.h"
  2. #ifndef IGL_NO_ANTTWEAKBAR
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <sstream>
  6. #include <iostream>
  7. #include <iomanip>
  8. #include <map>
  9. // GLOBAL WRAPPERS
  10. namespace
  11. {
  12. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > > ReTw_custom_types;
  13. }
  14. IGL_INLINE TwType igl::ReTwDefineEnum(
  15. const char *name,
  16. const TwEnumVal *enumValues,
  17. unsigned int nbValues)
  18. {
  19. using namespace std;
  20. // copy enum valus into vector
  21. std::vector<TwEnumVal> enum_vals;
  22. enum_vals.resize(nbValues);
  23. for(unsigned int j = 0; j<nbValues;j++)
  24. {
  25. enum_vals[j] = enumValues[j];
  26. }
  27. TwType type = TwDefineEnum(name,enumValues,nbValues);
  28. ReTw_custom_types[type] =
  29. std::pair<const char *,std::vector<TwEnumVal> >(name,enum_vals);
  30. return type;
  31. }
  32. IGL_INLINE TwType igl::ReTwDefineEnum(
  33. const char * _Name,
  34. const char * _EnumString)
  35. {
  36. // Taken directly from TwMgr.cpp, just replace TwDefineEnum with
  37. // ReTwDefineEnum
  38. using namespace std;
  39. {
  40. if (_EnumString == NULL)
  41. return ReTwDefineEnum(_Name, NULL, 0);
  42. // split enumString
  43. stringstream EnumStream(_EnumString);
  44. string Label;
  45. vector<string> Labels;
  46. while( getline(EnumStream, Label, ',') ) {
  47. // trim Label
  48. size_t Start = Label.find_first_not_of(" \n\r\t");
  49. size_t End = Label.find_last_not_of(" \n\r\t");
  50. if( Start==string::npos || End==string::npos )
  51. Label = "";
  52. else
  53. Label = Label.substr(Start, (End-Start)+1);
  54. // store Label
  55. Labels.push_back(Label);
  56. }
  57. // create TwEnumVal array
  58. vector<TwEnumVal> Vals(Labels.size());
  59. for( int i=0; i<(int)Labels.size(); i++ )
  60. {
  61. Vals[i].Value = i;
  62. // Wrong:
  63. //Vals[i].Label = Labels[i].c_str();
  64. // Allocate char on heap
  65. // http://stackoverflow.com/a/10050258/148668
  66. char * c_label = new char[Labels[i].length()+1];
  67. std::strcpy(c_label, Labels[i].c_str());
  68. Vals[i].Label = c_label;
  69. }
  70. const TwType type = ReTwDefineEnum(_Name, Vals.empty() ? NULL : &(Vals[0]), (unsigned int)Vals.size());
  71. return type;
  72. }
  73. }
  74. namespace
  75. {
  76. struct ReTwTypeString
  77. {
  78. TwType type;
  79. const char * type_str;
  80. };
  81. #define RETW_NUM_DEFAULT_TYPE_STRINGS 23
  82. ReTwTypeString ReTwDefaultTypeStrings[RETW_NUM_DEFAULT_TYPE_STRINGS] =
  83. {
  84. {TW_TYPE_UNDEF,"TW_TYPE_UNDEF"},
  85. {TW_TYPE_BOOLCPP,"TW_TYPE_BOOLCPP"},
  86. {TW_TYPE_BOOL8,"TW_TYPE_BOOL8"},
  87. {TW_TYPE_BOOL16,"TW_TYPE_BOOL16"},
  88. {TW_TYPE_BOOL32,"TW_TYPE_BOOL32"},
  89. {TW_TYPE_CHAR,"TW_TYPE_CHAR"},
  90. {TW_TYPE_INT8,"TW_TYPE_INT8"},
  91. {TW_TYPE_UINT8,"TW_TYPE_UINT8"},
  92. {TW_TYPE_INT16,"TW_TYPE_INT16"},
  93. {TW_TYPE_UINT16,"TW_TYPE_UINT16"},
  94. {TW_TYPE_INT32,"TW_TYPE_INT32"},
  95. {TW_TYPE_UINT32,"TW_TYPE_UINT32"},
  96. {TW_TYPE_FLOAT,"TW_TYPE_FLOAT"},
  97. {TW_TYPE_DOUBLE,"TW_TYPE_DOUBLE"},
  98. {TW_TYPE_COLOR32,"TW_TYPE_COLOR32"},
  99. {TW_TYPE_COLOR3F,"TW_TYPE_COLOR3F"},
  100. {TW_TYPE_COLOR4F,"TW_TYPE_COLOR4F"},
  101. {TW_TYPE_CDSTRING,"TW_TYPE_CDSTRING"},
  102. {TW_TYPE_STDSTRING,"TW_TYPE_STDSTRING"},
  103. {TW_TYPE_QUAT4F,"TW_TYPE_QUAT4F"},
  104. {TW_TYPE_QUAT4D,"TW_TYPE_QUAT4D"},
  105. {TW_TYPE_DIR3F,"TW_TYPE_DIR3F"},
  106. {TW_TYPE_DIR3D,"TW_TYPE_DIR3D"}
  107. };
  108. }
  109. IGL_INLINE igl::ReTwBar::ReTwBar():
  110. bar(NULL),rw_items(),cb_items()
  111. {
  112. }
  113. IGL_INLINE igl::ReTwBar::ReTwBar(const igl::ReTwBar & that):
  114. bar(that.bar),
  115. rw_items(that.rw_items),
  116. cb_items(that.cb_items)
  117. {
  118. }
  119. IGL_INLINE igl::ReTwBar & igl::ReTwBar::operator=(const igl::ReTwBar & that)
  120. {
  121. // check for self assignment
  122. if(this != &that)
  123. {
  124. bar = that.bar;
  125. rw_items = that.rw_items;
  126. cb_items = that.cb_items;
  127. }
  128. return *this;
  129. }
  130. // BAR WRAPPERS
  131. IGL_INLINE void igl::ReTwBar::TwNewBar(const char *name)
  132. {
  133. // double colon without anything in front of it means look for this in the
  134. // global namespace... I hope...
  135. this->name = name;
  136. this->bar = ::TwNewBar(name);
  137. }
  138. IGL_INLINE int igl::ReTwBar::TwAddVarRW(
  139. const char *name,
  140. TwType type,
  141. void *var,
  142. const char *def,
  143. const bool record)
  144. {
  145. int ret = ::TwAddVarRW(this->bar,name,type,var,def);
  146. if(ret && record)
  147. {
  148. rw_items.push_back(ReTwRWItem(name,type,var));
  149. }
  150. return ret;
  151. }
  152. IGL_INLINE int igl::ReTwBar::TwAddVarCB(
  153. const char *name,
  154. TwType type,
  155. TwSetVarCallback setCallback,
  156. TwGetVarCallback getCallback,
  157. void *clientData,
  158. const char *def,
  159. const bool record)
  160. {
  161. int ret =
  162. ::TwAddVarCB(this->bar,name,type,setCallback,getCallback,clientData,def);
  163. if(ret && record)
  164. {
  165. cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
  166. }
  167. return ret;
  168. }
  169. IGL_INLINE int igl::ReTwBar::TwAddVarRO(
  170. const char *name,
  171. TwType type,
  172. void *var,
  173. const char *def)
  174. {
  175. int ret = ::TwAddVarRO(this->bar,name,type,var,def);
  176. // Read only variables are not recorded
  177. //if(ret)
  178. //{
  179. // rw_items.push_back(ReTwRWItem(name,type,var));
  180. //}
  181. return ret;
  182. }
  183. IGL_INLINE int igl::ReTwBar::TwAddButton(
  184. const char *name,
  185. TwButtonCallback buttonCallback,
  186. void *clientData,
  187. const char *def)
  188. {
  189. int ret =
  190. ::TwAddButton(this->bar,name,buttonCallback,clientData,def);
  191. // buttons are not recorded
  192. //if(ret)
  193. //{
  194. // cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
  195. //}
  196. return ret;
  197. }
  198. IGL_INLINE int igl::ReTwBar::TwSetParam(
  199. const char *varName,
  200. const char *paramName,
  201. TwParamValueType paramValueType,
  202. unsigned int inValueCount,
  203. const void *inValues)
  204. {
  205. // For now just pass these along
  206. return
  207. ::TwSetParam(
  208. this->bar,
  209. varName,
  210. paramName,
  211. paramValueType,
  212. inValueCount,
  213. inValues);
  214. }
  215. IGL_INLINE int igl::ReTwBar::TwGetParam(
  216. const char *varName,
  217. const char *paramName,
  218. TwParamValueType paramValueType,
  219. unsigned int outValueMaxCount,
  220. void *outValues)
  221. {
  222. return
  223. ::TwGetParam(
  224. this->bar,
  225. varName,
  226. paramName,
  227. paramValueType,
  228. outValueMaxCount,
  229. outValues);
  230. }
  231. IGL_INLINE int igl::ReTwBar::TwRefreshBar()
  232. {
  233. return ::TwRefreshBar(this->bar);
  234. }
  235. IGL_INLINE int igl::ReTwBar::TwTerminate()
  236. {
  237. //std::cout<<"TwTerminate"<<std::endl;
  238. int r = ::TwTerminate();
  239. //std::cout<<" "<<r<<std::endl;
  240. return r;
  241. }
  242. IGL_INLINE bool igl::ReTwBar::save(const char *file_name)
  243. {
  244. FILE * fp;
  245. if(file_name == NULL)
  246. {
  247. fp = stdout;
  248. }else
  249. {
  250. fp = fopen(file_name,"w");
  251. }
  252. if(fp == NULL)
  253. {
  254. printf("ERROR: not able to open %s for writing...\n",file_name);
  255. return false;
  256. }
  257. // Print all RW variables
  258. for(
  259. std::vector<ReTwRWItem>::iterator it = rw_items.begin();
  260. it != rw_items.end();
  261. it++)
  262. {
  263. std::string s = (*it).name;
  264. const char * name = s.c_str();
  265. TwType type = (*it).type;
  266. void * var = (*it).var;
  267. fprintf(fp,"%s: %s\n",
  268. name,
  269. get_value_as_string(var,type).c_str());
  270. }
  271. char var[REANTTWEAKBAR_MAX_CB_VAR_SIZE];
  272. // Print all CB variables
  273. for(
  274. std::vector<ReTwCBItem>::iterator it = cb_items.begin();
  275. it != cb_items.end();
  276. it++)
  277. {
  278. const char * name = it->name.c_str();
  279. TwType type = it->type;
  280. //TwSetVarCallback setCallback = it->setCallback;
  281. TwGetVarCallback getCallback = it->getCallback;
  282. void * clientData = it->clientData;
  283. // I'm not sure how to do what I want to do. getCallback needs to be sure
  284. // that it can write to var. So var needs to point to a valid and big
  285. // enough chunk of memory
  286. getCallback(var,clientData);
  287. fprintf(fp,"%s: %s\n",
  288. name,
  289. get_value_as_string(var,type).c_str());
  290. }
  291. fprintf(fp,"\n");
  292. if(file_name != NULL)
  293. {
  294. fclose(fp);
  295. }
  296. // everything succeeded
  297. return true;
  298. }
  299. IGL_INLINE std::string igl::ReTwBar::get_value_as_string(
  300. void * var,
  301. TwType type)
  302. {
  303. std::stringstream sstr;
  304. switch(type)
  305. {
  306. case TW_TYPE_BOOLCPP:
  307. {
  308. sstr << "TW_TYPE_BOOLCPP" << " ";
  309. sstr << *(static_cast<bool*>(var));
  310. break;
  311. }
  312. case TW_TYPE_QUAT4D:
  313. {
  314. sstr << "TW_TYPE_QUAT4D" << " ";
  315. // Q: Why does casting to double* work? shouldn't I have to cast to
  316. // double**?
  317. double * q = static_cast<double*>(var);
  318. sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
  319. break;
  320. }
  321. case TW_TYPE_QUAT4F:
  322. {
  323. sstr << "TW_TYPE_QUAT4F" << " ";
  324. // Q: Why does casting to float* work? shouldn't I have to cast to
  325. // float**?
  326. float * q = static_cast<float*>(var);
  327. sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
  328. break;
  329. }
  330. case TW_TYPE_COLOR4F:
  331. {
  332. sstr << "TW_TYPE_COLOR4F" << " ";
  333. float * c = static_cast<float*>(var);
  334. sstr << c[0] << " " << c[1] << " " << c[2] << " " << c[3];
  335. break;
  336. }
  337. case TW_TYPE_COLOR3F:
  338. {
  339. sstr << "TW_TYPE_COLOR3F" << " ";
  340. float * c = static_cast<float*>(var);
  341. sstr << c[0] << " " << c[1] << " " << c[2];
  342. break;
  343. }
  344. case TW_TYPE_DIR3D:
  345. {
  346. sstr << "TW_TYPE_DIR3D" << " ";
  347. double * d = static_cast<double*>(var);
  348. sstr << d[0] << " " << d[1] << " " << d[2];
  349. break;
  350. }
  351. case TW_TYPE_DIR3F:
  352. {
  353. sstr << "TW_TYPE_DIR3F" << " ";
  354. float * d = static_cast<float*>(var);
  355. sstr << d[0] << " " << d[1] << " " << d[2];
  356. break;
  357. }
  358. case TW_TYPE_BOOL32:
  359. {
  360. sstr << "TW_TYPE_BOOL32" << " ";
  361. sstr << *(static_cast<int*>(var));
  362. break;
  363. }
  364. case TW_TYPE_UINT8:
  365. {
  366. sstr << "TW_TYPE_UINT8" << " ";
  367. // Cast to int so that it's human readable
  368. sstr << (int)*(static_cast<unsigned char*>(var));
  369. break;
  370. }
  371. case TW_TYPE_INT32:
  372. {
  373. sstr << "TW_TYPE_INT32" << " ";
  374. sstr << *(static_cast<int*>(var));
  375. break;
  376. }
  377. case TW_TYPE_FLOAT:
  378. {
  379. sstr << "TW_TYPE_FLOAT" << " ";
  380. sstr << *(static_cast<float*>(var));
  381. break;
  382. }
  383. case TW_TYPE_DOUBLE:
  384. {
  385. sstr << "TW_TYPE_DOUBLE" << " ";
  386. sstr << std::setprecision(15) << *(static_cast<double*>(var));
  387. break;
  388. }
  389. case TW_TYPE_STDSTRING:
  390. {
  391. sstr << "TW_TYPE_STDSTRING" << " ";
  392. std::string *destPtr = static_cast<std::string *>(var);
  393. sstr << destPtr->c_str();
  394. break;
  395. }
  396. default:
  397. {
  398. using namespace std;
  399. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::const_iterator iter =
  400. ReTw_custom_types.find(type);
  401. if(iter != ReTw_custom_types.end())
  402. {
  403. sstr << (*iter).second.first << " ";
  404. int enum_val = *(static_cast<int*>(var));
  405. // try find display name for enum value
  406. std::vector<TwEnumVal>::const_iterator eit = (*iter).second.second.begin();
  407. bool found = false;
  408. for(;eit<(*iter).second.second.end();eit++)
  409. {
  410. if(enum_val == eit->Value)
  411. {
  412. sstr << eit->Label;
  413. found = true;
  414. break;
  415. }
  416. }
  417. if(!found)
  418. {
  419. sstr << "ERROR_ENUM_VALUE_NOT_DEFINED";
  420. }
  421. }else
  422. {
  423. sstr << "ERROR_TYPE_NOT_SUPPORTED";
  424. }
  425. break;
  426. }
  427. }
  428. return sstr.str();
  429. }
  430. IGL_INLINE bool igl::ReTwBar::load(const char *file_name)
  431. {
  432. FILE * fp;
  433. fp = fopen(file_name,"r");
  434. if(fp == NULL)
  435. {
  436. printf("ERROR: not able to open %s for reading...\n",file_name);
  437. return false;
  438. }
  439. // go through file line by line
  440. char line[REANTTWEAKBAR_MAX_LINE];
  441. bool still_comments;
  442. char name[REANTTWEAKBAR_MAX_WORD];
  443. char type_str[REANTTWEAKBAR_MAX_WORD];
  444. char value_str[REANTTWEAKBAR_MAX_WORD];
  445. // line number
  446. int j = 0;
  447. bool finished = false;
  448. while(true)
  449. {
  450. // Eat comments
  451. still_comments = true;
  452. while(still_comments)
  453. {
  454. if(fgets(line,REANTTWEAKBAR_MAX_LINE,fp) == NULL)
  455. {
  456. finished = true;
  457. break;
  458. }
  459. // Blank lines and lines that begin with # are comments
  460. still_comments = (line[0] == '#' || line[0] == '\n');
  461. j++;
  462. }
  463. if(finished)
  464. {
  465. break;
  466. }
  467. sscanf(line,"%[^:]: %s %[^\n]",name,type_str,value_str);
  468. //printf("%s: %s %s\n",name, type_str,value_str);
  469. TwType type;
  470. if(!type_from_string(type_str,type))
  471. {
  472. printf("ERROR: %s type not found... Skipping...\n",type_str);
  473. continue;
  474. }
  475. set_value_from_string(name,type,value_str);
  476. }
  477. fclose(fp);
  478. // everything succeeded
  479. return true;
  480. }
  481. IGL_INLINE bool igl::ReTwBar::type_from_string(const char *type_str, TwType & type)
  482. {
  483. // first check default types
  484. for(int j = 0; j < RETW_NUM_DEFAULT_TYPE_STRINGS; j++)
  485. {
  486. if(strcmp(type_str,ReTwDefaultTypeStrings[j].type_str) == 0)
  487. {
  488. type = ReTwDefaultTypeStrings[j].type;
  489. return true;
  490. break;
  491. }
  492. }
  493. // then check custom types
  494. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::const_iterator iter =
  495. ReTw_custom_types.begin();
  496. for(;iter != ReTw_custom_types.end(); iter++)
  497. {
  498. if(strcmp((*iter).second.first,type_str)==0)
  499. {
  500. type = (*iter).first;
  501. return true;
  502. }
  503. }
  504. return false;
  505. }
  506. bool igl::ReTwBar::set_value_from_string(
  507. const char * name,
  508. TwType type,
  509. const char * value_str)
  510. {
  511. void * value = NULL;
  512. // possible value slots
  513. int i;
  514. float v;
  515. double dv;
  516. float f[4];
  517. double d[4];
  518. bool b;
  519. unsigned char uc;
  520. std::string s;
  521. // First try to get value from default types
  522. switch(type)
  523. {
  524. case TW_TYPE_BOOLCPP:
  525. {
  526. int ib;
  527. if(sscanf(value_str," %d",&ib) == 1)
  528. {
  529. b = ib!=0;
  530. value = &b;
  531. }else
  532. {
  533. printf("ERROR: Bad value format...\n");
  534. return false;
  535. }
  536. break;
  537. }
  538. case TW_TYPE_QUAT4D:
  539. //case TW_TYPE_COLOR4D:
  540. {
  541. if(sscanf(value_str," %lf %lf %lf %lf",&d[0],&d[1],&d[2],&d[3]) == 4)
  542. {
  543. value = &d;
  544. }else
  545. {
  546. printf("ERROR: Bad value format...\n");
  547. return false;
  548. }
  549. break;
  550. }
  551. case TW_TYPE_QUAT4F:
  552. case TW_TYPE_COLOR4F:
  553. {
  554. if(sscanf(value_str," %f %f %f %f",&f[0],&f[1],&f[2],&f[3]) == 4)
  555. {
  556. value = &f;
  557. }else
  558. {
  559. printf("ERROR: Bad value format...\n");
  560. return false;
  561. }
  562. break;
  563. }
  564. //case TW_TYPE_COLOR3D:
  565. case TW_TYPE_DIR3D:
  566. {
  567. if(sscanf(value_str," %lf %lf %lf",&d[0],&d[1],&d[2]) == 3)
  568. {
  569. value = &d;
  570. }else
  571. {
  572. printf("ERROR: Bad value format...\n");
  573. return false;
  574. }
  575. break;
  576. }
  577. case TW_TYPE_COLOR3F:
  578. case TW_TYPE_DIR3F:
  579. {
  580. if(sscanf(value_str," %f %f %f",&f[0],&f[1],&f[2]) == 3)
  581. {
  582. value = &f;
  583. }else
  584. {
  585. printf("ERROR: Bad value format...\n");
  586. return false;
  587. }
  588. break;
  589. }
  590. case TW_TYPE_UINT8:
  591. {
  592. if(sscanf(value_str," %d",&i) == 1)
  593. {
  594. // Cast to unsigned char
  595. uc = (unsigned char) i;
  596. value = &uc;
  597. }else
  598. {
  599. printf("ERROR: Bad value format...\n");
  600. return false;
  601. }
  602. break;
  603. }
  604. case TW_TYPE_BOOL32:
  605. case TW_TYPE_INT32:
  606. {
  607. if(sscanf(value_str," %d",&i) == 1)
  608. {
  609. value = &i;
  610. }else
  611. {
  612. printf("ERROR: Bad value format...\n");
  613. return false;
  614. }
  615. break;
  616. }
  617. case TW_TYPE_FLOAT:
  618. {
  619. if(sscanf(value_str," %f",&v) == 1)
  620. {
  621. value = &v;
  622. }else
  623. {
  624. printf("ERROR: Bad value format...\n");
  625. return false;
  626. }
  627. break;
  628. }
  629. case TW_TYPE_DOUBLE:
  630. {
  631. if(sscanf(value_str," %lf",&dv) == 1)
  632. {
  633. value = &dv;
  634. }else
  635. {
  636. printf("ERROR: Bad value format...\n");
  637. return false;
  638. }
  639. break;
  640. }
  641. case TW_TYPE_STDSTRING:
  642. {
  643. s = value_str;
  644. value = &s;
  645. break;
  646. }
  647. default:
  648. // Try to find type in custom enum types
  649. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::const_iterator iter =
  650. ReTw_custom_types.find(type);
  651. if(iter != ReTw_custom_types.end())
  652. {
  653. std::vector<TwEnumVal>::const_iterator eit = (*iter).second.second.begin();
  654. bool found = false;
  655. for(;eit<(*iter).second.second.end();eit++)
  656. {
  657. if(strcmp(value_str,eit->Label) == 0)
  658. {
  659. i = eit->Value;
  660. value = &i;
  661. found = true;
  662. break;
  663. }
  664. }
  665. if(!found)
  666. {
  667. printf("ERROR_ENUM_VALUE_NOT_DEFINED");
  668. }
  669. }else
  670. {
  671. printf("ERROR_TYPE_NOT_SUPPORTED\n");
  672. }
  673. break;
  674. }
  675. // Find variable based on name
  676. // First look in RW items
  677. bool item_found = false;
  678. for(
  679. std::vector<ReTwRWItem>::iterator it = rw_items.begin();
  680. it != rw_items.end();
  681. it++)
  682. {
  683. if(it->name == name)
  684. {
  685. void * var = it->var;
  686. switch(type)
  687. {
  688. case TW_TYPE_BOOLCPP:
  689. {
  690. bool * bvar = static_cast<bool*>(var);
  691. bool * bvalue = static_cast<bool*>(value);
  692. *bvar = *bvalue;
  693. break;
  694. }
  695. case TW_TYPE_QUAT4D:
  696. //case TW_TYPE_COLOR4D:
  697. {
  698. double * dvar = static_cast<double*>(var);
  699. double * dvalue = static_cast<double*>(value);
  700. dvar[0] = dvalue[0];
  701. dvar[1] = dvalue[1];
  702. dvar[2] = dvalue[2];
  703. dvar[3] = dvalue[3];
  704. break;
  705. }
  706. case TW_TYPE_QUAT4F:
  707. case TW_TYPE_COLOR4F:
  708. {
  709. float * fvar = static_cast<float*>(var);
  710. float * fvalue = static_cast<float*>(value);
  711. fvar[0] = fvalue[0];
  712. fvar[1] = fvalue[1];
  713. fvar[2] = fvalue[2];
  714. fvar[3] = fvalue[3];
  715. break;
  716. }
  717. //case TW_TYPE_COLOR3D:
  718. case TW_TYPE_DIR3D:
  719. {
  720. double * dvar = static_cast<double*>(var);
  721. double * dvalue = static_cast<double*>(value);
  722. dvar[0] = dvalue[0];
  723. dvar[1] = dvalue[1];
  724. dvar[2] = dvalue[2];
  725. break;
  726. }
  727. case TW_TYPE_COLOR3F:
  728. case TW_TYPE_DIR3F:
  729. {
  730. float * fvar = static_cast<float*>(var);
  731. float * fvalue = static_cast<float*>(value);
  732. fvar[0] = fvalue[0];
  733. fvar[1] = fvalue[1];
  734. fvar[2] = fvalue[2];
  735. break;
  736. }
  737. case TW_TYPE_UINT8:
  738. {
  739. unsigned char * ucvar = static_cast<unsigned char*>(var);
  740. unsigned char * ucvalue = static_cast<unsigned char*>(value);
  741. *ucvar = *ucvalue;
  742. break;
  743. }
  744. case TW_TYPE_BOOL32:
  745. case TW_TYPE_INT32:
  746. {
  747. int * ivar = static_cast<int*>(var);
  748. int * ivalue = static_cast<int*>(value);
  749. *ivar = *ivalue;
  750. break;
  751. }
  752. case TW_TYPE_FLOAT:
  753. {
  754. float * fvar = static_cast<float*>(var);
  755. float * fvalue = static_cast<float*>(value);
  756. *fvar = *fvalue;
  757. break;
  758. }
  759. case TW_TYPE_DOUBLE:
  760. {
  761. double * dvar = static_cast<double*>(var);
  762. double * fvalue = static_cast<double*>(value);
  763. *dvar = *fvalue;
  764. break;
  765. }
  766. case TW_TYPE_STDSTRING:
  767. {
  768. std::string * svar = static_cast<std::string*>(var);
  769. std::string * svalue = static_cast<std::string*>(value);
  770. *svar = *svalue;
  771. break;
  772. }
  773. default:
  774. // Try to find type in custom enum types
  775. std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
  776. ReTw_custom_types.find(type);
  777. if(iter != ReTw_custom_types.end())
  778. {
  779. int * ivar = static_cast<int*>(var);
  780. std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
  781. bool found = false;
  782. for(;eit<(*iter).second.second.end();eit++)
  783. {
  784. if(strcmp(value_str,eit->Label) == 0)
  785. {
  786. *ivar = eit->Value;
  787. found = true;
  788. break;
  789. }
  790. }
  791. if(!found)
  792. {
  793. printf("ERROR_ENUM_VALUE_NOT_DEFINED");
  794. }
  795. }else
  796. {
  797. printf("ERROR_TYPE_NOT_SUPPORTED\n");
  798. }
  799. break;
  800. }
  801. item_found = true;
  802. break;
  803. }
  804. }
  805. // Try looking in CB items
  806. if(!item_found)
  807. {
  808. for(
  809. std::vector<ReTwCBItem>::iterator it = cb_items.begin();
  810. it != cb_items.end();
  811. it++)
  812. {
  813. if(it->name==name)
  814. {
  815. it->setCallback(value,it->clientData);
  816. item_found = true;
  817. break;
  818. }
  819. }
  820. }
  821. if(!item_found)
  822. {
  823. printf("ERROR: item '%s' not found\n",name);
  824. }
  825. return true;
  826. }
  827. IGL_INLINE const std::vector<igl::ReTwRWItem> & igl::ReTwBar::get_rw_items()
  828. {
  829. return rw_items;
  830. }
  831. IGL_INLINE const std::vector<igl::ReTwCBItem> & igl::ReTwBar::get_cb_items()
  832. {
  833. return cb_items;
  834. }
  835. #endif