Back to index

salome-geom  6.5.0
Material_Model.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 // File   : Material_Model.cxx
00021 // Author : Margarita KARPUNINA, Open CASCADE S.A.S. (margarita.karpunina@opencascade.com)
00022 //
00023 
00024 #include "Material_Model.h"
00025 #include "GEOM_VTKPropertyMaterial.hxx"
00026 #include "Material_ResourceMgr.h"
00027 
00033 Material_Model::Material_Model()
00034 {
00035   myReflection  = ReflectionList(4);
00036   init(); // set default properties
00037 }
00038 
00042 Material_Model::~Material_Model()
00043 {
00044 }
00045 
00051 void Material_Model::fromProperties( const QString& props )
00052 {
00053   // reset to default values
00054   init();
00055 
00056   // parse material properties
00057   QStringList propList = props.split( ":", QString::SkipEmptyParts );
00058   foreach ( QString prop, propList ) 
00059   {
00060     QStringList pdata = prop.split( "=" );
00061     if ( pdata.count() < 2 ) continue;
00062     QString key   = pdata[0].trimmed().toLower();
00063     QString data  = pdata[1].trimmed().toLower();
00064     bool dblOk, boolOk;
00065     double dblValue  = data.toDouble( &dblOk );
00066     bool   boolValue = (bool)( data.toInt( &boolOk ) );
00067     QColor colorValue;
00068     
00069     if      ( key == "ambientcolor" && Qtx::stringToColor( data, colorValue ) ) {
00070       setColor( Ambient, colorValue );
00071     }
00072     else if ( key == "diffusecolor" && Qtx::stringToColor( data, colorValue ) ) {
00073       setColor( Diffuse, colorValue );
00074     }
00075     else if ( key == "specularcolor" && Qtx::stringToColor( data, colorValue ) ) {
00076       setColor( Specular, colorValue );
00077     }
00078     else if ( key == "emissivecolor" && Qtx::stringToColor( data, colorValue ) ) {
00079       setColor( Emissive, colorValue );
00080     }
00081     else if ( key == "ambientcoefficient" && dblOk ) {
00082       setReflection( Ambient, dblValue );
00083     }
00084     else if ( key == "diffusecoefficient" && dblOk ) {
00085       setReflection( Diffuse, dblValue );
00086     }
00087     else if ( key == "specularcoefficient" && dblOk ) {
00088       setReflection( Specular, dblValue );
00089     }
00090     else if ( key == "emissivecoefficient" && dblOk ) {
00091       setReflection( Emissive, dblValue );
00092     }
00093     else if ( key == "shininess" && dblOk ) {
00094       setShininess( dblValue );
00095     }
00096     else if ( key == "transparency" && dblOk ) {
00097       setTransparency( dblValue );
00098     }
00099     else if ( key == "physical" && boolOk ) {
00100       setPhysical( boolValue );
00101     }
00102     else if ( key == "ambient" && boolOk ) {
00103       setReflection( Ambient, boolValue );
00104     }
00105     else if ( key == "diffuse" && boolOk ) {
00106       setReflection( Diffuse, boolValue );
00107     }
00108     else if ( key == "specular" && boolOk ) {
00109       setReflection( Specular, boolValue );
00110     }
00111     else if ( key == "emissive" && boolOk ) {
00112       setReflection( Emissive, boolValue );
00113     }
00114   }
00115 }
00116 
00122 QString Material_Model::toProperties()
00123 {
00124   QStringList props;
00125   QString fmt = "%1=%2";
00126 
00127   // physical
00128   props << fmt.arg( "Physical" ).arg( isPhysical() );
00129 
00130   // shininess
00131   props << fmt.arg( "Shininess" ).arg( shininess() );
00132 
00133   //transparency
00134   props << fmt.arg( "Transparency" ).arg( transparency() );
00135 
00136   // ambient reflection
00137   props << fmt.arg( "Ambient" ).arg( hasReflection( Ambient ) );
00138   if ( color( Ambient ).isValid() )
00139     props << fmt.arg( "AmbientColor" ).arg( Qtx::colorToString( color( Ambient ) ) );
00140   props << fmt.arg( "AmbientCoefficient" ).arg( reflection( Ambient ) );
00141 
00142   // diffuse reflection
00143   props << fmt.arg( "Diffuse" ).arg( hasReflection( Diffuse ) );
00144   if ( color( Diffuse ).isValid() )
00145     props << fmt.arg( "DiffuseColor" ).arg( Qtx::colorToString( color( Diffuse ) ) );
00146   props << fmt.arg( "DiffuseCoefficient" ).arg( reflection( Diffuse ) );
00147 
00148   // specular reflection
00149   props << fmt.arg( "Specular" ).arg( hasReflection( Specular ) );
00150   if ( color( Specular ).isValid() )
00151     props << fmt.arg( "SpecularColor" ).arg( Qtx::colorToString( color( Specular ) ) );
00152   props << fmt.arg( "SpecularCoefficient" ).arg( reflection( Specular ) );
00153 
00154   // emissive reflection
00155   props << fmt.arg( "Emissive" ).arg( hasReflection( Emissive ) );
00156   if ( color( Emissive ).isValid() )
00157     props << fmt.arg( "EmissiveColor" ).arg( Qtx::colorToString( color( Emissive ) ) );
00158   props << fmt.arg( "EmissiveCoefficient" ).arg( reflection( Emissive ) );
00159 
00160   return props.join( ":" );
00161 }
00162 
00172 void Material_Model::fromResources( const QString& material, QtxResourceMgr* resMgr )
00173 {
00174   static QString common = "[common]";
00175   
00176   // reset to default values
00177   init();
00178 
00179   // material name is not specified: use default values
00180   if ( material.isEmpty() ) return;
00181 
00182   bool ownResourcesMgr = resMgr == 0;
00183   
00184   if ( ownResourcesMgr )
00185     resMgr = new Material_ResourceMgr();
00186 
00187   // read common section
00188   if ( material != common && resMgr->hasSection( common ) )
00189     fromResources( common, resMgr );
00190 
00191   // physical
00192   if ( resMgr->hasValue( material, "physical" ) ) {
00193     setPhysical( resMgr->booleanValue( material, "physical" ) );
00194   }
00195 
00196   // shininess
00197   if ( resMgr->hasValue( material, "shininess" ) ) {
00198     setShininess( resMgr->doubleValue( material, "shininess" ) );
00199   }
00200 
00201   // transparency
00202   if ( resMgr->hasValue( material, "transparency" ) ) {
00203     setTransparency( resMgr->doubleValue( material, "transparency" ) );
00204   }
00205 
00206   // ambient reflection
00207   if ( resMgr->hasValue( material, "ambient-color" ) ) {
00208     setColor( Ambient, resMgr->colorValue( material, "ambient-color" ) );
00209   }
00210   if ( resMgr->hasValue( material, "ambient-coefficient" ) ) {
00211     setReflection( Ambient, resMgr->doubleValue( material, "ambient-coefficient" ) );
00212   }
00213   if ( resMgr->hasValue( material, "ambient" ) ) {
00214     setReflection( Ambient, resMgr->booleanValue( material, "ambient" ) );
00215   }
00216 
00217   // diffuse reflection
00218   if ( resMgr->hasValue( material, "diffuse-color" ) ) {
00219     setColor( Diffuse, resMgr->colorValue( material, "diffuse-color" ) );
00220   }
00221   if ( resMgr->hasValue( material, "diffuse-coefficient" ) ) {
00222     setReflection( Diffuse, resMgr->doubleValue( material, "diffuse-coefficient" ) );
00223   }
00224   if ( resMgr->hasValue( material, "diffuse" ) ) {
00225     setReflection( Diffuse, resMgr->booleanValue( material, "diffuse" ) );
00226   }
00227 
00228   // specular reflection
00229   if ( resMgr->hasValue( material, "specular-color" ) ) {
00230     setColor( Specular, resMgr->colorValue( material, "specular-color" ) );
00231   }
00232   if ( resMgr->hasValue( material, "specular-coefficient" ) ) {
00233     setReflection( Specular, resMgr->doubleValue( material, "specular-coefficient" ) );
00234   }
00235   if ( resMgr->hasValue( material, "specular" ) ) {
00236     setReflection( Specular, resMgr->booleanValue( material, "specular" ) );
00237   }
00238 
00239   // emissive reflection
00240   if ( resMgr->hasValue( material, "emissive-color" ) ) {
00241     setColor( Emissive, resMgr->colorValue( material, "emissive-color" ) );
00242   }
00243   if ( resMgr->hasValue( material, "emissive-coefficient" ) ) {
00244     setReflection( Emissive, resMgr->doubleValue( material, "emissive-coefficient" ) );
00245   }
00246   if ( resMgr->hasValue( material, "emissive" ) ) {
00247     setReflection( Emissive, resMgr->booleanValue( material, "emissive" ) );
00248   }
00249 
00250   if ( ownResourcesMgr )
00251     delete resMgr;
00252 }
00253 
00260 void Material_Model::toResources( const QString& material, QtxResourceMgr* resMgr )
00261 {
00262   if ( resMgr && !material.isEmpty() ) {
00263     // remove resources section (to clean-up all previous properties)
00264     resMgr->remove( material );
00265 
00266     // physical
00267     resMgr->setValue( material, "physical", isPhysical() );
00268 
00269     // shininess
00270     resMgr->setValue( material, "shininess", shininess() );
00271 
00272     // transparency
00273     resMgr->setValue( material, "transparency", transparency() );
00274 
00275     // ambient reflection
00276     if ( color( Ambient ).isValid() )
00277       resMgr->setValue( material, "ambient-color", color( Ambient ) );
00278     resMgr->setValue( material, "ambient-coefficient", reflection( Ambient ) );
00279     resMgr->setValue( material, "ambient", hasReflection( Ambient ) );
00280 
00281     // diffuse reflection
00282     if ( color( Diffuse ).isValid() )
00283       resMgr->setValue( material, "diffuse-color", color( Diffuse ) );
00284     resMgr->setValue( material, "diffuse-coefficient", reflection( Diffuse ) );
00285     resMgr->setValue( material, "diffuse", hasReflection( Diffuse ) );
00286 
00287     // Specular reflection
00288     if ( color( Specular ).isValid() )
00289       resMgr->setValue( material, "specular-color", color( Specular ) );
00290     resMgr->setValue( material, "specular-coefficient", reflection( Specular ) );
00291     resMgr->setValue( material, "specular", hasReflection( Specular ) );
00292 
00293     // Emissive reflection
00294     if ( color( Emissive ).isValid() )
00295       resMgr->setValue( material, "emissive-color", color( Emissive ) );
00296     resMgr->setValue( material, "emissive-coefficient", reflection( Emissive ) );
00297     resMgr->setValue( material, "emissive", hasReflection( Emissive ) );
00298   }
00299 }
00300 
00310 // void Material_Model::fromPreferences( QtxResourceMgr* resMgr )
00311 // {
00312 //   if ( resMgr ) {
00313 //     // default material is Plastic
00314 //     fromResources( resMgr->stringValue( "Geometry", "material", "Plastic" ) );
00315 //   }
00316 // }
00317 
00323 bool Material_Model::isPhysical() const
00324 {
00325   return myIsPhysical;
00326 }
00327 
00333 void Material_Model::setPhysical( bool value )
00334 {
00335   myIsPhysical = value;
00336 }
00337 
00344 bool Material_Model::hasReflection( ReflectionType type ) const
00345 {
00346   bool value = false;
00347   if ( type >= 0 && type < 4 )
00348     value = myReflection[ type ].enabled;
00349   return value;
00350 }
00351 
00358 void Material_Model::setReflection( ReflectionType type, bool value )
00359 {
00360   if ( type >= 0 && type < 4 )
00361     myReflection[ type ].enabled = value;
00362 }
00363 
00370 QColor Material_Model::color( ReflectionType type ) const
00371 {
00372   QColor value;
00373   if ( type >= 0 && type < 4 )
00374     value = myReflection[ type ].color;
00375   return value;
00376 }
00377 
00384 void Material_Model::setColor( ReflectionType type, const QColor& value )
00385 {
00386   if ( type >= 0 && type < 4 )
00387     myReflection[ type ].color = value;
00388 }
00389 
00396 double Material_Model::reflection( ReflectionType type ) const
00397 {
00398   double value = 0.0;
00399   if ( type >= 0 && type < 4 )
00400     value = myReflection[ type ].coef;
00401   return value;
00402 }
00403 
00410 void Material_Model::setReflection( ReflectionType type, double value )
00411 {
00412   if ( type >= 0 && type < 4 )
00413     myReflection[ type ].coef = value;
00414 }
00415 
00421 double Material_Model::shininess() const
00422 {
00423   return myShininess;
00424 }
00425 
00431 void Material_Model::setShininess( double value )
00432 {
00433   myShininess = value;
00434 }
00435 
00441 double Material_Model::transparency() const
00442 {
00443   return myTransparency;
00444 }
00445 
00451 void Material_Model::setTransparency( double value )
00452 {
00453   myTransparency = value;
00454 }
00455 
00459 void Material_Model::init()
00460 {  
00461   QColor c;
00462 
00463   // non-physical by default
00464   setPhysical( false );
00465   // shininess
00466   setShininess( 0.039 );
00467   // transparency
00468   setTransparency( 0.0 );
00469 
00470   // ambient reflection (enabled by default)
00471   Qtx::stringToColor( "#333333", c );
00472   setColor( Ambient, c );
00473   setReflection( Ambient, 0.3 );
00474   setReflection( Ambient, true );
00475 
00476   // diffuse reflection (enabled by default)
00477   Qtx::stringToColor( "#000000", c );
00478   setColor( Diffuse, c );
00479   setReflection( Diffuse, 0.65 );
00480   setReflection( Diffuse, true );
00481 
00482   // specular reflection (enabled by default)
00483   Qtx::stringToColor( "#ffffff", c );
00484   setColor( Specular, c );
00485   setReflection( Specular, 0.0  );
00486   setReflection( Specular, true );
00487 
00488   // emissive reflection (disabled by default)
00489   Qtx::stringToColor( "#000000", c );
00490   setColor( Emissive, c );
00491   setReflection( Emissive, 0.0  );
00492   setReflection( Emissive, false );
00493 }
00494 
00499 Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
00500 {
00501   // Get material aspect from the current model
00502   Graphic3d_MaterialAspect aspect;
00503 
00504   QColor c;
00505   
00506   // ambient reflection
00507   if ( color( Ambient ).isValid() ) {
00508     c = color( Ambient );
00509     aspect.SetAmbientColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
00510   }
00511   aspect.SetAmbient( reflection( Ambient ));
00512   if ( hasReflection( Ambient ) )
00513     aspect.SetReflectionModeOn( Graphic3d_TOR_AMBIENT );
00514   else
00515     aspect.SetReflectionModeOff( Graphic3d_TOR_AMBIENT );
00516   
00517   // diffuse reflection
00518   if ( color( Diffuse ).isValid() ) {
00519     c = color( Diffuse );
00520     aspect.SetDiffuseColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
00521   }
00522   aspect.SetDiffuse( reflection( Diffuse ));
00523   if ( hasReflection( Diffuse ) )
00524     aspect.SetReflectionModeOn( Graphic3d_TOR_DIFFUSE );
00525   else
00526     aspect.SetReflectionModeOff( Graphic3d_TOR_DIFFUSE );
00527 
00528   // specular reflection
00529   if ( color( Specular ).isValid() ) {
00530     c = color( Specular );
00531     aspect.SetSpecularColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
00532   }
00533   aspect.SetSpecular( reflection( Specular ));
00534   if ( hasReflection( Specular ) )
00535     aspect.SetReflectionModeOn( Graphic3d_TOR_SPECULAR );
00536   else
00537     aspect.SetReflectionModeOff( Graphic3d_TOR_SPECULAR );
00538 
00539   // emissive reflection
00540   if ( color( Emissive ).isValid() ) {
00541     c = color( Emissive );
00542     aspect.SetEmissiveColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
00543   }
00544   aspect.SetEmissive( reflection( Emissive ));
00545   if ( hasReflection( Emissive ) )
00546     aspect.SetReflectionModeOn( Graphic3d_TOR_EMISSION );
00547   else
00548     aspect.SetReflectionModeOff( Graphic3d_TOR_EMISSION );
00549   
00550   // shininess
00551   aspect.SetShininess( shininess() );
00552 
00553   // transparency
00554   aspect.SetTransparency( transparency() );
00555 
00556   // material type
00557   aspect.SetMaterialType( isPhysical() ? Graphic3d_MATERIAL_PHYSIC : Graphic3d_MATERIAL_ASPECT );
00558 
00559   return aspect;
00560 }
00561 
00566 GEOM_VTKPropertyMaterial* Material_Model::getMaterialVTKProperty()
00567 {
00568   // NOTE: In VTK it's impossible to switch on/off specific reflection type
00569   // NOTE: In VTK emissive reflection type is not supported
00570   // NOTE: In VTK shininess is specified via SpecularPower attribute
00571   // NOTE: In VTK transparency is specified via Opacity attribute
00572 
00573   // Get material properties from the current model
00574   GEOM_VTKPropertyMaterial* prop = GEOM_VTKPropertyMaterial::New();
00575 
00576   QColor c;
00577 
00578   // ambient reflection
00579   if ( color( Ambient ).isValid() && hasReflection( Ambient ) ) {
00580     c = color( Ambient );
00581     prop->SetAmbientColor( c.redF(), c.greenF(), c.blueF() );
00582     prop->SetAmbient( reflection( Ambient ) );
00583   }
00584 
00585   // diffuse reflection
00586   if ( color( Diffuse ).isValid() && hasReflection( Diffuse ) ) {
00587     c = color( Diffuse );
00588     prop->SetDiffuseColor( c.redF(), c.greenF(), c.blueF() );
00589     prop->SetDiffuse( reflection( Diffuse ) );
00590   }
00591 
00592   // specular reflection
00593   if ( color( Specular ).isValid() && hasReflection( Specular ) ) {
00594     c = color( Specular );
00595     prop->SetSpecularColor( c.redF(), c.greenF(), c.blueF() );
00596     prop->SetSpecular( reflection( Specular ) );
00597   }
00598 
00599   // shininess
00600   prop->SetSpecularPower( shininess()*100.0 );
00601 
00602   // transparency
00603   prop->SetOpacity( 1 - transparency() );
00604 
00605   // material type
00606   prop->SetPhysical( isPhysical() );
00607 
00608   return prop;
00609 }
00610