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(RefractionIndex, "ior")
29 IMPLEMENT_DOMSTRING(EmissiveFactor, "emissive_factor")
30 IMPLEMENT_DOMSTRING(Metallic, "metallic")
31 IMPLEMENT_DOMSTRING(Roughness, "roughness")
32 IMPLEMENT_DOMSTRING(BaseColorTexture, "base_color_texture")
33 IMPLEMENT_DOMSTRING(MetallicRoughnessTexture, "metallic_roughness_texture")
34 IMPLEMENT_DOMSTRING(EmissiveTexture, "emissive_texture")
35 IMPLEMENT_DOMSTRING(OcclusionTexture, "occlusion_texture")
36 IMPLEMENT_DOMSTRING(NormalTexture, "normal_texture")
38 IMPLEMENT_DOMSTRING(AmbientColor, "ambient_color")
39 IMPLEMENT_DOMSTRING(DiffuseColor, "diffuse_color")
40 IMPLEMENT_DOMSTRING(SpecularColor, "specular_color")
41 IMPLEMENT_DOMSTRING(EmissiveColor, "emissive_color")
42 IMPLEMENT_DOMSTRING(Shininess, "shininess")
43 IMPLEMENT_DOMSTRING(Transparency, "transparency")
44 IMPLEMENT_DOMSTRING(DiffuseTexture, "diffuse_texture")
46 //! Encode alpha mode into character.
47 static const char* alphaModeToString (Graphic3d_AlphaMode theMode)
51 case Graphic3d_AlphaMode_Opaque: return "Opaque";
52 case Graphic3d_AlphaMode_Mask: return "Mask";
53 case Graphic3d_AlphaMode_Blend: return "Blend";
54 case Graphic3d_AlphaMode_BlendAuto: return "Auto";
59 //! Decode alpha mode from string.
60 static Graphic3d_AlphaMode alphaModeFromString (const char* theMode)
64 case 'O': return Graphic3d_AlphaMode_Opaque;
65 case 'M': return Graphic3d_AlphaMode_Mask;
66 case 'B': return Graphic3d_AlphaMode_Blend;
67 case 'A': return Graphic3d_AlphaMode_BlendAuto;
69 return Graphic3d_AlphaMode_BlendAuto;
72 //! Encode short real value.
73 static void writeReal (XmlObjMgt_Persistent& theTarget,
74 const XmlObjMgt_DOMString& theName,
75 const Standard_ShortReal theValue)
77 theTarget.Element().setAttribute (theName, TCollection_AsciiString(theValue).ToCString());
80 //! Encode short real value.
81 static bool readReal (const XmlObjMgt_Element& theElement,
82 const XmlObjMgt_DOMString& theName,
83 Standard_ShortReal& theValue)
85 Standard_Real aValue = 0.0;
86 if (XmlObjMgt::GetReal (theElement.getAttribute (theName), aValue))
88 theValue = (Standard_ShortReal )aValue;
95 static void writeVec3 (XmlObjMgt_Persistent& theTarget,
96 const XmlObjMgt_DOMString& theName,
97 const Graphic3d_Vec3& theVec3)
99 TCollection_AsciiString aString = TCollection_AsciiString() + theVec3[0] + " " + theVec3[1] + " " + theVec3[2];
100 theTarget.Element().setAttribute (theName, aString.ToCString());
104 static bool readVec3 (const XmlObjMgt_Element& theElement,
105 const XmlObjMgt_DOMString& theName,
106 Graphic3d_Vec3& theVec3)
108 Graphic3d_Vec3 aVec3;
109 LDOMString aString = theElement.getAttribute (theName);
110 const char* aPos = aString.GetString();
112 aVec3[0] = (float )Strtod (aPos, &aNext);
114 aVec3[1] = (float )Strtod (aPos, &aNext);
116 aVec3[2] = (float )Strtod (aPos, &aNext);
126 static bool readColor (const XmlObjMgt_Element& theElement,
127 const XmlObjMgt_DOMString& theName,
128 Quantity_Color& theColor)
130 Graphic3d_Vec3 aVec3;
131 if (readVec3 (theElement, theName, aVec3))
133 theColor = Quantity_Color (aVec3);
140 static void writeVec4 (XmlObjMgt_Persistent& theTarget,
141 const XmlObjMgt_DOMString& theName,
142 const Graphic3d_Vec4& theVec4)
144 TCollection_AsciiString aString = TCollection_AsciiString() + theVec4[0] + " " + theVec4[1] + " " + theVec4[2] + " " + theVec4[3];
145 theTarget.Element().setAttribute (theName, aString.ToCString());
149 static bool readVec4 (const XmlObjMgt_Element& theElement,
150 const XmlObjMgt_DOMString& theName,
151 Graphic3d_Vec4& theVec4)
153 Graphic3d_Vec4 aVec4;
154 LDOMString aString = theElement.getAttribute (theName);
155 const char* aPos = aString.GetString();
157 aVec4[0] = (float )Strtod (aPos, &aNext);
159 aVec4[1] = (float )Strtod (aPos, &aNext);
161 aVec4[2] = (float )Strtod (aPos, &aNext);
163 aVec4[3] = (float )Strtod (aPos, &aNext);
173 static bool readColor (const XmlObjMgt_Element& theElement,
174 const XmlObjMgt_DOMString& theName,
175 Quantity_ColorRGBA& theColor)
177 Graphic3d_Vec4 aVec4;
178 if (readVec4 (theElement, theName, aVec4))
180 theColor = Quantity_ColorRGBA (aVec4);
186 //! Encode texture path.
187 static void writeTexture (XmlObjMgt_Persistent& theTarget,
188 const XmlObjMgt_DOMString& theName,
189 const Handle(Image_Texture)& theImage)
191 if (!theImage.IsNull()
192 && !theImage->FilePath().IsEmpty()
193 && theImage->FileOffset() == -1)
195 theTarget.Element().setAttribute (theName, theImage->FilePath().ToCString());
199 //! Decode texture path.
200 static void readTexture (const XmlObjMgt_Element& theElement,
201 const XmlObjMgt_DOMString& theName,
202 Handle(Image_Texture)& theImage)
204 TCollection_AsciiString aPath (theElement.getAttribute (theName).GetString());
205 if (!aPath.IsEmpty())
207 theImage = new Image_Texture (aPath);
211 //=======================================================================
212 //function : XmlMXCAFDoc_VisMaterialDriver
214 //=======================================================================
215 XmlMXCAFDoc_VisMaterialDriver::XmlMXCAFDoc_VisMaterialDriver (const Handle(Message_Messenger)& theMsgDriver)
216 : XmlMDF_ADriver (theMsgDriver, "xcaf", "VisMaterial")
221 //=======================================================================
222 //function : NewEmpty
224 //=======================================================================
225 Handle(TDF_Attribute) XmlMXCAFDoc_VisMaterialDriver::NewEmpty() const
227 return new XCAFDoc_VisMaterial();
230 //=======================================================================
232 //purpose : persistent -> transient (retrieve)
233 //=======================================================================
234 Standard_Boolean XmlMXCAFDoc_VisMaterialDriver::Paste (const XmlObjMgt_Persistent& theSource,
235 const Handle(TDF_Attribute)& theTarget,
236 XmlObjMgt_RRelocationTable& ) const
238 Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theTarget);
240 const XmlObjMgt_DOMString aDoubleSidedStr = theSource.Element().getAttribute (::IsDoubleSided());
241 Standard_Integer isDoubleSided = 1;
242 aDoubleSidedStr.GetInteger (isDoubleSided);
243 Standard_ShortReal anAlphaCutOff = 0.5f;
244 readReal (theSource, ::AlphaCutOff(), anAlphaCutOff);
245 aMat->SetDoubleSided (isDoubleSided != 0);
246 aMat->SetAlphaMode (alphaModeFromString (theSource.Element().getAttribute (::AlphaMode()).GetString()), anAlphaCutOff);
248 Quantity_ColorRGBA aBaseColor;
249 if (readColor (theSource, ::BaseColor(), aBaseColor))
251 XCAFDoc_VisMaterialPBR aPbrMat;
252 aPbrMat.IsDefined = true;
253 aPbrMat.BaseColor = aBaseColor;
254 readVec3 (theSource, ::EmissiveFactor(), aPbrMat.EmissiveFactor);
255 readReal (theSource, ::Metallic(), aPbrMat.Metallic);
256 readReal (theSource, ::Roughness(), aPbrMat.Roughness);
257 readReal (theSource, ::RefractionIndex(), aPbrMat.RefractionIndex);
258 readTexture (theSource, ::BaseColorTexture(), aPbrMat.BaseColorTexture);
259 readTexture (theSource, ::MetallicRoughnessTexture(), aPbrMat.MetallicRoughnessTexture);
260 readTexture (theSource, ::EmissiveTexture(), aPbrMat.EmissiveTexture);
261 readTexture (theSource, ::OcclusionTexture(), aPbrMat.OcclusionTexture);
262 readTexture (theSource, ::NormalTexture(), aPbrMat.NormalTexture);
263 aMat->SetPbrMaterial (aPbrMat);
266 Quantity_Color aDiffColor;
267 if (readColor (theSource, ::DiffuseColor(), aDiffColor))
269 XCAFDoc_VisMaterialCommon aComMat;
270 aComMat.IsDefined = true;
271 aComMat.DiffuseColor = aDiffColor;
272 readColor (theSource, ::AmbientColor(), aComMat.AmbientColor);
273 readColor (theSource, ::SpecularColor(), aComMat.SpecularColor);
274 readColor (theSource, ::EmissiveColor(), aComMat.EmissiveColor);
275 readReal (theSource, ::Shininess(), aComMat.Shininess);
276 readReal (theSource, ::Transparency(), aComMat.Transparency);
277 readTexture (theSource, ::DiffuseTexture(), aComMat.DiffuseTexture);
278 aMat->SetCommonMaterial (aComMat);
280 return Standard_True;
283 //=======================================================================
285 //purpose : transient -> persistent (store)
286 //=======================================================================
287 void XmlMXCAFDoc_VisMaterialDriver::Paste (const Handle(TDF_Attribute)& theSource,
288 XmlObjMgt_Persistent& theTarget,
289 XmlObjMgt_SRelocationTable& ) const
291 Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theSource);
293 theTarget.Element().setAttribute (::IsDoubleSided(), aMat->IsDoubleSided() ? 1 : 0);
294 theTarget.Element().setAttribute (::AlphaMode(), alphaModeToString (aMat->AlphaMode()));
295 writeReal (theTarget, ::AlphaCutOff(), aMat->AlphaCutOff());
296 if (aMat->HasPbrMaterial())
298 const XCAFDoc_VisMaterialPBR& aPbrMat = aMat->PbrMaterial();
299 writeVec4 (theTarget, ::BaseColor(), aPbrMat.BaseColor);
300 writeVec3 (theTarget, ::EmissiveFactor(), aPbrMat.EmissiveFactor);
301 writeReal (theTarget, ::Metallic(), aPbrMat.Metallic);
302 writeReal (theTarget, ::Roughness(), aPbrMat.Roughness);
303 writeReal (theTarget, ::RefractionIndex(), aPbrMat.RefractionIndex);
304 writeTexture (theTarget, ::BaseColorTexture(), aPbrMat.BaseColorTexture);
305 writeTexture (theTarget, ::MetallicRoughnessTexture(), aPbrMat.MetallicRoughnessTexture);
306 writeTexture (theTarget, ::EmissiveTexture(), aPbrMat.EmissiveTexture);
307 writeTexture (theTarget, ::OcclusionTexture(), aPbrMat.OcclusionTexture);
308 writeTexture (theTarget, ::NormalTexture(), aPbrMat.NormalTexture);
311 if (aMat->HasCommonMaterial())
313 const XCAFDoc_VisMaterialCommon& aComMat = aMat->CommonMaterial();
314 writeVec3 (theTarget, ::AmbientColor(), aComMat.AmbientColor);
315 writeVec3 (theTarget, ::DiffuseColor(), aComMat.DiffuseColor);
316 writeVec3 (theTarget, ::SpecularColor(), aComMat.SpecularColor);
317 writeVec3 (theTarget, ::EmissiveColor(), aComMat.EmissiveColor);
318 writeReal (theTarget, ::Shininess(), aComMat.Shininess);
319 writeReal (theTarget, ::Transparency(), aComMat.Transparency);
320 writeTexture (theTarget, ::DiffuseTexture(), aComMat.DiffuseTexture);