OMKParametersAccessor.cpp

Go to the documentation of this file.
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 }

logo OpenMask

Documentation generated on Mon Jun 9 11:45:57 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007