1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : Material_Model.cxx
21 // Author : Margarita KARPUNINA, Open CASCADE S.A.S. (margarita.karpunina@opencascade.com)
24 #include "Material_Model.h"
25 #include "Material_ResourceMgr.h"
27 #include <GEOM_Constants.h>
29 #include <QtxResourceMgr.h>
30 #include <SUIT_ResourceMgr.h>
31 #include <SUIT_Session.h>
34 #include <Graphic3d_AspectFillArea3d.hxx>
37 #include <vtkProperty.h>
42 Create new SALOME material model with default properties.
44 Material_Model::Material_Model()
53 Material_Model::~Material_Model()
58 \brief Construct material model according to the given list of
61 \param theProps the list of material properties
62 \return material model object with correspondent properties
63 \sa getMaterialProperty()
65 Material_Model* Material_Model::getMaterialModel( QStringList theProps )
67 Material_Model* aModel = new Material_Model();
69 foreach ( QString aProp, theProps ) {
70 if ( aProp.isNull() ) continue;
72 // Set current ambient color
73 aModel->setColor( aProp, "AmbientColor=", Material_Model::Ambient );
74 // Set current ambient coefficient
75 aModel->setCoefficient( aProp, "AmbientCoefficient=", Material_Model::Ambient );
77 // Set current diffuse color
78 aModel->setColor( aProp, "DiffuseColor=", Material_Model::Diffuse );
79 // Set current diffuse coefficient
80 aModel->setCoefficient( aProp, "DiffuseCoefficient=", Material_Model::Diffuse );
82 // Set current specular color
83 aModel->setColor( aProp, "SpecularColor=", Material_Model::Specular );
84 // Set current specular coefficient
85 aModel->setCoefficient( aProp, "SpecularCoefficient=", Material_Model::Specular );
87 // Set current emission color
88 aModel->setColor( aProp, "EmissionColor=", Material_Model::Emission );
89 // Set current emission coefficient
90 aModel->setCoefficient( aProp, "EmissionCoefficient=", Material_Model::Emission );
92 // Set current shininess
93 QString aPropName = "Shininess=";
94 int anId = aProp.indexOf(aPropName);
97 double aCoef = aProp.right( aProp.length() - (anId+aPropName.length()) ).toDouble(&ok);
99 aModel->setShininess( aCoef );
107 \brief Construct string of material properties for this model object
109 \return a string representing a set of material properties
110 \sa getMaterialModel()
112 QString Material_Model::getMaterialProperty()
114 // Parse material properties of the current model and form a string for persistent purpose
117 bool isReflectionTypeActive;
121 // Ambient reflection
122 isReflectionTypeActive = hasAmbientReflection();
123 if ( isReflectionTypeActive ) {
124 c = color( Material_Model::Ambient );
125 coef = coefficient(Material_Model::Ambient);
126 // Insert properties into persistent string
127 aMaterial = "AmbientColor=%1%2AmbientCoefficient=%3";
128 aMaterial = aMaterial.arg( Qtx::colorToString(c) );
129 aMaterial = aMaterial.arg( DIGIT_SEPARATOR );
130 aMaterial = aMaterial.arg( coef );
132 // Diffuse reflection
133 isReflectionTypeActive = hasDiffuseReflection();
134 if ( isReflectionTypeActive ) {
135 c = color( Material_Model::Diffuse );
136 coef = coefficient(Material_Model::Diffuse);
137 // Insert properties into persistent string
138 aMaterial += "%1DiffuseColor=%2%3DiffuseCoefficient=%4";
139 aMaterial = aMaterial.arg( DIGIT_SEPARATOR );
140 aMaterial = aMaterial.arg( Qtx::colorToString(c) );
141 aMaterial = aMaterial.arg( DIGIT_SEPARATOR );
142 aMaterial = aMaterial.arg( coef );
144 // Specular reflection
145 isReflectionTypeActive = hasSpecularReflection();
146 if ( isReflectionTypeActive ) {
147 c = color( Material_Model::Specular );
148 coef = coefficient(Material_Model::Specular);
149 // Insert properties into persistent string
150 aMaterial += "%1SpecularColor=%2%3SpecularCoefficient=%4";
151 aMaterial = aMaterial.arg( DIGIT_SEPARATOR );
152 aMaterial = aMaterial.arg( Qtx::colorToString(c) );
153 aMaterial = aMaterial.arg( DIGIT_SEPARATOR );
154 aMaterial = aMaterial.arg( coef );
156 // Emission reflection
157 isReflectionTypeActive = hasEmissionReflection();
158 if ( isReflectionTypeActive ) {
159 c = color( Material_Model::Emission );
160 coef = coefficient(Material_Model::Emission);
161 // Insert properties into persistent string
162 aMaterial += "%1EmissionColor=%2%3EmissionCoefficient=%4";
163 aMaterial = aMaterial.arg( DIGIT_SEPARATOR );
164 aMaterial = aMaterial.arg( Qtx::colorToString(c) );
165 aMaterial = aMaterial.arg( DIGIT_SEPARATOR );
166 aMaterial = aMaterial.arg( coef );
168 if ( !aMaterial.isEmpty() ) {
170 // Insert properties into persistent string
171 aMaterial += "%1Shininess=%2";
172 aMaterial = aMaterial.arg( DIGIT_SEPARATOR );
173 aMaterial = aMaterial.arg( shininess() );
180 \brief Construct OCCT material aspect object based on the current model
182 \return material aspect object with correspondent properties
184 Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
186 // Get material aspect from the current model
187 Graphic3d_MaterialAspect aMat;
189 bool isReflectionTypeActive;
193 // Ambient reflection
194 isReflectionTypeActive = hasAmbientReflection();
195 if ( isReflectionTypeActive ) {
196 aMat.SetReflectionModeOn( Graphic3d_TOR_AMBIENT );
197 c = color( Material_Model::Ambient );
198 aMat.SetAmbientColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
199 coef = coefficient( Material_Model::Ambient );
200 aMat.SetAmbient( coef );
202 // Diffuse reflection
203 isReflectionTypeActive = hasDiffuseReflection();
204 if ( isReflectionTypeActive ) {
205 aMat.SetReflectionModeOn( Graphic3d_TOR_DIFFUSE );
206 c = color( Material_Model::Diffuse );
207 aMat.SetDiffuseColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
208 coef = coefficient( Material_Model::Diffuse );
209 aMat.SetDiffuse( coef );
211 // Specular reflection
212 isReflectionTypeActive = hasSpecularReflection();
213 if ( isReflectionTypeActive ) {
214 aMat.SetReflectionModeOn( Graphic3d_TOR_SPECULAR );
215 c = color( Material_Model::Specular );
216 aMat.SetSpecularColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
217 coef = coefficient( Material_Model::Specular );
218 aMat.SetSpecular( coef );
220 // Emission reflection
221 isReflectionTypeActive = hasEmissionReflection();
222 if ( isReflectionTypeActive ) {
223 aMat.SetReflectionModeOn( Graphic3d_TOR_EMISSION );
224 c = color( Material_Model::Emission );
225 aMat.SetEmissiveColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
226 coef = coefficient( Material_Model::Emission );
227 aMat.SetEmissive( coef );
230 aMat.SetShininess( shininess() );
236 \brief Construct VTK property with properties of material based on the current model
238 \return VTK property with correspondent material properties
240 vtkProperty* Material_Model::getMaterialVTKProperty()
242 // Get material properties from the current model
243 vtkProperty* aProperty = vtkProperty::New();
245 bool isReflectionTypeActive;
249 // Ambient reflection
250 isReflectionTypeActive = hasAmbientReflection();
251 if ( isReflectionTypeActive ) {
252 c = color( Material_Model::Ambient );
253 aProperty->SetAmbientColor( c.redF(), c.greenF(), c.blueF() ); //SalomeApp_Tools::color( c )
254 coef = coefficient( Material_Model::Ambient );
255 aProperty->SetAmbient( coef );
257 // Diffuse reflection
258 isReflectionTypeActive = hasDiffuseReflection();
259 if ( isReflectionTypeActive ) {
260 c = color( Material_Model::Diffuse );
261 aProperty->SetDiffuseColor( c.redF(), c.greenF(), c.blueF() );
262 coef = coefficient( Material_Model::Diffuse );
263 aProperty->SetDiffuse( coef );
265 // Specular reflection
266 isReflectionTypeActive = hasSpecularReflection();
267 if ( isReflectionTypeActive ) {
268 c = color( Material_Model::Specular );
269 aProperty->SetSpecularColor( c.redF(), c.greenF(), c.blueF() );
270 coef = coefficient( Material_Model::Specular );
271 aProperty->SetSpecular( coef );
274 aProperty->SetSpecularPower( shininess()*100.0 );
280 \brief Initialize material model with default values
282 void Material_Model::initDefaults()
284 // Set default ambient color
285 setColor( Ambient, "#333333" );
286 // Set default ambient coefficient
287 setCoefficient( Ambient, 0.3 );
289 // Set default diffuse color
290 setColor( Diffuse, "#000000" );
291 // Set default diffuse coefficient
292 setCoefficient( Diffuse, 0.65 );
294 // Set default specular color
295 setColor( Specular, "#ffffff" );
296 // Set default specular coefficient
297 setCoefficient( Specular, 0.0 );
299 // Set default shininess
300 setShininess( 0.039 );
304 \brief Clear current content of this material model
306 void Material_Model::clearModel()
309 myCoefficients.clear();
314 \brief Initialize material model from the resources
316 This function can be used to retrieve material properties from the resource file(s).
317 Note, that paremeters \a theResMgr and \a theResSection are stored by the model to be used
318 later with save() method.
320 \param theResMgr resources manager
321 \param theResSection resources section name
324 void Material_Model::fromResources( QtxResourceMgr* theResMgr,
325 const QString& theResSection,
328 // Clear current content of the model
329 // before setting properties from resources
332 myResourceMgr = theResMgr;
333 myResourceSection = theResSection;
335 // init from resource manager
336 if ( !resourceMgr() )
339 if ( theResSection.compare( "Geometry" ) == 0 ) {
341 myResourceSection = theResMgr->stringValue("Geometry", "front_material", "Gold");
344 myResourceSection = theResMgr->stringValue("Geometry", "back_material", "");
345 if ( myResourceSection.isEmpty() )
346 myResourceSection = theResMgr->stringValue("Geometry", "front_material", "Gold");
349 myResourceMgr = new Material_ResourceMgr();
352 QString section = resourceSection( theIsFront );
354 // If there is no material preference in XML files,
355 // use the default material hardcoded in material model
356 if ( section.isEmpty() ) {
362 if ( resourceMgr()->hasValue( section, "ambient-color" ) ) {
363 setColor( Ambient, resourceMgr()->colorValue( section, "ambient-color" ) );
365 // Set ambient coefficient
366 if ( resourceMgr()->hasValue( section, "ambient-coefficient" ) ) {
367 setCoefficient( Ambient, resourceMgr()->doubleValue( section, "ambient-coefficient" ) );
371 if ( resourceMgr()->hasValue( section, "diffuse-color" ) ) {
372 setColor( Diffuse, resourceMgr()->colorValue( section, "diffuse-color" ) );
374 // Set diffuse coefficient
375 if ( resourceMgr()->hasValue( section, "diffuse-coefficient" ) ) {
376 setCoefficient( Diffuse, resourceMgr()->doubleValue( section, "diffuse-coefficient" ) );
379 // Set specular color
380 if ( resourceMgr()->hasValue( section, "specular-color" ) ) {
381 setColor( Specular, resourceMgr()->colorValue( section, "specular-color" ) );
383 // Set specular coefficient
384 if ( resourceMgr()->hasValue( section, "specular-coefficient" ) ) {
385 setCoefficient( Specular, resourceMgr()->doubleValue( section, "specular-coefficient" ) );
388 // Set emission color
389 if ( resourceMgr()->hasValue( section, "emission-color" ) ) {
390 setColor( Emission, resourceMgr()->colorValue( section, "emission-color" ) );
392 // Set emission coefficient
393 if ( resourceMgr()->hasValue( section, "emission-coefficient" ) ) {
394 setCoefficient( Emission, resourceMgr()->doubleValue( section, "emission-coefficient" ) );
398 if ( resourceMgr()->hasValue( section, "shininess" ) ) {
399 setShininess( resourceMgr()->doubleValue( section, "shininess" ) );
404 \brief Save material properties to the resource file.
406 If paremeters \a theResMgr and \a theResSection are not specified, default ones
407 (those passed to the fromResources() function) are used instead.
409 \param theResMgr resources manager
410 \param theResSection resources section name
413 void Material_Model::save( QtxResourceMgr* theResMgr,
414 const QString& theResSection,
418 theResMgr = resourceMgr();
422 QString section = theResSection.isEmpty() ? resourceSection( theIsFront ) : theResSection;
423 myResourceSection = section;
425 if ( hasAmbientReflection() ) {
426 // Save ambient color
427 theResMgr->setValue( section, "ambient-color", color( Ambient ) );
428 // Save ambient coefficient
429 theResMgr->setValue( section, "ambient-coefficient", coefficient( Ambient ) );
432 // Remove ambient color
433 theResMgr->remove( section, "ambient-color" );
434 // Remove ambient coefficient
435 theResMgr->remove( section, "ambient-coefficient" );
438 if ( hasDiffuseReflection() ) {
439 // Save diffuse color
440 theResMgr->setValue( section, "diffuse-color", color( Diffuse ) );
441 // Save diffuse coefficient
442 theResMgr->setValue( section, "diffuse-coefficient", coefficient( Diffuse ) );
445 // Remove diffuse color
446 theResMgr->remove( section, "diffuse-color" );
447 // Remove diffuse coefficient
448 theResMgr->remove( section, "diffuse-coefficient" );
451 if ( hasSpecularReflection() ) {
452 // Save specular color
453 theResMgr->setValue( section, "specular-color", color( Specular ) );
454 // Save specular coefficient
455 theResMgr->setValue( section, "specular-coefficient", coefficient( Specular ) );
458 // Remove specular color
459 theResMgr->remove( section, "specular-color" );
460 // Remove specular coefficient
461 theResMgr->remove( section, "specular-coefficient" );
464 if ( hasEmissionReflection() ) {
465 // Save emission color
466 theResMgr->setValue( section, "emission-color", color( Emission ) );
467 // Save emission coefficient
468 theResMgr->setValue( section, "emission-coefficient", coefficient( Emission ) );
471 // Remove emission color
472 theResMgr->remove( section, "emission-color" );
473 // Remove emission coefficient
474 theResMgr->remove( section, "emission-coefficient" );
478 theResMgr->setValue( section, "shininess", shininess() );
482 \brief Get resource manager used by this material model.
484 \return pointer to the resource manager passed previously to the fromResources() method
485 \sa fromResources(), resourceSection()
487 QtxResourceMgr* Material_Model::resourceMgr() const
489 return myResourceMgr;
493 \brief Get resources section name
495 If section name is empty, default material name from "Geometry" section
496 is returned ("front_material" or "back_material" is used depending on
499 \param theIsFront the flag indicating that section of front or back material
501 \return resource section name passed previously to the fromResources() method
502 \sa fromResources(), resourceMgr()
504 QString Material_Model::resourceSection( bool theIsFront ) const
506 return !myResourceSection.isEmpty() ? myResourceSection :
507 SUIT_Session::session()->resourceMgr()->stringValue("Geometry",
508 ( theIsFront ? "front_material" : "back_material" ),
513 \brief Check if ambient reflection type is defined for this material
515 \return true if ambient reflection type is defined for this material,
518 bool Material_Model::hasAmbientReflection()
520 return ( !myColors.isEmpty() && myColors.contains(Ambient) || !myCoefficients.isEmpty() && myCoefficients.contains(Ambient) );
524 \brief Check if diffuse reflection type is defined for this material
526 \return true if diffuse reflection type is defined for this material,
529 bool Material_Model::hasDiffuseReflection()
531 return ( !myColors.isEmpty() && myColors.contains(Diffuse) || !myCoefficients.isEmpty() && myCoefficients.contains(Diffuse) );
535 \brief Check if specular reflection type is defined for this material
537 \return true if specular reflection type is defined for this material,
540 bool Material_Model::hasSpecularReflection()
542 return ( !myColors.isEmpty() && myColors.contains(Specular) || !myCoefficients.isEmpty() && myCoefficients.contains(Specular) );
546 \brief Check if emission reflection type is defined for this material
548 \return true if emission reflection type is defined for this material,
551 bool Material_Model::hasEmissionReflection()
553 return ( !myColors.isEmpty() && myColors.contains(Emission) || !myCoefficients.isEmpty() && myCoefficients.contains(Emission) );
557 \brief Get color value for the given reflection type
558 \param theReflectionType reflection type
559 \return a color which should be used by the given reflection type
562 QColor Material_Model::color( ReflectionType theReflectionType ) const
564 return myColors[ theReflectionType ];
568 \brief Set color value for the given reflection type
570 \param theReflectionType reflection type
571 \param theColor a color to be used by the given reflection type
574 void Material_Model::setColor( ReflectionType theReflectionType,
575 const QColor& theColor )
577 myColors[ theReflectionType ] = theColor;
581 \brief Set color of the current material from the given string
582 \param theProp the considered property
583 \param theColorName the name of the color property
584 \param theReflectionType the type of reflection
586 void Material_Model::setColor( QString theProp,
587 QString theColorName,
588 ReflectionType theReflectionType )
590 int anId = theProp.indexOf( theColorName );
593 if ( Qtx::stringToColor( theProp.right( theProp.length() - ( anId + theColorName.length() ) ), c ) )
594 setColor( theReflectionType, c );
599 \brief Remove color value for the given reflection type
601 \param theReflectionType reflection type
602 \sa color(), setColor()
604 void Material_Model::removeColor( ReflectionType theReflectionType )
606 myColors.remove( theReflectionType );
610 \brief Get coefficient value for the given reflection type
611 \param theReflectionType reflection type
612 \return a coefficient which should be used by the given reflection type
615 double Material_Model::coefficient( ReflectionType theReflectionType ) const
617 return myCoefficients[ theReflectionType ];
621 \brief Set coefficient value for the given reflection type
623 \param theReflectionType reflection type
624 \param theCoefficient a coefficient to be used by the given reflection type
627 void Material_Model::setCoefficient( ReflectionType theReflectionType,
628 double theCoefficient )
630 myCoefficients[ theReflectionType ] = theCoefficient;
634 \brief Set coefficient of the current material from the given string
635 \param theProp the considered property
636 \param theCoefName the name of the color property
637 \param theReflectionType the type of reflection
639 void Material_Model::setCoefficient( QString theProp,
641 ReflectionType theReflectionType )
643 int anId = theProp.indexOf( theCoefName );
646 double aCoef = theProp.right( theProp.length() - ( anId + theCoefName.length() ) ).toDouble( &ok );
648 setCoefficient( theReflectionType, aCoef );
653 \brief Remove coefficient value for the given reflection type
655 \param theReflectionType reflection type
656 \sa coefficient(), setCoefficient()
658 void Material_Model::removeCoefficient( ReflectionType theReflectionType )
660 myCoefficients.remove( theReflectionType );
664 \brief Get shininess value
665 \return a shininess value of this material
668 double Material_Model::shininess() const
674 \brief Set shininess value
676 \param theShininess a shininess value of this material
679 void Material_Model::setShininess( double theShininess)
681 myShininess = theShininess;