a4815d55 |
1 | // Copyright (c) 2019 OPEN CASCADE SAS |
2 | // |
3 | // This file is part of Open CASCADE Technology software library. |
4 | // |
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. |
10 | // |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
13 | |
14 | #include <XCAFDoc_VisMaterial.hxx> |
15 | |
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> |
21 | |
22 | IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_VisMaterial, TDF_Attribute) |
23 | |
24 | //======================================================================= |
25 | //function : GetID |
26 | //purpose : |
27 | //======================================================================= |
28 | const Standard_GUID& XCAFDoc_VisMaterial::GetID() |
29 | { |
30 | static Standard_GUID THE_VIS_MAT_ID ("EBB00255-03A0-4845-BD3B-A70EEDEEFA78"); |
31 | return THE_VIS_MAT_ID; |
32 | } |
33 | |
34 | //======================================================================= |
35 | //function : Constructor |
36 | //purpose : |
37 | //======================================================================= |
38 | XCAFDoc_VisMaterial::XCAFDoc_VisMaterial() |
39 | : myAlphaMode (Graphic3d_AlphaMode_BlendAuto), |
40 | myAlphaCutOff (0.5f), |
41 | myIsDoubleSided (Standard_True) |
42 | { |
43 | // |
44 | } |
45 | |
46 | //======================================================================= |
47 | //function : SetMetalRougnessMaterial |
48 | //purpose : |
49 | //======================================================================= |
50 | void XCAFDoc_VisMaterial::SetPbrMaterial (const XCAFDoc_VisMaterialPBR& theMaterial) |
51 | { |
52 | Backup(); |
53 | myPbrMat = theMaterial; |
54 | } |
55 | |
56 | //======================================================================= |
57 | //function : SetCommonMaterial |
58 | //purpose : |
59 | //======================================================================= |
60 | void XCAFDoc_VisMaterial::SetCommonMaterial (const XCAFDoc_VisMaterialCommon& theMaterial) |
61 | { |
62 | Backup(); |
63 | myCommonMat = theMaterial; |
64 | } |
65 | |
66 | //======================================================================= |
67 | //function : SetAlphaMode |
68 | //purpose : |
69 | //======================================================================= |
70 | void XCAFDoc_VisMaterial::SetAlphaMode (Graphic3d_AlphaMode theMode, |
71 | Standard_ShortReal theCutOff) |
72 | { |
73 | Backup(); |
74 | myAlphaMode = theMode; |
75 | myAlphaCutOff = theCutOff; |
76 | } |
77 | |
78 | //======================================================================= |
79 | //function : SetDoubleSided |
80 | //purpose : |
81 | //======================================================================= |
82 | void XCAFDoc_VisMaterial::SetDoubleSided (Standard_Boolean theIsDoubleSided) |
83 | { |
84 | Backup(); |
85 | myIsDoubleSided = theIsDoubleSided; |
86 | } |
87 | |
88 | //======================================================================= |
89 | //function : Restore |
90 | //purpose : |
91 | //======================================================================= |
92 | void XCAFDoc_VisMaterial::Restore (const Handle(TDF_Attribute)& theWith) |
93 | { |
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 | myIsDoubleSided = anOther->myIsDoubleSided; |
100 | } |
101 | |
102 | //======================================================================= |
103 | //function : NewEmpty |
104 | //purpose : |
105 | //======================================================================= |
106 | Handle(TDF_Attribute) XCAFDoc_VisMaterial::NewEmpty() const |
107 | { |
108 | return new XCAFDoc_VisMaterial(); |
109 | } |
110 | |
111 | //======================================================================= |
112 | //function : Paste |
113 | //purpose : |
114 | //======================================================================= |
115 | void XCAFDoc_VisMaterial::Paste (const Handle(TDF_Attribute)& theInto, |
116 | const Handle(TDF_RelocationTable)& ) const |
117 | { |
118 | XCAFDoc_VisMaterial* anOther = dynamic_cast<XCAFDoc_VisMaterial* >(theInto.get()); |
119 | anOther->Backup(); |
120 | anOther->myPbrMat = myPbrMat; |
121 | anOther->myCommonMat = myCommonMat; |
122 | anOther->myAlphaMode = myAlphaMode; |
123 | anOther->myAlphaCutOff = myAlphaCutOff; |
124 | anOther->myIsDoubleSided = myIsDoubleSided; |
125 | } |
126 | |
127 | // ======================================================================= |
128 | // function : BaseColor |
129 | // purpose : |
130 | // ======================================================================= |
131 | Quantity_ColorRGBA XCAFDoc_VisMaterial::BaseColor() const |
132 | { |
133 | if (myPbrMat.IsDefined) |
134 | { |
135 | return myPbrMat.BaseColor; |
136 | } |
137 | else if (myCommonMat.IsDefined) |
138 | { |
139 | return Quantity_ColorRGBA (myCommonMat.DiffuseColor, 1.0f - myCommonMat.Transparency); |
140 | } |
141 | return Quantity_ColorRGBA (Quantity_NOC_WHITE); |
142 | } |
143 | |
144 | //======================================================================= |
145 | //function : ConvertToCommonMaterial |
146 | //purpose : |
147 | //======================================================================= |
148 | XCAFDoc_VisMaterialCommon XCAFDoc_VisMaterial::ConvertToCommonMaterial() |
149 | { |
150 | if (myCommonMat.IsDefined) |
151 | { |
152 | return myCommonMat; |
153 | } |
154 | else if (!myPbrMat.IsDefined) |
155 | { |
156 | return XCAFDoc_VisMaterialCommon(); |
157 | } |
158 | |
159 | // convert metal-roughness into common |
160 | XCAFDoc_VisMaterialCommon aComMat; |
161 | aComMat.IsDefined = true; |
a14f2b47 |
162 | aComMat.DiffuseTexture = myPbrMat.BaseColorTexture; |
a4815d55 |
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 | return aComMat; |
168 | } |
169 | |
a4815d55 |
170 | //======================================================================= |
171 | //function : ConvertToPbrMaterial |
172 | //purpose : |
173 | //======================================================================= |
174 | XCAFDoc_VisMaterialPBR XCAFDoc_VisMaterial::ConvertToPbrMaterial() |
175 | { |
176 | if (myPbrMat.IsDefined) |
177 | { |
178 | return myPbrMat; |
179 | } |
180 | else if (!myCommonMat.IsDefined) |
181 | { |
182 | return XCAFDoc_VisMaterialPBR(); |
183 | } |
184 | |
185 | XCAFDoc_VisMaterialPBR aPbrMat; |
186 | aPbrMat.IsDefined = true; |
a14f2b47 |
187 | aPbrMat.BaseColorTexture = myCommonMat.DiffuseTexture; |
a4815d55 |
188 | aPbrMat.BaseColor.SetRGB (myCommonMat.DiffuseColor); |
189 | aPbrMat.BaseColor.SetAlpha (1.0f - myCommonMat.Transparency); |
67312b79 |
190 | aPbrMat.Metallic = Graphic3d_PBRMaterial::MetallicFromSpecular (myCommonMat.SpecularColor); |
191 | aPbrMat.Roughness = Graphic3d_PBRMaterial::RoughnessFromSpecular (myCommonMat.SpecularColor, myCommonMat.Shininess); |
a4815d55 |
192 | return aPbrMat; |
193 | } |
194 | |
195 | //======================================================================= |
196 | //function : FillMaterialAspect |
197 | //purpose : |
198 | //======================================================================= |
199 | void XCAFDoc_VisMaterial::FillMaterialAspect (Graphic3d_MaterialAspect& theAspect) const |
200 | { |
201 | if (myCommonMat.IsDefined) |
202 | { |
203 | theAspect = Graphic3d_MaterialAspect (Graphic3d_NOM_UserDefined); |
204 | theAspect.SetAmbientColor (myCommonMat.AmbientColor); |
205 | theAspect.SetDiffuseColor (myCommonMat.DiffuseColor); |
206 | theAspect.SetSpecularColor(myCommonMat.SpecularColor); |
207 | theAspect.SetEmissiveColor(myCommonMat.EmissiveColor); |
208 | theAspect.SetTransparency (myCommonMat.Transparency); |
209 | theAspect.SetShininess (myCommonMat.Shininess); |
210 | |
211 | // convert common into metal-roughness |
212 | if (!myPbrMat.IsDefined) |
213 | { |
a4815d55 |
214 | Graphic3d_PBRMaterial aPbr; |
215 | aPbr.SetColor (myCommonMat.DiffuseColor); |
67312b79 |
216 | aPbr.SetMetallic (Graphic3d_PBRMaterial::MetallicFromSpecular (myCommonMat.SpecularColor)); |
217 | aPbr.SetRoughness (Graphic3d_PBRMaterial::RoughnessFromSpecular (myCommonMat.SpecularColor, myCommonMat.Shininess)); |
a4815d55 |
218 | theAspect.SetPBRMaterial (aPbr); |
67312b79 |
219 | theAspect.SetBSDF (Graphic3d_BSDF::CreateMetallicRoughness (aPbr)); |
a4815d55 |
220 | } |
221 | } |
222 | |
223 | if (myPbrMat.IsDefined) |
224 | { |
225 | if (!myCommonMat.IsDefined) |
226 | { |
227 | // convert metal-roughness into common |
228 | theAspect = Graphic3d_MaterialAspect (Graphic3d_NOM_UserDefined); |
229 | theAspect.SetDiffuseColor (myPbrMat.BaseColor.GetRGB()); |
230 | theAspect.SetAlpha (myPbrMat.BaseColor.Alpha()); |
231 | theAspect.SetSpecularColor(Quantity_Color (Graphic3d_Vec3 (myPbrMat.Metallic))); |
232 | theAspect.SetShininess (1.0f - myPbrMat.Roughness); |
233 | } |
234 | |
a4815d55 |
235 | Graphic3d_PBRMaterial aPbr; |
236 | aPbr.SetColor (myPbrMat.BaseColor); |
237 | aPbr.SetMetallic (myPbrMat.Metallic); |
238 | aPbr.SetRoughness(myPbrMat.Roughness); |
72f6dc61 |
239 | aPbr.SetEmission (myPbrMat.EmissiveFactor); |
0858125f |
240 | aPbr.SetIOR (myPbrMat.RefractionIndex); |
241 | theAspect.SetRefractionIndex (myPbrMat.RefractionIndex); |
a4815d55 |
242 | theAspect.SetPBRMaterial (aPbr); |
67312b79 |
243 | theAspect.SetBSDF (Graphic3d_BSDF::CreateMetallicRoughness (aPbr)); |
a4815d55 |
244 | } |
245 | } |
246 | |
247 | //======================================================================= |
248 | //function : FillAspect |
249 | //purpose : |
250 | //======================================================================= |
251 | void XCAFDoc_VisMaterial::FillAspect (const Handle(Graphic3d_Aspects)& theAspect) const |
252 | { |
253 | if (IsEmpty()) |
254 | { |
255 | return; |
256 | } |
257 | |
258 | Graphic3d_MaterialAspect aMaterial; |
259 | FillMaterialAspect (aMaterial); |
260 | theAspect->SetFrontMaterial (aMaterial); |
261 | theAspect->SetAlphaMode (myAlphaMode , myAlphaCutOff); |
262 | theAspect->SetSuppressBackFaces (!myIsDoubleSided); |
263 | |
72f6dc61 |
264 | const Handle(Image_Texture)& aColorTexture = !myPbrMat.BaseColorTexture.IsNull() ? myPbrMat.BaseColorTexture : myCommonMat.DiffuseTexture; |
265 | Standard_Integer aNbTexUnits = 0; |
266 | if (!aColorTexture.IsNull()) { ++aNbTexUnits; } |
267 | if (!myPbrMat.EmissiveTexture.IsNull()) { ++aNbTexUnits; } |
268 | if (!myPbrMat.NormalTexture.IsNull()) { ++aNbTexUnits; } |
269 | if (!myPbrMat.OcclusionTexture.IsNull()) { ++aNbTexUnits; } |
270 | if (!myPbrMat.MetallicRoughnessTexture.IsNull()) { ++aNbTexUnits; } |
271 | if (aNbTexUnits == 0) |
a4815d55 |
272 | { |
72f6dc61 |
273 | return; |
a4815d55 |
274 | } |
72f6dc61 |
275 | |
276 | Standard_Integer aTexIter = 0; |
277 | Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (aNbTexUnits); |
278 | if (!aColorTexture.IsNull()) |
a4815d55 |
279 | { |
72f6dc61 |
280 | aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_BaseColor)); |
a4815d55 |
281 | } |
72f6dc61 |
282 | if (!myPbrMat.EmissiveTexture.IsNull()) |
a4815d55 |
283 | { |
72f6dc61 |
284 | aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.EmissiveTexture, Graphic3d_TextureUnit_Emissive)); |
a4815d55 |
285 | } |
72f6dc61 |
286 | if (!myPbrMat.OcclusionTexture.IsNull()) |
a4815d55 |
287 | { |
72f6dc61 |
288 | aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.OcclusionTexture, Graphic3d_TextureUnit_Occlusion)); |
a4815d55 |
289 | } |
72f6dc61 |
290 | if (!myPbrMat.NormalTexture.IsNull()) |
a4815d55 |
291 | { |
72f6dc61 |
292 | aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.NormalTexture, Graphic3d_TextureUnit_Normal)); |
a4815d55 |
293 | } |
72f6dc61 |
294 | if (!myPbrMat.MetallicRoughnessTexture.IsNull()) |
a4815d55 |
295 | { |
72f6dc61 |
296 | aTextureSet->SetValue (aTexIter++, new XCAFPrs_Texture (*myPbrMat.MetallicRoughnessTexture, Graphic3d_TextureUnit_MetallicRoughness)); |
a4815d55 |
297 | } |
72f6dc61 |
298 | |
299 | theAspect->SetTextureSet (aTextureSet); |
300 | theAspect->SetTextureMapOn (true); |
a4815d55 |
301 | } |
bc73b006 |
302 | |
303 | //======================================================================= |
304 | //function : DumpJson |
305 | //purpose : |
306 | //======================================================================= |
307 | void XCAFDoc_VisMaterial::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const |
308 | { |
309 | OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream) |
310 | |
311 | OCCT_DUMP_BASE_CLASS (theOStream, theDepth, TDF_Attribute) |
312 | |
313 | OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myRawName.get()) |
314 | |
315 | OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myPbrMat) |
316 | OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCommonMat) |
317 | |
318 | OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAlphaMode) |
319 | OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAlphaCutOff) |
320 | OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsDoubleSided) |
321 | } |