00001 /* 00002 * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software 00003 * 00004 * The Software has been developped within the Siames Project. 00005 * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights 00006 * 00007 * The Software has been registered with the Agence pour la Protection des 00008 * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200 00009 * 00010 * This file may be distributed under the terms of the Q Public License 00011 * version 1.0 as defined by Trolltech AS of Norway and appearing in the file 00012 * LICENSE.QPL included in the packaging of this file. 00013 * 00014 * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 00015 * for the software may use this file in accordance with that specific license 00016 * 00017 */ 00018 #include <OMKParametersAccessor.inl> 00019 #include <OMKName.h> 00020 #include <OMKSimulatedObject.h> 00021 #include "OMKTransformType.h" 00022 #include "OMKColorType.h" 00023 #include "OMKTracer.h" 00024 #include "OMKConfigurationParameterDescriptor.h" 00025 00026 using namespace OMK ; 00027 //------------------------------------------------------------------- 00028 // Get the node named "name" 00029 const ConfigurationParameterDescriptor * ParametersAccessor::getNodeValue( 00030 const ConfigurationParameterDescriptor * node, 00031 const std::string & name, 00032 std::string & errorStr ) 00033 { 00034 const ConfigurationParameterDescriptor * nodeValue = node ? node->getSubDescriptorByName( name ) : 0 ; 00035 if ( !node && errorStr.empty() ) 00036 errorStr = "Invalid ConfigurationParameterDescriptor node" ; 00037 if ( !nodeValue && errorStr.empty() ) 00038 errorStr = "Parameter not found" ; 00039 return nodeValue ; 00040 } 00041 00042 //------------------------------------------------------------------- 00043 // Return a bool to put it in a test like 00044 // return getValue(...) || displayError(...) 00045 // so return always false 00046 bool ParametersAccessor::displayError( 00047 const std::string & name, 00048 const std::string & functionName, 00049 SimulatedObject* object, 00050 const std::string & errorStr ) 00051 { 00052 if( !errorStr.empty() ) 00053 { 00054 if( object ) 00055 { 00056 OMERROR( "Error in ParametersAccessor::" << functionName 00057 << " with parameter [" + name + "] for " << OMK::debugMsg( object ) << std::endl 00058 << ">>> :-( " << errorStr ) ; 00059 } 00060 else 00061 { 00062 OMTRACEID( OMK_DEBUG_OMK_OBJ, "Warning in ParametersAccessor::" << functionName 00063 << " with parameter [" + name + "]" << std::endl 00064 << ">>> :-| " << errorStr ) ; 00065 } 00066 } 00067 // Return always false 00068 return false ; 00069 } 00070 00071 //------------------------------------------------------------------- 00072 // Retrieve a object name and check its existance in the tree 00073 bool ParametersAccessor::getAndCheckObject( 00074 const ConfigurationParameterDescriptor * node, 00075 const std::string & name, 00076 Name & objectName, 00077 Controller & controller, 00078 SimulatedObject * object /*= 0 */ ) 00079 { 00080 std::string errorStr ; 00081 // Get the node for the value 00082 const ConfigurationParameterDescriptor * nodeValue = getNodeValue( node, name, errorStr ) ; 00083 // if it is good, get the value else display error 00084 bool ok = ( nodeValue != NULL ) ; 00085 ok = ok && getValue( nodeValue, objectName, errorStr ) ; 00086 if( ok ) 00087 { 00088 try 00089 { 00090 //check wether paramVariable exists: if it does not, a OMKUserException is thrown 00091 controller.getObjectDescriptorOfObject( objectName ); 00092 } 00093 catch( UserException e ) 00094 { 00095 ok = false ; 00096 errorStr = "Object \"" ; 00097 errorStr += objectName.getCString(); 00098 errorStr += "\" doesn't exist" ; 00099 } 00100 } 00101 return ok || displayError( name, "getAndCheckObject", object, errorStr ) ; 00102 } 00103 //------------------------------------------------------------------- 00104 // Get value for a bool 00105 bool ParametersAccessor::getValue( const ConfigurationParameterDescriptor * nodeValue, 00106 bool & flag, 00107 std::string& errorStr ) 00108 { 00109 std::string str; 00110 if( !getValue( nodeValue, str, errorStr ) ) 00111 { // Error 00112 return false; 00113 } 00114 std::transform( str.begin(), str.end(), str.begin(), toupper ); 00115 flag = ( str == "TRUE" || str == "ON" || str == "ENABLE" || str == "YES" || str == "1" ) ; 00116 bool ok = flag || ( str == "FALSE" || str == "OFF" || str == "DISABLE" || str == "NO" || str == "0" ) ; 00117 if( !ok ) 00118 { 00119 errorStr = "Cannot read the boolean" ; 00120 } 00121 return ok ; 00122 } 00123 00124 //------------------------------------------------------------------- 00125 // Get value for a OMK::Type::Color 00126 bool ParametersAccessor::getValue( const ConfigurationParameterDescriptor * nodeValue, 00127 OMK::Type::Color & color, 00128 std::string& errorStr ) 00129 { 00130 if( !nodeValue ) 00131 return false; // Error no valid node 00132 00133 if( nodeValue->getAssociatedString()[0] == '{' ) 00134 { 00135 // array format => read it 00136 // rgb or rgba 00137 bool ok = ( 3 == nodeValue->getNumberOfSubItems() 00138 || 4 == nodeValue->getNumberOfSubItems() ); 00139 if ( !ok && errorStr.empty() ) 00140 errorStr = "Bad format of OMK::Type::Color (need 3 or 4 arguments)" ; 00141 // 4 values => rgb + alpha 00142 bool withAlpha = ( 4 == nodeValue->getNumberOfSubItems() ) ; 00143 float r = 0.0f; 00144 float g = 0.0f; 00145 float b = 0.0f; 00146 float a = 1.0f; 00147 if( ok ) 00148 { 00149 ok = ok && getValue( nodeValue->getSubDescriptorByPosition( 0 ), r, errorStr ) ; 00150 ok = ok && getValue( nodeValue->getSubDescriptorByPosition( 1 ), g, errorStr ) ; 00151 ok = ok && getValue( nodeValue->getSubDescriptorByPosition( 2 ), b, errorStr ) ; 00152 if( withAlpha ) ok = ok && getValue( nodeValue->getSubDescriptorByPosition( 3 ), a, errorStr ) ; 00153 if ( !ok ) 00154 errorStr += ". Cannot get one of the OMK::Type::Color argument" ; 00155 } 00156 // Normalize in [0, 1] set 00157 if( 1.0f < r || 1.0f < g || 1.0f < b ) 00158 { 00159 r /= 255.0f; 00160 g /= 255.0f; 00161 b /= 255.0f; 00162 } 00163 ok = ok 00164 && ( 0.0f <= r ) && ( r <= 1.0f ) 00165 && ( 0.0f <= g ) && ( g <= 1.0f ) 00166 && ( 0.0f <= b ) && ( b <= 1.0f ) 00167 && ( 0.0f <= a ) && ( a <= 1.0f ) ; 00168 if ( !ok && errorStr.empty() ) 00169 errorStr = "One of the OMK::Type::Color argument is not in the good range [0.0 1.0] or [0 255]" ; 00170 00171 if( ok ) 00172 { // Create the color 00173 color = OMK::Type::Color( r, g, b, a ) ; 00174 } 00175 return ok; 00176 } 00177 // string format 00178 return getTxtValue( nodeValue->getAssociatedString(), color ); 00179 } 00180 00181 00182 //------------------------------------------------------------------- 00183 // Get value for a Transform 00184 bool ParametersAccessor::getValue( const ConfigurationParameterDescriptor * nodeValue, 00185 OMK::Type::Transform & transform, 00186 std::string& errorStr ) 00187 { 00188 if( !nodeValue ) 00189 return false; // Error no valid node 00190 00191 bool ok = false ; 00192 if( nodeValue->getAssociatedString()[0] == '{' ) 00193 { 00194 transform = OMK::Type::Transform::sk_identity ; 00195 00196 // array format => read it 00197 // rgb or rgba 00198 ok = ( 1 <= nodeValue->getNumberOfSubItems() 00199 && nodeValue->getNumberOfSubItems() <= 3 ); 00200 if ( !ok && errorStr.empty() ) 00201 { 00202 errorStr = "Bad format of Transform (need 1 to 3 arguments)" ; 00203 } 00204 // get the 3 sub nodes for translation, rotation and scale 00205 const ConfigurationParameterDescriptor * translationNode = 00206 nodeValue->getSubDescriptorByPosition( 0 ) ; 00207 const ConfigurationParameterDescriptor * rotationNode = 00208 ( 2 <= nodeValue->getNumberOfSubItems() ) ? nodeValue->getSubDescriptorByPosition( 1 ) : 0 ; 00209 const ConfigurationParameterDescriptor * scaleNode = 00210 ( 3 == nodeValue->getNumberOfSubItems() ) ? nodeValue->getSubDescriptorByPosition( 2 ) : 0 ; 00211 00212 // Translation 00213 Wm4::Vector3f translation = Wm4::Vector3f::ZERO ; 00214 if( ok && translationNode ) 00215 { 00216 ok = 3 == translationNode->getNumberOfSubItems() ; 00217 float t[ 3 ] = { 0.0f, 0.0f, 0.0f } ; 00218 for ( int i = 0 ; i < 3 && ok ; i++ ) 00219 { 00220 ok = ok && getValue( translationNode->getSubDescriptorByPosition( i ), t[ i ], errorStr ) ; 00221 } 00222 if ( ok ) 00223 { 00224 transform.setTranslate( Wm4::Vector3f( t ) ) ; 00225 } 00226 else 00227 { 00228 errorStr += ". Cannot get one of the translation of the Transform argument" ; 00229 } 00230 } 00231 00232 // Rotation 00233 Wm4::Matrix3f rotation = Wm4::Matrix3f::IDENTITY ; 00234 if( ok && rotationNode ) 00235 { 00236 float rm[ 9 ] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f } ; 00237 // check for 3 or 9 items 00238 int nbItems = rotationNode->getNumberOfSubItems() ; 00239 ok = 9 == nbItems || 4 == nbItems || 3 == nbItems ; 00240 char angleType( 'r' ); 00241 if( 4 == nbItems ) 00242 { // The 4th flag is the type 00243 nbItems = 3 ; // only 3 numeric values 00244 getValue( rotationNode->getSubDescriptorByPosition( 3 ), angleType, errorStr ) ; 00245 } 00246 // gets the items value 00247 for ( int i = 0 ; i < nbItems && ok ; i++ ) 00248 { 00249 ok = ok && getValue( rotationNode->getSubDescriptorByPosition( i ), rm[ i ], errorStr ) ; 00250 } 00251 if( 9 == nbItems ) 00252 { // Rotation matrix 00253 if ( ok ) 00254 { 00255 rotation = Wm4::Matrix3f( rm, true ) ; // Row major 00256 transform.setRotate( rotation ) ; 00257 } 00258 else 00259 { 00260 errorStr += ". Cannot get one of the rotation matrix of the Transform argument" ; 00261 } 00262 } 00263 else if( 3 == nbItems ) 00264 { // Rotation angles Euler Radian 00265 if ( ok ) 00266 { 00267 switch( angleType ) 00268 { 00269 case 'r' : // Radian nothing to do 00270 break; 00271 case 'd' : // Degrees 00272 rm[ 0 ] *= Wm4::Mathf::DEG_TO_RAD ; 00273 rm[ 1 ] *= Wm4::Mathf::DEG_TO_RAD ; 00274 rm[ 2 ] *= Wm4::Mathf::DEG_TO_RAD ; 00275 break ; 00276 case 'g' : // Grad 00277 rm[ 0 ] *= Wm4::Mathf::DEG_TO_RAD * 0.9f ; 00278 rm[ 1 ] *= Wm4::Mathf::DEG_TO_RAD * 0.9f ; 00279 rm[ 2 ] *= Wm4::Mathf::DEG_TO_RAD * 0.9f ; 00280 break ; 00281 case 'p' : // Fraction of pi 00282 rm[ 0 ] *= Wm4::Mathf::PI ; 00283 rm[ 1 ] *= Wm4::Mathf::PI ; 00284 rm[ 2 ] *= Wm4::Mathf::PI ; 00285 break ; 00286 default : 00287 ok = false ; 00288 errorStr += "Unknow type of angle (only 'r', 'd', 'g' and 'p' are allowed)" ; 00289 } 00290 rotation.FromEulerAnglesXYZ( rm[ 0 ] , 00291 rm[ 1 ] , 00292 rm[ 2 ] ); // Euler angles 00293 transform.setRotate( rotation ) ; 00294 } 00295 else 00296 { 00297 errorStr += ". Cannot get one of the rotation Euler angle of the Transform argument" ; 00298 } 00299 } 00300 else 00301 { 00302 errorStr += "Cannot get the rotation of the Transform argument" ; 00303 } 00304 } 00305 00306 // Scale 00307 Wm4::Vector3f scale = Wm4::Vector3f::ONE ; 00308 if( ok && scaleNode ) 00309 { 00310 int nbItems = scaleNode->getNumberOfSubItems() ; 00311 ok = 1 == nbItems || 3 == nbItems ; 00312 float s[ 3 ] = { 1.0f, 1.0f, 1.0f } ; 00313 for ( int i = 0 ; i < nbItems && ok ; i++ ) 00314 { 00315 ok = ok && getValue( scaleNode->getSubDescriptorByPosition( i ), s[ i ], errorStr ) ; 00316 } 00317 if( 1 == nbItems ) 00318 { // Uniform scale 00319 if ( ok ) 00320 { 00321 transform.setUniformScale( s[ 0 ] ) ; 00322 } 00323 else 00324 { 00325 errorStr += ". Cannot get the uniform scale of the Transform argument" ; 00326 } 00327 } 00328 else if( 3 == nbItems ) 00329 { // No uniform scale 00330 if ( ok ) 00331 { 00332 transform.setScale( Wm4::Vector3f( s ) ) ; 00333 } 00334 else 00335 { 00336 errorStr += ". Cannot get one of the scale of the Transform argument" ; 00337 } 00338 } 00339 else 00340 { 00341 errorStr += "Cannot get the scale of the Transform argument" ; 00342 } 00343 } 00344 } 00345 else 00346 { 00347 ok = getTxtValue( nodeValue->getAssociatedString(), transform ) ; 00348 } 00349 transform.updateFlags() ; 00350 00351 // string format 00352 return ok ; 00353 } 00354 //------------------------------------------------------------------- 00355 ConfigurationParameterDescriptor *ParametersAccessor::setValue( const bool& value, 00356 std::string& errorStr ) 00357 { 00358 return new UniqueConfigurationParameter( value ? "true" : "false" ) ; 00359 } 00360 00361 //------------------------------------------------------------------- 00362 ConfigurationParameterDescriptor *ParametersAccessor::setValue( const OMK::Type::Color& color, 00363 std::string& errorStr ) 00364 { 00365 ConfigurationParameterDescriptor *node = new MultipleConfigurationParameter() ; 00366 bool ok = true ; 00367 std::string text ; 00368 ok = ok && setTxtValue( text, color.getR() ) ; 00369 if( ok ) node->appendSubDescriptor( new UniqueConfigurationParameter( text ) ) ; 00370 ok = ok && setTxtValue( text, color.getG() ) ; 00371 if( ok ) node->appendSubDescriptor( new UniqueConfigurationParameter( text ) ) ; 00372 ok = ok && setTxtValue( text, color.getB() ) ; 00373 if( ok ) node->appendSubDescriptor( new UniqueConfigurationParameter( text ) ) ; 00374 if( color.getA() != 1.0f ) 00375 { 00376 ok = ok && setTxtValue( text, color.getA() ) ; 00377 if( ok ) node->appendSubDescriptor( new UniqueConfigurationParameter( text ) ) ; 00378 } 00379 if( !ok ) 00380 { 00381 delete node ; 00382 node = 0 ; 00383 errorStr = "Unable to convert the color into a node" ; 00384 } 00385 return node ; 00386 } 00387 00388 //------------------------------------------------------------------- 00389 ConfigurationParameterDescriptor *ParametersAccessor::setValue( const OMK::Type::Transform& transf, 00390 std::string& errorStr ) 00391 { 00392 bool ok = true ; 00393 bool needScale = !transf.isUniformScale() || transf.getUniformScale() != 1.0f ; 00394 std::string text ; 00395 ConfigurationParameterDescriptor *node = new MultipleConfigurationParameter() ; 00396 // Translate 00397 { 00398 ConfigurationParameterDescriptor *translateNode = new MultipleConfigurationParameter() ; 00399 node->appendSubDescriptor( translateNode ) ; 00400 for( int i = 0 ; i < 3 ; i++ ) 00401 { 00402 ok = ok && setTxtValue( text, transf.getTranslate()[ i ] ) ; 00403 if( ok ) translateNode->appendSubDescriptor( new UniqueConfigurationParameter( text ) ) ; 00404 } 00405 } 00406 // Rotate 00407 if( ok && ( needScale || transf.getRotate() != Wm4::Matrix3f::IDENTITY ) ) 00408 { 00409 ConfigurationParameterDescriptor *rotateNode = new MultipleConfigurationParameter() ; 00410 node->appendSubDescriptor( rotateNode ) ; 00411 for( int r = 0 ; r < 3 ; r++ ) 00412 { 00413 for( int c = 0 ; c < 3 ; c++ ) 00414 { 00415 ok = ok && setTxtValue( text, transf.getRotate()[r][c] ) ; 00416 if( ok ) rotateNode->appendSubDescriptor( new UniqueConfigurationParameter( text ) ) ; 00417 } 00418 } 00419 } 00420 // Scale 00421 if( ok && needScale ) 00422 { 00423 ConfigurationParameterDescriptor *scaleNode = new MultipleConfigurationParameter() ; 00424 node->appendSubDescriptor( scaleNode ) ; 00425 for( int i = 0 ; i < ( transf.isUniformScale() ? 1 : 3 ) ; i++ ) 00426 { 00427 ok = ok && setTxtValue( text, transf.getScale()[ i ] ) ; 00428 if( ok ) scaleNode->appendSubDescriptor( new UniqueConfigurationParameter( text ) ) ; 00429 } 00430 } 00431 // ok ? 00432 if( !ok ) 00433 { 00434 errorStr = "Unable to convert the tranform into a node" ; 00435 delete node ; 00436 node = 0 ; 00437 } 00438 return node ; 00439 } 00440 //------------------------------------------------------------------- 00441 ConfigurationParameterDescriptor * ParametersAccessor::set( 00442 ConfigurationParameterDescriptor *& node, 00443 const std::string& name, 00444 ConfigurationParameterDescriptor * newNode ) 00445 { 00446 if( newNode ) 00447 { 00448 if( !node ) node = new MultipleConfigurationParameter() ; 00449 node->appendSubDescriptorNamed( name, newNode ) ; 00450 } 00451 else 00452 { 00453 OMERROR( "Warning in ParametersAccessor::Set with parameter [" + name + "]" << std::endl 00454 << ">>> :-( The node to append is null" ) ; 00455 } 00456 return newNode ; 00457 }
Documentation generated on Mon Jun 9 11:45:57 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |