1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00
occt/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.cxx
kgv a4815d5509 0029902: Data Exchange, XCAF - provide extended Material definition for visualization purposes
Introduced new attribute XCAFDoc_VisMaterial storing visualization material definition.

XCAFPrs_Style has been exteneded Material() property.
XCAFPrs_AISObject::DispatchStyles() maps new XCAFPrs_Style::Material() property onto graphics aspects.

RWGltf_GltfJsonParser and RWObj_CafReader now put Material definition into XCAF document instead of a color label.
RWGltf_MaterialMetallicRoughness - added missing properties AlphaMode, AlphaCutOff and IsDoubleSided;
fixed default values in constructor for Metallic and Roughness.

Added commands XGetAllVisMaterials, XGetVisMaterial, XAddVisMaterial,
XRemoveVisMaterial, XSetVisMaterial, XUnsetVisMaterial for working with
new visualization materials table in the document.
2019-10-22 15:15:53 +03:00

320 lines
12 KiB
C++

// Copyright (c) 2019 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <XmlMXCAFDoc_VisMaterialDriver.hxx>
#include <Message_Messenger.hxx>
#include <XCAFDoc_VisMaterial.hxx>
#include <XmlObjMgt.hxx>
#include <XmlObjMgt_Persistent.hxx>
IMPLEMENT_STANDARD_RTTIEXT(XmlMXCAFDoc_VisMaterialDriver, XmlMDF_ADriver)
IMPLEMENT_DOMSTRING(IsDoubleSided, "isdoublesided")
IMPLEMENT_DOMSTRING(AlphaMode, "alpha_mode")
IMPLEMENT_DOMSTRING(AlphaCutOff, "alpha_cutoff")
//
IMPLEMENT_DOMSTRING(BaseColor, "base_color")
IMPLEMENT_DOMSTRING(EmissiveFactor, "emissive_factor")
IMPLEMENT_DOMSTRING(Metallic, "metallic")
IMPLEMENT_DOMSTRING(Roughness, "roughness")
IMPLEMENT_DOMSTRING(BaseColorTexture, "base_color_texture")
IMPLEMENT_DOMSTRING(MetallicRoughnessTexture, "metallic_roughness_texture")
IMPLEMENT_DOMSTRING(EmissiveTexture, "emissive_texture")
IMPLEMENT_DOMSTRING(OcclusionTexture, "occlusion_texture")
IMPLEMENT_DOMSTRING(NormalTexture, "normal_texture")
//
IMPLEMENT_DOMSTRING(AmbientColor, "ambient_color")
IMPLEMENT_DOMSTRING(DiffuseColor, "diffuse_color")
IMPLEMENT_DOMSTRING(SpecularColor, "specular_color")
IMPLEMENT_DOMSTRING(EmissiveColor, "emissive_color")
IMPLEMENT_DOMSTRING(Shininess, "shininess")
IMPLEMENT_DOMSTRING(Transparency, "transparency")
IMPLEMENT_DOMSTRING(DiffuseTexture, "diffuse_texture")
//! Encode alpha mode into character.
static const char* alphaModeToString (Graphic3d_AlphaMode theMode)
{
switch (theMode)
{
case Graphic3d_AlphaMode_Opaque: return "Opaque";
case Graphic3d_AlphaMode_Mask: return "Mask";
case Graphic3d_AlphaMode_Blend: return "Blend";
case Graphic3d_AlphaMode_BlendAuto: return "Auto";
}
return "Auto";
}
//! Decode alpha mode from string.
static Graphic3d_AlphaMode alphaModeFromString (const char* theMode)
{
switch (*theMode)
{
case 'O': return Graphic3d_AlphaMode_Opaque;
case 'M': return Graphic3d_AlphaMode_Mask;
case 'B': return Graphic3d_AlphaMode_Blend;
case 'A': return Graphic3d_AlphaMode_BlendAuto;
}
return Graphic3d_AlphaMode_BlendAuto;
}
//! Encode short real value.
static void writeReal (XmlObjMgt_Persistent& theTarget,
const XmlObjMgt_DOMString& theName,
const Standard_ShortReal theValue)
{
theTarget.Element().setAttribute (theName, TCollection_AsciiString(theValue).ToCString());
}
//! Encode short real value.
static bool readReal (const XmlObjMgt_Element& theElement,
const XmlObjMgt_DOMString& theName,
Standard_ShortReal& theValue)
{
Standard_Real aValue = 0.0;
if (XmlObjMgt::GetReal (theElement.getAttribute (theName), aValue))
{
theValue = (Standard_ShortReal )aValue;
return true;
}
return false;
}
//! Encode vec3.
static void writeVec3 (XmlObjMgt_Persistent& theTarget,
const XmlObjMgt_DOMString& theName,
const Graphic3d_Vec3& theVec3)
{
TCollection_AsciiString aString = TCollection_AsciiString() + theVec3[0] + " " + theVec3[1] + " " + theVec3[2];
theTarget.Element().setAttribute (theName, aString.ToCString());
}
//! Decode vec3.
static bool readVec3 (const XmlObjMgt_Element& theElement,
const XmlObjMgt_DOMString& theName,
Graphic3d_Vec3& theVec3)
{
Graphic3d_Vec3 aVec3;
LDOMString aString = theElement.getAttribute (theName);
const char* aPos = aString.GetString();
char* aNext = NULL;
aVec3[0] = (float )Strtod (aPos, &aNext);
aPos = aNext;
aVec3[1] = (float )Strtod (aPos, &aNext);
aPos = aNext;
aVec3[2] = (float )Strtod (aPos, &aNext);
if (aPos != aNext)
{
theVec3 = aVec3;
return true;
}
return false;
}
//! Decode vec3.
static bool readColor (const XmlObjMgt_Element& theElement,
const XmlObjMgt_DOMString& theName,
Quantity_Color& theColor)
{
Graphic3d_Vec3 aVec3;
if (readVec3 (theElement, theName, aVec3))
{
theColor = Quantity_Color (aVec3);
return true;
}
return false;
}
//! Encode vec4.
static void writeVec4 (XmlObjMgt_Persistent& theTarget,
const XmlObjMgt_DOMString& theName,
const Graphic3d_Vec4& theVec4)
{
TCollection_AsciiString aString = TCollection_AsciiString() + theVec4[0] + " " + theVec4[1] + " " + theVec4[2] + " " + theVec4[3];
theTarget.Element().setAttribute (theName, aString.ToCString());
}
//! Decode vec34
static bool readVec4 (const XmlObjMgt_Element& theElement,
const XmlObjMgt_DOMString& theName,
Graphic3d_Vec4& theVec4)
{
Graphic3d_Vec4 aVec4;
LDOMString aString = theElement.getAttribute (theName);
const char* aPos = aString.GetString();
char* aNext = NULL;
aVec4[0] = (float )Strtod (aPos, &aNext);
aPos = aNext;
aVec4[1] = (float )Strtod (aPos, &aNext);
aPos = aNext;
aVec4[2] = (float )Strtod (aPos, &aNext);
aPos = aNext;
aVec4[3] = (float )Strtod (aPos, &aNext);
if (aPos != aNext)
{
theVec4 = aVec4;
return true;
}
return false;
}
//! Decode vec4.
static bool readColor (const XmlObjMgt_Element& theElement,
const XmlObjMgt_DOMString& theName,
Quantity_ColorRGBA& theColor)
{
Graphic3d_Vec4 aVec4;
if (readVec4 (theElement, theName, aVec4))
{
theColor = Quantity_ColorRGBA (aVec4);
return true;
}
return false;
}
//! Encode texture path.
static void writeTexture (XmlObjMgt_Persistent& theTarget,
const XmlObjMgt_DOMString& theName,
const Handle(Image_Texture)& theImage)
{
if (!theImage.IsNull()
&& !theImage->FilePath().IsEmpty()
&& theImage->FileOffset() == -1)
{
theTarget.Element().setAttribute (theName, theImage->FilePath().ToCString());
}
}
//! Decode texture path.
static void readTexture (const XmlObjMgt_Element& theElement,
const XmlObjMgt_DOMString& theName,
Handle(Image_Texture)& theImage)
{
TCollection_AsciiString aPath (theElement.getAttribute (theName).GetString());
if (!aPath.IsEmpty())
{
theImage = new Image_Texture (aPath);
}
}
//=======================================================================
//function : XmlMXCAFDoc_VisMaterialDriver
//purpose :
//=======================================================================
XmlMXCAFDoc_VisMaterialDriver::XmlMXCAFDoc_VisMaterialDriver (const Handle(Message_Messenger)& theMsgDriver)
: XmlMDF_ADriver (theMsgDriver, "xcaf", "VisMaterial")
{
//
}
//=======================================================================
//function : NewEmpty
//purpose :
//=======================================================================
Handle(TDF_Attribute) XmlMXCAFDoc_VisMaterialDriver::NewEmpty() const
{
return new XCAFDoc_VisMaterial();
}
//=======================================================================
//function : Paste
//purpose : persistent -> transient (retrieve)
//=======================================================================
Standard_Boolean XmlMXCAFDoc_VisMaterialDriver::Paste (const XmlObjMgt_Persistent& theSource,
const Handle(TDF_Attribute)& theTarget,
XmlObjMgt_RRelocationTable& ) const
{
Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theTarget);
const XmlObjMgt_DOMString aDoubleSidedStr = theSource.Element().getAttribute (::IsDoubleSided());
Standard_Integer isDoubleSided = 1;
aDoubleSidedStr.GetInteger (isDoubleSided);
Standard_ShortReal anAlphaCutOff = 0.5f;
readReal (theSource, ::AlphaCutOff(), anAlphaCutOff);
aMat->SetDoubleSided (isDoubleSided != 0);
aMat->SetAlphaMode (alphaModeFromString (theSource.Element().getAttribute (::AlphaMode()).GetString()), anAlphaCutOff);
Quantity_ColorRGBA aBaseColor;
if (readColor (theSource, ::BaseColor(), aBaseColor))
{
XCAFDoc_VisMaterialPBR aPbrMat;
aPbrMat.IsDefined = true;
aPbrMat.BaseColor = aBaseColor;
readVec3 (theSource, ::EmissiveFactor(), aPbrMat.EmissiveFactor);
readReal (theSource, ::Metallic(), aPbrMat.Metallic);
readReal (theSource, ::Roughness(), aPbrMat.Roughness);
readTexture (theSource, ::BaseColorTexture(), aPbrMat.BaseColorTexture);
readTexture (theSource, ::MetallicRoughnessTexture(), aPbrMat.MetallicRoughnessTexture);
readTexture (theSource, ::EmissiveTexture(), aPbrMat.EmissiveTexture);
readTexture (theSource, ::OcclusionTexture(), aPbrMat.OcclusionTexture);
readTexture (theSource, ::NormalTexture(), aPbrMat.NormalTexture);
aMat->SetPbrMaterial (aPbrMat);
}
Quantity_Color aDiffColor;
if (readColor (theSource, ::DiffuseColor(), aDiffColor))
{
XCAFDoc_VisMaterialCommon aComMat;
aComMat.IsDefined = true;
aComMat.DiffuseColor = aDiffColor;
readColor (theSource, ::AmbientColor(), aComMat.AmbientColor);
readColor (theSource, ::SpecularColor(), aComMat.SpecularColor);
readColor (theSource, ::EmissiveColor(), aComMat.EmissiveColor);
readReal (theSource, ::Shininess(), aComMat.Shininess);
readReal (theSource, ::Transparency(), aComMat.Transparency);
readTexture (theSource, ::DiffuseTexture(), aComMat.DiffuseTexture);
aMat->SetCommonMaterial (aComMat);
}
return Standard_True;
}
//=======================================================================
//function : Paste
//purpose : transient -> persistent (store)
//=======================================================================
void XmlMXCAFDoc_VisMaterialDriver::Paste (const Handle(TDF_Attribute)& theSource,
XmlObjMgt_Persistent& theTarget,
XmlObjMgt_SRelocationTable& ) const
{
Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theSource);
theTarget.Element().setAttribute (::IsDoubleSided(), aMat->IsDoubleSided() ? 1 : 0);
theTarget.Element().setAttribute (::AlphaMode(), alphaModeToString (aMat->AlphaMode()));
writeReal (theTarget, ::AlphaCutOff(), aMat->AlphaCutOff());
if (aMat->HasPbrMaterial())
{
const XCAFDoc_VisMaterialPBR& aPbrMat = aMat->PbrMaterial();
writeVec4 (theTarget, ::BaseColor(), aPbrMat.BaseColor);
writeVec3 (theTarget, ::EmissiveFactor(), aPbrMat.EmissiveFactor);
writeReal (theTarget, ::Metallic(), aPbrMat.Metallic);
writeReal (theTarget, ::Roughness(), aPbrMat.Roughness);
writeTexture (theTarget, ::BaseColorTexture(), aPbrMat.BaseColorTexture);
writeTexture (theTarget, ::MetallicRoughnessTexture(), aPbrMat.MetallicRoughnessTexture);
writeTexture (theTarget, ::EmissiveTexture(), aPbrMat.EmissiveTexture);
writeTexture (theTarget, ::OcclusionTexture(), aPbrMat.OcclusionTexture);
writeTexture (theTarget, ::NormalTexture(), aPbrMat.NormalTexture);
}
if (aMat->HasCommonMaterial())
{
const XCAFDoc_VisMaterialCommon& aComMat = aMat->CommonMaterial();
writeVec3 (theTarget, ::AmbientColor(), aComMat.AmbientColor);
writeVec3 (theTarget, ::DiffuseColor(), aComMat.DiffuseColor);
writeVec3 (theTarget, ::SpecularColor(), aComMat.SpecularColor);
writeVec3 (theTarget, ::EmissiveColor(), aComMat.EmissiveColor);
writeReal (theTarget, ::Shininess(), aComMat.Shininess);
writeReal (theTarget, ::Transparency(), aComMat.Transparency);
writeTexture (theTarget, ::DiffuseTexture(), aComMat.DiffuseTexture);
}
}