1 // Copyright (c) 2019 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <XCAFDoc_VisMaterial.hxx>
16 #include <Graphic3d_Aspects.hxx>
17 #include <Graphic3d_MaterialAspect.hxx>
18 #include <Standard_GUID.hxx>
19 #include <TDF_Label.hxx>
20 #include <XCAFPrs_Texture.hxx>
22 IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_VisMaterial, TDF_Attribute)
24 //=======================================================================
27 //=======================================================================
28 const Standard_GUID& XCAFDoc_VisMaterial::GetID()
30 static Standard_GUID THE_VIS_MAT_ID ("EBB00255-03A0-4845-BD3B-A70EEDEEFA78");
31 return THE_VIS_MAT_ID;
34 //=======================================================================
35 //function : Constructor
37 //=======================================================================
38 XCAFDoc_VisMaterial::XCAFDoc_VisMaterial()
39 : myAlphaMode (Graphic3d_AlphaMode_BlendAuto),
41 myFaceCulling (Graphic3d_TypeOfBackfacingModel_Auto)
46 //=======================================================================
47 //function : SetMetalRougnessMaterial
49 //=======================================================================
50 void XCAFDoc_VisMaterial::SetPbrMaterial (const XCAFDoc_VisMaterialPBR& theMaterial)
53 myPbrMat = theMaterial;
56 //=======================================================================
57 //function : SetCommonMaterial
59 //=======================================================================
60 void XCAFDoc_VisMaterial::SetCommonMaterial (const XCAFDoc_VisMaterialCommon& theMaterial)
63 myCommonMat = theMaterial;
66 //=======================================================================
67 //function : SetAlphaMode
69 //=======================================================================
70 void XCAFDoc_VisMaterial::SetAlphaMode (Graphic3d_AlphaMode theMode,
71 Standard_ShortReal theCutOff)
74 myAlphaMode = theMode;
75 myAlphaCutOff = theCutOff;
78 //=======================================================================
79 //function : SetFaceCulling
81 //=======================================================================
82 void XCAFDoc_VisMaterial::SetFaceCulling (Graphic3d_TypeOfBackfacingModel theFaceCulling)
85 myFaceCulling = theFaceCulling;
88 //=======================================================================
91 //=======================================================================
92 void XCAFDoc_VisMaterial::Restore (const Handle(TDF_Attribute)& theWith)
94 XCAFDoc_VisMaterial* anOther = dynamic_cast<XCAFDoc_VisMaterial* >(theWith.get());
95 myPbrMat = anOther->myPbrMat;
96 myCommonMat = anOther->myCommonMat;
97 myAlphaMode = anOther->myAlphaMode;
98 myAlphaCutOff = anOther->myAlphaCutOff;
99 myFaceCulling = anOther->myFaceCulling;
102 //=======================================================================
103 //function : NewEmpty
105 //=======================================================================
106 Handle(TDF_Attribute) XCAFDoc_VisMaterial::NewEmpty() const
108 return new XCAFDoc_VisMaterial();
111 //=======================================================================
114 //=======================================================================
115 void XCAFDoc_VisMaterial::Paste (const Handle(TDF_Attribute)& theInto,
116 const Handle(TDF_RelocationTable)& ) const
118 XCAFDoc_VisMaterial* anOther = dynamic_cast<XCAFDoc_VisMaterial* >(theInto.get());
120 anOther->myPbrMat = myPbrMat;
121 anOther->myCommonMat = myCommonMat;
122 anOther->myAlphaMode = myAlphaMode;
123 anOther->myAlphaCutOff = myAlphaCutOff;
124 anOther->myFaceCulling = myFaceCulling;
127 // =======================================================================
128 // function : BaseColor
130 // =======================================================================
131 Quantity_ColorRGBA XCAFDoc_VisMaterial::BaseColor() const
133 if (myPbrMat.IsDefined)
135 return myPbrMat.BaseColor;
137 else if (myCommonMat.IsDefined)
139 return Quantity_ColorRGBA (myCommonMat.DiffuseColor, 1.0f - myCommonMat.Transparency);
141 return Quantity_ColorRGBA (Quantity_NOC_WHITE);
144 //=======================================================================
145 //function : ConvertToCommonMaterial
147 //=======================================================================
148 XCAFDoc_VisMaterialCommon XCAFDoc_VisMaterial::ConvertToCommonMaterial()
150 if (myCommonMat.IsDefined)
154 else if (!myPbrMat.IsDefined)
156 return XCAFDoc_VisMaterialCommon();
159 // convert metal-roughness into common
160 XCAFDoc_VisMaterialCommon aComMat;
161 aComMat.IsDefined = true;
162 aComMat.DiffuseTexture = myPbrMat.BaseColorTexture;
163 aComMat.DiffuseColor = myPbrMat.BaseColor.GetRGB();
164 aComMat.SpecularColor = Quantity_Color (Graphic3d_Vec3 (myPbrMat.Metallic));
165 aComMat.Transparency = 1.0f - myPbrMat.BaseColor.Alpha();
166 aComMat.Shininess = 1.0f - myPbrMat.Roughness;
167 if (myPbrMat.EmissiveTexture.IsNull())
169 aComMat.EmissiveColor = Quantity_Color (myPbrMat.EmissiveFactor.cwiseMin (Graphic3d_Vec3 (1.0f)));
174 //=======================================================================
175 //function : ConvertToPbrMaterial
177 //=======================================================================
178 XCAFDoc_VisMaterialPBR XCAFDoc_VisMaterial::ConvertToPbrMaterial()
180 if (myPbrMat.IsDefined)
184 else if (!myCommonMat.IsDefined)
186 return XCAFDoc_VisMaterialPBR();
189 XCAFDoc_VisMaterialPBR aPbrMat;
190 aPbrMat.IsDefined = true;
191 aPbrMat.BaseColorTexture = myCommonMat.DiffuseTexture;
192 aPbrMat.BaseColor.SetRGB (myCommonMat.DiffuseColor);
193 aPbrMat.BaseColor.SetAlpha (1.0f - myCommonMat.Transparency);
194 aPbrMat.Metallic = myCommonMat.Transparency <= ShortRealEpsilon()
195 ? Graphic3d_PBRMaterial::MetallicFromSpecular (myCommonMat.SpecularColor)
197 aPbrMat.Roughness = Graphic3d_PBRMaterial::RoughnessFromSpecular (myCommonMat.SpecularColor, myCommonMat.Shininess);
198 aPbrMat.EmissiveFactor = myCommonMat.EmissiveColor;
202 //=======================================================================
203 //function : FillMaterialAspect
205 //=======================================================================
206 void XCAFDoc_VisMaterial::FillMaterialAspect (Graphic3d_MaterialAspect& theAspect) const
208 if (myCommonMat.IsDefined)
210 theAspect = Graphic3d_MaterialAspect (Graphic3d_NameOfMaterial_UserDefined);
211 theAspect.SetAmbientColor (myCommonMat.AmbientColor);
212 theAspect.SetDiffuseColor (myCommonMat.DiffuseColor);
213 theAspect.SetSpecularColor(myCommonMat.SpecularColor);
214 theAspect.SetEmissiveColor(myCommonMat.EmissiveColor);
215 theAspect.SetTransparency (myCommonMat.Transparency);
216 theAspect.SetShininess (myCommonMat.Shininess);
218 // convert common into metal-roughness
219 if (!myPbrMat.IsDefined)
221 Graphic3d_PBRMaterial aPbr;
222 aPbr.SetColor (myCommonMat.DiffuseColor);
223 aPbr.SetMetallic (myCommonMat.Transparency <= ShortRealEpsilon()
224 ? Graphic3d_PBRMaterial::MetallicFromSpecular (myCommonMat.SpecularColor)
226 aPbr.SetRoughness (Graphic3d_PBRMaterial::RoughnessFromSpecular (myCommonMat.SpecularColor, myCommonMat.Shininess));
227 aPbr.SetEmission (myCommonMat.EmissiveColor);
228 theAspect.SetPBRMaterial (aPbr);
229 theAspect.SetBSDF (Graphic3d_BSDF::CreateMetallicRoughness (aPbr));
233 if (myPbrMat.IsDefined)
235 if (!myCommonMat.IsDefined)
237 // convert metal-roughness into common
238 theAspect = Graphic3d_MaterialAspect (Graphic3d_NameOfMaterial_UserDefined);
239 theAspect.SetDiffuseColor (myPbrMat.BaseColor.GetRGB());
240 theAspect.SetAlpha (myPbrMat.BaseColor.Alpha());
241 theAspect.SetSpecularColor(Quantity_Color (Graphic3d_Vec3 (myPbrMat.Metallic)));
242 theAspect.SetShininess (1.0f - myPbrMat.Roughness);
243 theAspect.SetEmissiveColor (Quantity_Color (myPbrMat.EmissiveFactor.cwiseMin (Graphic3d_Vec3 (1.0f))));
246 Graphic3d_PBRMaterial aPbr;
247 aPbr.SetColor (myPbrMat.BaseColor);
248 aPbr.SetMetallic (myPbrMat.Metallic);
249 aPbr.SetRoughness(myPbrMat.Roughness);
250 aPbr.SetEmission (myPbrMat.EmissiveFactor);
251 aPbr.SetIOR (myPbrMat.RefractionIndex);
252 theAspect.SetRefractionIndex (myPbrMat.RefractionIndex);
253 theAspect.SetPBRMaterial (aPbr);
254 theAspect.SetBSDF (Graphic3d_BSDF::CreateMetallicRoughness (aPbr));
258 //=======================================================================
259 //function : FillAspect
261 //=======================================================================
262 void XCAFDoc_VisMaterial::FillAspect (const Handle(Graphic3d_Aspects)& theAspect) const
269 Graphic3d_MaterialAspect aMaterial;
270 FillMaterialAspect (aMaterial);
271 theAspect->SetFrontMaterial (aMaterial);
272 theAspect->SetAlphaMode (myAlphaMode , myAlphaCutOff);
273 theAspect->SetFaceCulling (myFaceCulling);
275 const Handle(Image_Texture)& aColorTexture = !myPbrMat.BaseColorTexture.IsNull() ? myPbrMat.BaseColorTexture : myCommonMat.DiffuseTexture;
276 Standard_Integer aNbTexUnits = 0;
277 if (!aColorTexture.IsNull()) { ++aNbTexUnits; }
278 if (!myPbrMat.EmissiveTexture.IsNull()) { ++aNbTexUnits; }
279 if (!myPbrMat.NormalTexture.IsNull()) { ++aNbTexUnits; }
280 if (!myPbrMat.OcclusionTexture.IsNull()) { ++aNbTexUnits; }
281 if (!myPbrMat.MetallicRoughnessTexture.IsNull()) { ++aNbTexUnits; }
282 if (aNbTexUnits == 0)
287 Standard_Integer aTexIter = 0;
288 Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (aNbTexUnits);
289 if (!aColorTexture.IsNull())
291 aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_BaseColor));
293 if (!myPbrMat.EmissiveTexture.IsNull())
295 aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.EmissiveTexture, Graphic3d_TextureUnit_Emissive));
297 if (!myPbrMat.OcclusionTexture.IsNull())
299 aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.OcclusionTexture, Graphic3d_TextureUnit_Occlusion));
301 if (!myPbrMat.NormalTexture.IsNull())
303 aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.NormalTexture, Graphic3d_TextureUnit_Normal));
305 if (!myPbrMat.MetallicRoughnessTexture.IsNull())
307 aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.MetallicRoughnessTexture, Graphic3d_TextureUnit_MetallicRoughness));
310 theAspect->SetTextureSet (aTextureSet);
311 theAspect->SetTextureMapOn (true);
314 //=======================================================================
315 //function : DumpJson
317 //=======================================================================
318 void XCAFDoc_VisMaterial::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
320 OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
322 OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute)
324 OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myRawName.get())
326 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPbrMat)
327 OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCommonMat)
329 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAlphaMode)
330 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAlphaCutOff)
331 OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myFaceCulling)