mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
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.
320 lines
12 KiB
C++
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);
|
|
}
|
|
}
|