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 <BinMXCAFDoc_VisMaterialDriver.hxx>
15
16 #include <BinObjMgt_Persistent.hxx>
17 #include <Message_Messenger.hxx>
18 #include <XCAFDoc_VisMaterial.hxx>
19
IMPLEMENT_STANDARD_RTTIEXT(BinMXCAFDoc_VisMaterialDriver,BinMDF_ADriver)20 IMPLEMENT_STANDARD_RTTIEXT(BinMXCAFDoc_VisMaterialDriver, BinMDF_ADriver)
21
22 //! Encode alpha mode into character.
23 static Standard_Byte alphaModeToChar (Graphic3d_AlphaMode theMode)
24 {
25 switch (theMode)
26 {
27 case Graphic3d_AlphaMode_Opaque: return 'O';
28 case Graphic3d_AlphaMode_Mask: return 'M';
29 case Graphic3d_AlphaMode_Blend: return 'B';
30 case Graphic3d_AlphaMode_MaskBlend: return 'b';
31 case Graphic3d_AlphaMode_BlendAuto: return 'A';
32 }
33 return 'A';
34 }
35
36 //! Decode alpha mode from character.
alphaModeFromChar(Standard_Byte theMode)37 static Graphic3d_AlphaMode alphaModeFromChar (Standard_Byte theMode)
38 {
39 switch (theMode)
40 {
41 case 'O': return Graphic3d_AlphaMode_Opaque;
42 case 'M': return Graphic3d_AlphaMode_Mask;
43 case 'B': return Graphic3d_AlphaMode_Blend;
44 case 'b': return Graphic3d_AlphaMode_MaskBlend;
45 case 'A': return Graphic3d_AlphaMode_BlendAuto;
46 }
47 return Graphic3d_AlphaMode_BlendAuto;
48 }
49
50 //! Encode face culling mode into character.
faceCullToChar(Graphic3d_TypeOfBackfacingModel theMode)51 static Standard_Byte faceCullToChar (Graphic3d_TypeOfBackfacingModel theMode)
52 {
53 switch (theMode)
54 {
55 case Graphic3d_TypeOfBackfacingModel_Auto: return '0';
56 case Graphic3d_TypeOfBackfacingModel_BackCulled: return 'B';
57 case Graphic3d_TypeOfBackfacingModel_DoubleSided: return '1';
58 }
59 return '0';
60 }
61
62 //! Decode face culling mode from character.
faceCullFromChar(Standard_Byte theMode)63 static Graphic3d_TypeOfBackfacingModel faceCullFromChar (Standard_Byte theMode)
64 {
65 switch (theMode)
66 {
67 case '0': return Graphic3d_TypeOfBackfacingModel_Auto;
68 case 'B': return Graphic3d_TypeOfBackfacingModel_BackCulled;
69 case '1': return Graphic3d_TypeOfBackfacingModel_DoubleSided;
70 }
71 return Graphic3d_TypeOfBackfacingModel_Auto;
72 }
73
74 //! Encode vec3.
writeVec3(BinObjMgt_Persistent & theTarget,const Graphic3d_Vec3 & theVec3)75 static void writeVec3 (BinObjMgt_Persistent& theTarget,
76 const Graphic3d_Vec3& theVec3)
77 {
78 theTarget.PutShortReal (theVec3[0]);
79 theTarget.PutShortReal (theVec3[1]);
80 theTarget.PutShortReal (theVec3[2]);
81 }
82
83 //! Encode vec4.
writeVec4(BinObjMgt_Persistent & theTarget,const Graphic3d_Vec4 & theVec4)84 static void writeVec4 (BinObjMgt_Persistent& theTarget,
85 const Graphic3d_Vec4& theVec4)
86 {
87 theTarget.PutShortReal (theVec4[0]);
88 theTarget.PutShortReal (theVec4[1]);
89 theTarget.PutShortReal (theVec4[2]);
90 theTarget.PutShortReal (theVec4[3]);
91 }
92
93 //! Decode vec3.
readVec3(const BinObjMgt_Persistent & theSource,Graphic3d_Vec3 & theVec3)94 static void readVec3 (const BinObjMgt_Persistent& theSource,
95 Graphic3d_Vec3& theVec3)
96 {
97 theSource.GetShortReal (theVec3[0]);
98 theSource.GetShortReal (theVec3[1]);
99 theSource.GetShortReal (theVec3[2]);
100 }
101
102 //! Decode vec3.
readColor(const BinObjMgt_Persistent & theSource,Quantity_Color & theColor)103 static void readColor (const BinObjMgt_Persistent& theSource,
104 Quantity_Color& theColor)
105 {
106 Graphic3d_Vec3 aVec3;
107 readVec3 (theSource, aVec3);
108 theColor = Quantity_Color (aVec3);
109 }
110
111 //! Decode vec4.
readColor(const BinObjMgt_Persistent & theSource,Quantity_ColorRGBA & theColor)112 static void readColor (const BinObjMgt_Persistent& theSource,
113 Quantity_ColorRGBA& theColor)
114 {
115 Graphic3d_Vec4 aVec4;
116 theSource.GetShortReal (aVec4[0]);
117 theSource.GetShortReal (aVec4[1]);
118 theSource.GetShortReal (aVec4[2]);
119 theSource.GetShortReal (aVec4[3]);
120 theColor = Quantity_ColorRGBA (aVec4);
121 }
122
123 //! Encode texture path.
writeTexture(BinObjMgt_Persistent & theTarget,const Handle (Image_Texture)& theImage)124 static void writeTexture (BinObjMgt_Persistent& theTarget,
125 const Handle(Image_Texture)& theImage)
126 {
127 theTarget.PutAsciiString (!theImage.IsNull()
128 && !theImage->FilePath().IsEmpty()
129 && theImage->FileOffset() == -1
130 ? theImage->FilePath()
131 : "");
132 }
133
134 //! Decode texture path.
readTexture(const BinObjMgt_Persistent & theSource,Handle (Image_Texture)& theTexture)135 static void readTexture (const BinObjMgt_Persistent& theSource,
136 Handle(Image_Texture)& theTexture)
137 {
138 TCollection_AsciiString aPath;
139 theSource.GetAsciiString (aPath);
140 if (!aPath.IsEmpty())
141 {
142 theTexture = new Image_Texture (aPath);
143 }
144 }
145
146 //=======================================================================
147 //function : Constructor
148 //purpose :
149 //=======================================================================
BinMXCAFDoc_VisMaterialDriver(const Handle (Message_Messenger)& theMsgDriver)150 BinMXCAFDoc_VisMaterialDriver::BinMXCAFDoc_VisMaterialDriver (const Handle(Message_Messenger)& theMsgDriver)
151 : BinMDF_ADriver(theMsgDriver, STANDARD_TYPE(XCAFDoc_VisMaterial)->Name())
152 {
153 }
154
155 //=======================================================================
156 //function : NewEmpty
157 //purpose :
158 //=======================================================================
Handle(TDF_Attribute)159 Handle(TDF_Attribute) BinMXCAFDoc_VisMaterialDriver::NewEmpty() const
160 {
161 return new XCAFDoc_VisMaterial();
162 }
163
164 //=======================================================================
165 //function : Paste
166 //purpose :
167 //=======================================================================
Paste(const BinObjMgt_Persistent & theSource,const Handle (TDF_Attribute)& theTarget,BinObjMgt_RRelocationTable &) const168 Standard_Boolean BinMXCAFDoc_VisMaterialDriver::Paste (const BinObjMgt_Persistent& theSource,
169 const Handle(TDF_Attribute)& theTarget,
170 BinObjMgt_RRelocationTable& /*theRelocTable*/) const
171 {
172 Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theTarget);
173 Standard_Byte aVerMaj = 0, aVerMin = 0;
174 theSource.GetByte (aVerMaj);
175 theSource.GetByte (aVerMin);
176 if (aVerMaj < 1 || aVerMaj > MaterialVersionMajor)
177 {
178 myMessageDriver->Send (TCollection_AsciiString ("Skipping XCAFDoc_VisMaterial of unknown version ")
179 + Standard_Integer(aVerMaj) + "." + Standard_Integer(aVerMin)
180 + " (supported version: " + Standard_Integer(MaterialVersionMajor) + "." + Standard_Integer(MaterialVersionMinor) + ")");
181 return false;
182 }
183
184 Standard_Byte isDoubleSided = 0, anAlphaMode = 0;
185 Standard_ShortReal anAlphaCutOff = 0.5f;
186 theSource.GetByte (isDoubleSided);
187 theSource.GetByte (anAlphaMode);
188 theSource.GetShortReal (anAlphaCutOff);
189 aMat->SetFaceCulling (faceCullFromChar (isDoubleSided));
190 aMat->SetAlphaMode (alphaModeFromChar (anAlphaMode), anAlphaCutOff);
191
192 XCAFDoc_VisMaterialPBR aPbrMat;
193 theSource.GetBoolean (aPbrMat.IsDefined);
194 if (aPbrMat.IsDefined)
195 {
196 readColor (theSource, aPbrMat.BaseColor);
197 readVec3 (theSource, aPbrMat.EmissiveFactor);
198 theSource.GetShortReal (aPbrMat.Metallic);
199 theSource.GetShortReal (aPbrMat.Roughness);
200 readTexture (theSource, aPbrMat.BaseColorTexture);
201 readTexture (theSource, aPbrMat.MetallicRoughnessTexture);
202 readTexture (theSource, aPbrMat.EmissiveTexture);
203 readTexture (theSource, aPbrMat.OcclusionTexture);
204 readTexture (theSource, aPbrMat.NormalTexture);
205 aMat->SetPbrMaterial (aPbrMat);
206 }
207
208 bool hasComMat = false;
209 theSource.GetBoolean (hasComMat);
210 if (hasComMat)
211 {
212 XCAFDoc_VisMaterialCommon aComMat;
213 aComMat.IsDefined = true;
214 readColor (theSource, aComMat.AmbientColor);
215 readColor (theSource, aComMat.DiffuseColor);
216 readColor (theSource, aComMat.SpecularColor);
217 readColor (theSource, aComMat.EmissiveColor);
218 theSource.GetShortReal (aComMat.Shininess);
219 theSource.GetShortReal (aComMat.Transparency);
220 readTexture (theSource, aComMat.DiffuseTexture);
221 aMat->SetCommonMaterial (aComMat);
222 }
223
224 if (aVerMaj > MaterialVersionMajor_1
225 || (aVerMaj == MaterialVersionMajor_1
226 && aVerMin >= MaterialVersionMinor_1))
227 {
228 if (aPbrMat.IsDefined)
229 {
230 theSource.GetShortReal (aPbrMat.RefractionIndex);
231 }
232 }
233
234 if (aPbrMat.IsDefined)
235 {
236 aMat->SetPbrMaterial (aPbrMat);
237 }
238
239 return Standard_True;
240 }
241
242 //=======================================================================
243 //function : Paste
244 //purpose :
245 //=======================================================================
Paste(const Handle (TDF_Attribute)& theSource,BinObjMgt_Persistent & theTarget,BinObjMgt_SRelocationTable &) const246 void BinMXCAFDoc_VisMaterialDriver::Paste (const Handle(TDF_Attribute)& theSource,
247 BinObjMgt_Persistent& theTarget,
248 BinObjMgt_SRelocationTable& ) const
249 {
250 Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theSource);
251 theTarget.PutByte (MaterialVersionMajor);
252 theTarget.PutByte (MaterialVersionMinor);
253
254 theTarget.PutByte (faceCullToChar (aMat->FaceCulling()));
255 theTarget.PutByte (alphaModeToChar (aMat->AlphaMode()));
256 theTarget.PutShortReal (aMat->AlphaCutOff());
257
258 theTarget.PutBoolean (aMat->HasPbrMaterial());
259 if (aMat->HasPbrMaterial())
260 {
261 const XCAFDoc_VisMaterialPBR& aPbrMat = aMat->PbrMaterial();
262 writeVec4 (theTarget, aPbrMat.BaseColor);
263 writeVec3 (theTarget, aPbrMat.EmissiveFactor);
264 theTarget.PutShortReal (aPbrMat.Metallic);
265 theTarget.PutShortReal (aPbrMat.Roughness);
266 writeTexture (theTarget, aPbrMat.BaseColorTexture);
267 writeTexture (theTarget, aPbrMat.MetallicRoughnessTexture);
268 writeTexture (theTarget, aPbrMat.EmissiveTexture);
269 writeTexture (theTarget, aPbrMat.OcclusionTexture);
270 writeTexture (theTarget, aPbrMat.NormalTexture);
271 }
272
273 theTarget.PutBoolean (aMat->HasCommonMaterial());
274 if (aMat->HasCommonMaterial())
275 {
276 const XCAFDoc_VisMaterialCommon& aComMat = aMat->CommonMaterial();
277 writeVec3 (theTarget, aComMat.AmbientColor);
278 writeVec3 (theTarget, aComMat.DiffuseColor);
279 writeVec3 (theTarget, aComMat.SpecularColor);
280 writeVec3 (theTarget, aComMat.EmissiveColor);
281 theTarget.PutShortReal (aComMat.Shininess);
282 theTarget.PutShortReal (aComMat.Transparency);
283 writeTexture (theTarget, aComMat.DiffuseTexture);
284 }
285
286 if (aMat->HasPbrMaterial())
287 {
288 theTarget.PutShortReal (aMat->PbrMaterial().RefractionIndex);
289 }
290 }
291