X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blobdiff_plain;f=src%2FXCAFDoc%2FXCAFDoc_VisMaterial.cxx;h=d76c94a0d126963f0e08697b6f4d5ec2dd5575e3;hb=a4815d5509b863bea5204b39e9deb373d85fb63a;hpb=ba00aab7a0f30b2a77d3faa4191249b32a9e03b0 diff --git a/src/XCAFDoc/XCAFDoc_VisMaterial.cxx b/src/XCAFDoc/XCAFDoc_VisMaterial.cxx new file mode 100644 index 0000000000..d76c94a0d1 --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_VisMaterial.cxx @@ -0,0 +1,318 @@ +// Copyright (c) 2019 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#include +#include +#include +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_VisMaterial, TDF_Attribute) + +//======================================================================= +//function : GetID +//purpose : +//======================================================================= +const Standard_GUID& XCAFDoc_VisMaterial::GetID() +{ + static Standard_GUID THE_VIS_MAT_ID ("EBB00255-03A0-4845-BD3B-A70EEDEEFA78"); + return THE_VIS_MAT_ID; +} + +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +XCAFDoc_VisMaterial::XCAFDoc_VisMaterial() +: myAlphaMode (Graphic3d_AlphaMode_BlendAuto), + myAlphaCutOff (0.5f), + myIsDoubleSided (Standard_True) +{ + // +} + +//======================================================================= +//function : SetMetalRougnessMaterial +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::SetPbrMaterial (const XCAFDoc_VisMaterialPBR& theMaterial) +{ + Backup(); + myPbrMat = theMaterial; +} + +//======================================================================= +//function : SetCommonMaterial +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::SetCommonMaterial (const XCAFDoc_VisMaterialCommon& theMaterial) +{ + Backup(); + myCommonMat = theMaterial; +} + +//======================================================================= +//function : SetAlphaMode +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::SetAlphaMode (Graphic3d_AlphaMode theMode, + Standard_ShortReal theCutOff) +{ + Backup(); + myAlphaMode = theMode; + myAlphaCutOff = theCutOff; +} + +//======================================================================= +//function : SetDoubleSided +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::SetDoubleSided (Standard_Boolean theIsDoubleSided) +{ + Backup(); + myIsDoubleSided = theIsDoubleSided; +} + +//======================================================================= +//function : Restore +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::Restore (const Handle(TDF_Attribute)& theWith) +{ + XCAFDoc_VisMaterial* anOther = dynamic_cast(theWith.get()); + myPbrMat = anOther->myPbrMat; + myCommonMat = anOther->myCommonMat; + myAlphaMode = anOther->myAlphaMode; + myAlphaCutOff = anOther->myAlphaCutOff; + myIsDoubleSided = anOther->myIsDoubleSided; +} + +//======================================================================= +//function : NewEmpty +//purpose : +//======================================================================= +Handle(TDF_Attribute) XCAFDoc_VisMaterial::NewEmpty() const +{ + return new XCAFDoc_VisMaterial(); +} + +//======================================================================= +//function : Paste +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::Paste (const Handle(TDF_Attribute)& theInto, + const Handle(TDF_RelocationTable)& ) const +{ + XCAFDoc_VisMaterial* anOther = dynamic_cast(theInto.get()); + anOther->Backup(); + anOther->myPbrMat = myPbrMat; + anOther->myCommonMat = myCommonMat; + anOther->myAlphaMode = myAlphaMode; + anOther->myAlphaCutOff = myAlphaCutOff; + anOther->myIsDoubleSided = myIsDoubleSided; +} + +// ======================================================================= +// function : BaseColor +// purpose : +// ======================================================================= +Quantity_ColorRGBA XCAFDoc_VisMaterial::BaseColor() const +{ + if (myPbrMat.IsDefined) + { + return myPbrMat.BaseColor; + } + else if (myCommonMat.IsDefined) + { + return Quantity_ColorRGBA (myCommonMat.DiffuseColor, 1.0f - myCommonMat.Transparency); + } + return Quantity_ColorRGBA (Quantity_NOC_WHITE); +} + +//======================================================================= +//function : ConvertToCommonMaterial +//purpose : +//======================================================================= +XCAFDoc_VisMaterialCommon XCAFDoc_VisMaterial::ConvertToCommonMaterial() +{ + if (myCommonMat.IsDefined) + { + return myCommonMat; + } + else if (!myPbrMat.IsDefined) + { + return XCAFDoc_VisMaterialCommon(); + } + + // convert metal-roughness into common + XCAFDoc_VisMaterialCommon aComMat; + aComMat.IsDefined = true; + aComMat.DiffuseColor = myPbrMat.BaseColor.GetRGB(); + aComMat.SpecularColor = Quantity_Color (Graphic3d_Vec3 (myPbrMat.Metallic)); + aComMat.Transparency = 1.0f - myPbrMat.BaseColor.Alpha(); + aComMat.Shininess = 1.0f - myPbrMat.Roughness; + return aComMat; +} + +//! Compute material roughness from common material. +static Standard_ShortReal roughnessFromCommon (const XCAFDoc_VisMaterialCommon& theMat) +{ + Standard_Real aRoughnessFactor = 1.0 - theMat.Shininess; + //Standard_Real aSpecIntens = theMat.SpecularColor.Light() * theMat.SpecularColor; + const Standard_Real aSpecIntens = theMat.SpecularColor.Red() * 0.2125 + + theMat.SpecularColor.Green() * 0.7154 + + theMat.SpecularColor.Blue() * 0.0721; + if (aSpecIntens < 0.1) + { + // low specular intensity should produce a rough material even if shininess is high + aRoughnessFactor *= (1.0 - aSpecIntens); + } + return (Standard_ShortReal )aRoughnessFactor; +} + +//======================================================================= +//function : ConvertToPbrMaterial +//purpose : +//======================================================================= +XCAFDoc_VisMaterialPBR XCAFDoc_VisMaterial::ConvertToPbrMaterial() +{ + if (myPbrMat.IsDefined) + { + return myPbrMat; + } + else if (!myCommonMat.IsDefined) + { + return XCAFDoc_VisMaterialPBR(); + } + + XCAFDoc_VisMaterialPBR aPbrMat; + aPbrMat.IsDefined = true; + aPbrMat.BaseColor.SetRGB (myCommonMat.DiffuseColor); + aPbrMat.BaseColor.SetAlpha (1.0f - myCommonMat.Transparency); + // we allow to save any number in range [0, 1] but logically metallicity can be either 0 or 1 + aPbrMat.Metallic = ((Graphic3d_Vec3 )myCommonMat.SpecularColor).maxComp(); // > 0.1f ? 1.0 : 0.0; + aPbrMat.Roughness = roughnessFromCommon (myCommonMat); + return aPbrMat; +} + +//======================================================================= +//function : FillMaterialAspect +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::FillMaterialAspect (Graphic3d_MaterialAspect& theAspect) const +{ + if (myCommonMat.IsDefined) + { + theAspect = Graphic3d_MaterialAspect (Graphic3d_NOM_UserDefined); + theAspect.SetAmbientColor (myCommonMat.AmbientColor); + theAspect.SetDiffuseColor (myCommonMat.DiffuseColor); + theAspect.SetSpecularColor(myCommonMat.SpecularColor); + theAspect.SetEmissiveColor(myCommonMat.EmissiveColor); + theAspect.SetTransparency (myCommonMat.Transparency); + theAspect.SetShininess (myCommonMat.Shininess); + + // convert common into metal-roughness + if (!myPbrMat.IsDefined) + { + #ifdef _Graphic3d_PBRMaterial_HeaderFile + Graphic3d_PBRMaterial aPbr; + aPbr.SetColor (myCommonMat.DiffuseColor); + aPbr.SetMetallic (((Graphic3d_Vec3 )myCommonMat.SpecularColor).maxComp()); + aPbr.SetRoughness (roughnessFromCommon (myCommonMat)); + theAspect.SetPBRMaterial (aPbr); + #endif + } + } + + if (myPbrMat.IsDefined) + { + if (!myCommonMat.IsDefined) + { + // convert metal-roughness into common + theAspect = Graphic3d_MaterialAspect (Graphic3d_NOM_UserDefined); + theAspect.SetDiffuseColor (myPbrMat.BaseColor.GetRGB()); + theAspect.SetAlpha (myPbrMat.BaseColor.Alpha()); + theAspect.SetSpecularColor(Quantity_Color (Graphic3d_Vec3 (myPbrMat.Metallic))); + theAspect.SetShininess (1.0f - myPbrMat.Roughness); + } + + #ifdef _Graphic3d_PBRMaterial_HeaderFile + Graphic3d_PBRMaterial aPbr; + aPbr.SetColor (myPbrMat.BaseColor); + aPbr.SetMetallic (myPbrMat.Metallic); + aPbr.SetRoughness(myPbrMat.Roughness); + aPbr.SetEmission (myPbrMat.EmissiveFactor); + theAspect.SetPBRMaterial (aPbr); + #endif + } +} + +//======================================================================= +//function : FillAspect +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::FillAspect (const Handle(Graphic3d_Aspects)& theAspect) const +{ + if (IsEmpty()) + { + return; + } + + Graphic3d_MaterialAspect aMaterial; + FillMaterialAspect (aMaterial); + theAspect->SetFrontMaterial (aMaterial); + theAspect->SetAlphaMode (myAlphaMode , myAlphaCutOff); + theAspect->SetSuppressBackFaces (!myIsDoubleSided); + + Handle(Image_Texture) aColorTexture, aNormTexture; + if (!myCommonMat.DiffuseTexture.IsNull()) + { + aColorTexture = myCommonMat.DiffuseTexture; + } + else if (!myPbrMat.BaseColorTexture.IsNull()) + { + aColorTexture = myPbrMat.BaseColorTexture; + } + + if (!myPbrMat.NormalTexture.IsNull()) + { + aNormTexture = myPbrMat.NormalTexture; + } + + Standard_Integer aNbTextures = 0; + if (!aColorTexture.IsNull()) + { + ++aNbTextures; + } + if (!aNormTexture.IsNull()) + { + //++aNbTextures; + } + if (aNbTextures != 0) + { + Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (aNbTextures); + Standard_Integer aTextureIndex = 0; + if (!aColorTexture.IsNull()) + { + aTextureSet->SetValue (aTextureIndex++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_BaseColor)); + } + if (!aNormTexture.IsNull()) + { + //aTextureSet->SetValue (aTextureIndex++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_Normal)); + } + theAspect->SetTextureSet (aTextureSet); + theAspect->SetTextureMapOn (true); + } +}