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 <XmlMXCAFDoc_VisMaterialDriver.hxx>
16 #include <Message_Messenger.hxx>
17 #include <XCAFDoc_VisMaterial.hxx>
18 #include <XmlObjMgt.hxx>
19 #include <XmlObjMgt_Persistent.hxx>
21 IMPLEMENT_STANDARD_RTTIEXT(XmlMXCAFDoc_VisMaterialDriver, XmlMDF_ADriver)
23 IMPLEMENT_DOMSTRING(IsDoubleSided, "isdoublesided")
24 IMPLEMENT_DOMSTRING(AlphaMode, "alpha_mode")
25 IMPLEMENT_DOMSTRING(AlphaCutOff, "alpha_cutoff")
27 IMPLEMENT_DOMSTRING(BaseColor, "base_color")
28 IMPLEMENT_DOMSTRING(EmissiveFactor, "emissive_factor")
29 IMPLEMENT_DOMSTRING(Metallic, "metallic")
30 IMPLEMENT_DOMSTRING(Roughness, "roughness")
31 IMPLEMENT_DOMSTRING(BaseColorTexture, "base_color_texture")
32 IMPLEMENT_DOMSTRING(MetallicRoughnessTexture, "metallic_roughness_texture")
33 IMPLEMENT_DOMSTRING(EmissiveTexture, "emissive_texture")
34 IMPLEMENT_DOMSTRING(OcclusionTexture, "occlusion_texture")
35 IMPLEMENT_DOMSTRING(NormalTexture, "normal_texture")
37 IMPLEMENT_DOMSTRING(AmbientColor, "ambient_color")
38 IMPLEMENT_DOMSTRING(DiffuseColor, "diffuse_color")
39 IMPLEMENT_DOMSTRING(SpecularColor, "specular_color")
40 IMPLEMENT_DOMSTRING(EmissiveColor, "emissive_color")
41 IMPLEMENT_DOMSTRING(Shininess, "shininess")
42 IMPLEMENT_DOMSTRING(Transparency, "transparency")
43 IMPLEMENT_DOMSTRING(DiffuseTexture, "diffuse_texture")
45 //! Encode alpha mode into character.
46 static const char* alphaModeToString (Graphic3d_AlphaMode theMode)
50 case Graphic3d_AlphaMode_Opaque: return "Opaque";
51 case Graphic3d_AlphaMode_Mask: return "Mask";
52 case Graphic3d_AlphaMode_Blend: return "Blend";
53 case Graphic3d_AlphaMode_BlendAuto: return "Auto";
58 //! Decode alpha mode from string.
59 static Graphic3d_AlphaMode alphaModeFromString (const char* theMode)
63 case 'O': return Graphic3d_AlphaMode_Opaque;
64 case 'M': return Graphic3d_AlphaMode_Mask;
65 case 'B': return Graphic3d_AlphaMode_Blend;
66 case 'A': return Graphic3d_AlphaMode_BlendAuto;
68 return Graphic3d_AlphaMode_BlendAuto;
71 //! Encode short real value.
72 static void writeReal (XmlObjMgt_Persistent& theTarget,
73 const XmlObjMgt_DOMString& theName,
74 const Standard_ShortReal theValue)
76 theTarget.Element().setAttribute (theName, TCollection_AsciiString(theValue).ToCString());
79 //! Encode short real value.
80 static bool readReal (const XmlObjMgt_Element& theElement,
81 const XmlObjMgt_DOMString& theName,
82 Standard_ShortReal& theValue)
84 Standard_Real aValue = 0.0;
85 if (XmlObjMgt::GetReal (theElement.getAttribute (theName), aValue))
87 theValue = (Standard_ShortReal )aValue;
94 static void writeVec3 (XmlObjMgt_Persistent& theTarget,
95 const XmlObjMgt_DOMString& theName,
96 const Graphic3d_Vec3& theVec3)
98 TCollection_AsciiString aString = TCollection_AsciiString() + theVec3[0] + " " + theVec3[1] + " " + theVec3[2];
99 theTarget.Element().setAttribute (theName, aString.ToCString());
103 static bool readVec3 (const XmlObjMgt_Element& theElement,
104 const XmlObjMgt_DOMString& theName,
105 Graphic3d_Vec3& theVec3)
107 Graphic3d_Vec3 aVec3;
108 LDOMString aString = theElement.getAttribute (theName);
109 const char* aPos = aString.GetString();
111 aVec3[0] = (float )Strtod (aPos, &aNext);
113 aVec3[1] = (float )Strtod (aPos, &aNext);
115 aVec3[2] = (float )Strtod (aPos, &aNext);
125 static bool readColor (const XmlObjMgt_Element& theElement,
126 const XmlObjMgt_DOMString& theName,
127 Quantity_Color& theColor)
129 Graphic3d_Vec3 aVec3;
130 if (readVec3 (theElement, theName, aVec3))
132 theColor = Quantity_Color (aVec3);
139 static void writeVec4 (XmlObjMgt_Persistent& theTarget,
140 const XmlObjMgt_DOMString& theName,
141 const Graphic3d_Vec4& theVec4)
143 TCollection_AsciiString aString = TCollection_AsciiString() + theVec4[0] + " " + theVec4[1] + " " + theVec4[2] + " " + theVec4[3];
144 theTarget.Element().setAttribute (theName, aString.ToCString());
148 static bool readVec4 (const XmlObjMgt_Element& theElement,
149 const XmlObjMgt_DOMString& theName,
150 Graphic3d_Vec4& theVec4)
152 Graphic3d_Vec4 aVec4;
153 LDOMString aString = theElement.getAttribute (theName);
154 const char* aPos = aString.GetString();
156 aVec4[0] = (float )Strtod (aPos, &aNext);
158 aVec4[1] = (float )Strtod (aPos, &aNext);
160 aVec4[2] = (float )Strtod (aPos, &aNext);
162 aVec4[3] = (float )Strtod (aPos, &aNext);
172 static bool readColor (const XmlObjMgt_Element& theElement,
173 const XmlObjMgt_DOMString& theName,
174 Quantity_ColorRGBA& theColor)
176 Graphic3d_Vec4 aVec4;
177 if (readVec4 (theElement, theName, aVec4))
179 theColor = Quantity_ColorRGBA (aVec4);
185 //! Encode texture path.
186 static void writeTexture (XmlObjMgt_Persistent& theTarget,
187 const XmlObjMgt_DOMString& theName,
188 const Handle(Image_Texture)& theImage)
190 if (!theImage.IsNull()
191 && !theImage->FilePath().IsEmpty()
192 && theImage->FileOffset() == -1)
194 theTarget.Element().setAttribute (theName, theImage->FilePath().ToCString());
198 //! Decode texture path.
199 static void readTexture (const XmlObjMgt_Element& theElement,
200 const XmlObjMgt_DOMString& theName,
201 Handle(Image_Texture)& theImage)
203 TCollection_AsciiString aPath (theElement.getAttribute (theName).GetString());
204 if (!aPath.IsEmpty())
206 theImage = new Image_Texture (aPath);
210 //=======================================================================
211 //function : XmlMXCAFDoc_VisMaterialDriver
213 //=======================================================================
214 XmlMXCAFDoc_VisMaterialDriver::XmlMXCAFDoc_VisMaterialDriver (const Handle(Message_Messenger)& theMsgDriver)
215 : XmlMDF_ADriver (theMsgDriver, "xcaf", "VisMaterial")
220 //=======================================================================
221 //function : NewEmpty
223 //=======================================================================
224 Handle(TDF_Attribute) XmlMXCAFDoc_VisMaterialDriver::NewEmpty() const
226 return new XCAFDoc_VisMaterial();
229 //=======================================================================
231 //purpose : persistent -> transient (retrieve)
232 //=======================================================================
233 Standard_Boolean XmlMXCAFDoc_VisMaterialDriver::Paste (const XmlObjMgt_Persistent& theSource,
234 const Handle(TDF_Attribute)& theTarget,
235 XmlObjMgt_RRelocationTable& ) const
237 Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theTarget);
239 const XmlObjMgt_DOMString aDoubleSidedStr = theSource.Element().getAttribute (::IsDoubleSided());
240 Standard_Integer isDoubleSided = 1;
241 aDoubleSidedStr.GetInteger (isDoubleSided);
242 Standard_ShortReal anAlphaCutOff = 0.5f;
243 readReal (theSource, ::AlphaCutOff(), anAlphaCutOff);
244 aMat->SetDoubleSided (isDoubleSided != 0);
245 aMat->SetAlphaMode (alphaModeFromString (theSource.Element().getAttribute (::AlphaMode()).GetString()), anAlphaCutOff);
247 Quantity_ColorRGBA aBaseColor;
248 if (readColor (theSource, ::BaseColor(), aBaseColor))
250 XCAFDoc_VisMaterialPBR aPbrMat;
251 aPbrMat.IsDefined = true;
252 aPbrMat.BaseColor = aBaseColor;
253 readVec3 (theSource, ::EmissiveFactor(), aPbrMat.EmissiveFactor);
254 readReal (theSource, ::Metallic(), aPbrMat.Metallic);
255 readReal (theSource, ::Roughness(), aPbrMat.Roughness);
256 readTexture (theSource, ::BaseColorTexture(), aPbrMat.BaseColorTexture);
257 readTexture (theSource, ::MetallicRoughnessTexture(), aPbrMat.MetallicRoughnessTexture);
258 readTexture (theSource, ::EmissiveTexture(), aPbrMat.EmissiveTexture);
259 readTexture (theSource, ::OcclusionTexture(), aPbrMat.OcclusionTexture);
260 readTexture (theSource, ::NormalTexture(), aPbrMat.NormalTexture);
261 aMat->SetPbrMaterial (aPbrMat);
264 Quantity_Color aDiffColor;
265 if (readColor (theSource, ::DiffuseColor(), aDiffColor))
267 XCAFDoc_VisMaterialCommon aComMat;
268 aComMat.IsDefined = true;
269 aComMat.DiffuseColor = aDiffColor;
270 readColor (theSource, ::AmbientColor(), aComMat.AmbientColor);
271 readColor (theSource, ::SpecularColor(), aComMat.SpecularColor);
272 readColor (theSource, ::EmissiveColor(), aComMat.EmissiveColor);
273 readReal (theSource, ::Shininess(), aComMat.Shininess);
274 readReal (theSource, ::Transparency(), aComMat.Transparency);
275 readTexture (theSource, ::DiffuseTexture(), aComMat.DiffuseTexture);
276 aMat->SetCommonMaterial (aComMat);
278 return Standard_True;
281 //=======================================================================
283 //purpose : transient -> persistent (store)
284 //=======================================================================
285 void XmlMXCAFDoc_VisMaterialDriver::Paste (const Handle(TDF_Attribute)& theSource,
286 XmlObjMgt_Persistent& theTarget,
287 XmlObjMgt_SRelocationTable& ) const
289 Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theSource);
291 theTarget.Element().setAttribute (::IsDoubleSided(), aMat->IsDoubleSided() ? 1 : 0);
292 theTarget.Element().setAttribute (::AlphaMode(), alphaModeToString (aMat->AlphaMode()));
293 writeReal (theTarget, ::AlphaCutOff(), aMat->AlphaCutOff());
294 if (aMat->HasPbrMaterial())
296 const XCAFDoc_VisMaterialPBR& aPbrMat = aMat->PbrMaterial();
297 writeVec4 (theTarget, ::BaseColor(), aPbrMat.BaseColor);
298 writeVec3 (theTarget, ::EmissiveFactor(), aPbrMat.EmissiveFactor);
299 writeReal (theTarget, ::Metallic(), aPbrMat.Metallic);
300 writeReal (theTarget, ::Roughness(), aPbrMat.Roughness);
301 writeTexture (theTarget, ::BaseColorTexture(), aPbrMat.BaseColorTexture);
302 writeTexture (theTarget, ::MetallicRoughnessTexture(), aPbrMat.MetallicRoughnessTexture);
303 writeTexture (theTarget, ::EmissiveTexture(), aPbrMat.EmissiveTexture);
304 writeTexture (theTarget, ::OcclusionTexture(), aPbrMat.OcclusionTexture);
305 writeTexture (theTarget, ::NormalTexture(), aPbrMat.NormalTexture);
308 if (aMat->HasCommonMaterial())
310 const XCAFDoc_VisMaterialCommon& aComMat = aMat->CommonMaterial();
311 writeVec3 (theTarget, ::AmbientColor(), aComMat.AmbientColor);
312 writeVec3 (theTarget, ::DiffuseColor(), aComMat.DiffuseColor);
313 writeVec3 (theTarget, ::SpecularColor(), aComMat.SpecularColor);
314 writeVec3 (theTarget, ::EmissiveColor(), aComMat.EmissiveColor);
315 writeReal (theTarget, ::Shininess(), aComMat.Shininess);
316 writeReal (theTarget, ::Transparency(), aComMat.Transparency);
317 writeTexture (theTarget, ::DiffuseTexture(), aComMat.DiffuseTexture);