]> SALOME platform Git repositories - modules/geom.git/blobdiff - src/Material/Material_Model.cxx
Salome HOME
Merge from V6_main 11/02/2013
[modules/geom.git] / src / Material / Material_Model.cxx
index 9744571c5e395b63572288d004b20d4ff3d0c532..949d7d2b0a131b60048ca59bba95c705579702f6 100644 (file)
@@ -25,6 +25,8 @@
 #include "GEOM_VTKPropertyMaterial.hxx"
 #include "Material_ResourceMgr.h"
 
+#include <QMutexLocker>
+
 /*!
   \brief Constructor
 
@@ -78,21 +80,36 @@ void Material_Model::fromProperties( const QString& props )
     else if ( key == "emissivecolor" && Qtx::stringToColor( data, colorValue ) ) {
       setColor( Emissive, colorValue );
     }
-    else if ( key == "ambientcoefficient" && dblOk ) {
+    else if ( key == "frontambientcoefficient" && dblOk ) {
       setReflection( Ambient, dblValue );
     }
-    else if ( key == "diffusecoefficient" && dblOk ) {
+    else if ( key == "backambientcoefficient" && dblOk ) {
+      setReflection( Ambient, dblValue, false );
+    }
+    else if ( key == "frontdiffusecoefficient" && dblOk ) {
       setReflection( Diffuse, dblValue );
     }
-    else if ( key == "specularcoefficient" && dblOk ) {
+    else if ( key == "backdiffusecoefficient" && dblOk ) {
+      setReflection( Diffuse, dblValue, false );
+    }
+    else if ( key == "frontspecularcoefficient" && dblOk ) {
       setReflection( Specular, dblValue );
     }
-    else if ( key == "emissivecoefficient" && dblOk ) {
+    else if ( key == "backspecularcoefficient" && dblOk ) {
+      setReflection( Specular, dblValue, false );
+    }
+    else if ( key == "frontemissivecoefficient" && dblOk ) {
       setReflection( Emissive, dblValue );
     }
-    else if ( key == "shininess" && dblOk ) {
+    else if ( key == "backemissivecoefficient" && dblOk ) {
+      setReflection( Emissive, dblValue, false );
+    }
+    else if ( key == "frontshininess" && dblOk ) {
       setShininess( dblValue );
     }
+    else if ( key == "backshininess" && dblOk ) {
+      setShininess( dblValue, false );
+    }
     else if ( key == "transparency" && dblOk ) {
       setTransparency( dblValue );
     }
@@ -128,7 +145,7 @@ QString Material_Model::toProperties()
   props << fmt.arg( "Physical" ).arg( isPhysical() );
 
   // shininess
-  props << fmt.arg( "Shininess" ).arg( shininess() );
+  props << fmt.arg( "FrontShininess" ).arg( QString::number ( shininess( true ), 'g', 4 ) ) << fmt.arg( "BackShininess" ).arg( QString::number ( shininess( false ), 'g', 4 ) );
 
   //transparency
   props << fmt.arg( "Transparency" ).arg( transparency() );
@@ -137,25 +154,25 @@ QString Material_Model::toProperties()
   props << fmt.arg( "Ambient" ).arg( hasReflection( Ambient ) );
   if ( color( Ambient ).isValid() )
     props << fmt.arg( "AmbientColor" ).arg( Qtx::colorToString( color( Ambient ) ) );
-  props << fmt.arg( "AmbientCoefficient" ).arg( reflection( Ambient ) );
+  props << fmt.arg( "FrontAmbientCoefficient" ).arg( QString::number ( reflection( Ambient, true ), 'g', 4 ) ) << fmt.arg( "BackAmbientCoefficient" ).arg( QString::number ( reflection( Ambient, false ), 'g', 4 ) );
 
   // diffuse reflection
   props << fmt.arg( "Diffuse" ).arg( hasReflection( Diffuse ) );
   if ( color( Diffuse ).isValid() )
     props << fmt.arg( "DiffuseColor" ).arg( Qtx::colorToString( color( Diffuse ) ) );
-  props << fmt.arg( "DiffuseCoefficient" ).arg( reflection( Diffuse ) );
+  props << fmt.arg( "FrontDiffuseCoefficient" ).arg( QString::number ( reflection( Diffuse, true ), 'g', 4 ) ) << fmt.arg( "BackDiffuseCoefficient" ).arg( QString::number ( reflection( Diffuse, false ), 'g', 4 ) );
 
   // specular reflection
   props << fmt.arg( "Specular" ).arg( hasReflection( Specular ) );
   if ( color( Specular ).isValid() )
     props << fmt.arg( "SpecularColor" ).arg( Qtx::colorToString( color( Specular ) ) );
-  props << fmt.arg( "SpecularCoefficient" ).arg( reflection( Specular ) );
+  props << fmt.arg( "FrontSpecularCoefficient" ).arg( QString::number ( reflection( Specular, true ), 'g', 4 ) ) << fmt.arg( "BackSpecularCoefficient" ).arg( QString::number ( reflection( Specular, false ), 'g', 4 ) );
 
   // emissive reflection
   props << fmt.arg( "Emissive" ).arg( hasReflection( Emissive ) );
   if ( color( Emissive ).isValid() )
     props << fmt.arg( "EmissiveColor" ).arg( Qtx::colorToString( color( Emissive ) ) );
-  props << fmt.arg( "EmissiveCoefficient" ).arg( reflection( Emissive ) );
+  props << fmt.arg( "FrontEmissiveCoefficient" ).arg( QString::number ( reflection( Emissive, true ), 'g', 4 ) ) << fmt.arg( "BackEmissiveCoefficient" ).arg( QString::number ( reflection( Emissive, false ), 'g', 4 ) );
 
   return props.join( ":" );
 }
@@ -169,7 +186,7 @@ QString Material_Model::toProperties()
   \param resMgr resource manager (if not specified, new resources manager is created)
   \sa toResources()
 */
-void Material_Model::fromResources( const QString& material, QtxResourceMgr* resMgr )
+void Material_Model::fromResources( const QString& material, Material_ResourceMgr* resMgr )
 {
   static QString common = "[common]";
   
@@ -179,23 +196,33 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res
   // material name is not specified: use default values
   if ( material.isEmpty() ) return;
 
-  bool ownResourcesMgr = resMgr == 0;
-  
-  if ( ownResourcesMgr )
-    resMgr = new Material_ResourceMgr();
+  if ( !resMgr )
+    resMgr = Material_ResourceMgr::resourceMgr();
+
+  // lock resources manager
+  QMutexLocker lock( &resMgr->myMutex );
 
   // read common section
   if ( material != common && resMgr->hasSection( common ) )
-    fromResources( common, resMgr );
+    read( common, resMgr );
+
+  // read material section
+  read( material, resMgr );
+}
 
+void Material_Model::read( const QString& material, Material_ResourceMgr* resMgr )
+{
   // physical
   if ( resMgr->hasValue( material, "physical" ) ) {
     setPhysical( resMgr->booleanValue( material, "physical" ) );
   }
 
   // shininess
-  if ( resMgr->hasValue( material, "shininess" ) ) {
-    setShininess( resMgr->doubleValue( material, "shininess" ) );
+  if ( resMgr->hasValue( material, "front_shininess" ) ) {
+    setShininess( resMgr->doubleValue( material, "front_shininess" ) );
+  }
+  if ( resMgr->hasValue( material, "back_shininess" ) ) {
+    setShininess( resMgr->doubleValue( material, "back_shininess" ), false );
   }
 
   // transparency
@@ -207,8 +234,11 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res
   if ( resMgr->hasValue( material, "ambient-color" ) ) {
     setColor( Ambient, resMgr->colorValue( material, "ambient-color" ) );
   }
-  if ( resMgr->hasValue( material, "ambient-coefficient" ) ) {
-    setReflection( Ambient, resMgr->doubleValue( material, "ambient-coefficient" ) );
+  if ( resMgr->hasValue( material, "front_ambient-coefficient" ) ) {
+    setReflection( Ambient, resMgr->doubleValue( material, "front_ambient-coefficient" ) );
+  }
+  if ( resMgr->hasValue( material, "back_ambient-coefficient" ) ) {
+    setReflection( Ambient, resMgr->doubleValue( material, "back_ambient-coefficient" ), false );
   }
   if ( resMgr->hasValue( material, "ambient" ) ) {
     setReflection( Ambient, resMgr->booleanValue( material, "ambient" ) );
@@ -218,8 +248,11 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res
   if ( resMgr->hasValue( material, "diffuse-color" ) ) {
     setColor( Diffuse, resMgr->colorValue( material, "diffuse-color" ) );
   }
-  if ( resMgr->hasValue( material, "diffuse-coefficient" ) ) {
-    setReflection( Diffuse, resMgr->doubleValue( material, "diffuse-coefficient" ) );
+  if ( resMgr->hasValue( material, "front_diffuse-coefficient" ) ) {
+    setReflection( Diffuse, resMgr->doubleValue( material, "front_diffuse-coefficient" ) );
+  }
+  if ( resMgr->hasValue( material, "back_diffuse-coefficient" ) ) {
+    setReflection( Diffuse, resMgr->doubleValue( material, "back_diffuse-coefficient" ), false );
   }
   if ( resMgr->hasValue( material, "diffuse" ) ) {
     setReflection( Diffuse, resMgr->booleanValue( material, "diffuse" ) );
@@ -229,8 +262,11 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res
   if ( resMgr->hasValue( material, "specular-color" ) ) {
     setColor( Specular, resMgr->colorValue( material, "specular-color" ) );
   }
-  if ( resMgr->hasValue( material, "specular-coefficient" ) ) {
-    setReflection( Specular, resMgr->doubleValue( material, "specular-coefficient" ) );
+  if ( resMgr->hasValue( material, "front_specular-coefficient" ) ) {
+    setReflection( Specular, resMgr->doubleValue( material, "front_specular-coefficient" ) );
+  }
+  if ( resMgr->hasValue( material, "back_specular-coefficient" ) ) {
+    setReflection( Specular, resMgr->doubleValue( material, "back_specular-coefficient" ), false );
   }
   if ( resMgr->hasValue( material, "specular" ) ) {
     setReflection( Specular, resMgr->booleanValue( material, "specular" ) );
@@ -240,15 +276,15 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res
   if ( resMgr->hasValue( material, "emissive-color" ) ) {
     setColor( Emissive, resMgr->colorValue( material, "emissive-color" ) );
   }
-  if ( resMgr->hasValue( material, "emissive-coefficient" ) ) {
-    setReflection( Emissive, resMgr->doubleValue( material, "emissive-coefficient" ) );
+  if ( resMgr->hasValue( material, "front_emissive-coefficient" ) ) {
+    setReflection( Emissive, resMgr->doubleValue( material, "front_emissive-coefficient" ) );
+  }
+  if ( resMgr->hasValue( material, "back_emissive-coefficient" ) ) {
+    setReflection( Emissive, resMgr->doubleValue( material, "back_emissive-coefficient" ), false );
   }
   if ( resMgr->hasValue( material, "emissive" ) ) {
     setReflection( Emissive, resMgr->booleanValue( material, "emissive" ) );
   }
-
-  if ( ownResourcesMgr )
-    delete resMgr;
 }
 
 /*!
@@ -257,9 +293,12 @@ void Material_Model::fromResources( const QString& material, QtxResourceMgr* res
   \param resMgr resource manager
   \sa fromResources()
 */
-void Material_Model::toResources( const QString& material, QtxResourceMgr* resMgr )
+void Material_Model::toResources( const QString& material, Material_ResourceMgr* resMgr )
 {
   if ( resMgr && !material.isEmpty() ) {
+    // lock resources manager
+    QMutexLocker lock( &resMgr->myMutex );
+  
     // remove resources section (to clean-up all previous properties)
     resMgr->remove( material );
 
@@ -267,7 +306,8 @@ void Material_Model::toResources( const QString& material, QtxResourceMgr* resMg
     resMgr->setValue( material, "physical", isPhysical() );
 
     // shininess
-    resMgr->setValue( material, "shininess", shininess() );
+    resMgr->setValue( material, "front_shininess", shininess( true) );
+    resMgr->setValue( material, "back_shininess", shininess( false ) );
 
     // transparency
     resMgr->setValue( material, "transparency", transparency() );
@@ -275,46 +315,33 @@ void Material_Model::toResources( const QString& material, QtxResourceMgr* resMg
     // ambient reflection
     if ( color( Ambient ).isValid() )
       resMgr->setValue( material, "ambient-color", color( Ambient ) );
-    resMgr->setValue( material, "ambient-coefficient", reflection( Ambient ) );
+    resMgr->setValue( material, "front_ambient-coefficient", reflection( Ambient ) );
+    resMgr->setValue( material, "back_ambient-coefficient", reflection( Ambient, false ) );
     resMgr->setValue( material, "ambient", hasReflection( Ambient ) );
 
     // diffuse reflection
     if ( color( Diffuse ).isValid() )
       resMgr->setValue( material, "diffuse-color", color( Diffuse ) );
-    resMgr->setValue( material, "diffuse-coefficient", reflection( Diffuse ) );
+    resMgr->setValue( material, "front_diffuse-coefficient", reflection( Diffuse ) );
+    resMgr->setValue( material, "back_diffuse-coefficient", reflection( Diffuse, false ) );
     resMgr->setValue( material, "diffuse", hasReflection( Diffuse ) );
 
     // Specular reflection
     if ( color( Specular ).isValid() )
       resMgr->setValue( material, "specular-color", color( Specular ) );
-    resMgr->setValue( material, "specular-coefficient", reflection( Specular ) );
+    resMgr->setValue( material, "front_specular-coefficient", reflection( Specular ) );
+    resMgr->setValue( material, "back_specular-coefficient", reflection( Specular, false ) );
     resMgr->setValue( material, "specular", hasReflection( Specular ) );
 
     // Emissive reflection
     if ( color( Emissive ).isValid() )
       resMgr->setValue( material, "emissive-color", color( Emissive ) );
-    resMgr->setValue( material, "emissive-coefficient", reflection( Emissive ) );
+    resMgr->setValue( material, "front_emissive-coefficient", reflection( Emissive ) );
+    resMgr->setValue( material, "back_emissive-coefficient", reflection( Emissive, false ) );
     resMgr->setValue( material, "emissive", hasReflection( Emissive ) );
   }
 }
 
-/*!
-  \brief Initialize material model from the preferences
-
-  The material name is retrieved from the "material" parameter of the "Geometry" section
-  of the specified resources manager.
-
-  \param resMgr resources manager
-  \sa fromResources(), toResources()
-*/
-// void Material_Model::fromPreferences( QtxResourceMgr* resMgr )
-// {
-//   if ( resMgr ) {
-//     // default material is Plastic
-//     fromResources( resMgr->stringValue( "Geometry", "material", "Plastic" ) );
-//   }
-// }
-
 /*!
   \brief Get material type
   \return \c true if material is physical or \c false otherwise
@@ -390,14 +417,18 @@ void Material_Model::setColor( ReflectionType type, const QColor& value )
 /*!
   \brief Get coefficient value for the given reflection type
   \param type reflection type
+  \param theIsFront boolean flag for choosing side
   \return coefficient value for the specified reflection type
-  \sa setReflection(ReflectionType, double)
+  \sa setReflection(ReflectionType, double, bool = true)
 */
-double Material_Model::reflection( ReflectionType type ) const
+double Material_Model::reflection( ReflectionType type, bool theIsFront ) const
 {
   double value = 0.0;
   if ( type >= 0 && type < 4 )
-    value = myReflection[ type ].coef;
+    if ( theIsFront )
+      value = myReflection[ type ].front_coef;
+    else
+      value = myReflection[ type ].back_coef;
   return value;
 }
 
@@ -405,32 +436,44 @@ double Material_Model::reflection( ReflectionType type ) const
   \brief Set coefficient value for the given reflection type
   \param type reflection type
   \param value coefficient to be used by the given reflection type
-  \sa reflection()
+  \param theIsFront boolean flag for choosing side
+  \sa reflection( bool = true)
 */
-void Material_Model::setReflection( ReflectionType type, double value )
+void Material_Model::setReflection( ReflectionType type, double value, bool theIsFront )
 {
   if ( type >= 0 && type < 4 )
-    myReflection[ type ].coef = value;
+    if ( theIsFront )
+      myReflection[ type ].front_coef = value;
+    else
+      myReflection[ type ].back_coef = value;
 }
 
 /*!
   \brief Get shininess value
+  \param theIsFront boolean flag for choosing side
   \return shininess value of the material
-  \sa setShininess()
+  \sa setShininess( double, bool = true )
 */
-double Material_Model::shininess() const
+double Material_Model::shininess( bool theIsFront ) const
 {
-  return myShininess;
+  if ( theIsFront )
+    return myFrontShininess;
+  else
+    return myBackShininess;
 }
 
 /*!
   \brief Set shininess value
   \param value new shininess value
-  \sa shininess()
+  \param theIsFront boolean flag for choosing side
+  \sa shininess( bool = true )
 */
-void Material_Model::setShininess( double value )
+void Material_Model::setShininess( double value, bool theIsFront )
 {
-  myShininess = value;
+  if ( theIsFront )
+    myFrontShininess = value;
+  else
+    myBackShininess = value;
 }
 
 /*!
@@ -464,39 +507,45 @@ void Material_Model::init()
   setPhysical( false );
   // shininess
   setShininess( 0.039 );
+  setShininess( 0.039, false );
   // transparency
   setTransparency( 0.0 );
 
   // ambient reflection (enabled by default)
   Qtx::stringToColor( "#333333", c );
   setColor( Ambient, c );
-  setReflection( Ambient, 0.3 );
+  setReflection( Ambient, 0.3, true );
+  setReflection( Ambient, 0.3, false );
   setReflection( Ambient, true );
 
   // diffuse reflection (enabled by default)
   Qtx::stringToColor( "#000000", c );
   setColor( Diffuse, c );
   setReflection( Diffuse, 0.65 );
+  setReflection( Diffuse, 0.65, false );
   setReflection( Diffuse, true );
 
   // specular reflection (enabled by default)
   Qtx::stringToColor( "#ffffff", c );
   setColor( Specular, c );
-  setReflection( Specular, 0.0  );
+  setReflection( Specular, 0.0 );
+  setReflection( Specular, 0.0, false );
   setReflection( Specular, true );
 
   // emissive reflection (disabled by default)
   Qtx::stringToColor( "#000000", c );
   setColor( Emissive, c );
-  setReflection( Emissive, 0.0  );
+  setReflection( Emissive, 0.0 );
+  setReflection( Emissive, 0.0, false );
   setReflection( Emissive, false );
 }
 
 /*!
   \brief Construct OCCT material aspect from material model
+  \param theIsFront boolean flag for choosing side
   \return material aspect object with corresponding properties
 */
-Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
+Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect( bool theIsFront )
 {
   // Get material aspect from the current model
   Graphic3d_MaterialAspect aspect;
@@ -508,7 +557,7 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
     c = color( Ambient );
     aspect.SetAmbientColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
   }
-  aspect.SetAmbient( reflection( Ambient ));
+  aspect.SetAmbient( reflection( Ambient, theIsFront ));
   if ( hasReflection( Ambient ) )
     aspect.SetReflectionModeOn( Graphic3d_TOR_AMBIENT );
   else
@@ -519,7 +568,7 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
     c = color( Diffuse );
     aspect.SetDiffuseColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
   }
-  aspect.SetDiffuse( reflection( Diffuse ));
+  aspect.SetDiffuse( reflection( Diffuse, theIsFront ));
   if ( hasReflection( Diffuse ) )
     aspect.SetReflectionModeOn( Graphic3d_TOR_DIFFUSE );
   else
@@ -530,7 +579,7 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
     c = color( Specular );
     aspect.SetSpecularColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
   }
-  aspect.SetSpecular( reflection( Specular ));
+  aspect.SetSpecular( reflection( Specular, theIsFront ));
   if ( hasReflection( Specular ) )
     aspect.SetReflectionModeOn( Graphic3d_TOR_SPECULAR );
   else
@@ -541,14 +590,14 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
     c = color( Emissive );
     aspect.SetEmissiveColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
   }
-  aspect.SetEmissive( reflection( Emissive ));
+  aspect.SetEmissive( reflection( Emissive, theIsFront ));
   if ( hasReflection( Emissive ) )
     aspect.SetReflectionModeOn( Graphic3d_TOR_EMISSION );
   else
     aspect.SetReflectionModeOff( Graphic3d_TOR_EMISSION );
   
   // shininess
-  aspect.SetShininess( shininess() );
+  aspect.SetShininess( shininess( theIsFront ) );
 
   // transparency
   aspect.SetTransparency( transparency() );
@@ -561,9 +610,10 @@ Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
 
 /*!
   \brief Construct VTK property from material model
+  \param theIsFront boolean flag for choosing side
   \return VTK property with correspondent material properties
 */
-GEOM_VTKPropertyMaterial* Material_Model::getMaterialVTKProperty()
+GEOM_VTKPropertyMaterial* Material_Model::getMaterialVTKProperty( bool theIsFront )
 {
   // NOTE: In VTK it's impossible to switch on/off specific reflection type
   // NOTE: In VTK emissive reflection type is not supported
@@ -579,25 +629,25 @@ GEOM_VTKPropertyMaterial* Material_Model::getMaterialVTKProperty()
   if ( color( Ambient ).isValid() && hasReflection( Ambient ) ) {
     c = color( Ambient );
     prop->SetAmbientColor( c.redF(), c.greenF(), c.blueF() );
-    prop->SetAmbient( reflection( Ambient ) );
+    prop->SetAmbient( reflection( Ambient, theIsFront ) );
   }
 
   // diffuse reflection
   if ( color( Diffuse ).isValid() && hasReflection( Diffuse ) ) {
     c = color( Diffuse );
     prop->SetDiffuseColor( c.redF(), c.greenF(), c.blueF() );
-    prop->SetDiffuse( reflection( Diffuse ) );
+    prop->SetDiffuse( reflection( Diffuse, theIsFront ) );
   }
 
   // specular reflection
   if ( color( Specular ).isValid() && hasReflection( Specular ) ) {
     c = color( Specular );
     prop->SetSpecularColor( c.redF(), c.greenF(), c.blueF() );
-    prop->SetSpecular( reflection( Specular ) );
+    prop->SetSpecular( reflection( Specular, theIsFront ) );
   }
 
   // shininess
-  prop->SetSpecularPower( shininess()*100.0 );
+  prop->SetSpecularPower( shininess( theIsFront )*100.0 );
 
   // transparency
   prop->SetOpacity( 1 - transparency() );