1 // Copyright (C) 2007-2012 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 "GEOM_VTKPropertyMaterial.hxx"
26 #include "Material_ResourceMgr.h"
31 Create new SALOME material model with default properties.
33 Material_Model::Material_Model()
35 myReflection = ReflectionList(4);
36 init(); // set default properties
42 Material_Model::~Material_Model()
47 \brief Initialize material data from the given properties list
48 \param props material properties
51 void Material_Model::fromProperties( const QString& props )
53 // reset to default values
56 // parse material properties
57 QStringList propList = props.split( ":", QString::SkipEmptyParts );
58 foreach ( QString prop, propList )
60 QStringList pdata = prop.split( "=" );
61 if ( pdata.count() < 2 ) continue;
62 QString key = pdata[0].trimmed().toLower();
63 QString data = pdata[1].trimmed().toLower();
65 double dblValue = data.toDouble( &dblOk );
66 bool boolValue = (bool)( data.toInt( &boolOk ) );
69 if ( key == "ambientcolor" && Qtx::stringToColor( data, colorValue ) ) {
70 setColor( Ambient, colorValue );
72 else if ( key == "diffusecolor" && Qtx::stringToColor( data, colorValue ) ) {
73 setColor( Diffuse, colorValue );
75 else if ( key == "specularcolor" && Qtx::stringToColor( data, colorValue ) ) {
76 setColor( Specular, colorValue );
78 else if ( key == "emissivecolor" && Qtx::stringToColor( data, colorValue ) ) {
79 setColor( Emissive, colorValue );
81 else if ( key == "ambientcoefficient" && dblOk ) {
82 setReflection( Ambient, dblValue );
84 else if ( key == "diffusecoefficient" && dblOk ) {
85 setReflection( Diffuse, dblValue );
87 else if ( key == "specularcoefficient" && dblOk ) {
88 setReflection( Specular, dblValue );
90 else if ( key == "emissivecoefficient" && dblOk ) {
91 setReflection( Emissive, dblValue );
93 else if ( key == "shininess" && dblOk ) {
94 setShininess( dblValue );
96 else if ( key == "transparency" && dblOk ) {
97 setTransparency( dblValue );
99 else if ( key == "physical" && boolOk ) {
100 setPhysical( boolValue );
102 else if ( key == "ambient" && boolOk ) {
103 setReflection( Ambient, boolValue );
105 else if ( key == "diffuse" && boolOk ) {
106 setReflection( Diffuse, boolValue );
108 else if ( key == "specular" && boolOk ) {
109 setReflection( Specular, boolValue );
111 else if ( key == "emissive" && boolOk ) {
112 setReflection( Emissive, boolValue );
118 \brief Get material properties string representation
119 \return string representing of material properties
122 QString Material_Model::toProperties()
125 QString fmt = "%1=%2";
128 props << fmt.arg( "Physical" ).arg( isPhysical() );
131 props << fmt.arg( "Shininess" ).arg( shininess() );
134 props << fmt.arg( "Transparency" ).arg( transparency() );
136 // ambient reflection
137 props << fmt.arg( "Ambient" ).arg( hasReflection( Ambient ) );
138 if ( color( Ambient ).isValid() )
139 props << fmt.arg( "AmbientColor" ).arg( Qtx::colorToString( color( Ambient ) ) );
140 props << fmt.arg( "AmbientCoefficient" ).arg( reflection( Ambient ) );
142 // diffuse reflection
143 props << fmt.arg( "Diffuse" ).arg( hasReflection( Diffuse ) );
144 if ( color( Diffuse ).isValid() )
145 props << fmt.arg( "DiffuseColor" ).arg( Qtx::colorToString( color( Diffuse ) ) );
146 props << fmt.arg( "DiffuseCoefficient" ).arg( reflection( Diffuse ) );
148 // specular reflection
149 props << fmt.arg( "Specular" ).arg( hasReflection( Specular ) );
150 if ( color( Specular ).isValid() )
151 props << fmt.arg( "SpecularColor" ).arg( Qtx::colorToString( color( Specular ) ) );
152 props << fmt.arg( "SpecularCoefficient" ).arg( reflection( Specular ) );
154 // emissive reflection
155 props << fmt.arg( "Emissive" ).arg( hasReflection( Emissive ) );
156 if ( color( Emissive ).isValid() )
157 props << fmt.arg( "EmissiveColor" ).arg( Qtx::colorToString( color( Emissive ) ) );
158 props << fmt.arg( "EmissiveCoefficient" ).arg( reflection( Emissive ) );
160 return props.join( ":" );
164 \brief Initialize material model from the resources
166 This function can be used to retrieve material properties from the resource file.
168 \param material material name (if not specified, model is initialized by default material)
169 \param resMgr resource manager (if not specified, new resources manager is created)
172 void Material_Model::fromResources( const QString& material, QtxResourceMgr* resMgr )
174 static QString common = "[common]";
176 // reset to default values
179 // material name is not specified: use default values
180 if ( material.isEmpty() ) return;
182 bool ownResourcesMgr = resMgr == 0;
184 if ( ownResourcesMgr )
185 resMgr = new Material_ResourceMgr();
187 // read common section
188 if ( material != common && resMgr->hasSection( common ) )
189 fromResources( common, resMgr );
192 if ( resMgr->hasValue( material, "physical" ) ) {
193 setPhysical( resMgr->booleanValue( material, "physical" ) );
197 if ( resMgr->hasValue( material, "shininess" ) ) {
198 setShininess( resMgr->doubleValue( material, "shininess" ) );
202 if ( resMgr->hasValue( material, "transparency" ) ) {
203 setTransparency( resMgr->doubleValue( material, "transparency" ) );
206 // ambient reflection
207 if ( resMgr->hasValue( material, "ambient-color" ) ) {
208 setColor( Ambient, resMgr->colorValue( material, "ambient-color" ) );
210 if ( resMgr->hasValue( material, "ambient-coefficient" ) ) {
211 setReflection( Ambient, resMgr->doubleValue( material, "ambient-coefficient" ) );
213 if ( resMgr->hasValue( material, "ambient" ) ) {
214 setReflection( Ambient, resMgr->booleanValue( material, "ambient" ) );
217 // diffuse reflection
218 if ( resMgr->hasValue( material, "diffuse-color" ) ) {
219 setColor( Diffuse, resMgr->colorValue( material, "diffuse-color" ) );
221 if ( resMgr->hasValue( material, "diffuse-coefficient" ) ) {
222 setReflection( Diffuse, resMgr->doubleValue( material, "diffuse-coefficient" ) );
224 if ( resMgr->hasValue( material, "diffuse" ) ) {
225 setReflection( Diffuse, resMgr->booleanValue( material, "diffuse" ) );
228 // specular reflection
229 if ( resMgr->hasValue( material, "specular-color" ) ) {
230 setColor( Specular, resMgr->colorValue( material, "specular-color" ) );
232 if ( resMgr->hasValue( material, "specular-coefficient" ) ) {
233 setReflection( Specular, resMgr->doubleValue( material, "specular-coefficient" ) );
235 if ( resMgr->hasValue( material, "specular" ) ) {
236 setReflection( Specular, resMgr->booleanValue( material, "specular" ) );
239 // emissive reflection
240 if ( resMgr->hasValue( material, "emissive-color" ) ) {
241 setColor( Emissive, resMgr->colorValue( material, "emissive-color" ) );
243 if ( resMgr->hasValue( material, "emissive-coefficient" ) ) {
244 setReflection( Emissive, resMgr->doubleValue( material, "emissive-coefficient" ) );
246 if ( resMgr->hasValue( material, "emissive" ) ) {
247 setReflection( Emissive, resMgr->booleanValue( material, "emissive" ) );
250 if ( ownResourcesMgr )
255 \brief Save material properties to the resource file.
256 \param material material name
257 \param resMgr resource manager
260 void Material_Model::toResources( const QString& material, QtxResourceMgr* resMgr )
262 if ( resMgr && !material.isEmpty() ) {
263 // remove resources section (to clean-up all previous properties)
264 resMgr->remove( material );
267 resMgr->setValue( material, "physical", isPhysical() );
270 resMgr->setValue( material, "shininess", shininess() );
273 resMgr->setValue( material, "transparency", transparency() );
275 // ambient reflection
276 if ( color( Ambient ).isValid() )
277 resMgr->setValue( material, "ambient-color", color( Ambient ) );
278 resMgr->setValue( material, "ambient-coefficient", reflection( Ambient ) );
279 resMgr->setValue( material, "ambient", hasReflection( Ambient ) );
281 // diffuse reflection
282 if ( color( Diffuse ).isValid() )
283 resMgr->setValue( material, "diffuse-color", color( Diffuse ) );
284 resMgr->setValue( material, "diffuse-coefficient", reflection( Diffuse ) );
285 resMgr->setValue( material, "diffuse", hasReflection( Diffuse ) );
287 // Specular reflection
288 if ( color( Specular ).isValid() )
289 resMgr->setValue( material, "specular-color", color( Specular ) );
290 resMgr->setValue( material, "specular-coefficient", reflection( Specular ) );
291 resMgr->setValue( material, "specular", hasReflection( Specular ) );
293 // Emissive reflection
294 if ( color( Emissive ).isValid() )
295 resMgr->setValue( material, "emissive-color", color( Emissive ) );
296 resMgr->setValue( material, "emissive-coefficient", reflection( Emissive ) );
297 resMgr->setValue( material, "emissive", hasReflection( Emissive ) );
302 \brief Initialize material model from the preferences
304 The material name is retrieved from the "material" parameter of the "Geometry" section
305 of the specified resources manager.
307 \param resMgr resources manager
308 \sa fromResources(), toResources()
310 // void Material_Model::fromPreferences( QtxResourceMgr* resMgr )
313 // // default material is Plastic
314 // fromResources( resMgr->stringValue( "Geometry", "material", "Plastic" ) );
319 \brief Get material type
320 \return \c true if material is physical or \c false otherwise
323 bool Material_Model::isPhysical() const
329 \brief Set material type
330 \param value \c true if material is physical or \c false otherwise
333 void Material_Model::setPhysical( bool value )
335 myIsPhysical = value;
339 \brief Check if given reflection is enabled
340 \param type reflection type
341 \return \c true if specified reflection type is enabled or \c false otherwise
342 \sa setReflection(ReflectionType, bool)
344 bool Material_Model::hasReflection( ReflectionType type ) const
347 if ( type >= 0 && type < 4 )
348 value = myReflection[ type ].enabled;
353 \brief Enable/disable given reflection type
354 \param type reflection type
355 \param value boolean flag
358 void Material_Model::setReflection( ReflectionType type, bool value )
360 if ( type >= 0 && type < 4 )
361 myReflection[ type ].enabled = value;
365 \brief Get color value for the given reflection type
366 \param type reflection type
367 \return color associated with the specified reflection type
370 QColor Material_Model::color( ReflectionType type ) const
373 if ( type >= 0 && type < 4 )
374 value = myReflection[ type ].color;
379 \brief Set color value for the given reflection type
380 \param type reflection type
381 \param value color to be used for specified reflection type
384 void Material_Model::setColor( ReflectionType type, const QColor& value )
386 if ( type >= 0 && type < 4 )
387 myReflection[ type ].color = value;
391 \brief Get coefficient value for the given reflection type
392 \param type reflection type
393 \return coefficient value for the specified reflection type
394 \sa setReflection(ReflectionType, double)
396 double Material_Model::reflection( ReflectionType type ) const
399 if ( type >= 0 && type < 4 )
400 value = myReflection[ type ].coef;
405 \brief Set coefficient value for the given reflection type
406 \param type reflection type
407 \param value coefficient to be used by the given reflection type
410 void Material_Model::setReflection( ReflectionType type, double value )
412 if ( type >= 0 && type < 4 )
413 myReflection[ type ].coef = value;
417 \brief Get shininess value
418 \return shininess value of the material
421 double Material_Model::shininess() const
427 \brief Set shininess value
428 \param value new shininess value
431 void Material_Model::setShininess( double value )
437 \brief Get transparency value
438 \return transparency value of the material
439 \sa setTransparency()
441 double Material_Model::transparency() const
443 return myTransparency;
447 \brief Set transparency value
448 \param value new transparency value
451 void Material_Model::setTransparency( double value )
453 myTransparency = value;
457 \brief Initialize material model with default values
459 void Material_Model::init()
463 // non-physical by default
464 setPhysical( false );
466 setShininess( 0.039 );
468 setTransparency( 0.0 );
470 // ambient reflection (enabled by default)
471 Qtx::stringToColor( "#333333", c );
472 setColor( Ambient, c );
473 setReflection( Ambient, 0.3 );
474 setReflection( Ambient, true );
476 // diffuse reflection (enabled by default)
477 Qtx::stringToColor( "#000000", c );
478 setColor( Diffuse, c );
479 setReflection( Diffuse, 0.65 );
480 setReflection( Diffuse, true );
482 // specular reflection (enabled by default)
483 Qtx::stringToColor( "#ffffff", c );
484 setColor( Specular, c );
485 setReflection( Specular, 0.0 );
486 setReflection( Specular, true );
488 // emissive reflection (disabled by default)
489 Qtx::stringToColor( "#000000", c );
490 setColor( Emissive, c );
491 setReflection( Emissive, 0.0 );
492 setReflection( Emissive, false );
496 \brief Construct OCCT material aspect from material model
497 \return material aspect object with corresponding properties
499 Graphic3d_MaterialAspect Material_Model::getMaterialOCCAspect()
501 // Get material aspect from the current model
502 Graphic3d_MaterialAspect aspect;
506 // ambient reflection
507 if ( color( Ambient ).isValid() ) {
508 c = color( Ambient );
509 aspect.SetAmbientColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
511 aspect.SetAmbient( reflection( Ambient ));
512 if ( hasReflection( Ambient ) )
513 aspect.SetReflectionModeOn( Graphic3d_TOR_AMBIENT );
515 aspect.SetReflectionModeOff( Graphic3d_TOR_AMBIENT );
517 // diffuse reflection
518 if ( color( Diffuse ).isValid() ) {
519 c = color( Diffuse );
520 aspect.SetDiffuseColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
522 aspect.SetDiffuse( reflection( Diffuse ));
523 if ( hasReflection( Diffuse ) )
524 aspect.SetReflectionModeOn( Graphic3d_TOR_DIFFUSE );
526 aspect.SetReflectionModeOff( Graphic3d_TOR_DIFFUSE );
528 // specular reflection
529 if ( color( Specular ).isValid() ) {
530 c = color( Specular );
531 aspect.SetSpecularColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
533 aspect.SetSpecular( reflection( Specular ));
534 if ( hasReflection( Specular ) )
535 aspect.SetReflectionModeOn( Graphic3d_TOR_SPECULAR );
537 aspect.SetReflectionModeOff( Graphic3d_TOR_SPECULAR );
539 // emissive reflection
540 if ( color( Emissive ).isValid() ) {
541 c = color( Emissive );
542 aspect.SetEmissiveColor( Quantity_Color( c.redF(), c.greenF(), c.blueF(), Quantity_TOC_RGB ) );
544 aspect.SetEmissive( reflection( Emissive ));
545 if ( hasReflection( Emissive ) )
546 aspect.SetReflectionModeOn( Graphic3d_TOR_EMISSION );
548 aspect.SetReflectionModeOff( Graphic3d_TOR_EMISSION );
551 aspect.SetShininess( shininess() );
554 aspect.SetTransparency( transparency() );
557 aspect.SetMaterialType( isPhysical() ? Graphic3d_MATERIAL_PHYSIC : Graphic3d_MATERIAL_ASPECT );
563 \brief Construct VTK property from material model
564 \return VTK property with correspondent material properties
566 GEOM_VTKPropertyMaterial* Material_Model::getMaterialVTKProperty()
568 // NOTE: In VTK it's impossible to switch on/off specific reflection type
569 // NOTE: In VTK emissive reflection type is not supported
570 // NOTE: In VTK shininess is specified via SpecularPower attribute
571 // NOTE: In VTK transparency is specified via Opacity attribute
573 // Get material properties from the current model
574 GEOM_VTKPropertyMaterial* prop = GEOM_VTKPropertyMaterial::New();
578 // ambient reflection
579 if ( color( Ambient ).isValid() && hasReflection( Ambient ) ) {
580 c = color( Ambient );
581 prop->SetAmbientColor( c.redF(), c.greenF(), c.blueF() );
582 prop->SetAmbient( reflection( Ambient ) );
585 // diffuse reflection
586 if ( color( Diffuse ).isValid() && hasReflection( Diffuse ) ) {
587 c = color( Diffuse );
588 prop->SetDiffuseColor( c.redF(), c.greenF(), c.blueF() );
589 prop->SetDiffuse( reflection( Diffuse ) );
592 // specular reflection
593 if ( color( Specular ).isValid() && hasReflection( Specular ) ) {
594 c = color( Specular );
595 prop->SetSpecularColor( c.redF(), c.greenF(), c.blueF() );
596 prop->SetSpecular( reflection( Specular ) );
600 prop->SetSpecularPower( shininess()*100.0 );
603 prop->SetOpacity( 1 - transparency() );
606 prop->SetPhysical( isPhysical() );