mirror of
https://github.com/FULU-Foundation/OrcaSlicer-bambulab.git
synced 2026-05-17 02:42:47 -07:00
Fixing dep build script on Windows and removing some warnings. Use bundled igl by default. Not building with the dependency scripts if not explicitly stated. This way, it will stay in Fix the libigl patch to include C source files in header only mode.
935 lines
23 KiB
C++
935 lines
23 KiB
C++
// This file is part of libigl, a simple c++ geometry processing library.
|
|
//
|
|
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public License
|
|
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
|
// obtain one at http://mozilla.org/MPL/2.0/.
|
|
#include "ReAntTweakBar.h"
|
|
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <sstream>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <map>
|
|
|
|
// GLOBAL WRAPPERS
|
|
namespace
|
|
{
|
|
std::map<
|
|
TwType,std::pair<const char *,std::vector<TwEnumVal> >
|
|
> ReTw_custom_types;
|
|
}
|
|
|
|
IGL_INLINE TwType igl::anttweakbar::ReTwDefineEnum(
|
|
const char *name,
|
|
const TwEnumVal *enumValues,
|
|
unsigned int nbValues)
|
|
{
|
|
using namespace std;
|
|
// copy enum valus into vector
|
|
std::vector<TwEnumVal> enum_vals;
|
|
enum_vals.resize(nbValues);
|
|
for(unsigned int j = 0; j<nbValues;j++)
|
|
{
|
|
enum_vals[j] = enumValues[j];
|
|
}
|
|
TwType type = TwDefineEnum(name,enumValues,nbValues);
|
|
|
|
ReTw_custom_types[type] =
|
|
std::pair<const char *,std::vector<TwEnumVal> >(name,enum_vals);
|
|
|
|
return type;
|
|
}
|
|
|
|
IGL_INLINE TwType igl::anttweakbar::ReTwDefineEnumFromString(
|
|
const char * _Name,
|
|
const char * _EnumString)
|
|
{
|
|
// Taken directly from TwMgr.cpp, just replace TwDefineEnum with
|
|
// ReTwDefineEnum
|
|
using namespace std;
|
|
{
|
|
if (_EnumString == NULL)
|
|
return ReTwDefineEnum(_Name, NULL, 0);
|
|
|
|
// split enumString
|
|
stringstream EnumStream(_EnumString);
|
|
string Label;
|
|
vector<string> Labels;
|
|
while( getline(EnumStream, Label, ',') ) {
|
|
// trim Label
|
|
size_t Start = Label.find_first_not_of(" \n\r\t");
|
|
size_t End = Label.find_last_not_of(" \n\r\t");
|
|
if( Start==string::npos || End==string::npos )
|
|
Label = "";
|
|
else
|
|
Label = Label.substr(Start, (End-Start)+1);
|
|
// store Label
|
|
Labels.push_back(Label);
|
|
}
|
|
// create TwEnumVal array
|
|
vector<TwEnumVal> Vals(Labels.size());
|
|
for( int i=0; i<(int)Labels.size(); i++ )
|
|
{
|
|
Vals[i].Value = i;
|
|
// Wrong:
|
|
//Vals[i].Label = Labels[i].c_str();
|
|
// Allocate char on heap
|
|
// http://stackoverflow.com/a/10050258/148668
|
|
char * c_label = new char[Labels[i].length()+1];
|
|
std::strcpy(c_label, Labels[i].c_str());
|
|
Vals[i].Label = c_label;
|
|
}
|
|
|
|
const TwType type =
|
|
ReTwDefineEnum(_Name, Vals.empty() ?
|
|
NULL :
|
|
&(Vals[0]), (unsigned int)Vals.size());
|
|
return type;
|
|
}
|
|
}
|
|
|
|
namespace
|
|
{
|
|
struct ReTwTypeString
|
|
{
|
|
TwType type;
|
|
const char * type_str;
|
|
};
|
|
|
|
#define RETW_NUM_DEFAULT_TYPE_STRINGS 23
|
|
ReTwTypeString ReTwDefaultTypeStrings[RETW_NUM_DEFAULT_TYPE_STRINGS] =
|
|
{
|
|
{TW_TYPE_UNDEF,"TW_TYPE_UNDEF"},
|
|
{TW_TYPE_BOOLCPP,"TW_TYPE_BOOLCPP"},
|
|
{TW_TYPE_BOOL8,"TW_TYPE_BOOL8"},
|
|
{TW_TYPE_BOOL16,"TW_TYPE_BOOL16"},
|
|
{TW_TYPE_BOOL32,"TW_TYPE_BOOL32"},
|
|
{TW_TYPE_CHAR,"TW_TYPE_CHAR"},
|
|
{TW_TYPE_INT8,"TW_TYPE_INT8"},
|
|
{TW_TYPE_UINT8,"TW_TYPE_UINT8"},
|
|
{TW_TYPE_INT16,"TW_TYPE_INT16"},
|
|
{TW_TYPE_UINT16,"TW_TYPE_UINT16"},
|
|
{TW_TYPE_INT32,"TW_TYPE_INT32"},
|
|
{TW_TYPE_UINT32,"TW_TYPE_UINT32"},
|
|
{TW_TYPE_FLOAT,"TW_TYPE_FLOAT"},
|
|
{TW_TYPE_DOUBLE,"TW_TYPE_DOUBLE"},
|
|
{TW_TYPE_COLOR32,"TW_TYPE_COLOR32"},
|
|
{TW_TYPE_COLOR3F,"TW_TYPE_COLOR3F"},
|
|
{TW_TYPE_COLOR4F,"TW_TYPE_COLOR4F"},
|
|
{TW_TYPE_CDSTRING,"TW_TYPE_CDSTRING"},
|
|
{TW_TYPE_STDSTRING,"TW_TYPE_STDSTRING"},
|
|
{TW_TYPE_QUAT4F,"TW_TYPE_QUAT4F"},
|
|
{TW_TYPE_QUAT4D,"TW_TYPE_QUAT4D"},
|
|
{TW_TYPE_DIR3F,"TW_TYPE_DIR3F"},
|
|
{TW_TYPE_DIR3D,"TW_TYPE_DIR3D"}
|
|
};
|
|
}
|
|
|
|
IGL_INLINE igl::anttweakbar::ReTwBar::ReTwBar():
|
|
bar(NULL),
|
|
name(),
|
|
rw_items(),cb_items()
|
|
{
|
|
}
|
|
|
|
IGL_INLINE igl::anttweakbar::ReTwBar::ReTwBar(
|
|
const igl::anttweakbar::ReTwBar & that):
|
|
bar(that.bar),
|
|
name(that.name),
|
|
rw_items(that.rw_items),
|
|
cb_items(that.cb_items)
|
|
{
|
|
}
|
|
|
|
IGL_INLINE igl::anttweakbar::ReTwBar &
|
|
igl::anttweakbar::ReTwBar::operator=(const igl::anttweakbar::ReTwBar & that)
|
|
{
|
|
// check for self assignment
|
|
if(this != &that)
|
|
{
|
|
bar = that.bar;
|
|
rw_items = that.rw_items;
|
|
cb_items = that.cb_items;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
|
|
// BAR WRAPPERS
|
|
IGL_INLINE void igl::anttweakbar::ReTwBar::TwNewBar(const char * _name)
|
|
{
|
|
this->bar = ::TwNewBar(_name);
|
|
// Alec: This causes trouble (not sure why) in multiple applications
|
|
// (medit, puppet) Probably there is some sort of memory corrpution.
|
|
// this->name = _name;
|
|
// Suspiciously this also fails:
|
|
//this->name = "foobar";
|
|
}
|
|
|
|
IGL_INLINE int igl::anttweakbar::ReTwBar::TwAddVarRW(
|
|
const char *name,
|
|
TwType type,
|
|
void *var,
|
|
const char *def,
|
|
const bool record)
|
|
{
|
|
int ret = ::TwAddVarRW(this->bar,name,type,var,def);
|
|
if(ret && record)
|
|
{
|
|
rw_items.push_back(ReTwRWItem(name,type,var));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
IGL_INLINE int igl::anttweakbar::ReTwBar::TwAddVarCB(
|
|
const char *name,
|
|
TwType type,
|
|
TwSetVarCallback setCallback,
|
|
TwGetVarCallback getCallback,
|
|
void *clientData,
|
|
const char *def,
|
|
const bool record)
|
|
{
|
|
int ret =
|
|
::TwAddVarCB(this->bar,name,type,setCallback,getCallback,clientData,def);
|
|
if(ret && record)
|
|
{
|
|
cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
IGL_INLINE int igl::anttweakbar::ReTwBar::TwAddVarRO(
|
|
const char *name,
|
|
TwType type,
|
|
void *var,
|
|
const char *def)
|
|
{
|
|
int ret = ::TwAddVarRO(this->bar,name,type,var,def);
|
|
// Read only variables are not recorded
|
|
//if(ret)
|
|
//{
|
|
// rw_items.push_back(ReTwRWItem(name,type,var));
|
|
//}
|
|
return ret;
|
|
}
|
|
|
|
IGL_INLINE int igl::anttweakbar::ReTwBar::TwAddButton(
|
|
const char *name,
|
|
TwButtonCallback buttonCallback,
|
|
void *clientData,
|
|
const char *def)
|
|
{
|
|
int ret =
|
|
::TwAddButton(this->bar,name,buttonCallback,clientData,def);
|
|
// buttons are not recorded
|
|
//if(ret)
|
|
//{
|
|
// cb_items.push_back(ReTwCBItem(name,type,setCallback,getCallback,clientData));
|
|
//}
|
|
return ret;
|
|
}
|
|
|
|
IGL_INLINE int igl::anttweakbar::ReTwBar::TwSetParam(
|
|
const char *varName,
|
|
const char *paramName,
|
|
TwParamValueType paramValueType,
|
|
unsigned int inValueCount,
|
|
const void *inValues)
|
|
{
|
|
// For now just pass these along
|
|
return
|
|
::TwSetParam(
|
|
this->bar,
|
|
varName,
|
|
paramName,
|
|
paramValueType,
|
|
inValueCount,
|
|
inValues);
|
|
}
|
|
|
|
IGL_INLINE int igl::anttweakbar::ReTwBar::TwGetParam(
|
|
const char *varName,
|
|
const char *paramName,
|
|
TwParamValueType paramValueType,
|
|
unsigned int outValueMaxCount,
|
|
void *outValues)
|
|
{
|
|
return
|
|
::TwGetParam(
|
|
this->bar,
|
|
varName,
|
|
paramName,
|
|
paramValueType,
|
|
outValueMaxCount,
|
|
outValues);
|
|
}
|
|
|
|
IGL_INLINE int igl::anttweakbar::ReTwBar::TwRefreshBar()
|
|
{
|
|
return ::TwRefreshBar(this->bar);
|
|
}
|
|
|
|
IGL_INLINE int igl::anttweakbar::ReTwBar::TwTerminate()
|
|
{
|
|
//std::cout<<"TwTerminate"<<std::endl;
|
|
int r = ::TwTerminate();
|
|
//std::cout<<" "<<r<<std::endl;
|
|
return r;
|
|
}
|
|
|
|
IGL_INLINE bool igl::anttweakbar::ReTwBar::save(const char *file_name)
|
|
{
|
|
FILE * fp;
|
|
if(file_name == NULL)
|
|
{
|
|
fp = stdout;
|
|
}else
|
|
{
|
|
fp = fopen(file_name,"w");
|
|
}
|
|
|
|
if(fp == NULL)
|
|
{
|
|
printf("ERROR: not able to open %s for writing...\n",file_name);
|
|
return false;
|
|
}
|
|
|
|
// Print all RW variables
|
|
for(
|
|
std::vector<ReTwRWItem>::iterator it = rw_items.begin();
|
|
it != rw_items.end();
|
|
it++)
|
|
{
|
|
std::string s = (*it).name;
|
|
const char * name = s.c_str();
|
|
TwType type = (*it).type;
|
|
void * var = (*it).var;
|
|
fprintf(fp,"%s: %s\n",
|
|
name,
|
|
get_value_as_string(var,type).c_str());
|
|
}
|
|
|
|
char var[REANTTWEAKBAR_MAX_CB_VAR_SIZE];
|
|
// Print all CB variables
|
|
for(
|
|
std::vector<ReTwCBItem>::iterator it = cb_items.begin();
|
|
it != cb_items.end();
|
|
it++)
|
|
{
|
|
const char * name = it->name.c_str();
|
|
TwType type = it->type;
|
|
//TwSetVarCallback setCallback = it->setCallback;
|
|
TwGetVarCallback getCallback = it->getCallback;
|
|
void * clientData = it->clientData;
|
|
// I'm not sure how to do what I want to do. getCallback needs to be sure
|
|
// that it can write to var. So var needs to point to a valid and big
|
|
// enough chunk of memory
|
|
getCallback(var,clientData);
|
|
fprintf(fp,"%s: %s\n",
|
|
name,
|
|
get_value_as_string(var,type).c_str());
|
|
}
|
|
|
|
fprintf(fp,"\n");
|
|
|
|
if(file_name != NULL)
|
|
{
|
|
fclose(fp);
|
|
}
|
|
// everything succeeded
|
|
return true;
|
|
}
|
|
|
|
IGL_INLINE std::string igl::anttweakbar::ReTwBar::get_value_as_string(
|
|
void * var,
|
|
TwType type)
|
|
{
|
|
std::stringstream sstr;
|
|
switch(type)
|
|
{
|
|
case TW_TYPE_BOOLCPP:
|
|
{
|
|
sstr << "TW_TYPE_BOOLCPP" << " ";
|
|
sstr << *(static_cast<bool*>(var));
|
|
break;
|
|
}
|
|
case TW_TYPE_QUAT4D:
|
|
{
|
|
sstr << "TW_TYPE_QUAT4D" << " ";
|
|
// Q: Why does casting to double* work? shouldn't I have to cast to
|
|
// double**?
|
|
double * q = static_cast<double*>(var);
|
|
sstr << std::setprecision(15) << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
|
|
break;
|
|
}
|
|
case TW_TYPE_QUAT4F:
|
|
{
|
|
sstr << "TW_TYPE_QUAT4F" << " ";
|
|
// Q: Why does casting to float* work? shouldn't I have to cast to
|
|
// float**?
|
|
float * q = static_cast<float*>(var);
|
|
sstr << q[0] << " " << q[1] << " " << q[2] << " " << q[3];
|
|
break;
|
|
}
|
|
case TW_TYPE_COLOR4F:
|
|
{
|
|
sstr << "TW_TYPE_COLOR4F" << " ";
|
|
float * c = static_cast<float*>(var);
|
|
sstr << c[0] << " " << c[1] << " " << c[2] << " " << c[3];
|
|
break;
|
|
}
|
|
case TW_TYPE_COLOR3F:
|
|
{
|
|
sstr << "TW_TYPE_COLOR3F" << " ";
|
|
float * c = static_cast<float*>(var);
|
|
sstr << c[0] << " " << c[1] << " " << c[2];
|
|
break;
|
|
}
|
|
case TW_TYPE_DIR3D:
|
|
{
|
|
sstr << "TW_TYPE_DIR3D" << " ";
|
|
double * d = static_cast<double*>(var);
|
|
sstr << std::setprecision(15) << d[0] << " " << d[1] << " " << d[2];
|
|
break;
|
|
}
|
|
case TW_TYPE_DIR3F:
|
|
{
|
|
sstr << "TW_TYPE_DIR3F" << " ";
|
|
float * d = static_cast<float*>(var);
|
|
sstr << d[0] << " " << d[1] << " " << d[2];
|
|
break;
|
|
}
|
|
case TW_TYPE_BOOL32:
|
|
{
|
|
sstr << "TW_TYPE_BOOL32" << " ";
|
|
sstr << *(static_cast<int*>(var));
|
|
break;
|
|
}
|
|
case TW_TYPE_UINT8:
|
|
{
|
|
sstr << "TW_TYPE_UINT8" << " ";
|
|
// Cast to int so that it's human readable
|
|
sstr << (int)*(static_cast<unsigned char*>(var));
|
|
break;
|
|
}
|
|
case TW_TYPE_INT32:
|
|
{
|
|
sstr << "TW_TYPE_INT32" << " ";
|
|
sstr << *(static_cast<int*>(var));
|
|
break;
|
|
}
|
|
case TW_TYPE_UINT32:
|
|
{
|
|
sstr << "TW_TYPE_UINT32" << " ";
|
|
sstr << *(static_cast<unsigned int*>(var));
|
|
break;
|
|
}
|
|
case TW_TYPE_FLOAT:
|
|
{
|
|
sstr << "TW_TYPE_FLOAT" << " ";
|
|
sstr << *(static_cast<float*>(var));
|
|
break;
|
|
}
|
|
case TW_TYPE_DOUBLE:
|
|
{
|
|
sstr << "TW_TYPE_DOUBLE" << " ";
|
|
sstr << std::setprecision(15) << *(static_cast<double*>(var));
|
|
break;
|
|
}
|
|
case TW_TYPE_STDSTRING:
|
|
{
|
|
sstr << "TW_TYPE_STDSTRING" << " ";
|
|
std::string *destPtr = static_cast<std::string *>(var);
|
|
sstr << destPtr->c_str();
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
using namespace std;
|
|
std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::const_iterator iter =
|
|
ReTw_custom_types.find(type);
|
|
if(iter != ReTw_custom_types.end())
|
|
{
|
|
sstr << (*iter).second.first << " ";
|
|
int enum_val = *(static_cast<int*>(var));
|
|
// try find display name for enum value
|
|
std::vector<TwEnumVal>::const_iterator eit = (*iter).second.second.begin();
|
|
bool found = false;
|
|
for(;eit<(*iter).second.second.end();eit++)
|
|
{
|
|
if(enum_val == eit->Value)
|
|
{
|
|
sstr << eit->Label;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if(!found)
|
|
{
|
|
sstr << "ERROR_ENUM_VALUE_NOT_DEFINED";
|
|
}
|
|
}else
|
|
{
|
|
sstr << "ERROR_TYPE_NOT_SUPPORTED";
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return sstr.str();
|
|
}
|
|
|
|
IGL_INLINE bool igl::anttweakbar::ReTwBar::load(const char *file_name)
|
|
{
|
|
FILE * fp;
|
|
fp = fopen(file_name,"r");
|
|
|
|
if(fp == NULL)
|
|
{
|
|
printf("ERROR: not able to open %s for reading...\n",file_name);
|
|
return false;
|
|
}
|
|
|
|
// go through file line by line
|
|
char line[REANTTWEAKBAR_MAX_LINE];
|
|
bool still_comments;
|
|
char name[REANTTWEAKBAR_MAX_WORD];
|
|
char type_str[REANTTWEAKBAR_MAX_WORD];
|
|
char value_str[REANTTWEAKBAR_MAX_WORD];
|
|
|
|
|
|
// line number
|
|
int j = 0;
|
|
bool finished = false;
|
|
while(true)
|
|
{
|
|
// Eat comments
|
|
still_comments = true;
|
|
while(still_comments)
|
|
{
|
|
if(fgets(line,REANTTWEAKBAR_MAX_LINE,fp) == NULL)
|
|
{
|
|
finished = true;
|
|
break;
|
|
}
|
|
// Blank lines and lines that begin with # are comments
|
|
still_comments = (line[0] == '#' || line[0] == '\n');
|
|
j++;
|
|
}
|
|
if(finished)
|
|
{
|
|
break;
|
|
}
|
|
|
|
sscanf(line,"%[^:]: %s %[^\n]",name,type_str,value_str);
|
|
//printf("%s: %s %s\n",name, type_str,value_str);
|
|
|
|
TwType type;
|
|
if(!type_from_string(type_str,type))
|
|
{
|
|
printf("ERROR: %s type not found... Skipping...\n",type_str);
|
|
continue;
|
|
}
|
|
set_value_from_string(name,type,value_str);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
// everything succeeded
|
|
return true;
|
|
}
|
|
|
|
IGL_INLINE bool igl::anttweakbar::ReTwBar::type_from_string(
|
|
const char *type_str, TwType & type)
|
|
{
|
|
// first check default types
|
|
for(int j = 0; j < RETW_NUM_DEFAULT_TYPE_STRINGS; j++)
|
|
{
|
|
if(strcmp(type_str,ReTwDefaultTypeStrings[j].type_str) == 0)
|
|
{
|
|
type = ReTwDefaultTypeStrings[j].type;
|
|
return true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// then check custom types
|
|
std::map<
|
|
TwType,std::pair<const char *,std::vector<TwEnumVal> >
|
|
>::const_iterator iter =
|
|
ReTw_custom_types.begin();
|
|
for(;iter != ReTw_custom_types.end(); iter++)
|
|
{
|
|
if(strcmp((*iter).second.first,type_str)==0)
|
|
{
|
|
type = (*iter).first;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool igl::anttweakbar::ReTwBar::set_value_from_string(
|
|
const char * name,
|
|
TwType type,
|
|
const char * value_str)
|
|
{
|
|
void * value = NULL;
|
|
// possible value slots
|
|
int i;
|
|
float v;
|
|
double dv;
|
|
float f[4];
|
|
double d[4];
|
|
bool b;
|
|
unsigned int u;
|
|
unsigned char uc;
|
|
std::string s;
|
|
|
|
// First try to get value from default types
|
|
switch(type)
|
|
{
|
|
case TW_TYPE_BOOLCPP:
|
|
{
|
|
int ib;
|
|
if(sscanf(value_str," %d",&ib) == 1)
|
|
{
|
|
b = ib!=0;
|
|
value = &b;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_QUAT4D:
|
|
//case TW_TYPE_COLOR4D:
|
|
{
|
|
if(sscanf(value_str," %lf %lf %lf %lf",&d[0],&d[1],&d[2],&d[3]) == 4)
|
|
{
|
|
value = &d;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_QUAT4F:
|
|
case TW_TYPE_COLOR4F:
|
|
{
|
|
if(sscanf(value_str," %f %f %f %f",&f[0],&f[1],&f[2],&f[3]) == 4)
|
|
{
|
|
value = &f;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
//case TW_TYPE_COLOR3D:
|
|
case TW_TYPE_DIR3D:
|
|
{
|
|
if(sscanf(value_str," %lf %lf %lf",&d[0],&d[1],&d[2]) == 3)
|
|
{
|
|
value = &d;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_COLOR3F:
|
|
case TW_TYPE_DIR3F:
|
|
{
|
|
if(sscanf(value_str," %f %f %f",&f[0],&f[1],&f[2]) == 3)
|
|
{
|
|
value = &f;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_UINT8:
|
|
{
|
|
if(sscanf(value_str," %d",&i) == 1)
|
|
{
|
|
// Cast to unsigned char
|
|
uc = (unsigned char) i;
|
|
value = &uc;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_BOOL32:
|
|
case TW_TYPE_INT32:
|
|
{
|
|
if(sscanf(value_str," %d",&i) == 1)
|
|
{
|
|
value = &i;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_UINT32:
|
|
{
|
|
if(sscanf(value_str," %u",&u) == 1)
|
|
{
|
|
value = &u;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_FLOAT:
|
|
{
|
|
if(sscanf(value_str," %f",&v) == 1)
|
|
{
|
|
value = &v;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_DOUBLE:
|
|
{
|
|
if(sscanf(value_str," %lf",&dv) == 1)
|
|
{
|
|
value = &dv;
|
|
}else
|
|
{
|
|
printf("ERROR: Bad value format...\n");
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case TW_TYPE_STDSTRING:
|
|
{
|
|
s = value_str;
|
|
value = &s;
|
|
break;
|
|
}
|
|
default:
|
|
// Try to find type in custom enum types
|
|
std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::const_iterator iter =
|
|
ReTw_custom_types.find(type);
|
|
if(iter != ReTw_custom_types.end())
|
|
{
|
|
std::vector<TwEnumVal>::const_iterator eit = (*iter).second.second.begin();
|
|
bool found = false;
|
|
for(;eit<(*iter).second.second.end();eit++)
|
|
{
|
|
if(strcmp(value_str,eit->Label) == 0)
|
|
{
|
|
i = eit->Value;
|
|
value = &i;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if(!found)
|
|
{
|
|
printf("ERROR_ENUM_VALUE_NOT_DEFINED");
|
|
}
|
|
}else
|
|
{
|
|
printf("ERROR_TYPE_NOT_SUPPORTED\n");
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
// Find variable based on name
|
|
// First look in RW items
|
|
bool item_found = false;
|
|
for(
|
|
std::vector<ReTwRWItem>::iterator it = rw_items.begin();
|
|
it != rw_items.end();
|
|
it++)
|
|
{
|
|
if(it->name == name)
|
|
{
|
|
void * var = it->var;
|
|
switch(type)
|
|
{
|
|
case TW_TYPE_BOOLCPP:
|
|
{
|
|
bool * bvar = static_cast<bool*>(var);
|
|
bool * bvalue = static_cast<bool*>(value);
|
|
*bvar = *bvalue;
|
|
break;
|
|
}
|
|
case TW_TYPE_QUAT4D:
|
|
//case TW_TYPE_COLOR4D:
|
|
{
|
|
double * dvar = static_cast<double*>(var);
|
|
double * dvalue = static_cast<double*>(value);
|
|
dvar[0] = dvalue[0];
|
|
dvar[1] = dvalue[1];
|
|
dvar[2] = dvalue[2];
|
|
dvar[3] = dvalue[3];
|
|
break;
|
|
}
|
|
case TW_TYPE_QUAT4F:
|
|
case TW_TYPE_COLOR4F:
|
|
{
|
|
float * fvar = static_cast<float*>(var);
|
|
float * fvalue = static_cast<float*>(value);
|
|
fvar[0] = fvalue[0];
|
|
fvar[1] = fvalue[1];
|
|
fvar[2] = fvalue[2];
|
|
fvar[3] = fvalue[3];
|
|
break;
|
|
}
|
|
//case TW_TYPE_COLOR3D:
|
|
case TW_TYPE_DIR3D:
|
|
{
|
|
double * dvar = static_cast<double*>(var);
|
|
double * dvalue = static_cast<double*>(value);
|
|
dvar[0] = dvalue[0];
|
|
dvar[1] = dvalue[1];
|
|
dvar[2] = dvalue[2];
|
|
break;
|
|
}
|
|
case TW_TYPE_COLOR3F:
|
|
case TW_TYPE_DIR3F:
|
|
{
|
|
float * fvar = static_cast<float*>(var);
|
|
float * fvalue = static_cast<float*>(value);
|
|
fvar[0] = fvalue[0];
|
|
fvar[1] = fvalue[1];
|
|
fvar[2] = fvalue[2];
|
|
break;
|
|
}
|
|
case TW_TYPE_UINT8:
|
|
{
|
|
unsigned char * ucvar = static_cast<unsigned char*>(var);
|
|
unsigned char * ucvalue = static_cast<unsigned char*>(value);
|
|
*ucvar = *ucvalue;
|
|
break;
|
|
}
|
|
case TW_TYPE_BOOL32:
|
|
case TW_TYPE_INT32:
|
|
{
|
|
int * ivar = static_cast<int*>(var);
|
|
int * ivalue = static_cast<int*>(value);
|
|
*ivar = *ivalue;
|
|
break;
|
|
}
|
|
case TW_TYPE_UINT32:
|
|
{
|
|
unsigned int * uvar = static_cast<unsigned int*>(var);
|
|
unsigned int * uvalue = static_cast<unsigned int*>(value);
|
|
*uvar = *uvalue;
|
|
break;
|
|
}
|
|
case TW_TYPE_FLOAT:
|
|
{
|
|
float * fvar = static_cast<float*>(var);
|
|
float * fvalue = static_cast<float*>(value);
|
|
*fvar = *fvalue;
|
|
break;
|
|
}
|
|
case TW_TYPE_DOUBLE:
|
|
{
|
|
double * dvar = static_cast<double*>(var);
|
|
double * fvalue = static_cast<double*>(value);
|
|
*dvar = *fvalue;
|
|
break;
|
|
}
|
|
case TW_TYPE_STDSTRING:
|
|
{
|
|
std::string * svar = static_cast<std::string*>(var);
|
|
std::string * svalue = static_cast<std::string*>(value);
|
|
*svar = *svalue;
|
|
break;
|
|
}
|
|
default:
|
|
// Try to find type in custom enum types
|
|
std::map<TwType,std::pair<const char *,std::vector<TwEnumVal> > >::iterator iter =
|
|
ReTw_custom_types.find(type);
|
|
if(iter != ReTw_custom_types.end())
|
|
{
|
|
int * ivar = static_cast<int*>(var);
|
|
std::vector<TwEnumVal>::iterator eit = (*iter).second.second.begin();
|
|
bool found = false;
|
|
for(;eit<(*iter).second.second.end();eit++)
|
|
{
|
|
if(strcmp(value_str,eit->Label) == 0)
|
|
{
|
|
*ivar = eit->Value;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if(!found)
|
|
{
|
|
printf("ERROR_ENUM_VALUE_NOT_DEFINED");
|
|
}
|
|
}else
|
|
{
|
|
printf("ERROR_TYPE_NOT_SUPPORTED\n");
|
|
}
|
|
break;
|
|
}
|
|
item_found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Try looking in CB items
|
|
if(!item_found)
|
|
{
|
|
for(
|
|
std::vector<ReTwCBItem>::iterator it = cb_items.begin();
|
|
it != cb_items.end();
|
|
it++)
|
|
{
|
|
if(it->name==name)
|
|
{
|
|
it->setCallback(value,it->clientData);
|
|
item_found = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!item_found)
|
|
{
|
|
printf("ERROR: item '%s' not found\n",name);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
IGL_INLINE const std::vector<igl::anttweakbar::ReTwRWItem> &
|
|
igl::anttweakbar::ReTwBar::get_rw_items()
|
|
{
|
|
return rw_items;
|
|
}
|
|
|
|
IGL_INLINE const std::vector<igl::anttweakbar::ReTwCBItem> &
|
|
igl::anttweakbar::ReTwBar::get_cb_items()
|
|
{
|
|
return cb_items;
|
|
}
|