From: kgv Date: Wed, 3 Jul 2019 08:28:26 +0000 (+0300) Subject: 0029902: Data Exchange, XCAF - provide extended Material definition for visualization... X-Git-Tag: V7_5_0_beta~376 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=a4815d5509b863bea5204b39e9deb373d85fb63a 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. --- diff --git a/src/AIS/AIS_ColoredDrawer.hxx b/src/AIS/AIS_ColoredDrawer.hxx index 84b555a018..e3c8eee622 100644 --- a/src/AIS/AIS_ColoredDrawer.hxx +++ b/src/AIS/AIS_ColoredDrawer.hxx @@ -26,6 +26,7 @@ public: //! Default constructor. AIS_ColoredDrawer (const Handle(Prs3d_Drawer)& theLink) : myIsHidden (false), + myHasOwnMaterial(false), myHasOwnColor (false), myHasOwnTransp(false), myHasOwnWidth (false) @@ -36,6 +37,10 @@ public: bool IsHidden() const { return myIsHidden; } void SetHidden (const bool theToHide) { myIsHidden = theToHide;} + bool HasOwnMaterial() const { return myHasOwnMaterial; } + void UnsetOwnMaterial() { myHasOwnMaterial = false; } + void SetOwnMaterial() { myHasOwnMaterial = true; } + bool HasOwnColor() const { return myHasOwnColor; } void UnsetOwnColor() { myHasOwnColor = false; } void SetOwnColor (const Quantity_Color& /*theColor*/) { myHasOwnColor = true; } @@ -51,6 +56,7 @@ public: public: //! @name list of overridden properties bool myIsHidden; + bool myHasOwnMaterial; bool myHasOwnColor; bool myHasOwnTransp; bool myHasOwnWidth; diff --git a/src/AIS/AIS_ColoredShape.cxx b/src/AIS/AIS_ColoredShape.cxx index c433572a25..c5ca8990c2 100644 --- a/src/AIS/AIS_ColoredShape.cxx +++ b/src/AIS/AIS_ColoredShape.cxx @@ -333,7 +333,11 @@ void AIS_ColoredShape::SetMaterial (const Graphic3d_MaterialAspect& theMaterial) for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next()) { const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value(); - //if (aDrawer->HasOwnMaterial()) continue; + if (aDrawer->HasOwnMaterial()) + { + continue; + } + if (aDrawer->HasOwnShadingAspect()) { setMaterial (aDrawer, theMaterial, aDrawer->HasOwnColor(), aDrawer->HasOwnTransparency()); diff --git a/src/BinMXCAFDoc/BinMXCAFDoc.cxx b/src/BinMXCAFDoc/BinMXCAFDoc.cxx index 28b13c5abb..930ccd6e80 100644 --- a/src/BinMXCAFDoc/BinMXCAFDoc.cxx +++ b/src/BinMXCAFDoc/BinMXCAFDoc.cxx @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include #include @@ -77,6 +79,7 @@ void BinMXCAFDoc::AddDrivers(const Handle(BinMDF_ADriverTable)& theDriverTable, theDriverTable->AddDriver( new BinMXCAFDoc_DimensionDriver (theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_DimTolDriver (theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_MaterialDriver (theMsgDrv)); + theDriverTable->AddDriver( new BinMXCAFDoc_VisMaterialDriver (theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_NoteBalloonDriver (theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_NoteBinDataDriver (theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_NoteCommentDriver (theMsgDrv)); @@ -88,6 +91,7 @@ void BinMXCAFDoc::AddDrivers(const Handle(BinMDF_ADriverTable)& theDriverTable, theDriverTable->AddDriver( new BinMXCAFDoc_ShapeToolDriver (theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_DimTolToolDriver (theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_MaterialToolDriver(theMsgDrv)); + theDriverTable->AddDriver( new BinMXCAFDoc_VisMaterialToolDriver(theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_NotesToolDriver (theMsgDrv)); theDriverTable->AddDriver( new BinMXCAFDoc_ViewToolDriver (theMsgDrv)); } diff --git a/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialDriver.cxx b/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialDriver.cxx new file mode 100644 index 0000000000..2807225b72 --- /dev/null +++ b/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialDriver.cxx @@ -0,0 +1,245 @@ +// 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 + +#include +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(BinMXCAFDoc_VisMaterialDriver, BinMDF_ADriver) + +//! Encode alpha mode into character. +static Standard_Byte alphaModeToChar (Graphic3d_AlphaMode theMode) +{ + switch (theMode) + { + case Graphic3d_AlphaMode_Opaque: return 'O'; + case Graphic3d_AlphaMode_Mask: return 'M'; + case Graphic3d_AlphaMode_Blend: return 'B'; + case Graphic3d_AlphaMode_BlendAuto: return 'A'; + } + return 'A'; +} + +//! Decode alpha mode from character. +static Graphic3d_AlphaMode alphaModeFromChar (Standard_Byte 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 vec3. +static void writeVec3 (BinObjMgt_Persistent& theTarget, + const Graphic3d_Vec3& theVec3) +{ + theTarget.PutShortReal (theVec3[0]); + theTarget.PutShortReal (theVec3[1]); + theTarget.PutShortReal (theVec3[2]); +} + +//! Encode vec4. +static void writeVec4 (BinObjMgt_Persistent& theTarget, + const Graphic3d_Vec4& theVec4) +{ + theTarget.PutShortReal (theVec4[0]); + theTarget.PutShortReal (theVec4[1]); + theTarget.PutShortReal (theVec4[2]); + theTarget.PutShortReal (theVec4[3]); +} + +//! Decode vec3. +static void readVec3 (const BinObjMgt_Persistent& theSource, + Graphic3d_Vec3& theVec3) +{ + theSource.GetShortReal (theVec3[0]); + theSource.GetShortReal (theVec3[1]); + theSource.GetShortReal (theVec3[2]); +} + +//! Decode vec3. +static void readColor (const BinObjMgt_Persistent& theSource, + Quantity_Color& theColor) +{ + Graphic3d_Vec3 aVec3; + readVec3 (theSource, aVec3); + theColor = Quantity_Color (aVec3); +} + +//! Decode vec4. +static void readColor (const BinObjMgt_Persistent& theSource, + Quantity_ColorRGBA& theColor) +{ + Graphic3d_Vec4 aVec4; + theSource.GetShortReal (aVec4[0]); + theSource.GetShortReal (aVec4[1]); + theSource.GetShortReal (aVec4[2]); + theSource.GetShortReal (aVec4[3]); + theColor = Quantity_ColorRGBA (aVec4); +} + +//! Encode texture path. +static void writeTexture (BinObjMgt_Persistent& theTarget, + const Handle(Image_Texture)& theImage) +{ + theTarget.PutAsciiString (!theImage.IsNull() + && !theImage->FilePath().IsEmpty() + && theImage->FileOffset() == -1 + ? theImage->FilePath() + : ""); +} + +//! Decode texture path. +static void readTexture (const BinObjMgt_Persistent& theSource, + Handle(Image_Texture)& theTexture) +{ + TCollection_AsciiString aPath; + theSource.GetAsciiString (aPath); + if (!aPath.IsEmpty()) + { + theTexture = new Image_Texture (aPath); + } +} + +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +BinMXCAFDoc_VisMaterialDriver::BinMXCAFDoc_VisMaterialDriver (const Handle(Message_Messenger)& theMsgDriver) +: BinMDF_ADriver(theMsgDriver, STANDARD_TYPE(XCAFDoc_VisMaterial)->Name()) +{ +} + +//======================================================================= +//function : NewEmpty +//purpose : +//======================================================================= +Handle(TDF_Attribute) BinMXCAFDoc_VisMaterialDriver::NewEmpty() const +{ + return new XCAFDoc_VisMaterial(); +} + +//======================================================================= +//function : Paste +//purpose : +//======================================================================= +Standard_Boolean BinMXCAFDoc_VisMaterialDriver::Paste (const BinObjMgt_Persistent& theSource, + const Handle(TDF_Attribute)& theTarget, + BinObjMgt_RRelocationTable& /*theRelocTable*/) const +{ + Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theTarget); + Standard_Byte aVerMaj = 0, aVerMin = 0; + theSource.GetByte (aVerMaj); + theSource.GetByte (aVerMin); + if (aVerMaj < 1 || aVerMaj > MaterialVersionMajor) + { + myMessageDriver->Send (TCollection_AsciiString ("Skipping XCAFDoc_VisMaterial of unknown version ") + + Standard_Integer(aVerMaj) + "." + Standard_Integer(aVerMin) + + " (supported version: " + Standard_Integer(MaterialVersionMajor) + "." + Standard_Integer(MaterialVersionMinor) + ")"); + return false; + } + + Standard_Byte isDoubleSided = 0, anAlphaMode = 0; + Standard_ShortReal anAlphaCutOff = 0.5f; + theSource.GetByte (isDoubleSided); + theSource.GetByte (anAlphaMode); + theSource.GetShortReal (anAlphaCutOff); + aMat->SetDoubleSided (isDoubleSided == '1'); + aMat->SetAlphaMode (alphaModeFromChar (anAlphaMode), anAlphaCutOff); + + bool hasPbrMat = false; + theSource.GetBoolean (hasPbrMat); + if (hasPbrMat) + { + XCAFDoc_VisMaterialPBR aPbrMat; + aPbrMat.IsDefined = true; + readColor (theSource, aPbrMat.BaseColor); + readVec3 (theSource, aPbrMat.EmissiveFactor); + theSource.GetShortReal (aPbrMat.Metallic); + theSource.GetShortReal (aPbrMat.Roughness); + readTexture (theSource, aPbrMat.BaseColorTexture); + readTexture (theSource, aPbrMat.MetallicRoughnessTexture); + readTexture (theSource, aPbrMat.EmissiveTexture); + readTexture (theSource, aPbrMat.OcclusionTexture); + readTexture (theSource, aPbrMat.NormalTexture); + aMat->SetPbrMaterial (aPbrMat); + } + + bool hasComMat = false; + theSource.GetBoolean (hasComMat); + if (hasComMat) + { + XCAFDoc_VisMaterialCommon aComMat; + aComMat.IsDefined = true; + readColor (theSource, aComMat.AmbientColor); + readColor (theSource, aComMat.DiffuseColor); + readColor (theSource, aComMat.SpecularColor); + readColor (theSource, aComMat.EmissiveColor); + theSource.GetShortReal (aComMat.Shininess); + theSource.GetShortReal (aComMat.Transparency); + readTexture (theSource, aComMat.DiffuseTexture); + aMat->SetCommonMaterial (aComMat); + } + return Standard_True; +} + +//======================================================================= +//function : Paste +//purpose : +//======================================================================= +void BinMXCAFDoc_VisMaterialDriver::Paste (const Handle(TDF_Attribute)& theSource, + BinObjMgt_Persistent& theTarget, + BinObjMgt_SRelocationTable& ) const +{ + Handle(XCAFDoc_VisMaterial) aMat = Handle(XCAFDoc_VisMaterial)::DownCast(theSource); + theTarget.PutByte (MaterialVersionMajor); + theTarget.PutByte (MaterialVersionMinor); + + theTarget.PutByte (aMat->IsDoubleSided() ? '1' : '0'); + theTarget.PutByte (alphaModeToChar (aMat->AlphaMode())); + theTarget.PutShortReal (aMat->AlphaCutOff()); + + theTarget.PutBoolean (aMat->HasPbrMaterial()); + if (aMat->HasPbrMaterial()) + { + const XCAFDoc_VisMaterialPBR& aPbrMat = aMat->PbrMaterial(); + writeVec4 (theTarget, aPbrMat.BaseColor); + writeVec3 (theTarget, aPbrMat.EmissiveFactor); + theTarget.PutShortReal (aPbrMat.Metallic); + theTarget.PutShortReal (aPbrMat.Roughness); + writeTexture (theTarget, aPbrMat.BaseColorTexture); + writeTexture (theTarget, aPbrMat.MetallicRoughnessTexture); + writeTexture (theTarget, aPbrMat.EmissiveTexture); + writeTexture (theTarget, aPbrMat.OcclusionTexture); + writeTexture (theTarget, aPbrMat.NormalTexture); + } + + theTarget.PutBoolean (aMat->HasCommonMaterial()); + if (aMat->HasCommonMaterial()) + { + const XCAFDoc_VisMaterialCommon& aComMat = aMat->CommonMaterial(); + writeVec3 (theTarget, aComMat.AmbientColor); + writeVec3 (theTarget, aComMat.DiffuseColor); + writeVec3 (theTarget, aComMat.SpecularColor); + writeVec3 (theTarget, aComMat.EmissiveColor); + theTarget.PutShortReal (aComMat.Shininess); + theTarget.PutShortReal (aComMat.Transparency); + writeTexture (theTarget, aComMat.DiffuseTexture); + } +} diff --git a/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialDriver.hxx b/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialDriver.hxx new file mode 100644 index 0000000000..db98c1bcd9 --- /dev/null +++ b/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialDriver.hxx @@ -0,0 +1,51 @@ +// 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. + +#ifndef _BinMXCAFDoc_VisMaterialDriver_HeaderFile +#define _BinMXCAFDoc_VisMaterialDriver_HeaderFile + +#include +#include +#include +#include + +DEFINE_STANDARD_HANDLE(BinMXCAFDoc_VisMaterialDriver, BinMDF_ADriver) + +//! Binary persistence driver for XCAFDoc_VisMaterial attribute. +class BinMXCAFDoc_VisMaterialDriver : public BinMDF_ADriver +{ + DEFINE_STANDARD_RTTIEXT(BinMXCAFDoc_VisMaterialDriver, BinMDF_ADriver) + + //! Persistence version (major for breaking changes, minor for adding new fields at end). + enum { MaterialVersionMajor = 1, MaterialVersionMinor = 0 }; +public: + + //! Main constructor. + Standard_EXPORT BinMXCAFDoc_VisMaterialDriver (const Handle(Message_Messenger)& theMsgDriver); + + //! Create new instance of XCAFDoc_VisMaterial. + Standard_EXPORT virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE; + + //! Paste attribute from persistence into document. + Standard_EXPORT virtual Standard_Boolean Paste (const BinObjMgt_Persistent& theSource, + const Handle(TDF_Attribute)& theTarget, + BinObjMgt_RRelocationTable& theRelocTable) const Standard_OVERRIDE; + + //! Paste attribute from document into persistence. + Standard_EXPORT virtual void Paste (const Handle(TDF_Attribute)& theSource, + BinObjMgt_Persistent& theTarget, + BinObjMgt_SRelocationTable& theRelocTable) const Standard_OVERRIDE; + +}; + +#endif // _BinMXCAFDoc_VisMaterialDriver_HeaderFile diff --git a/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialToolDriver.cxx b/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialToolDriver.cxx new file mode 100644 index 0000000000..b31cfbf233 --- /dev/null +++ b/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialToolDriver.cxx @@ -0,0 +1,59 @@ +// 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 + +#include + +IMPLEMENT_STANDARD_RTTIEXT(BinMXCAFDoc_VisMaterialToolDriver, BinMDF_ADriver) + +//======================================================================= +//function : BinMXCAFDoc_VisMaterialToolDriver +//purpose : +//======================================================================= +BinMXCAFDoc_VisMaterialToolDriver::BinMXCAFDoc_VisMaterialToolDriver (const Handle(Message_Messenger)& theMsgDriver) +: BinMDF_ADriver (theMsgDriver, STANDARD_TYPE(XCAFDoc_VisMaterialTool)->Name()) +{ + // +} + +//======================================================================= +//function : NewEmpty +//purpose : +//======================================================================= +Handle(TDF_Attribute) BinMXCAFDoc_VisMaterialToolDriver::NewEmpty() const +{ + return new XCAFDoc_VisMaterialTool(); +} + +//======================================================================= +//function : Paste +//purpose : +//======================================================================= +Standard_Boolean BinMXCAFDoc_VisMaterialToolDriver::Paste (const BinObjMgt_Persistent& , + const Handle(TDF_Attribute)& , + BinObjMgt_RRelocationTable& ) const +{ + return Standard_True; +} + +//======================================================================= +//function : Paste +//purpose : +//======================================================================= +void BinMXCAFDoc_VisMaterialToolDriver::Paste (const Handle(TDF_Attribute)& , + BinObjMgt_Persistent& , + BinObjMgt_SRelocationTable& ) const +{ + // +} diff --git a/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialToolDriver.hxx b/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialToolDriver.hxx new file mode 100644 index 0000000000..9e55403a18 --- /dev/null +++ b/src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialToolDriver.hxx @@ -0,0 +1,45 @@ +// 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. + +#ifndef _BinMXCAFDoc_VisMaterialToolDriver_HeaderFile +#define _BinMXCAFDoc_VisMaterialToolDriver_HeaderFile + +#include + +DEFINE_STANDARD_HANDLE(BinMXCAFDoc_VisMaterialToolDriver, BinMDF_ADriver) + +//! Binary persistence driver for XCAFDoc_VisMaterialTool attribute. +class BinMXCAFDoc_VisMaterialToolDriver : public BinMDF_ADriver +{ + DEFINE_STANDARD_RTTIEXT(BinMXCAFDoc_VisMaterialToolDriver, BinMDF_ADriver) +public: + + //! Main constructor. + Standard_EXPORT BinMXCAFDoc_VisMaterialToolDriver (const Handle(Message_Messenger)& theMsgDriver); + + //! Create new instance of XCAFDoc_VisMaterialTool. + Standard_EXPORT virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE; + + //! Paste attribute from persistence into document. + Standard_EXPORT virtual Standard_Boolean Paste (const BinObjMgt_Persistent& theSource, + const Handle(TDF_Attribute)& theTarget, + BinObjMgt_RRelocationTable& theRelocTable) const Standard_OVERRIDE; + + //! Paste attribute from document into persistence. + Standard_EXPORT virtual void Paste (const Handle(TDF_Attribute)& theSource, + BinObjMgt_Persistent& theTarget, + BinObjMgt_SRelocationTable& theRelocTable) const Standard_OVERRIDE; + +}; + +#endif // _BinMXCAFDoc_VisMaterialToolDriver_HeaderFile diff --git a/src/BinMXCAFDoc/FILES b/src/BinMXCAFDoc/FILES index fbb3e87764..22daf02e37 100644 --- a/src/BinMXCAFDoc/FILES +++ b/src/BinMXCAFDoc/FILES @@ -51,5 +51,9 @@ BinMXCAFDoc_ViewDriver.cxx BinMXCAFDoc_ViewDriver.hxx BinMXCAFDoc_ViewToolDriver.cxx BinMXCAFDoc_ViewToolDriver.hxx +BinMXCAFDoc_VisMaterialDriver.cxx +BinMXCAFDoc_VisMaterialDriver.hxx +BinMXCAFDoc_VisMaterialToolDriver.cxx +BinMXCAFDoc_VisMaterialToolDriver.hxx BinMXCAFDoc_VolumeDriver.cxx BinMXCAFDoc_VolumeDriver.hxx diff --git a/src/IGESCAFControl/IGESCAFControl_Writer.cxx b/src/IGESCAFControl/IGESCAFControl_Writer.cxx index 2314700a80..fdca8f677e 100644 --- a/src/IGESCAFControl/IGESCAFControl_Writer.cxx +++ b/src/IGESCAFControl/IGESCAFControl_Writer.cxx @@ -276,6 +276,7 @@ void IGESCAFControl_Writer::MakeColors (const TopoDS_Shape &S, XCAFPrs_Style own = settings.FindFromKey(S); if ( own.IsSetColorCurv() ) style.SetColorCurv ( own.GetColorCurv() ); if ( own.IsSetColorSurf() ) style.SetColorSurf ( own.GetColorSurf() ); + style.SetMaterial (own.Material()); } // analyze whether current entity should get a color @@ -286,6 +287,12 @@ void IGESCAFControl_Writer::MakeColors (const TopoDS_Shape &S, hasColor = Standard_True; col = style.GetColorSurf(); } + else if (!style.Material().IsNull() + && !style.Material()->IsEmpty()) + { + hasColor = Standard_True; + col = style.Material()->BaseColor().GetRGB(); + } } else if ( S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE ) { if ( style.IsSetColorCurv() ) { diff --git a/src/RWGltf/FILES b/src/RWGltf/FILES index cd6d8a8dc0..d5b8199fac 100644 --- a/src/RWGltf/FILES +++ b/src/RWGltf/FILES @@ -1,6 +1,7 @@ RWGltf_GltfAccessor.hxx RWGltf_GltfAccessorCompType.hxx RWGltf_GltfAccessorLayout.hxx +RWGltf_GltfAlphaMode.hxx RWGltf_GltfArrayType.hxx RWGltf_GltfBufferView.hxx RWGltf_GltfBufferViewTarget.hxx diff --git a/src/RWGltf/RWGltf_GltfAlphaMode.hxx b/src/RWGltf/RWGltf_GltfAlphaMode.hxx new file mode 100644 index 0000000000..086f6733fc --- /dev/null +++ b/src/RWGltf/RWGltf_GltfAlphaMode.hxx @@ -0,0 +1,46 @@ +// Author: Kirill Gavrilov +// 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. + +#ifndef _RWGltf_GltfAlphaMode_HeaderFile +#define _RWGltf_GltfAlphaMode_HeaderFile + +#include + +//! Low-level glTF enumeration defining Alpha Mode. +enum RWGltf_GltfAlphaMode +{ + RWGltf_GltfAlphaMode_Opaque, //!< alpha value is ignored and the rendered output is fully opaque + RWGltf_GltfAlphaMode_Mask, //!< rendered output is either fully opaque or fully transparent depending on the alpha value and the specified alpha cutoff value + RWGltf_GltfAlphaMode_Blend, //!< alpha value is used to composite the source and destination areas +}; + +//! Parse RWGltf_GltfAlphaMode from string. +inline RWGltf_GltfAlphaMode RWGltf_GltfParseAlphaMode (const char* theType) +{ + if (IsEqual ("OPAQUE", theType)) + { + return RWGltf_GltfAlphaMode_Opaque; + } + else if (IsEqual ("MASK", theType)) + { + return RWGltf_GltfAlphaMode_Mask; + } + else if (IsEqual ("BLEND", theType)) + { + return RWGltf_GltfAlphaMode_Blend; + } + return RWGltf_GltfAlphaMode_Opaque; +} + +#endif // _RWGltf_GltfAlphaMode_HeaderFile diff --git a/src/RWGltf/RWGltf_GltfJsonParser.cxx b/src/RWGltf/RWGltf_GltfJsonParser.cxx index 20380b8f4c..0e772e96ae 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.cxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.cxx @@ -308,6 +308,7 @@ void RWGltf_GltfJsonParser::gltfParseMaterials() } aMat->Id = aMatId.GetString(); myMaterialsCommon.Bind (aMat->Id, aMat); + gltfBindMaterial (Handle(RWGltf_MaterialMetallicRoughness)(), aMat); } } else if (aMatList->IsArray()) @@ -342,10 +343,98 @@ void RWGltf_GltfJsonParser::gltfParseMaterials() aMatCommon->Id = TCollection_AsciiString ("mat_") + aMatIndex; myMaterialsCommon.Bind (TCollection_AsciiString (aMatIndex), aMatCommon); } + + gltfBindMaterial (aMatPbr, aMatCommon); } } } +// ======================================================================= +// function : gltfBindMaterial +// purpose : +// ======================================================================= +void RWGltf_GltfJsonParser::gltfBindMaterial (const Handle(RWGltf_MaterialMetallicRoughness)& theMatPbr, + const Handle(RWGltf_MaterialCommon)& theMatCommon) +{ + if (theMatPbr.IsNull() + && theMatCommon.IsNull()) + { + return; + } + + Handle(XCAFDoc_VisMaterial) aMat = new XCAFDoc_VisMaterial(); + if (!theMatCommon.IsNull()) + { + XCAFDoc_VisMaterialCommon aMatXde; + aMatXde.IsDefined = true; + aMatXde.AmbientColor = theMatCommon->AmbientColor; + aMatXde.DiffuseColor = theMatCommon->DiffuseColor; + aMatXde.SpecularColor = theMatCommon->SpecularColor; + aMatXde.EmissiveColor = theMatCommon->EmissiveColor; + aMatXde.Shininess = theMatCommon->Shininess; + aMatXde.Transparency = theMatCommon->Transparency; + aMatXde.DiffuseTexture = theMatCommon->DiffuseTexture; + if (aMatXde.DiffuseTexture.IsNull() + && !theMatCommon->AmbientTexture.IsNull()) + { + aMatXde.DiffuseTexture = theMatCommon->AmbientTexture; + } + aMat->SetCommonMaterial (aMatXde); + if (!theMatCommon->Name.IsEmpty()) + { + aMat->SetRawName (new TCollection_HAsciiString (theMatCommon->Name)); + } + } + if (!theMatPbr.IsNull()) + { + XCAFDoc_VisMaterialPBR aMatXde; + aMatXde.IsDefined = true; + aMatXde.MetallicRoughnessTexture = theMatPbr->MetallicRoughnessTexture; + aMatXde.BaseColorTexture = theMatPbr->BaseColorTexture; + aMatXde.EmissiveTexture = theMatPbr->EmissiveTexture; + aMatXde.OcclusionTexture = theMatPbr->OcclusionTexture; + aMatXde.NormalTexture = theMatPbr->NormalTexture; + aMatXde.BaseColor = theMatPbr->BaseColor; + aMatXde.EmissiveFactor = theMatPbr->EmissiveFactor; + aMatXde.Metallic = theMatPbr->Metallic; + aMatXde.Roughness = theMatPbr->Roughness; + aMat->SetPbrMaterial (aMatXde); + + Graphic3d_AlphaMode anAlphaMode = Graphic3d_AlphaMode_BlendAuto; + switch (theMatPbr->AlphaMode) + { + case RWGltf_GltfAlphaMode_Opaque: + { + anAlphaMode = Graphic3d_AlphaMode_Opaque; + if (aMatXde.BaseColor.Alpha() < 1.0f) + { + Message::DefaultMessenger()->Send ("glTF reader - material with non-zero Transparency specifies Opaque AlphaMode", Message_Warning); + } + break; + } + case RWGltf_GltfAlphaMode_Mask: + { + anAlphaMode = Graphic3d_AlphaMode_Mask; + break; + } + case RWGltf_GltfAlphaMode_Blend: + { + anAlphaMode = Graphic3d_AlphaMode_Blend; + break; + } + } + aMat->SetAlphaMode (anAlphaMode, theMatPbr->AlphaCutOff); + aMat->SetDoubleSided (theMatPbr->IsDoubleSided); + + if (!theMatPbr->Name.IsEmpty()) + { + aMat->SetRawName (new TCollection_HAsciiString (theMatPbr->Name)); + } + } + + myMaterials.Bind (!theMatPbr.IsNull() ? theMatPbr->Id : theMatCommon->Id, aMat); +} + // ======================================================================= // function : gltfParseStdMaterial // purpose : @@ -450,6 +539,9 @@ bool RWGltf_GltfJsonParser::gltfParsePbrMaterial (Handle(RWGltf_MaterialMetallic const RWGltf_JsonValue* anEmissFactorVal = findObjectMember (theMatNode, "emissiveFactor"); const RWGltf_JsonValue* anEmissTexVal = findObjectMember (theMatNode, "emissiveTexture"); const RWGltf_JsonValue* anOcclusionTexVal = findObjectMember (theMatNode, "occlusionTexture"); + const RWGltf_JsonValue* aDoubleSidedVal = findObjectMember (theMatNode, "doubleSided"); + const RWGltf_JsonValue* anAlphaModeVal = findObjectMember (theMatNode, "alphaMode"); + const RWGltf_JsonValue* anAlphaCutoffVal = findObjectMember (theMatNode, "alphaCutoff"); if (aMetalRoughVal == NULL) { return false; @@ -462,6 +554,22 @@ bool RWGltf_GltfJsonParser::gltfParsePbrMaterial (Handle(RWGltf_MaterialMetallic const RWGltf_JsonValue* aRoughnessFactorVal = findObjectMember (*aMetalRoughVal, "roughnessFactor"); const RWGltf_JsonValue* aMetalRoughTexVal = findObjectMember (*aMetalRoughVal, "metallicRoughnessTexture"); + if (aDoubleSidedVal != NULL + && aDoubleSidedVal->IsBool()) + { + theMat->IsDoubleSided = aDoubleSidedVal->GetBool(); + } + if (anAlphaCutoffVal != NULL + && anAlphaCutoffVal->IsNumber()) + { + theMat->AlphaCutOff = (float )anAlphaCutoffVal->GetDouble(); + } + if (anAlphaModeVal != NULL + && anAlphaModeVal->IsString()) + { + theMat->AlphaMode = RWGltf_GltfParseAlphaMode (anAlphaModeVal->GetString()); + } + if (aBaseColorTexVal != NULL && aBaseColorTexVal->IsObject()) { @@ -1116,7 +1224,14 @@ bool RWGltf_GltfJsonParser::gltfParseMesh (TopoDS_Shape& theMeshShape, { RWMesh_NodeAttributes aShapeAttribs; aShapeAttribs.RawName = aUserName; - aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor()); + + // assign material and not color + //aShapeAttribs.Style.SetColorSurf (aMeshData->BaseColor()); + + Handle(XCAFDoc_VisMaterial) aMat; + myMaterials.Find (!aMeshData->MaterialPbr().IsNull() ? aMeshData->MaterialPbr()->Id : aMeshData->MaterialCommon()->Id, aMat); + aShapeAttribs.Style.SetMaterial (aMat); + myAttribMap->Bind (aFace, aShapeAttribs); } myFaceList.Append (aFace); @@ -1586,7 +1701,12 @@ void RWGltf_GltfJsonParser::bindNamedShape (TopoDS_Shape& theShape, { if (aLateData->HasStyle()) { - aShapeAttribs.Style.SetColorSurf (aLateData->BaseColor()); + // assign material and not color + //aShapeAttribs.Style.SetColorSurf (aLateData->BaseColor()); + + Handle(XCAFDoc_VisMaterial) aMat; + myMaterials.Find (!aLateData->MaterialPbr().IsNull() ? aLateData->MaterialPbr()->Id : aLateData->MaterialCommon()->Id, aMat); + aShapeAttribs.Style.SetMaterial (aMat); } if (aShapeAttribs.Name.IsEmpty() && myUseMeshNameAsFallback) diff --git a/src/RWGltf/RWGltf_GltfJsonParser.pxx b/src/RWGltf/RWGltf_GltfJsonParser.pxx index a152f7c821..1e4e2419eb 100644 --- a/src/RWGltf/RWGltf_GltfJsonParser.pxx +++ b/src/RWGltf/RWGltf_GltfJsonParser.pxx @@ -150,6 +150,10 @@ protected: Standard_EXPORT bool gltfParseTexture (Handle(Image_Texture)& theTexture, const RWGltf_JsonValue* theTextureId); + //! Bind material definition to the map. + Standard_EXPORT void gltfBindMaterial (const Handle(RWGltf_MaterialMetallicRoughness)& theMatPbr, + const Handle(RWGltf_MaterialCommon)& theMatCommon); + protected: //! Parse scene array of nodes recursively. @@ -397,6 +401,7 @@ protected: NCollection_DataMap myMaterialsPbr; NCollection_DataMap myMaterialsCommon; + NCollection_DataMap myMaterials; NCollection_DataMap myShapeMap[2]; NCollection_DataMap myProbedFiles; diff --git a/src/RWGltf/RWGltf_MaterialMetallicRoughness.hxx b/src/RWGltf/RWGltf_MaterialMetallicRoughness.hxx index 60f279c475..a2079417ef 100644 --- a/src/RWGltf/RWGltf_MaterialMetallicRoughness.hxx +++ b/src/RWGltf/RWGltf_MaterialMetallicRoughness.hxx @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -38,12 +39,18 @@ public: Graphic3d_Vec3 EmissiveFactor; //!< emissive color; [0.0, 0.0, 0.0] by default Standard_ShortReal Metallic; //!< metalness (or scale factor to the texture) within range [0.0, 1.0]; 1.0 by default Standard_ShortReal Roughness; //!< roughness (or scale factor to the texture) within range [0.0, 1.0]; 1.0 by default + Standard_ShortReal AlphaCutOff; //!< alpha cutoff value; 0.5 by default + RWGltf_GltfAlphaMode AlphaMode; //!< alpha mode; RWGltf_GltfAlphaMode_Opaque by default + Standard_Boolean IsDoubleSided; //!< specifies whether the material is double sided; FALSE by default - RWGltf_MaterialMetallicRoughness() + RWGltf_MaterialMetallicRoughness() : BaseColor (1.0f, 1.0f, 1.0f, 1.0f), EmissiveFactor (0.0f, 0.0f, 0.0f), - Metallic (0.0f), - Roughness (0.0f) {} + Metallic (1.0f), + Roughness (1.0f), + AlphaCutOff (0.5f), + AlphaMode (RWGltf_GltfAlphaMode_Opaque), + IsDoubleSided (Standard_False) {} }; diff --git a/src/RWMesh/RWMesh_CafReader.cxx b/src/RWMesh/RWMesh_CafReader.cxx index 9f198d6d91..ec0fc02a47 100644 --- a/src/RWMesh/RWMesh_CafReader.cxx +++ b/src/RWMesh/RWMesh_CafReader.cxx @@ -32,6 +32,7 @@ #include #include #include +#include IMPLEMENT_STANDARD_RTTIEXT(RWMesh_CafReader, Standard_Transient) @@ -276,6 +277,19 @@ Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (const TopoDS_Shape& theShape { aColorTool->SetColor (aNewRefLabel, aShapeAttribs.Style.GetColorCurv(), XCAFDoc_ColorCurv); } + if (!aShapeAttribs.Style.Material().IsNull()) + { + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (myXdeDoc->Main()); + TDF_Label aMaterialLabel = aShapeAttribs.Style.Material()->Label(); + if (aMaterialLabel.IsNull()) + { + const TCollection_AsciiString aMatName = !aShapeAttribs.Style.Material()->RawName().IsNull() + ? aShapeAttribs.Style.Material()->RawName()->String() + : ""; + aMaterialLabel = aMatTool->AddMaterial (aShapeAttribs.Style.Material(), aMatName); + } + aMatTool->SetShapeMaterial (aNewRefLabel, aMaterialLabel); + } // store sub-shapes (iterator is set to ignore Location) TCollection_AsciiString aDummyName; diff --git a/src/RWObj/RWObj_CafReader.cxx b/src/RWObj/RWObj_CafReader.cxx index 2ff06cec99..dee58693fd 100644 --- a/src/RWObj/RWObj_CafReader.cxx +++ b/src/RWObj/RWObj_CafReader.cxx @@ -49,7 +49,29 @@ void RWObj_CafReader::BindNamedShape (const TopoDS_Shape& theShape, aShapeAttribs.Name = theName; if (theMaterial != NULL) { - aShapeAttribs.Style.SetColorSurf (Quantity_ColorRGBA (theMaterial->DiffuseColor, 1.0f - theMaterial->Transparency)); + // assign material and not color + //aShapeAttribs.Style.SetColorSurf (Quantity_ColorRGBA (theMaterial->DiffuseColor, 1.0f - theMaterial->Transparency)); + + Handle(XCAFDoc_VisMaterial) aMat = new XCAFDoc_VisMaterial(); + if (!myObjMaterialMap.Find (theMaterial->Name, aMat)) // material names are used as unique keys in OBJ + { + XCAFDoc_VisMaterialCommon aMatXde; + aMatXde.IsDefined = true; + aMatXde.AmbientColor = theMaterial->AmbientColor; + aMatXde.DiffuseColor = theMaterial->DiffuseColor; + aMatXde.SpecularColor = theMaterial->SpecularColor; + aMatXde.Shininess = theMaterial->Shininess; + aMatXde.Transparency = theMaterial->Transparency; + if (!theMaterial->DiffuseTexture.IsEmpty()) + { + aMatXde.DiffuseTexture = new Image_Texture (theMaterial->DiffuseTexture); + } + + aMat = new XCAFDoc_VisMaterial(); + aMat->SetCommonMaterial (aMatXde); + aMat->SetRawName (new TCollection_HAsciiString (theMaterial->Name)); + } + aShapeAttribs.Style.SetMaterial (aMat); } myAttribMap.Bind (theShape, aShapeAttribs); diff --git a/src/RWObj/RWObj_CafReader.hxx b/src/RWObj/RWObj_CafReader.hxx index a924a5f53b..faf9664104 100644 --- a/src/RWObj/RWObj_CafReader.hxx +++ b/src/RWObj/RWObj_CafReader.hxx @@ -56,6 +56,7 @@ protected: protected: + NCollection_DataMap myObjMaterialMap; Standard_Boolean myIsSinglePrecision; //!< flag for reading vertex data with single or double floating point precision }; diff --git a/src/STEPCAFControl/STEPCAFControl_Writer.cxx b/src/STEPCAFControl/STEPCAFControl_Writer.cxx index 673d98c557..2264585b7e 100644 --- a/src/STEPCAFControl/STEPCAFControl_Writer.cxx +++ b/src/STEPCAFControl/STEPCAFControl_Writer.cxx @@ -233,6 +233,8 @@ #include #include #include +#include +#include #include #include #include @@ -1163,6 +1165,7 @@ Standard_Boolean STEPCAFControl_Writer::WriteColors (const Handle(XSControl_Work // Iterate on shapes in the document Handle(XCAFDoc_ColorTool) CTool = XCAFDoc_DocumentTool::ColorTool( labels(1) ); + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool( labels(1) ); if ( CTool.IsNull() ) return Standard_False; STEPConstruct_Styles Styles ( WS ); @@ -1232,6 +1235,16 @@ Standard_Boolean STEPCAFControl_Writer::WriteColors (const Handle(XSControl_Work style.SetColorSurf ( C ); if ( CTool->GetColor ( lab, XCAFDoc_ColorCurv, C ) ) style.SetColorCurv ( C ); + if (!style.IsSetColorSurf()) + { + Handle(XCAFDoc_VisMaterial) aVisMat = aMatTool->GetShapeMaterial (lab); + if (!aVisMat.IsNull() + && !aVisMat->IsEmpty()) + { + // only color can be stored in STEP + style.SetColorSurf (aVisMat->BaseColor()); + } + } // commented, cause we are need to take reference from // if ( isComponent && lab == L && !isVisible) @@ -1659,6 +1672,7 @@ Standard_Boolean STEPCAFControl_Writer::WriteLayers (const Handle(XSControl_Work //======================================================================= static Standard_Boolean getSHUOstyle(const TDF_Label& aSHUOlab, const Handle(XCAFDoc_ColorTool)& CTool, + const Handle(XCAFDoc_VisMaterialTool)& theMatTool, XCAFPrs_Style& SHUOstyle) { Quantity_Color C; @@ -1673,6 +1687,16 @@ static Standard_Boolean getSHUOstyle(const TDF_Label& aSHUOlab, SHUOstyle.SetColorSurf ( C ); if ( CTool->GetColor ( aSHUOlab, XCAFDoc_ColorCurv, C ) ) SHUOstyle.SetColorCurv ( C ); + if (!SHUOstyle.IsSetColorSurf()) + { + Handle(XCAFDoc_VisMaterial) aVisMat = theMatTool->GetShapeMaterial (aSHUOlab); + if (!aVisMat.IsNull() + && !aVisMat->IsEmpty()) + { + // only color can be stored in STEP + SHUOstyle.SetColorSurf (aVisMat->BaseColor()); + } + } } if ( !SHUOstyle.IsSetColorCurv() && !SHUOstyle.IsSetColorSurf() && @@ -1977,6 +2001,7 @@ Standard_Boolean STEPCAFControl_Writer::WriteSHUOs (const Handle(XSControl_WorkS // get working data Handle(XCAFDoc_ColorTool) CTool = XCAFDoc_DocumentTool::ColorTool( labels(1) ); + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool( labels(1) ); if (CTool.IsNull() ) return Standard_False; // map of transfered SHUO @@ -2009,7 +2034,7 @@ Standard_Boolean STEPCAFControl_Writer::WriteSHUOs (const Handle(XSControl_WorkS aMapOfMainSHUO.Add( aSHUO ); // check if it is styled SHUO XCAFPrs_Style SHUOstyle; - if ( !getSHUOstyle ( aSHUOlab, CTool, SHUOstyle ) ) { + if ( !getSHUOstyle ( aSHUOlab, CTool, aMatTool, SHUOstyle ) ) { #ifdef OCCT_DEBUG std::cout << "Warning: " << __FILE__ << ": do not store SHUO without any style to the STEP model" << std::endl; #endif diff --git a/src/TKBinXCAF/EXTERNLIB b/src/TKBinXCAF/EXTERNLIB index ac4b3345c3..53eaf11055 100755 --- a/src/TKBinXCAF/EXTERNLIB +++ b/src/TKBinXCAF/EXTERNLIB @@ -1,6 +1,7 @@ TKBRep TKXCAF TKMath +TKService TKernel TKBinL TKG2d diff --git a/src/TKXmlXCAF/EXTERNLIB b/src/TKXmlXCAF/EXTERNLIB index 5b656d9482..b1c7c70d17 100755 --- a/src/TKXmlXCAF/EXTERNLIB +++ b/src/TKXmlXCAF/EXTERNLIB @@ -3,6 +3,7 @@ TKBRep TKCDF TKMath TKernel +TKService TKG2d TKGeomBase TKCAF diff --git a/src/VrmlData/VrmlData_ShapeConvert.cxx b/src/VrmlData/VrmlData_ShapeConvert.cxx index 99c5fffdfc..bf5d86f086 100644 --- a/src/VrmlData/VrmlData_ShapeConvert.cxx +++ b/src/VrmlData/VrmlData_ShapeConvert.cxx @@ -52,7 +52,9 @@ #include #include #include - +#include +#include +#include //======================================================================= //function : AddShape @@ -597,6 +599,7 @@ void VrmlData_ShapeConvert::addShape (const Handle(VrmlData_Group)& theParent, { Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool(theDoc->Main()); Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theDoc->Main()); + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool(theDoc->Main()); NCollection_DataMap aChildShapeToLabels; TDF_LabelSequence aChildLabels; @@ -661,26 +664,50 @@ void VrmlData_ShapeConvert::addShape (const Handle(VrmlData_Group)& theParent, } // set color - TDF_Label aColorL; - Standard_Boolean findColor = Standard_False; - const TDF_Label* aLabel = aChildShapeToLabels.Seek(anExp.Current()); - if (aLabel != NULL) + XCAFPrs_Style aStyle; + Quantity_ColorRGBA aColor; + TDF_Label aLabel, anAttribLab; + if (aChildShapeToLabels.Find (anExp.Current(), aLabel)) { - findColor = aColorTool->GetColor(*aLabel, XCAFDoc_ColorSurf, aColorL) - || aColorTool->GetColor(*aLabel, XCAFDoc_ColorGen, aColorL); + Handle(XCAFDoc_VisMaterial) aVisMat = aMatTool->GetShapeMaterial (aLabel); + if (!aVisMat.IsNull() + && !aVisMat->IsEmpty()) + { + anAttribLab = aVisMat->Label(); + aStyle.SetMaterial (aVisMat); + } + else if (aColorTool->GetColor (aLabel, XCAFDoc_ColorSurf, anAttribLab) + || aColorTool->GetColor (aLabel, XCAFDoc_ColorGen, anAttribLab)) + { + aColorTool->GetColor (anAttribLab, aColor); + aStyle.SetColorSurf (aColor); + } } - if (!findColor) + if (!aStyle.IsSetColorSurf() + && aStyle.Material().IsNull()) { - findColor = aColorTool->GetColor(theLabel, XCAFDoc_ColorSurf, aColorL) - || aColorTool->GetColor(theLabel, XCAFDoc_ColorGen, aColorL); + Handle(XCAFDoc_VisMaterial) aVisMat = aMatTool->GetShapeMaterial (theLabel); + if (!aVisMat.IsNull() + && !aVisMat->IsEmpty()) + { + anAttribLab = aVisMat->Label(); + aStyle.SetMaterial (aVisMat); + } + if (aColorTool->GetColor (theLabel, XCAFDoc_ColorSurf, anAttribLab) + || aColorTool->GetColor (theLabel, XCAFDoc_ColorGen, anAttribLab)) + { + aColorTool->GetColor (anAttribLab, aColor); + aStyle.SetColorSurf (aColor); + } } - if (!findColor) + if (!aStyle.IsSetColorSurf() + && aStyle.Material().IsNull()) { aShapeNode->SetAppearance(defaultMaterialFace()); } else { - aShapeNode->SetAppearance(makeMaterialFromColor(aColorL, aColorTool)); + aShapeNode->SetAppearance (makeMaterialFromStyle (aStyle, anAttribLab)); } myScene.AddNode(aShapeNode, theParent.IsNull() && aGroup.IsNull()); @@ -877,22 +904,20 @@ void VrmlData_ShapeConvert::ConvertDocument(const Handle(TDocStd_Document) &theD } } - //======================================================================= -//function : makeMaterialFromColor -//purpose : +//function : makeMaterialFromStyle +//purpose : //======================================================================= - -Handle(VrmlData_Appearance) VrmlData_ShapeConvert::makeMaterialFromColor( - const TDF_Label& theColorL, - const Handle(XCAFDoc_ColorTool)& theColorTool) const +Handle(VrmlData_Appearance) VrmlData_ShapeConvert::makeMaterialFromStyle (const XCAFPrs_Style& theStyle, + const TDF_Label& theAttribLab) const { - Quantity_ColorRGBA aColor; - theColorTool->GetColor(theColorL, aColor); + const Quantity_ColorRGBA aColor = !theStyle.Material().IsNull() + ? theStyle.Material()->BaseColor() + : theStyle.GetColorSurfRGBA(); TCollection_AsciiString aNodeName = "_materialFace_"; Handle(TDataStd_Name) aNameAttribute; - if (theColorL.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) + if (theAttribLab.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) { aNodeName.AssignCat(aNameAttribute->Get()); Standard_Integer n = aNodeName.Search(" "); @@ -912,19 +937,16 @@ Handle(VrmlData_Appearance) VrmlData_ShapeConvert::makeMaterialFromColor( aNodeName.AssignCat(aColor_sRGB.b()); } - Handle(VrmlData_Appearance) anAppearance = - Handle(VrmlData_Appearance)::DownCast(myScene.FindNode(aNodeName.ToCString())); - if (anAppearance.IsNull()) { - const Handle(VrmlData_Material) aMaterial = - new VrmlData_Material(myScene, 0L); - aMaterial->SetDiffuseColor(aColor.GetRGB()); - myScene.AddNode(aMaterial, Standard_False); - anAppearance = new VrmlData_Appearance(myScene, aNodeName.ToCString()); - anAppearance->SetMaterial(aMaterial); - myScene.AddNode(anAppearance, Standard_False); + Handle(VrmlData_Appearance) anAppearance = Handle(VrmlData_Appearance)::DownCast(myScene.FindNode(aNodeName.ToCString())); + if (anAppearance.IsNull()) + { + Handle(VrmlData_Material) aMaterial = new VrmlData_Material (myScene, 0L); + aMaterial->SetDiffuseColor (aColor.GetRGB()); + myScene.AddNode (aMaterial, Standard_False); + anAppearance = new VrmlData_Appearance (myScene, aNodeName.ToCString()); + anAppearance->SetMaterial (aMaterial); + myScene.AddNode (anAppearance, Standard_False); } return anAppearance; } - - diff --git a/src/VrmlData/VrmlData_ShapeConvert.hxx b/src/VrmlData/VrmlData_ShapeConvert.hxx index f7e2eb040f..0c3361e82c 100644 --- a/src/VrmlData/VrmlData_ShapeConvert.hxx +++ b/src/VrmlData/VrmlData_ShapeConvert.hxx @@ -28,7 +28,7 @@ class VrmlData_Coordinate; class TopoDS_Face; class Poly_Polygon3D; class Poly_Triangulation; -class XCAFDoc_ColorTool; +class XCAFPrs_Style; class TDocStd_Document; class TDF_Label; @@ -129,9 +129,8 @@ class VrmlData_ShapeConvert const TDF_Label& theLabel, const Handle(TDocStd_Document)& theDoc); - Handle(VrmlData_Appearance) makeMaterialFromColor(const TDF_Label& theColorL, - const Handle(XCAFDoc_ColorTool)& theColorTool) const; - + Handle(VrmlData_Appearance) makeMaterialFromStyle (const XCAFPrs_Style& theStyle, + const TDF_Label& theAttribLab) const; private: // ---------- PRIVATE FIELDS ---------- diff --git a/src/XCAFDoc/FILES b/src/XCAFDoc/FILES index 07384bb750..5b3030fdd8 100755 --- a/src/XCAFDoc/FILES +++ b/src/XCAFDoc/FILES @@ -63,5 +63,11 @@ XCAFDoc_View.cxx XCAFDoc_View.hxx XCAFDoc_ViewTool.cxx XCAFDoc_ViewTool.hxx +XCAFDoc_VisMaterial.cxx +XCAFDoc_VisMaterial.hxx +XCAFDoc_VisMaterialCommon.hxx +XCAFDoc_VisMaterialPBR.hxx +XCAFDoc_VisMaterialTool.cxx +XCAFDoc_VisMaterialTool.hxx XCAFDoc_Volume.cxx XCAFDoc_Volume.hxx diff --git a/src/XCAFDoc/XCAFDoc.cxx b/src/XCAFDoc/XCAFDoc.cxx index a60b110204..d00a8d281a 100644 --- a/src/XCAFDoc/XCAFDoc.cxx +++ b/src/XCAFDoc/XCAFDoc.cxx @@ -171,6 +171,15 @@ const Standard_GUID& XCAFDoc::MaterialRefGUID () return ID; } +//======================================================================= +//function : VisMaterialRefGUID +//purpose : +//======================================================================= +const Standard_GUID& XCAFDoc::VisMaterialRefGUID() +{ + static const Standard_GUID ID ("936F4070-5369-405D-A7AD-2AC76C860EC8"); + return ID; +} //======================================================================= //function : NoteRefGUID diff --git a/src/XCAFDoc/XCAFDoc.hxx b/src/XCAFDoc/XCAFDoc.hxx index 52169374e1..c4bc8f2996 100644 --- a/src/XCAFDoc/XCAFDoc.hxx +++ b/src/XCAFDoc/XCAFDoc.hxx @@ -98,6 +98,9 @@ public: Standard_EXPORT static const Standard_GUID& MaterialRefGUID(); + //! Return GUID for TreeNode representing Visualization Material. + Standard_EXPORT static const Standard_GUID& VisMaterialRefGUID(); + //! Return GUIDs for representing notes Standard_EXPORT static const Standard_GUID& NoteRefGUID(); diff --git a/src/XCAFDoc/XCAFDoc_ColorTool.cxx b/src/XCAFDoc/XCAFDoc_ColorTool.cxx index 1385f83a57..815dc0e083 100644 --- a/src/XCAFDoc/XCAFDoc_ColorTool.cxx +++ b/src/XCAFDoc/XCAFDoc_ColorTool.cxx @@ -33,7 +33,25 @@ IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_ColorTool,TDF_Attribute) -#define AUTONAMING // automatically set names for labels +static Standard_Boolean XCAFDoc_ColorTool_AutoNaming = Standard_True; + +//======================================================================= +//function : SetAutoNaming +//purpose : +//======================================================================= +void XCAFDoc_ColorTool::SetAutoNaming (Standard_Boolean theIsAutoNaming) +{ + XCAFDoc_ColorTool_AutoNaming = theIsAutoNaming; +} + +//======================================================================= +//function : AutoNaming +//purpose : +//======================================================================= +Standard_Boolean XCAFDoc_ColorTool::AutoNaming() +{ + return XCAFDoc_ColorTool_AutoNaming; +} //======================================================================= //function : BaseLabel @@ -175,36 +193,32 @@ TDF_Label XCAFDoc_ColorTool::AddColor (const Quantity_Color& col) const //purpose : //======================================================================= -TDF_Label XCAFDoc_ColorTool::AddColor(const Quantity_ColorRGBA& col) const +TDF_Label XCAFDoc_ColorTool::AddColor (const Quantity_ColorRGBA& theColor) const { - TDF_Label L; - if (FindColor(col, L)) return L; + TDF_Label aLab; + if (FindColor (theColor, aLab)) + { + return aLab; + } // create a new color entry - TDF_TagSource aTag; - L = aTag.NewChild(Label()); - - XCAFDoc_Color::Set(L, col); - -#ifdef AUTONAMING - // set name according to color value - TCollection_AsciiString str; - Quantity_Color aColor = col.GetRGB(); - str += aColor.StringName(aColor.Name()); - str += " ("; - str += TCollection_AsciiString(aColor.Red()); - str += ","; - str += TCollection_AsciiString(aColor.Green()); - str += ","; - str += TCollection_AsciiString(aColor.Blue()); - str += ","; - str += TCollection_AsciiString(col.Alpha()); - str += ")"; - TDataStd_Name::Set(L, str); -#endif + aLab = aTag.NewChild (Label()); + XCAFDoc_Color::Set (aLab, theColor); + + if (XCAFDoc_ColorTool_AutoNaming) + { + // set name according to color value + const NCollection_Vec4& anRgbaF = theColor; + const NCollection_Vec4 anRgba (anRgbaF * 255.0f); + char aColorHex[32]; + Sprintf (aColorHex, "%02X%02X%02X%02X", anRgba.r(), anRgba.g(), anRgba.b(), anRgba.a()); + const TCollection_AsciiString aName = TCollection_AsciiString (Quantity_Color::StringName (theColor.GetRGB().Name())) + + " (#" + aColorHex + ")"; + TDataStd_Name::Set (aLab, aName); + } - return L; + return aLab; } //======================================================================= diff --git a/src/XCAFDoc/XCAFDoc_ColorTool.hxx b/src/XCAFDoc/XCAFDoc_ColorTool.hxx index 8a582ed574..8b40145b19 100644 --- a/src/XCAFDoc/XCAFDoc_ColorTool.hxx +++ b/src/XCAFDoc/XCAFDoc_ColorTool.hxx @@ -43,10 +43,17 @@ DEFINE_STANDARD_HANDLE(XCAFDoc_ColorTool, TDF_Attribute) //! Provide tools for management of Colors section of document. class XCAFDoc_ColorTool : public TDF_Attribute { +public: + //! Returns current auto-naming mode; TRUE by default. + //! If TRUE then for added colors the TDataStd_Name attribute will be automatically added. + //! This setting is global. + Standard_EXPORT static Standard_Boolean AutoNaming(); + + //! See also AutoNaming(). + Standard_EXPORT static void SetAutoNaming (Standard_Boolean theIsAutoNaming); public: - Standard_EXPORT XCAFDoc_ColorTool(); //! Creates (if not exist) ColorTool. diff --git a/src/XCAFDoc/XCAFDoc_DocumentTool.cxx b/src/XCAFDoc/XCAFDoc_DocumentTool.cxx index 5614c690f0..1163ff2c86 100644 --- a/src/XCAFDoc/XCAFDoc_DocumentTool.cxx +++ b/src/XCAFDoc/XCAFDoc_DocumentTool.cxx @@ -13,6 +13,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include #include #include @@ -27,12 +28,12 @@ #include #include #include -#include #include #include #include #include #include +#include IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_DocumentTool,TDF_Attribute) @@ -225,6 +226,17 @@ TDF_Label XCAFDoc_DocumentTool::NotesLabel(const TDF_Label& acces) return L; } +//======================================================================= +//function : VisMaterialLabel +//purpose : +//======================================================================= +TDF_Label XCAFDoc_DocumentTool::VisMaterialLabel (const TDF_Label& theLabel) +{ + TDF_Label aLabel = DocLabel (theLabel).FindChild (10, Standard_True); + TDataStd_Name::Set (aLabel, "VisMaterials"); + return aLabel; +} + //======================================================================= //function : ShapeTool //purpose : @@ -246,6 +258,14 @@ Handle(XCAFDoc_ColorTool) XCAFDoc_DocumentTool::ColorTool (const TDF_Label& acce return XCAFDoc_ColorTool::Set(ColorsLabel(acces)); } +//======================================================================= +//function : VisMaterialTool +//purpose : +//======================================================================= +Handle(XCAFDoc_VisMaterialTool) XCAFDoc_DocumentTool::VisMaterialTool (const TDF_Label& theLabel) +{ + return XCAFDoc_VisMaterialTool::Set (VisMaterialLabel (theLabel)); +} //======================================================================= //function : LayerTool diff --git a/src/XCAFDoc/XCAFDoc_DocumentTool.hxx b/src/XCAFDoc/XCAFDoc_DocumentTool.hxx index 51a793fcca..0a26709afc 100644 --- a/src/XCAFDoc/XCAFDoc_DocumentTool.hxx +++ b/src/XCAFDoc/XCAFDoc_DocumentTool.hxx @@ -32,6 +32,7 @@ class XCAFDoc_DimTolTool; class XCAFDoc_MaterialTool; class XCAFDoc_NotesTool; class XCAFDoc_ViewTool; +class XCAFDoc_VisMaterialTool; class TDF_Attribute; class TDF_RelocationTable; @@ -47,7 +48,6 @@ class XCAFDoc_DocumentTool : public TDF_Attribute public: - Standard_EXPORT static const Standard_GUID& GetID(); //! Create (if not exist) DocumentTool attribute @@ -89,12 +89,19 @@ public: //! Returns sub-label of DocLabel() with tag 9. Standard_EXPORT static TDF_Label NotesLabel(const TDF_Label& acces); + //! Returns sub-label of DocLabel() with tag 10. + Standard_EXPORT static TDF_Label VisMaterialLabel (const TDF_Label& theLabel); + //! Creates (if it does not exist) ShapeTool attribute on ShapesLabel(). Standard_EXPORT static Handle(XCAFDoc_ShapeTool) ShapeTool (const TDF_Label& acces); //! Creates (if it does not exist) ColorTool attribute on ColorsLabel(). Standard_EXPORT static Handle(XCAFDoc_ColorTool) ColorTool (const TDF_Label& acces); - + + //! Creates (if it does not exist) XCAFDoc_VisMaterialTool attribute on VisMaterialLabel(). + //! Should not be confused with MaterialTool() defining physical/manufacturing materials. + Standard_EXPORT static Handle(XCAFDoc_VisMaterialTool) VisMaterialTool (const TDF_Label& theLabel); + //! Creates (if it does not exist) LayerTool attribute on LayersLabel(). Standard_EXPORT static Handle(XCAFDoc_LayerTool) LayerTool (const TDF_Label& acces); @@ -113,6 +120,8 @@ public: //! Creates (if it does not exist) NotesTool attribute on NotesLabel(). Standard_EXPORT static Handle(XCAFDoc_NotesTool) NotesTool(const TDF_Label& acces); +public: + Standard_EXPORT XCAFDoc_DocumentTool(); //! to be called when reading this attribute from file @@ -128,22 +137,6 @@ public: DEFINE_STANDARD_RTTIEXT(XCAFDoc_DocumentTool,TDF_Attribute) -protected: - - - - -private: - - - - }; - - - - - - #endif // _XCAFDoc_DocumentTool_HeaderFile diff --git a/src/XCAFDoc/XCAFDoc_VisMaterial.cxx b/src/XCAFDoc/XCAFDoc_VisMaterial.cxx new file mode 100644 index 0000000000..d76c94a0d1 --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_VisMaterial.cxx @@ -0,0 +1,318 @@ +// 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 + +#include +#include +#include +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_VisMaterial, TDF_Attribute) + +//======================================================================= +//function : GetID +//purpose : +//======================================================================= +const Standard_GUID& XCAFDoc_VisMaterial::GetID() +{ + static Standard_GUID THE_VIS_MAT_ID ("EBB00255-03A0-4845-BD3B-A70EEDEEFA78"); + return THE_VIS_MAT_ID; +} + +//======================================================================= +//function : Constructor +//purpose : +//======================================================================= +XCAFDoc_VisMaterial::XCAFDoc_VisMaterial() +: myAlphaMode (Graphic3d_AlphaMode_BlendAuto), + myAlphaCutOff (0.5f), + myIsDoubleSided (Standard_True) +{ + // +} + +//======================================================================= +//function : SetMetalRougnessMaterial +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::SetPbrMaterial (const XCAFDoc_VisMaterialPBR& theMaterial) +{ + Backup(); + myPbrMat = theMaterial; +} + +//======================================================================= +//function : SetCommonMaterial +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::SetCommonMaterial (const XCAFDoc_VisMaterialCommon& theMaterial) +{ + Backup(); + myCommonMat = theMaterial; +} + +//======================================================================= +//function : SetAlphaMode +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::SetAlphaMode (Graphic3d_AlphaMode theMode, + Standard_ShortReal theCutOff) +{ + Backup(); + myAlphaMode = theMode; + myAlphaCutOff = theCutOff; +} + +//======================================================================= +//function : SetDoubleSided +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::SetDoubleSided (Standard_Boolean theIsDoubleSided) +{ + Backup(); + myIsDoubleSided = theIsDoubleSided; +} + +//======================================================================= +//function : Restore +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::Restore (const Handle(TDF_Attribute)& theWith) +{ + XCAFDoc_VisMaterial* anOther = dynamic_cast(theWith.get()); + myPbrMat = anOther->myPbrMat; + myCommonMat = anOther->myCommonMat; + myAlphaMode = anOther->myAlphaMode; + myAlphaCutOff = anOther->myAlphaCutOff; + myIsDoubleSided = anOther->myIsDoubleSided; +} + +//======================================================================= +//function : NewEmpty +//purpose : +//======================================================================= +Handle(TDF_Attribute) XCAFDoc_VisMaterial::NewEmpty() const +{ + return new XCAFDoc_VisMaterial(); +} + +//======================================================================= +//function : Paste +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::Paste (const Handle(TDF_Attribute)& theInto, + const Handle(TDF_RelocationTable)& ) const +{ + XCAFDoc_VisMaterial* anOther = dynamic_cast(theInto.get()); + anOther->Backup(); + anOther->myPbrMat = myPbrMat; + anOther->myCommonMat = myCommonMat; + anOther->myAlphaMode = myAlphaMode; + anOther->myAlphaCutOff = myAlphaCutOff; + anOther->myIsDoubleSided = myIsDoubleSided; +} + +// ======================================================================= +// function : BaseColor +// purpose : +// ======================================================================= +Quantity_ColorRGBA XCAFDoc_VisMaterial::BaseColor() const +{ + if (myPbrMat.IsDefined) + { + return myPbrMat.BaseColor; + } + else if (myCommonMat.IsDefined) + { + return Quantity_ColorRGBA (myCommonMat.DiffuseColor, 1.0f - myCommonMat.Transparency); + } + return Quantity_ColorRGBA (Quantity_NOC_WHITE); +} + +//======================================================================= +//function : ConvertToCommonMaterial +//purpose : +//======================================================================= +XCAFDoc_VisMaterialCommon XCAFDoc_VisMaterial::ConvertToCommonMaterial() +{ + if (myCommonMat.IsDefined) + { + return myCommonMat; + } + else if (!myPbrMat.IsDefined) + { + return XCAFDoc_VisMaterialCommon(); + } + + // convert metal-roughness into common + XCAFDoc_VisMaterialCommon aComMat; + aComMat.IsDefined = true; + aComMat.DiffuseColor = myPbrMat.BaseColor.GetRGB(); + aComMat.SpecularColor = Quantity_Color (Graphic3d_Vec3 (myPbrMat.Metallic)); + aComMat.Transparency = 1.0f - myPbrMat.BaseColor.Alpha(); + aComMat.Shininess = 1.0f - myPbrMat.Roughness; + return aComMat; +} + +//! Compute material roughness from common material. +static Standard_ShortReal roughnessFromCommon (const XCAFDoc_VisMaterialCommon& theMat) +{ + Standard_Real aRoughnessFactor = 1.0 - theMat.Shininess; + //Standard_Real aSpecIntens = theMat.SpecularColor.Light() * theMat.SpecularColor; + const Standard_Real aSpecIntens = theMat.SpecularColor.Red() * 0.2125 + + theMat.SpecularColor.Green() * 0.7154 + + theMat.SpecularColor.Blue() * 0.0721; + if (aSpecIntens < 0.1) + { + // low specular intensity should produce a rough material even if shininess is high + aRoughnessFactor *= (1.0 - aSpecIntens); + } + return (Standard_ShortReal )aRoughnessFactor; +} + +//======================================================================= +//function : ConvertToPbrMaterial +//purpose : +//======================================================================= +XCAFDoc_VisMaterialPBR XCAFDoc_VisMaterial::ConvertToPbrMaterial() +{ + if (myPbrMat.IsDefined) + { + return myPbrMat; + } + else if (!myCommonMat.IsDefined) + { + return XCAFDoc_VisMaterialPBR(); + } + + XCAFDoc_VisMaterialPBR aPbrMat; + aPbrMat.IsDefined = true; + aPbrMat.BaseColor.SetRGB (myCommonMat.DiffuseColor); + aPbrMat.BaseColor.SetAlpha (1.0f - myCommonMat.Transparency); + // we allow to save any number in range [0, 1] but logically metallicity can be either 0 or 1 + aPbrMat.Metallic = ((Graphic3d_Vec3 )myCommonMat.SpecularColor).maxComp(); // > 0.1f ? 1.0 : 0.0; + aPbrMat.Roughness = roughnessFromCommon (myCommonMat); + return aPbrMat; +} + +//======================================================================= +//function : FillMaterialAspect +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::FillMaterialAspect (Graphic3d_MaterialAspect& theAspect) const +{ + if (myCommonMat.IsDefined) + { + theAspect = Graphic3d_MaterialAspect (Graphic3d_NOM_UserDefined); + theAspect.SetAmbientColor (myCommonMat.AmbientColor); + theAspect.SetDiffuseColor (myCommonMat.DiffuseColor); + theAspect.SetSpecularColor(myCommonMat.SpecularColor); + theAspect.SetEmissiveColor(myCommonMat.EmissiveColor); + theAspect.SetTransparency (myCommonMat.Transparency); + theAspect.SetShininess (myCommonMat.Shininess); + + // convert common into metal-roughness + if (!myPbrMat.IsDefined) + { + #ifdef _Graphic3d_PBRMaterial_HeaderFile + Graphic3d_PBRMaterial aPbr; + aPbr.SetColor (myCommonMat.DiffuseColor); + aPbr.SetMetallic (((Graphic3d_Vec3 )myCommonMat.SpecularColor).maxComp()); + aPbr.SetRoughness (roughnessFromCommon (myCommonMat)); + theAspect.SetPBRMaterial (aPbr); + #endif + } + } + + if (myPbrMat.IsDefined) + { + if (!myCommonMat.IsDefined) + { + // convert metal-roughness into common + theAspect = Graphic3d_MaterialAspect (Graphic3d_NOM_UserDefined); + theAspect.SetDiffuseColor (myPbrMat.BaseColor.GetRGB()); + theAspect.SetAlpha (myPbrMat.BaseColor.Alpha()); + theAspect.SetSpecularColor(Quantity_Color (Graphic3d_Vec3 (myPbrMat.Metallic))); + theAspect.SetShininess (1.0f - myPbrMat.Roughness); + } + + #ifdef _Graphic3d_PBRMaterial_HeaderFile + Graphic3d_PBRMaterial aPbr; + aPbr.SetColor (myPbrMat.BaseColor); + aPbr.SetMetallic (myPbrMat.Metallic); + aPbr.SetRoughness(myPbrMat.Roughness); + aPbr.SetEmission (myPbrMat.EmissiveFactor); + theAspect.SetPBRMaterial (aPbr); + #endif + } +} + +//======================================================================= +//function : FillAspect +//purpose : +//======================================================================= +void XCAFDoc_VisMaterial::FillAspect (const Handle(Graphic3d_Aspects)& theAspect) const +{ + if (IsEmpty()) + { + return; + } + + Graphic3d_MaterialAspect aMaterial; + FillMaterialAspect (aMaterial); + theAspect->SetFrontMaterial (aMaterial); + theAspect->SetAlphaMode (myAlphaMode , myAlphaCutOff); + theAspect->SetSuppressBackFaces (!myIsDoubleSided); + + Handle(Image_Texture) aColorTexture, aNormTexture; + if (!myCommonMat.DiffuseTexture.IsNull()) + { + aColorTexture = myCommonMat.DiffuseTexture; + } + else if (!myPbrMat.BaseColorTexture.IsNull()) + { + aColorTexture = myPbrMat.BaseColorTexture; + } + + if (!myPbrMat.NormalTexture.IsNull()) + { + aNormTexture = myPbrMat.NormalTexture; + } + + Standard_Integer aNbTextures = 0; + if (!aColorTexture.IsNull()) + { + ++aNbTextures; + } + if (!aNormTexture.IsNull()) + { + //++aNbTextures; + } + if (aNbTextures != 0) + { + Handle(Graphic3d_TextureSet) aTextureSet = new Graphic3d_TextureSet (aNbTextures); + Standard_Integer aTextureIndex = 0; + if (!aColorTexture.IsNull()) + { + aTextureSet->SetValue (aTextureIndex++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_BaseColor)); + } + if (!aNormTexture.IsNull()) + { + //aTextureSet->SetValue (aTextureIndex++, new XCAFPrs_Texture (*aColorTexture, Graphic3d_TextureUnit_Normal)); + } + theAspect->SetTextureSet (aTextureSet); + theAspect->SetTextureMapOn (true); + } +} diff --git a/src/XCAFDoc/XCAFDoc_VisMaterial.hxx b/src/XCAFDoc/XCAFDoc_VisMaterial.hxx new file mode 100644 index 0000000000..41ec4afebb --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_VisMaterial.hxx @@ -0,0 +1,171 @@ +// 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. + +#ifndef _XCAFDoc_VisMaterial_HeaderFile +#define _XCAFDoc_VisMaterial_HeaderFile + +#include +#include +#include + +class Graphic3d_Aspects; +class Graphic3d_MaterialAspect; + +//! Attribute storing Material definition for visualization purposes. +//! +//! Visualization material provides extended information about how object should be displayed on the screen +//! (albedo, metalness, roughness - not just a single color as in case of XCAFDoc_Color). +//! It is expected to correlate with physical material properties (XCAFDoc_Material), but not necessarily (like painted/polished/rusty object). +//! +//! The document defines the list of visualization materials via global attribute XCAFDoc_VisMaterialTool, +//! while particular material assignment to the shape is done through tree-nodes links. +//! Therefore, XCAFDoc_VisMaterialTool methods should be used for managing XCAFDoc_VisMaterial attributes. +//! +//! Visualization material definition consists of two options: Common and PBR (for Physically Based Rendering). +//! Common material definition is an obsolete model defined by very first version of OpenGL graphics API +//! and having specific hardware-accelerated implementation in past (like T&L). +//! PBR metallic-roughness model is closer to physical material properties, and intended to be used within physically-based renderer. +//! +//! For compatibility reasons, this attribute allows defining both material models, +//! so that it is up-to Data Exchange and Application deciding which one to define and use for rendering (depending on viewer capabilities). +//! Automatic conversion from one model to another is possible, but lossy (converted material will not look the same). +//! +//! Within Data Exchange, different file formats have different capabilities for storing visualization material properties +//! from simple color (STEP, IGES), to common (OBJ, glTF 1.0) and PBR (glTF 2.0). +//! This should be taken into account while defining or converting document into one or another format - material definition might be lost or disturbed. +//! +//! @sa XCAFDoc_VisMaterialTool +class XCAFDoc_VisMaterial : public TDF_Attribute +{ + DEFINE_STANDARD_RTTIEXT(XCAFDoc_VisMaterial, TDF_Attribute) +public: + + //! Return attribute GUID. + Standard_EXPORT static const Standard_GUID& GetID(); + +public: + + //! Empty constructor. + Standard_EXPORT XCAFDoc_VisMaterial(); + + //! Return TRUE if material definition is empty. + bool IsEmpty() const { return !myPbrMat.IsDefined && !myCommonMat.IsDefined; } + + //! Fill in material aspect. + Standard_EXPORT void FillMaterialAspect (Graphic3d_MaterialAspect& theAspect) const; + + //! Fill in graphic aspects. + Standard_EXPORT void FillAspect (const Handle(Graphic3d_Aspects)& theAspect) const; + + //! Return TRUE if metal-roughness PBR material is defined. + Standard_Boolean HasPbrMaterial() const { return myPbrMat.IsDefined; } + + //! Return metal-roughness PBR material. + const XCAFDoc_VisMaterialPBR& PbrMaterial() const { return myPbrMat; } + + //! Setup metal-roughness PBR material. + Standard_EXPORT void SetPbrMaterial (const XCAFDoc_VisMaterialPBR& theMaterial); + + //! Setup undefined metal-roughness PBR material. + void UnsetPbrMaterial() { SetPbrMaterial (XCAFDoc_VisMaterialPBR()); } + + //! Return TRUE if common material is defined. + Standard_Boolean HasCommonMaterial() const { return myCommonMat.IsDefined; } + + //! Return common material. + const XCAFDoc_VisMaterialCommon& CommonMaterial() const { return myCommonMat; } + + //! Setup common material. + Standard_EXPORT void SetCommonMaterial (const XCAFDoc_VisMaterialCommon& theMaterial); + + //! Setup undefined common material. + void UnsetCommonMaterial() { SetCommonMaterial (XCAFDoc_VisMaterialCommon()); } + + //! Return base color. + Standard_EXPORT Quantity_ColorRGBA BaseColor() const; + + //! Return alpha mode; Graphic3d_AlphaMode_BlendAuto by default. + Graphic3d_AlphaMode AlphaMode() const { return myAlphaMode; } + + //! Return alpha cutoff value; 0.5 by default. + Standard_ShortReal AlphaCutOff() const { return myAlphaCutOff; } + + //! Set alpha mode. + Standard_EXPORT void SetAlphaMode (Graphic3d_AlphaMode theMode, + Standard_ShortReal theCutOff = 0.5f); + + //! Specifies whether the material is double sided; TRUE by default. + Standard_Boolean IsDoubleSided() const { return myIsDoubleSided; } + + //! Specifies whether the material is double sided. + Standard_EXPORT void SetDoubleSided (Standard_Boolean theIsDoubleSided); + + //! Return material name / tag (transient data, not stored in the document). + const Handle(TCollection_HAsciiString)& RawName() const { return myRawName; } + + //! Set material name / tag (transient data, not stored in the document). + void SetRawName (const Handle(TCollection_HAsciiString)& theName) { myRawName = theName; } + + //! Compare two materials. + //! Performs deep comparison by actual values - e.g. can be useful for merging materials. + Standard_Boolean IsEqual (const Handle(XCAFDoc_VisMaterial)& theOther) const + { + if (theOther.get() == this) + { + return true; + } + return theOther->myIsDoubleSided == myIsDoubleSided + && theOther->myAlphaCutOff == myAlphaCutOff + && theOther->myAlphaMode == myAlphaMode + && theOther->myCommonMat.IsEqual (myCommonMat) + && theOther->myPbrMat.IsEqual (myPbrMat); + } + + //! Return Common material or convert PBR into Common material. + Standard_EXPORT XCAFDoc_VisMaterialCommon ConvertToCommonMaterial(); + + //! Return PBR material or convert Common into PBR material. + Standard_EXPORT XCAFDoc_VisMaterialPBR ConvertToPbrMaterial(); + +public: //! @name interface implementation + + //! Return GUID of this attribute type. + virtual const Standard_GUID& ID() const Standard_OVERRIDE { return GetID(); } + + //! Restore attribute from specified state. + //! @param theWith [in] attribute state to restore (copy into this) + Standard_EXPORT virtual void Restore (const Handle(TDF_Attribute)& theWith) Standard_OVERRIDE; + + //! Create a new empty attribute. + Standard_EXPORT virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE; + + //! Paste this attribute into another one. + //! @param theInto [in/out] target attribute to copy this into + //! @param theRelTable [in] relocation table + Standard_EXPORT virtual void Paste (const Handle(TDF_Attribute)& theInto, + const Handle(TDF_RelocationTable)& theRelTable) const Standard_OVERRIDE; + +private: + + Handle(TCollection_HAsciiString) myRawName; //!< material name / tag (transient data) + XCAFDoc_VisMaterialPBR myPbrMat; //!< metal-roughness material definition + XCAFDoc_VisMaterialCommon myCommonMat; //!< common material definition + Graphic3d_AlphaMode myAlphaMode; //!< alpha mode; Graphic3d_AlphaMode_BlendAuto by default + Standard_ShortReal myAlphaCutOff; //!< alpha cutoff value; 0.5 by default + Standard_Boolean myIsDoubleSided; //!< specifies whether the material is double sided; TRUE by default + +}; + +DEFINE_STANDARD_HANDLE(XCAFDoc_VisMaterial, TDF_Attribute) + +#endif // _XCAFDoc_VisMaterial_HeaderFile diff --git a/src/XCAFDoc/XCAFDoc_VisMaterialCommon.hxx b/src/XCAFDoc/XCAFDoc_VisMaterialCommon.hxx new file mode 100644 index 0000000000..dfb01d6e2e --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_VisMaterialCommon.hxx @@ -0,0 +1,73 @@ +// 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. + +#ifndef _XCAFDoc_VisMaterialCommon_HeaderFile +#define _XCAFDoc_VisMaterialCommon_HeaderFile + +#include +#include +#include +#include + +class Graphic3d_Aspects; +class Graphic3d_MaterialAspect; + +//! Common (obsolete) material definition. +struct XCAFDoc_VisMaterialCommon +{ + Handle(Image_Texture) DiffuseTexture; //!< image defining diffuse color + Quantity_Color AmbientColor; //!< ambient color + Quantity_Color DiffuseColor; //!< diffuse color + Quantity_Color SpecularColor; //!< specular color + Quantity_Color EmissiveColor; //!< emission color + Standard_ShortReal Shininess; //!< shininess value + Standard_ShortReal Transparency; //!< transparency value within [0, 1] range with 0 meaning opaque + Standard_Boolean IsDefined; //!< defined flag; FALSE by default + + //! Empty constructor. + XCAFDoc_VisMaterialCommon() + : AmbientColor (0.1, 0.1, 0.1, Quantity_TOC_RGB), + DiffuseColor (0.8, 0.8, 0.8, Quantity_TOC_RGB), + SpecularColor(0.2, 0.2, 0.2, Quantity_TOC_RGB), + EmissiveColor(0.0, 0.0, 0.0, Quantity_TOC_RGB), + Shininess (1.0f), + Transparency (0.0f), + IsDefined (Standard_False) {} + + //! Compare two materials. + Standard_Boolean IsEqual (const XCAFDoc_VisMaterialCommon& theOther) const + { + if (&theOther == this) + { + return true; + } + else if (theOther.IsDefined != IsDefined) + { + return false; + } + else if (!IsDefined) + { + return true; + } + + return theOther.DiffuseTexture == DiffuseTexture + && theOther.AmbientColor == AmbientColor + && theOther.DiffuseColor == DiffuseColor + && theOther.SpecularColor == SpecularColor + && theOther.EmissiveColor == EmissiveColor + && theOther.Shininess == Shininess + && theOther.Transparency == Transparency; + } +}; + +#endif // _XCAFDoc_VisMaterialCommon_HeaderFile diff --git a/src/XCAFDoc/XCAFDoc_VisMaterialPBR.hxx b/src/XCAFDoc/XCAFDoc_VisMaterialPBR.hxx new file mode 100644 index 0000000000..bbe3d3c7cb --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_VisMaterialPBR.hxx @@ -0,0 +1,72 @@ +// 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. + +#ifndef _XCAFDoc_VisMaterialPBR_HeaderFile +#define _XCAFDoc_VisMaterialPBR_HeaderFile + +#include +#include +#include +#include + +//! Metallic-roughness PBR material definition. +struct XCAFDoc_VisMaterialPBR +{ + Handle(Image_Texture) BaseColorTexture; //!< RGB texture for the base color + Handle(Image_Texture) MetallicRoughnessTexture; //!< RG texture packing the metallic and roughness properties together + Handle(Image_Texture) EmissiveTexture; //!< RGB emissive map controls the color and intensity of the light being emitted by the material + Handle(Image_Texture) OcclusionTexture; //!< R occlusion map indicating areas of indirect lighting + Handle(Image_Texture) NormalTexture; //!< normal map + Quantity_ColorRGBA BaseColor; //!< base color (or scale factor to the texture); [1.0, 1.0, 1.0, 1.0] by default + Graphic3d_Vec3 EmissiveFactor; //!< emissive color; [0.0, 0.0, 0.0] by default + Standard_ShortReal Metallic; //!< metalness (or scale factor to the texture) within range [0.0, 1.0]; 1.0 by default + Standard_ShortReal Roughness; //!< roughness (or scale factor to the texture) within range [0.0, 1.0]; 1.0 by default + Standard_Boolean IsDefined; //!< defined flag; FALSE by default + + //! Empty constructor. + XCAFDoc_VisMaterialPBR() + : BaseColor (1.0f, 1.0f, 1.0f, 1.0f), + EmissiveFactor (0.0f, 0.0f, 0.0f), + Metallic (1.0f), + Roughness (1.0f), + IsDefined (Standard_False) {} + + //! Compare two materials. + Standard_Boolean IsEqual (const XCAFDoc_VisMaterialPBR& theOther) const + { + if (&theOther == this) + { + return true; + } + else if (theOther.IsDefined != IsDefined) + { + return false; + } + else if (!IsDefined) + { + return true; + } + + return theOther.BaseColorTexture == BaseColorTexture + && theOther.MetallicRoughnessTexture == MetallicRoughnessTexture + && theOther.EmissiveTexture == EmissiveTexture + && theOther.OcclusionTexture == OcclusionTexture + && theOther.NormalTexture == NormalTexture + && theOther.BaseColor == BaseColor + && theOther.EmissiveFactor == EmissiveFactor + && theOther.Metallic == Metallic + && theOther.Roughness == Roughness; + } +}; + +#endif // _XCAFDoc_VisMaterialPBR_HeaderFile diff --git a/src/XCAFDoc/XCAFDoc_VisMaterialTool.cxx b/src/XCAFDoc/XCAFDoc_VisMaterialTool.cxx new file mode 100644 index 0000000000..fb19c9e1d6 --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_VisMaterialTool.cxx @@ -0,0 +1,292 @@ +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(XCAFDoc_VisMaterialTool, TDF_Attribute) + +//======================================================================= +//function : GetID +//purpose : +//======================================================================= +const Standard_GUID& XCAFDoc_VisMaterialTool::GetID() +{ + static Standard_GUID THE_VIS_MAT_TOOL_ID ("87B511CE-DA15-4A5E-98AF-E3F46AB5B6E8"); + return THE_VIS_MAT_TOOL_ID; +} + +//======================================================================= +//function : Set +//purpose : +//======================================================================= +Handle(XCAFDoc_VisMaterialTool) XCAFDoc_VisMaterialTool::Set (const TDF_Label& theLabel) +{ + Handle(XCAFDoc_VisMaterialTool) aTool; + if (!theLabel.FindAttribute (XCAFDoc_VisMaterialTool::GetID(), aTool)) + { + aTool = new XCAFDoc_VisMaterialTool(); + theLabel.AddAttribute (aTool); + aTool->myShapeTool = XCAFDoc_DocumentTool::ShapeTool (theLabel); + } + return aTool; +} + + +//======================================================================= +//function : XCAFDoc_VisMaterialTool +//purpose : +//======================================================================= +XCAFDoc_VisMaterialTool::XCAFDoc_VisMaterialTool() +{ + // +} + +//======================================================================= +//function : ShapeTool +//purpose : +//======================================================================= +const Handle(XCAFDoc_ShapeTool)& XCAFDoc_VisMaterialTool::ShapeTool() +{ + if (myShapeTool.IsNull()) + { + myShapeTool = XCAFDoc_DocumentTool::ShapeTool (Label()); + } + return myShapeTool; +} + +//======================================================================= +//function : GetMaterial +//purpose : +//======================================================================= +Handle(XCAFDoc_VisMaterial) XCAFDoc_VisMaterialTool::GetMaterial (const TDF_Label& theMatLabel) const +{ + Handle(XCAFDoc_VisMaterial) aMatAttrib; + if (theMatLabel.Father() == Label()) + { + theMatLabel.FindAttribute (XCAFDoc_VisMaterial::GetID(), aMatAttrib); + } + return aMatAttrib; +} + +//======================================================================= +//function : AddMaterial +//purpose : +//======================================================================= +TDF_Label XCAFDoc_VisMaterialTool::AddMaterial (const Handle(XCAFDoc_VisMaterial)& theMat, + const TCollection_AsciiString& theName) const +{ + TDF_TagSource aTag; + TDF_Label aLab = aTag.NewChild (Label()); + aLab.AddAttribute (theMat); + if (!theName.IsEmpty()) + { + TDataStd_Name::Set (aLab, theName); + } + return aLab; +} + +//======================================================================= +//function : AddMaterial +//purpose : +//======================================================================= +TDF_Label XCAFDoc_VisMaterialTool::AddMaterial (const TCollection_AsciiString& theName) const +{ + Handle(XCAFDoc_VisMaterial) aNewMat = new XCAFDoc_VisMaterial(); + TDF_TagSource aTag; + TDF_Label aLab = aTag.NewChild (Label()); + aLab.AddAttribute (aNewMat); + if (!theName.IsEmpty()) + { + TDataStd_Name::Set (aLab, theName); + } + return aLab; +} + +//======================================================================= +//function : RemoveMaterial +//purpose : +//======================================================================= +void XCAFDoc_VisMaterialTool::RemoveMaterial (const TDF_Label& theLabel) const +{ + theLabel.ForgetAllAttributes (true); +} + +//======================================================================= +//function : GetMaterials +//purpose : +//======================================================================= +void XCAFDoc_VisMaterialTool::GetMaterials (TDF_LabelSequence& theLabels) const +{ + theLabels.Clear(); + for (TDF_ChildIDIterator aChildIDIterator (Label(), XCAFDoc_VisMaterial::GetID()); aChildIDIterator.More(); aChildIDIterator.Next()) + { + const TDF_Label aLabel = aChildIDIterator.Value()->Label(); + if (IsMaterial (aLabel)) + { + theLabels.Append (aLabel); + } + } +} + +//======================================================================= +//function : SetShapeMaterial +//purpose : +//======================================================================= +void XCAFDoc_VisMaterialTool::SetShapeMaterial (const TDF_Label& theShapeLabel, + const TDF_Label& theMaterialLabel) const +{ + if (theMaterialLabel.IsNull()) + { + theShapeLabel.ForgetAttribute (XCAFDoc::VisMaterialRefGUID()); + return; + } + + // set reference + Handle(TDataStd_TreeNode) aMainNode = TDataStd_TreeNode::Set (theMaterialLabel, XCAFDoc::VisMaterialRefGUID()); + Handle(TDataStd_TreeNode) aRefNode = TDataStd_TreeNode::Set (theShapeLabel, XCAFDoc::VisMaterialRefGUID()); + aRefNode->Remove(); // abv: fix against bug in TreeNode::Append() + aMainNode->Prepend (aRefNode); +} + +//======================================================================= +//function : UnSetShapeMaterial +//purpose : +//======================================================================= +void XCAFDoc_VisMaterialTool::UnSetShapeMaterial (const TDF_Label& theShapeLabel) const +{ + theShapeLabel.ForgetAttribute (XCAFDoc::VisMaterialRefGUID()); +} + +//======================================================================= +//function : IsSetShapeMaterial +//purpose : +//======================================================================= +Standard_Boolean XCAFDoc_VisMaterialTool::IsSetShapeMaterial (const TDF_Label& theLabel) const +{ + Handle(TDataStd_TreeNode) aNode; + return theLabel.FindAttribute (XCAFDoc::VisMaterialRefGUID(), aNode) + && aNode->HasFather(); +} + +//======================================================================= +//function : GetShapeMaterial +//purpose : +//======================================================================= +Standard_Boolean XCAFDoc_VisMaterialTool::GetShapeMaterial (const TDF_Label& theShapeLabel, + TDF_Label& theMaterialLabel) +{ + Handle(TDataStd_TreeNode) aNode; + if (!theShapeLabel.FindAttribute (XCAFDoc::VisMaterialRefGUID(), aNode) + || !aNode->HasFather()) + { + return Standard_False; + } + + theMaterialLabel = aNode->Father()->Label(); + return Standard_True; +} + +//======================================================================= +//function : GetShapeMaterial +//purpose : +//======================================================================= +Handle(XCAFDoc_VisMaterial) XCAFDoc_VisMaterialTool::GetShapeMaterial (const TDF_Label& theShapeLabel) +{ + TDF_Label aMatLabel; + return Label().HasChild() // do not waste time on shape attributes if materials map is empty + && GetShapeMaterial (theShapeLabel, aMatLabel) + ? GetMaterial (aMatLabel) + : Handle(XCAFDoc_VisMaterial)(); +} + +//======================================================================= +//function : SetShapeMaterial +//purpose : +//======================================================================= +Standard_Boolean XCAFDoc_VisMaterialTool::SetShapeMaterial (const TopoDS_Shape& theShape, + const TDF_Label& theMaterialLabel) +{ + TDF_Label aShapeLabel; + if (!ShapeTool()->Search (theShape, aShapeLabel)) + { + return Standard_False; + } + + SetShapeMaterial (aShapeLabel, theMaterialLabel); + return Standard_True; +} + +//======================================================================= +//function : UnSetShapeMaterial +//purpose : +//======================================================================= +Standard_Boolean XCAFDoc_VisMaterialTool::UnSetShapeMaterial (const TopoDS_Shape& theShape) +{ + TDF_Label aShapeLabel; + if (!ShapeTool()->Search (theShape, aShapeLabel)) + { + return Standard_False; + } + + UnSetShapeMaterial (aShapeLabel); + return Standard_True; +} + +//======================================================================= +//function : IsSetShapeMaterial +//purpose : +//======================================================================= +Standard_Boolean XCAFDoc_VisMaterialTool::IsSetShapeMaterial (const TopoDS_Shape& theShape) +{ + TDF_Label aShapeLabel; + return ShapeTool()->Search (theShape, aShapeLabel) + && IsSetShapeMaterial (aShapeLabel); +} + +//======================================================================= +//function : GetShapeMaterial +//purpose : +//======================================================================= +Standard_Boolean XCAFDoc_VisMaterialTool::GetShapeMaterial (const TopoDS_Shape& theShape, + TDF_Label& theMaterialLabel) +{ + TDF_Label aShapeLabel; + return ShapeTool()->Search (theShape, aShapeLabel) + && GetShapeMaterial (aShapeLabel, theMaterialLabel); +} + +//======================================================================= +//function : GetShapeMaterial +//purpose : +//======================================================================= +Handle(XCAFDoc_VisMaterial) XCAFDoc_VisMaterialTool::GetShapeMaterial (const TopoDS_Shape& theShape) +{ + TDF_Label aMatLabel; + return GetShapeMaterial (theShape, aMatLabel) + ? GetMaterial (aMatLabel) + : Handle(XCAFDoc_VisMaterial)(); +} diff --git a/src/XCAFDoc/XCAFDoc_VisMaterialTool.hxx b/src/XCAFDoc/XCAFDoc_VisMaterialTool.hxx new file mode 100644 index 0000000000..2ab97132f0 --- /dev/null +++ b/src/XCAFDoc/XCAFDoc_VisMaterialTool.hxx @@ -0,0 +1,141 @@ +// 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. + +#ifndef _XCAFDoc_VisMaterialTool_HeaderFile +#define _XCAFDoc_VisMaterialTool_HeaderFile + +#include +#include +#include + +class TopoDS_Shape; +class Quantity_ColorRGBA; +class XCAFDoc_ShapeTool; +class XCAFDoc_VisMaterial; + +//! Provides tools to store and retrieve attributes (visualization materials) of TopoDS_Shape in and from TDocStd_Document. +//! +//! This attribute defines the list of visualization materials (XCAFDoc_VisMaterial) within the whole document. +//! Particular material is assigned to the shape through tree-nodes links. +//! +//! Visualization materials might co-exists with independent color attributes (XCAFDoc_ColorTool), +//! but beware to preserve consistency between them (it is better using one attribute type at once to avoid ambiguity). +//! Unlike color attributes, list of materials should be managed explicitly by application, +//! so that there is no tool eliminating material duplicates or removing unused materials. +//! +//! @sa XCAFDoc_VisMaterial +class XCAFDoc_VisMaterialTool : public TDF_Attribute +{ + DEFINE_STANDARD_RTTIEXT(XCAFDoc_VisMaterialTool, TDF_Attribute) +public: + + //! Creates (if not exist) ColorTool. + Standard_EXPORT static Handle(XCAFDoc_VisMaterialTool) Set (const TDF_Label& L); + + Standard_EXPORT static const Standard_GUID& GetID(); + +public: + //! Empty constructor. + Standard_EXPORT XCAFDoc_VisMaterialTool(); + + //! returns the label under which colors are stored + Standard_EXPORT TDF_Label BaseLabel() const { return Label(); } + + //! Returns internal XCAFDoc_ShapeTool tool + Standard_EXPORT const Handle(XCAFDoc_ShapeTool)& ShapeTool(); + + //! Returns TRUE if Label belongs to a Material Table. + Standard_Boolean IsMaterial (const TDF_Label& theLabel) const { return !GetMaterial (theLabel).IsNull(); } + + //! Returns Material defined by specified Label, or NULL if the label is not in Material Table. + Standard_EXPORT Handle(XCAFDoc_VisMaterial) GetMaterial (const TDF_Label& theMatLabel) const; + + //! Adds Material definition to a Material Table and returns its Label. + Standard_EXPORT TDF_Label AddMaterial (const Handle(XCAFDoc_VisMaterial)& theMat, + const TCollection_AsciiString& theName) const; + + //! Adds Material definition to a Material Table and returns its Label. + Standard_EXPORT TDF_Label AddMaterial(const TCollection_AsciiString& theName) const; + + //! Removes Material from the Material Table + Standard_EXPORT void RemoveMaterial (const TDF_Label& theLabel) const; + + //! Returns a sequence of Materials currently stored in the Material Table. + Standard_EXPORT void GetMaterials (TDF_LabelSequence& Labels) const; + + //! Sets new material to the shape. + Standard_EXPORT void SetShapeMaterial (const TDF_Label& theShapeLabel, + const TDF_Label& theMaterialLabel) const; + + //! Removes a link with GUID XCAFDoc::VisMaterialRefGUID() from shape label to material. + Standard_EXPORT void UnSetShapeMaterial (const TDF_Label& theShapeLabel) const; + + //! Returns TRUE if label has a material assignment. + Standard_EXPORT Standard_Boolean IsSetShapeMaterial (const TDF_Label& theLabel) const; + + //! Returns label with material assigned to shape label. + //! @param theShapeLabel [in] shape label + //! @param theMaterialLabel [out] material label + //! @return FALSE if no material is assigned + Standard_EXPORT static Standard_Boolean GetShapeMaterial (const TDF_Label& theShapeLabel, TDF_Label& theMaterialLabel); + + //! Returns material assigned to the shape label. + Standard_EXPORT Handle(XCAFDoc_VisMaterial) GetShapeMaterial (const TDF_Label& theShapeLabel); + + //! Sets a link with GUID XCAFDoc::VisMaterialRefGUID() from shape label to material label. + //! @param theShape [in] shape + //! @param theMaterialLabel [in] material label + //! @return FALSE if cannot find a label for shape + Standard_EXPORT Standard_Boolean SetShapeMaterial (const TopoDS_Shape& theShape, + const TDF_Label& theMaterialLabel); + + //! Removes a link with GUID XCAFDoc::VisMaterialRefGUID() from shape label to material. + //! @return TRUE if such link existed + Standard_EXPORT Standard_Boolean UnSetShapeMaterial (const TopoDS_Shape& theShape); + + //! Returns TRUE if shape has a material assignment. + Standard_EXPORT Standard_Boolean IsSetShapeMaterial (const TopoDS_Shape& theShape); + + //! Returns label with material assigned to shape. + //! @param theShape [in] shape + //! @param theMaterialLabel [out] material label + //! @return FALSE if no material is assigned + Standard_EXPORT Standard_Boolean GetShapeMaterial (const TopoDS_Shape& theShape, TDF_Label& theMaterialLabel); + + //! Returns material assigned to shape or NULL if not assigned. + Standard_EXPORT Handle(XCAFDoc_VisMaterial) GetShapeMaterial (const TopoDS_Shape& theShape); + +public: + + //! Returns GUID of this attribute type. + virtual const Standard_GUID& ID() const Standard_OVERRIDE { return GetID(); } + + //! Does nothing. + virtual void Restore (const Handle(TDF_Attribute)& ) Standard_OVERRIDE {} + + //! Creates new instance of this tool. + virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE { return new XCAFDoc_VisMaterialTool(); } + + //! Does nothing. + virtual void Paste (const Handle(TDF_Attribute)& , + const Handle(TDF_RelocationTable)& ) const Standard_OVERRIDE {} + +private: + + Handle(XCAFDoc_ShapeTool) myShapeTool; + +}; + +DEFINE_STANDARD_HANDLE(XCAFDoc_VisMaterialTool, TDF_Attribute) + +#endif // _XCAFDoc_VisMaterialTool_HeaderFile diff --git a/src/XCAFPrs/FILES b/src/XCAFPrs/FILES index 77d00e029b..b86972f7ca 100644 --- a/src/XCAFPrs/FILES +++ b/src/XCAFPrs/FILES @@ -16,3 +16,5 @@ XCAFPrs_Driver.cxx XCAFPrs_Driver.hxx XCAFPrs_Style.cxx XCAFPrs_Style.hxx +XCAFPrs_Texture.cxx +XCAFPrs_Texture.hxx diff --git a/src/XCAFPrs/XCAFPrs.cxx b/src/XCAFPrs/XCAFPrs.cxx index 4382b4ae2e..161d1f41f5 100644 --- a/src/XCAFPrs/XCAFPrs.cxx +++ b/src/XCAFPrs/XCAFPrs.cxx @@ -13,8 +13,8 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include -#include #include #include #include @@ -29,12 +29,33 @@ #include #include #include +#include #include -#include #include static Standard_Boolean viewnameMode = Standard_False; +//! Fill colors of XCAFPrs_Style structure. +static void fillStyleColors (XCAFPrs_Style& theStyle, + const Handle(XCAFDoc_ColorTool)& theTool, + const TDF_Label& theLabel) +{ + Quantity_ColorRGBA aColor; + if (theTool->GetColor (theLabel, XCAFDoc_ColorGen, aColor)) + { + theStyle.SetColorCurv (aColor.GetRGB()); + theStyle.SetColorSurf (aColor); + } + if (theTool->GetColor (theLabel, XCAFDoc_ColorSurf, aColor)) + { + theStyle.SetColorSurf (aColor); + } + if (theTool->GetColor (theLabel, XCAFDoc_ColorCurv, aColor)) + { + theStyle.SetColorCurv (aColor.GetRGB()); + } +} + static Standard_Boolean getShapesOfSHUO (TopLoc_IndexedMapOfLocation& theaPrevLocMap, const Handle(XCAFDoc_ShapeTool)& theSTool, const TDF_Label& theSHUOlab, @@ -128,6 +149,8 @@ void XCAFPrs::CollectStyleSettings (const TDF_Label& theLabel, // collect settings on subshapes Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool(theLabel); + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (theLabel); + TDF_LabelSequence aLabSeq; XCAFDoc_ShapeTool::GetSubShapes (theLabel, aLabSeq); // and add the shape itself @@ -136,12 +159,14 @@ void XCAFPrs::CollectStyleSettings (const TDF_Label& theLabel, { const TDF_Label& aLabel = aLabIter.Value(); XCAFPrs_Style aStyle; + aStyle.SetVisibility (aColorTool->IsVisible (aLabel)); + aStyle.SetMaterial (aMatTool->GetShapeMaterial (aLabel)); - Standard_Boolean isVisible = aColorTool->IsVisible (aLabel); - if (isVisible) + Handle(TColStd_HSequenceOfExtendedString) aLayerNames; + Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool (aLabel); + if (aStyle.IsVisible()) { - Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool (aLabel); - Handle(TColStd_HSequenceOfExtendedString) aLayerNames = new TColStd_HSequenceOfExtendedString(); + aLayerNames = new TColStd_HSequenceOfExtendedString(); aLayerTool->GetLayers (aLabel, aLayerNames); Standard_Integer aNbHidden = 0; for (TColStd_HSequenceOfExtendedString::Iterator aLayerIter (*aLayerNames); aLayerIter.More(); aLayerIter.Next()) @@ -152,54 +177,38 @@ void XCAFPrs::CollectStyleSettings (const TDF_Label& theLabel, ++aNbHidden; } } - isVisible = aNbHidden == 0 - || aNbHidden != aLayerNames->Length(); + aStyle.SetVisibility (aNbHidden == 0 + || aNbHidden != aLayerNames->Length()); } - if (!isVisible) - { - aStyle.SetVisibility (Standard_False); - } - else + if (aColorTool->IsColorByLayer (aLabel)) { - if (aColorTool->IsColorByLayer(aLabel)) + Quantity_ColorRGBA aLayerColor = theLayerColor; + if (aLayerNames.IsNull()) { - Quantity_ColorRGBA aLayerColor = theLayerColor; - Handle(XCAFDoc_LayerTool) aLayerTool = XCAFDoc_DocumentTool::LayerTool (aLabel); - Handle(TColStd_HSequenceOfExtendedString) aLayerNames = new TColStd_HSequenceOfExtendedString(); + aLayerNames = new TColStd_HSequenceOfExtendedString(); aLayerTool->GetLayers (aLabel, aLayerNames); - if (aLayerNames->Length() == 1) - { - TDF_Label aLayer = aLayerTool->FindLayer (aLayerNames->First()); - Quantity_ColorRGBA aColor; - if (aColorTool->GetColor (aLayer, XCAFDoc_ColorGen, aColor)) - aLayerColor = aColor; - } - - aStyle.SetColorCurv (aLayerColor.GetRGB()); - aStyle.SetColorSurf (aLayerColor); } - else + if (aLayerNames->Length() == 1) { + TDF_Label aLayer = aLayerTool->FindLayer (aLayerNames->First()); Quantity_ColorRGBA aColor; - if (aColorTool->GetColor (aLabel, XCAFDoc_ColorGen, aColor)) - { - aStyle.SetColorCurv (aColor.GetRGB()); - aStyle.SetColorSurf (aColor); - } - if (aColorTool->GetColor (aLabel, XCAFDoc_ColorSurf, aColor)) - { - aStyle.SetColorSurf (aColor); - } - if (aColorTool->GetColor (aLabel, XCAFDoc_ColorCurv, aColor)) + if (aColorTool->GetColor (aLayer, XCAFDoc_ColorGen, aColor)) { - aStyle.SetColorCurv (aColor.GetRGB()); + aLayerColor = aColor; } } + + aStyle.SetColorCurv (aLayerColor.GetRGB()); + aStyle.SetColorSurf (aLayerColor); + } + else + { + fillStyleColors (aStyle, aColorTool, aLabel); } // PTV try to set color from SHUO structure - Handle(XCAFDoc_ShapeTool) aShapeTool = aColorTool->ShapeTool(); + const Handle(XCAFDoc_ShapeTool)& aShapeTool = aColorTool->ShapeTool(); if (aShapeTool->IsComponent (aLabel)) { TDF_AttributeSequence aShuoAttribSeq; @@ -222,31 +231,11 @@ void XCAFPrs::CollectStyleSettings (const TDF_Label& theLabel, } } - Quantity_ColorRGBA aColor; XCAFPrs_Style aShuoStyle; - if (!aColorTool->IsVisible (aShuolab)) - { - aShuoStyle.SetVisibility (Standard_False); - } - else - { - if (aColorTool->GetColor (aShuolab, XCAFDoc_ColorGen, aColor)) - { - aShuoStyle.SetColorCurv (aColor.GetRGB()); - aShuoStyle.SetColorSurf (aColor); - } - if (aColorTool->GetColor (aShuolab, XCAFDoc_ColorSurf, aColor)) - { - aShuoStyle.SetColorSurf (aColor); - } - if (aColorTool->GetColor (aShuolab, XCAFDoc_ColorCurv, aColor)) - { - aShuoStyle.SetColorCurv (aColor.GetRGB()); - } - } - if (!aShuoStyle.IsSetColorCurv() - && !aShuoStyle.IsSetColorSurf() - && aShuoStyle.IsVisible()) + aShuoStyle.SetMaterial (aMatTool->GetShapeMaterial (aShuolab)); + aShuoStyle.SetVisibility(aColorTool->IsVisible (aShuolab)); + fillStyleColors (aShuoStyle, aColorTool, aShuolab); + if (aShuoStyle.IsEmpty()) { continue; } @@ -293,9 +282,7 @@ void XCAFPrs::CollectStyleSettings (const TDF_Label& theLabel, } } - if (!aStyle.IsSetColorCurv() - && !aStyle.IsSetColorSurf() - && aStyle.IsVisible()) + if (aStyle.IsEmpty()) { continue; } diff --git a/src/XCAFPrs/XCAFPrs_AISObject.cxx b/src/XCAFPrs/XCAFPrs_AISObject.cxx index 21ad5880d5..cfad0b0330 100644 --- a/src/XCAFPrs/XCAFPrs_AISObject.cxx +++ b/src/XCAFPrs/XCAFPrs_AISObject.cxx @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include - IMPLEMENT_STANDARD_RTTIEXT(XCAFPrs_AISObject,AIS_ColoredShape) //======================================================================= @@ -139,10 +139,7 @@ void XCAFPrs_AISObject::DispatchStyles (const Standard_Boolean theToSyncStyles) // Getting default colors XCAFPrs_Style aDefStyle; DefaultStyle (aDefStyle); - Quantity_Color aColorCurv = aDefStyle.GetColorCurv(); - Quantity_ColorRGBA aColorSurf = aDefStyle.GetColorSurfRGBA(); - - SetColors (myDrawer, aColorCurv, aColorSurf); + setStyleToDrawer (myDrawer, aDefStyle, aDefStyle, myDrawer->ShadingAspect()->Aspect()->FrontMaterial()); // collect sub-shapes with the same style into compounds BRep_Builder aBuilder; @@ -184,11 +181,17 @@ void XCAFPrs_AISObject::DispatchStyles (const Standard_Boolean theToSyncStyles) myShapeColors.Bind (aShapeCur, aDrawer); const XCAFPrs_Style& aStyle = aStyleGroupIter.Key(); aDrawer->SetHidden (!aStyle.IsVisible()); - - aColorCurv = aStyle.IsSetColorCurv() ? aStyle.GetColorCurv() : aDefStyle.GetColorCurv(); - aColorSurf = aStyle.IsSetColorSurf() ? aStyle.GetColorSurfRGBA() : aDefStyle.GetColorSurfRGBA(); - - SetColors (aDrawer, aColorCurv, aColorSurf); + if (!aStyle.Material().IsNull() + && !aStyle.Material()->IsEmpty()) + { + aDrawer->SetOwnMaterial(); + } + if (aStyle.IsSetColorSurf() + || aStyle.IsSetColorCurv()) + { + aDrawer->SetOwnColor (Quantity_Color()); + } + setStyleToDrawer (aDrawer, aStyle, aDefStyle, myDrawer->ShadingAspect()->Aspect()->FrontMaterial()); } aStyleGroups.Clear(); } @@ -243,83 +246,48 @@ void XCAFPrs_AISObject::Compute (const Handle(PrsMgr_PresentationManager3d)& the } //======================================================================= -//function : SetColors +//function : setStyleToDrawer //purpose : //======================================================================= -void XCAFPrs_AISObject::SetColors (const Handle(Prs3d_Drawer)& theDrawer, - const Quantity_Color& theColorCurv, - const Quantity_ColorRGBA& theColorSurf) +void XCAFPrs_AISObject::setStyleToDrawer (const Handle(Prs3d_Drawer)& theDrawer, + const XCAFPrs_Style& theStyle, + const XCAFPrs_Style& theDefStyle, + const Graphic3d_MaterialAspect& theDefMaterial) { - if (!theDrawer->HasOwnShadingAspect()) - { - theDrawer->SetShadingAspect (new Prs3d_ShadingAspect()); - if (theDrawer->HasLink()) - { - *theDrawer->ShadingAspect()->Aspect() = *theDrawer->Link()->ShadingAspect()->Aspect(); - } - } - if (!theDrawer->HasOwnLineAspect()) - { - theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0)); - if (theDrawer->HasLink()) - { - *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect(); - } - } - if (!theDrawer->HasOwnWireAspect()) - { - theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0)); - if (theDrawer->HasLink()) - { - *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect(); - } - } - if (!theDrawer->HasOwnUIsoAspect()) + theDrawer->SetupOwnShadingAspect(); + theDrawer->SetOwnLineAspects(); + + Quantity_ColorRGBA aSurfColor = theDefStyle.GetColorSurfRGBA(); + Quantity_Color aCurvColor = theDefStyle.GetColorCurv(); + Graphic3d_MaterialAspect aMaterial = theDefMaterial; + const Handle(XCAFDoc_VisMaterial)& anXMat = !theStyle.Material().IsNull() ? theStyle.Material() : theDefStyle.Material(); + if (!anXMat.IsNull() + && !anXMat->IsEmpty()) { - theDrawer->SetUIsoAspect (new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 0.5, 1)); - if (theDrawer->HasLink()) - { - *theDrawer->UIsoAspect()->Aspect() = *theDrawer->Link()->UIsoAspect()->Aspect(); - theDrawer->UIsoAspect()->SetNumber (theDrawer->Link()->UIsoAspect()->Number()); - } + anXMat->FillAspect (theDrawer->ShadingAspect()->Aspect()); + aMaterial = theDrawer->ShadingAspect()->Aspect()->FrontMaterial(); + aSurfColor = Quantity_ColorRGBA (aMaterial.Color(), aMaterial.Alpha()); + aCurvColor = aMaterial.Color(); } - if (!theDrawer->HasOwnVIsoAspect()) + if (theStyle.IsSetColorSurf()) { - theDrawer->SetVIsoAspect (new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 0.5, 1)); - if (theDrawer->HasLink()) - { - *theDrawer->VIsoAspect()->Aspect() = *theDrawer->Link()->VIsoAspect()->Aspect(); - theDrawer->VIsoAspect()->SetNumber (theDrawer->Link()->VIsoAspect()->Number()); - } - } - if (!theDrawer->HasOwnFreeBoundaryAspect()) - { - theDrawer->SetFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0)); - if (theDrawer->HasLink()) - { - *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect(); - } + aSurfColor = theStyle.GetColorSurfRGBA(); + aMaterial.SetColor (aSurfColor.GetRGB()); + aMaterial.SetAlpha (aSurfColor.Alpha()); } - if (!theDrawer->HasOwnUnFreeBoundaryAspect()) + if (theStyle.IsSetColorCurv()) { - theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0)); - if (theDrawer->HasLink()) - { - *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect(); - } + aCurvColor = theStyle.GetColorCurv(); } - theDrawer->UnFreeBoundaryAspect()->SetColor (theColorCurv); - theDrawer->FreeBoundaryAspect()->SetColor (theColorCurv); - theDrawer->WireAspect()->SetColor (theColorCurv); + theDrawer->UnFreeBoundaryAspect()->SetColor (aCurvColor); + theDrawer->FreeBoundaryAspect()->SetColor (aCurvColor); + theDrawer->WireAspect()->SetColor (aCurvColor); - Graphic3d_MaterialAspect aMaterial = myDrawer->ShadingAspect()->Aspect()->FrontMaterial(); - aMaterial.SetColor (theColorSurf.GetRGB()); - aMaterial.SetAlpha (theColorSurf.Alpha()); - theDrawer->ShadingAspect()->Aspect()->SetInteriorColor (theColorSurf); + theDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aSurfColor); theDrawer->ShadingAspect()->Aspect()->SetFrontMaterial (aMaterial); - theDrawer->UIsoAspect()->SetColor (theColorSurf.GetRGB()); - theDrawer->VIsoAspect()->SetColor (theColorSurf.GetRGB()); + theDrawer->UIsoAspect()->SetColor (aSurfColor.GetRGB()); + theDrawer->VIsoAspect()->SetColor (aSurfColor.GetRGB()); } //======================================================================= @@ -341,17 +309,25 @@ void XCAFPrs_AISObject::SetMaterial (const Graphic3d_MaterialAspect& theMaterial XCAFPrs_Style aDefStyle; DefaultStyle (aDefStyle); setMaterial (myDrawer, theMaterial, HasColor(), IsTransparent()); - SetColors (myDrawer, aDefStyle.GetColorCurv(), aDefStyle.GetColorSurf()); + setStyleToDrawer (myDrawer, aDefStyle, aDefStyle, myDrawer->ShadingAspect()->Aspect()->FrontMaterial()); for (AIS_DataMapOfShapeDrawer::Iterator anIter (myShapeColors); anIter.More(); anIter.Next()) { const Handle(AIS_ColoredDrawer)& aDrawer = anIter.Value(); + if (aDrawer->HasOwnMaterial()) + { + continue; + } - // take current color - const Quantity_Color aColorCurv = aDrawer->WireAspect()->Aspect()->Color(); - const Quantity_ColorRGBA aSurfColor = aDrawer->ShadingAspect()->Aspect()->InteriorColorRGBA(); - - // SetColors() will take the material from myDrawer - SetColors (aDrawer, aColorCurv, aSurfColor); + if (aDrawer->HasOwnShadingAspect()) + { + // take current color + const Quantity_ColorRGBA aSurfColor = aDrawer->ShadingAspect()->Aspect()->InteriorColorRGBA(); + Graphic3d_MaterialAspect aMaterial = myDrawer->ShadingAspect()->Aspect()->FrontMaterial(); + aMaterial.SetColor (aSurfColor.GetRGB()); + aMaterial.SetAlpha (aSurfColor.Alpha()); + aDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aSurfColor); + aDrawer->ShadingAspect()->Aspect()->SetFrontMaterial (aMaterial); + } } SynchronizeAspects(); } diff --git a/src/XCAFPrs/XCAFPrs_AISObject.hxx b/src/XCAFPrs/XCAFPrs_AISObject.hxx index 94139dc13a..34d604ff58 100644 --- a/src/XCAFPrs/XCAFPrs_AISObject.hxx +++ b/src/XCAFPrs/XCAFPrs_AISObject.hxx @@ -57,21 +57,19 @@ protected: const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode) Standard_OVERRIDE; - //! Set colors to drawer - Standard_EXPORT void SetColors (const Handle(Prs3d_Drawer)& theDrawer, - const Quantity_Color& theColorCurv, - const Quantity_ColorRGBA& theColorSurf); - - //! Set colors to drawer - void SetColors (const Handle(Prs3d_Drawer)& theDrawer, - const Quantity_Color& theColorCurv, - const Quantity_Color& theColorSurf) { SetColors (theDrawer, theColorCurv, Quantity_ColorRGBA (theColorSurf)); } - //! Fills out a default style object which is used when styles are //! not explicitly defined in the document. //! By default, the style uses white color for curves and surfaces. Standard_EXPORT virtual void DefaultStyle (XCAFPrs_Style& theStyle) const; +protected: + + //! Assign style to drawer. + static void setStyleToDrawer (const Handle(Prs3d_Drawer)& theDrawer, + const XCAFPrs_Style& theStyle, + const XCAFPrs_Style& theDefStyle, + const Graphic3d_MaterialAspect& theDefMaterial); + protected: TDF_Label myLabel; //!< label pointing onto the shape diff --git a/src/XCAFPrs/XCAFPrs_Style.hxx b/src/XCAFPrs/XCAFPrs_Style.hxx index d6e7afbc27..fedc277a22 100644 --- a/src/XCAFPrs/XCAFPrs_Style.hxx +++ b/src/XCAFPrs/XCAFPrs_Style.hxx @@ -20,6 +20,7 @@ #include #include #include +#include //! Represents a set of styling settings applicable to a (sub)shape class XCAFPrs_Style @@ -31,6 +32,21 @@ public: //! Empty constructor - colors are unset, visibility is TRUE. Standard_EXPORT XCAFPrs_Style(); + //! Return TRUE if style is empty - does not override any properties. + Standard_Boolean IsEmpty() const + { + return !myHasColorSurf + && !myHasColorCurv + && myMaterial.IsNull() + && myIsVisible; + } + + //! Return material. + const Handle(XCAFDoc_VisMaterial)& Material() const { return myMaterial; } + + //! Set material. + void SetMaterial (const Handle(XCAFDoc_VisMaterial)& theMaterial) { myMaterial = theMaterial; } + //! Return TRUE if surface color has been defined. Standard_Boolean IsSetColorSurf() const { return myHasColorSurf; } @@ -82,6 +98,7 @@ public: return myHasColorSurf == theOther.myHasColorSurf && myHasColorCurv == theOther.myHasColorCurv + && myMaterial == theOther.myMaterial && (!myHasColorSurf || myColorSurf == theOther.myColorSurf) && (!myHasColorCurv || myColorCurv == theOther.myColorCurv); } @@ -112,6 +129,10 @@ public: { aHashCode = aHashCode ^ Quantity_ColorHasher::HashCode (theStyle.myColorCurv, theUpperBound); } + if (!theStyle.myMaterial.IsNull()) + { + aHashCode = aHashCode ^ ::HashCode (theStyle.myMaterial, theUpperBound); + } return ::HashCode (aHashCode, theUpperBound); } @@ -126,6 +147,7 @@ public: protected: + Handle(XCAFDoc_VisMaterial) myMaterial; Quantity_ColorRGBA myColorSurf; Quantity_Color myColorCurv; Standard_Boolean myHasColorSurf; diff --git a/src/XCAFPrs/XCAFPrs_Texture.cxx b/src/XCAFPrs/XCAFPrs_Texture.cxx new file mode 100644 index 0000000000..1c8b3a0774 --- /dev/null +++ b/src/XCAFPrs/XCAFPrs_Texture.cxx @@ -0,0 +1,43 @@ +// 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 + +#include + +IMPLEMENT_STANDARD_RTTIEXT(XCAFPrs_Texture, Graphic3d_Texture2Dmanual) + +//======================================================================= +//function : XCAFPrs_Texture +//purpose : +//======================================================================= +XCAFPrs_Texture::XCAFPrs_Texture (const Image_Texture& theImageSource, + const Graphic3d_TextureUnit theUnit) +: Graphic3d_Texture2Dmanual (""), + myImageSource (theImageSource) +{ + if (!myImageSource.TextureId().IsEmpty()) + { + myTexId = myImageSource.TextureId(); + } + myParams->SetTextureUnit (theUnit); +} + +//======================================================================= +//function : GetImage +//purpose : +//======================================================================= +Handle(Image_PixMap) XCAFPrs_Texture::GetImage() const +{ + return myImageSource.ReadImage(); +} diff --git a/src/XCAFPrs/XCAFPrs_Texture.hxx b/src/XCAFPrs/XCAFPrs_Texture.hxx new file mode 100644 index 0000000000..ff8efa806d --- /dev/null +++ b/src/XCAFPrs/XCAFPrs_Texture.hxx @@ -0,0 +1,45 @@ +// Created on: 2000-08-11 +// Created by: Andrey BETENEV +// Copyright (c) 2000-2014 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. + +#ifndef _XCAFPrs_Texture_HeaderFile +#define _XCAFPrs_Texture_HeaderFile + +#include +#include +#include + +//! Texture holder. +class XCAFPrs_Texture : public Graphic3d_Texture2Dmanual +{ + DEFINE_STANDARD_RTTIEXT(XCAFPrs_Texture, Graphic3d_Texture2Dmanual) +public: + + //! Constructor. + Standard_EXPORT explicit XCAFPrs_Texture (const Image_Texture& theImageSource, + const Graphic3d_TextureUnit theUnit); + + //! Image reader. + Standard_EXPORT virtual Handle(Image_PixMap) GetImage() const Standard_OVERRIDE; + + //! Return image source. + const Image_Texture& GetImageSource() const { return myImageSource; } + +protected: + + Image_Texture myImageSource; + +}; + +#endif // _XCAFPrs_Texture_HeaderFile diff --git a/src/XDEDRAW/XDEDRAW_Colors.cxx b/src/XDEDRAW/XDEDRAW_Colors.cxx index 228f666fa1..59b88e168e 100644 --- a/src/XDEDRAW/XDEDRAW_Colors.cxx +++ b/src/XDEDRAW/XDEDRAW_Colors.cxx @@ -20,16 +20,20 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include #include #include #include +#include +#include #include //! Parse XCAFDoc_ColorType enumeration argument. @@ -60,6 +64,102 @@ static bool parseXDocColorType (const TCollection_AsciiString& theArg, return false; } +//! Print triplet of values. +template static S& operator<< (S& theStream, const NCollection_Vec3& theVec) +{ + theStream << theVec[0] << " " << theVec[1] << " " << theVec[2]; + return theStream; +} + +//! Print 4 values. +template static S& operator<< (S& theStream, const NCollection_Vec4& theVec) +{ + theStream << theVec[0] << " " << theVec[1] << " " << theVec[2] << " " << theVec[3]; + return theStream; +} + +//! Convert alpha mode into string. +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 "BlendAuto"; + } + return ""; +} + +//! Find existing visualization material in the document. +static TDF_Label findVisMaterial (const Handle(TDocStd_Document)& theDoc, + const TCollection_AsciiString& theKey) +{ + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (theDoc->Main()); + TDF_Label aMatLab; + TDF_Tool::Label (theDoc->GetData(), theKey, aMatLab); + if (!aMatLab.IsNull()) + { + return aMatTool->IsMaterial (aMatLab) ? aMatLab : TDF_Label(); + } + + TDF_LabelSequence aLabels; + aMatTool->GetMaterials (aLabels); + for (TDF_LabelSequence::Iterator aLabIter (aLabels); aLabIter.More(); aLabIter.Next()) + { + Handle(TDataStd_Name) aNodeName; + if (aLabIter.Value().FindAttribute (TDataStd_Name::GetID(), aNodeName) + && aNodeName->Get().IsEqual (theKey)) + { + return aLabIter.Value(); + } + } + return TDF_Label(); +} + +//! Check if image file exists. +static bool isImageFileExist (const TCollection_AsciiString& thePath) +{ + const OSD_Path aPath (thePath); + if (!OSD_File (aPath).Exists()) + { + std::cout << "Error: file '" << thePath << " not found\n"; + return false; + } + return true; +} + +//! Parse RGB values coming after specified argument. +static bool parseRgbColor (Standard_Integer& theArgIter, + Quantity_Color& theColor, + Standard_Integer theNbArgs, + const char** theArgVec) +{ + Standard_Integer aNbParsed = ViewerTest::ParseColor (theNbArgs - theArgIter - 1, + theArgVec + theArgIter + 1, + theColor); + if (aNbParsed == 0) + { + std::cout << "Syntax error at '" << theArgVec[theArgIter] << "'\n"; + return false; + } + theArgIter += aNbParsed; + return true; +} + +//! Parse normalized real value within 0..1 range. +static bool parseNormalizedReal (const char* theString, + Standard_ShortReal& theValue) +{ + theValue = (Standard_ShortReal )Draw::Atof (theString); + if (theValue < 0.0f || theValue > 1.0f) + { + std::cerr << "Syntax error at '" << theString << "'\n"; + return false; + } + return true; +} + //======================================================================= // Section: Work with colors //======================================================================= @@ -267,7 +367,6 @@ static Standard_Integer getAllColors (Draw_Interpretor& di, Standard_Integer arg return 0; } - static Standard_Integer addColor (Draw_Interpretor& di, Standard_Integer argc, const char** argv) { if (argc < 3) @@ -620,6 +719,510 @@ static Standard_Integer setStyledcolor (Draw_Interpretor& , Standard_Integer arg return 0; } +// ================================================================ +// Function : XGetAllVisMaterials +// Purpose : +// ================================================================ +static Standard_Integer XGetAllVisMaterials (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec) +{ + if (theNbArgs != 2 && theNbArgs != 3) + { + std::cout << "Syntax error: wrong number of arguments\n"; + return 1; + } + + Handle(TDocStd_Document) aDoc; + DDocStd::GetDocument (theArgVec[1], aDoc); + if (aDoc.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n"; + return 1; + } + + bool toPrintNames = true; + if (theNbArgs == 3) + { + TCollection_AsciiString anArgCase (theArgVec[2]); + anArgCase.LowerCase(); + if (anArgCase == "-names") + { + toPrintNames = true; + } + else if (anArgCase == "-labels") + { + toPrintNames = false; + } + } + + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main()); + TDF_LabelSequence aLabels; + aMatTool->GetMaterials (aLabels); + Standard_Integer aMatIndex = 1; + for (TDF_LabelSequence::Iterator aLabIter (aLabels); aLabIter.More(); aLabIter.Next(), ++aMatIndex) + { + const TDF_Label& aMatLab = aLabIter.Value(); + if (!toPrintNames) + { + TCollection_AsciiString anEntryId; + TDF_Tool::Entry (aMatLab, anEntryId); + theDI << anEntryId << " "; + continue; + } + + Handle(TDataStd_Name) aNodeName; + if (aMatLab.FindAttribute (TDataStd_Name::GetID(), aNodeName)) + { + theDI << aNodeName->Get() << " "; + } + else + { + TCollection_AsciiString aName = TCollection_AsciiString(""; + theDI << aName << " "; + } + } + return 0; +} + +// ================================================================ +// Function : XGetVisMaterial +// Purpose : +// ================================================================ +static Standard_Integer XGetVisMaterial (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec) +{ + if (theNbArgs != 3) + { + std::cout << "Syntax error: wrong number of arguments\n"; + return 1; + } + + Handle(TDocStd_Document) aDoc; + DDocStd::GetDocument (theArgVec[1], aDoc); + if (aDoc.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n"; + return 1; + } + + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main()); + Handle(XCAFDoc_VisMaterial) aMat; + TDF_Label aMatLab = findVisMaterial (aDoc, theArgVec[2]); + if (!aMatLab.IsNull()) + { + aMat = aMatTool->GetMaterial (aMatLab); + } + else + { + TDF_Label aShapeLab; + TDF_Tool::Label (aDoc->GetData(), theArgVec[2], aShapeLab); + if (aShapeLab.IsNull()) + { + TopoDS_Shape aShape = DBRep::Get (theArgVec[2]); + if (!aShape.IsNull()) + { + aShapeLab = aMatTool->ShapeTool()->FindShape (aShape); + } + } + if (!aShapeLab.IsNull() + && !aMatTool->ShapeTool()->IsShape (aShapeLab)) + { + aShapeLab.Nullify(); + } + if (aShapeLab.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[2] << " is not material nor shape\n"; + return 1; + } + + aMat = aMatTool->GetShapeMaterial (aShapeLab); + } + + if (aMat.IsNull()) + { + theDI << "EMPTY\n"; + return 0; + } + + TCollection_AsciiString anEntryId; + TDF_Tool::Entry (aMat->Label(), anEntryId); + theDI << "Label: " << anEntryId << "\n"; + + Handle(TDataStd_Name) aNodeName; + if (aMat->Label().FindAttribute (TDataStd_Name::GetID(), aNodeName)) + { + theDI << "Name: " << aNodeName->Get() << "\n"; + } + if (aMat->IsEmpty()) + { + theDI << "EMPTY\n"; + return 0; + } + theDI << "AlphaMode: " << alphaModeToString (aMat->AlphaMode()) << "\n"; + theDI << "AlphaCutOff: " << aMat->AlphaCutOff() << "\n"; + theDI << "IsDoubleSided: " << aMat->IsDoubleSided() << "\n"; + if (aMat->HasCommonMaterial()) + { + const XCAFDoc_VisMaterialCommon& aMatCom = aMat->CommonMaterial(); + theDI << "Common.Ambient: " << (Graphic3d_Vec3 )aMatCom.AmbientColor << "\n"; + theDI << "Common.Diffuse: " << (Graphic3d_Vec3 )aMatCom.DiffuseColor << "\n"; + if (!aMatCom.DiffuseTexture.IsNull()) + { + theDI << "Common.DiffuseTexture: " << aMatCom.DiffuseTexture->TextureId() << "\n"; + } + theDI << "Common.Specular: " << (Graphic3d_Vec3 )aMatCom.SpecularColor << "\n"; + theDI << "Common.Emissive: " << (Graphic3d_Vec3 )aMatCom.EmissiveColor << "\n"; + theDI << "Common.Shininess: " << aMatCom.Shininess << "\n"; + theDI << "Common.Transparency: " << aMatCom.Transparency << "\n"; + } + if (aMat->HasPbrMaterial()) + { + const XCAFDoc_VisMaterialPBR& aMatPbr = aMat->PbrMaterial(); + theDI << "PBR.BaseColor: " << (Graphic3d_Vec3 )aMatPbr.BaseColor.GetRGB() << "\n"; + theDI << "PBR.Transparency: " << (1.0 - aMatPbr.BaseColor.Alpha()) << "\n"; + if (!aMatPbr.BaseColorTexture.IsNull()) + { + theDI << "PBR.BaseColorTexture: " << aMatPbr.BaseColorTexture->TextureId() << "\n"; + } + theDI << "PBR.EmissiveFactor: " << aMatPbr.EmissiveFactor << "\n"; + if (!aMatPbr.EmissiveTexture.IsNull()) + { + theDI << "PBR.EmissiveTexture: " << aMatPbr.EmissiveTexture->TextureId() << "\n"; + } + theDI << "PBR.Metallic: " << aMatPbr.Metallic << "\n"; + theDI << "PBR.Roughness: " << aMatPbr.Roughness << "\n"; + if (!aMatPbr.MetallicRoughnessTexture.IsNull()) + { + theDI << "PBR.MetallicRoughnessTexture: " << aMatPbr.MetallicRoughnessTexture->TextureId() << "\n"; + } + if (!aMatPbr.OcclusionTexture.IsNull()) + { + theDI << "PBR.OcclusionTexture: " << aMatPbr.OcclusionTexture->TextureId() << "\n"; + } + if (!aMatPbr.NormalTexture.IsNull()) + { + theDI << "PBR.NormalTexture: " << aMatPbr.NormalTexture->TextureId() << "\n"; + } + } + return 0; +} + +// ================================================================ +// Function : XAddVisMaterial +// Purpose : +// ================================================================ +static Standard_Integer XAddVisMaterial (Draw_Interpretor& , Standard_Integer theNbArgs, const char** theArgVec) +{ + if (theNbArgs < 3) + { + std::cout << "Syntax error: wrong number of arguments\n"; + return 1; + } + + Handle(TDocStd_Document) aDoc; + DDocStd::GetDocument (theArgVec[1], aDoc); + if (aDoc.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n"; + return 1; + } + + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main()); + TDF_Label aMatLab = findVisMaterial (aDoc, theArgVec[2]); + if (aMatLab.IsNull()) + { + aMatLab = aMatTool->AddMaterial (theArgVec[2]); + } + + Handle(XCAFDoc_VisMaterial) aMat = aMatTool->GetMaterial (aMatLab); + XCAFDoc_VisMaterialCommon aMatCom = aMat->CommonMaterial(); + XCAFDoc_VisMaterialPBR aMatPbr = aMat->PbrMaterial(); + Standard_ShortReal aRealValue = 0.0f; + for (Standard_Integer anArgIter = 3; anArgIter < theNbArgs; ++anArgIter) + { + TCollection_AsciiString anArg (theArgVec[anArgIter]); + anArg.LowerCase(); + if ((anArg == "-transparency" + || anArg == "-alpha") + && anArgIter + 1 < theNbArgs + && parseNormalizedReal (theArgVec[anArgIter + 1], aMatCom.Transparency)) + { + ++anArgIter; + if (anArg == "-alpha") + { + aMatCom.Transparency = 1.0f - aMatCom.Transparency; + } + aMatPbr.BaseColor.SetAlpha (1.0f - aMatCom.Transparency); + } + else if (anArg == "-alphaMode" + && anArgIter + 2 < theNbArgs + && parseNormalizedReal (theArgVec[anArgIter + 2], aRealValue)) + { + TCollection_AsciiString aModeStr (theArgVec[anArgIter + 1]); + aModeStr.LowerCase(); + Graphic3d_AlphaMode anAlphaMode = Graphic3d_AlphaMode_Opaque; + if (aModeStr == "opaque") + { + anAlphaMode = Graphic3d_AlphaMode_Opaque; + } + else if (aModeStr == "mask") + { + anAlphaMode = Graphic3d_AlphaMode_Mask; + } + else if (aModeStr == "blend") + { + anAlphaMode = Graphic3d_AlphaMode_Blend; + } + else if (aModeStr == "blendauto") + { + anAlphaMode = Graphic3d_AlphaMode_BlendAuto; + } + else + { + std::cerr << "Syntax error at '" << anArg << "'\n"; + return 1; + } + aMat->SetAlphaMode (anAlphaMode, aRealValue); + anArgIter += 2; + } + else if (anArg == "-diffuse" + || anArg == "-basecolor" + || anArg == "-albedo") + { + Quantity_ColorRGBA aColorRGBA; + Standard_Integer aNbParsed = ViewerTest::ParseColor (theNbArgs - anArgIter - 1, + theArgVec + anArgIter + 1, + aColorRGBA); + if (aNbParsed == 0) + { + std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n"; + return 1; + } + anArgIter += aNbParsed; + + if (anArg == "-diffuse") + { + aMatCom.IsDefined = true; + aMatCom.DiffuseColor = aColorRGBA.GetRGB(); + if (aNbParsed == 2 || aNbParsed == 4) + { + aMatCom.Transparency = 1.0f - aColorRGBA.Alpha(); + } + } + else + { + aMatPbr.IsDefined = true; + if (aNbParsed == 2 || aNbParsed == 4) + { + aMatPbr.BaseColor = aColorRGBA; + } + else + { + aMatPbr.BaseColor.SetRGB (aColorRGBA.GetRGB()); + } + } + } + else if (anArg == "-specular" + && parseRgbColor (anArgIter, aMatCom.SpecularColor, + theNbArgs, theArgVec)) + { + aMatCom.IsDefined = true; + } + else if (anArg == "-ambient" + && parseRgbColor (anArgIter, aMatCom.AmbientColor, + theNbArgs, theArgVec)) + { + aMatCom.IsDefined = true; + } + else if (anArg == "-emissive" + && parseRgbColor (anArgIter, aMatCom.EmissiveColor, + theNbArgs, theArgVec)) + { + aMatCom.IsDefined = true; + } + else if (anArg == "-shininess" + && anArgIter + 1 < theNbArgs) + { + aMatCom.IsDefined = true; + aMatCom.Shininess = (float )Draw::Atof (theArgVec[++anArgIter]); + if (aMatCom.Shininess < 0.0f || aMatCom.Shininess > 1.0f) + { + std::cout << "Syntax error at '" << anArg << "'\n"; + return 1; + } + } + else if (anArgIter + 1 < theNbArgs + && anArg == "-diffusetexture" + && isImageFileExist (theArgVec[anArgIter + 1])) + { + aMatCom.IsDefined = true; + aMatCom.DiffuseTexture = new Image_Texture (theArgVec[++anArgIter]); + } + else if (anArgIter + 1 < theNbArgs + && anArg == "-basecolortexture" + && isImageFileExist (theArgVec[anArgIter + 1])) + { + aMatPbr.IsDefined = true; + aMatPbr.BaseColorTexture = new Image_Texture (theArgVec[++anArgIter]); + } + else if (anArgIter + 1 < theNbArgs + && anArg == "-emissivetexture" + && isImageFileExist (theArgVec[anArgIter + 1])) + { + aMatPbr.IsDefined = true; + aMatPbr.EmissiveTexture = new Image_Texture (theArgVec[++anArgIter]); + } + else if (anArgIter + 1 < theNbArgs + && anArg == "-metallicroughnesstexture" + && isImageFileExist (theArgVec[anArgIter + 1])) + { + aMatPbr.IsDefined = true; + aMatPbr.MetallicRoughnessTexture = new Image_Texture (theArgVec[++anArgIter]); + } + else if (anArgIter + 1 < theNbArgs + && anArg == "-normaltexture" + && isImageFileExist (theArgVec[anArgIter + 1])) + { + aMatPbr.IsDefined = true; + aMatPbr.NormalTexture = new Image_Texture (theArgVec[++anArgIter]); + } + else if (anArgIter + 1 < theNbArgs + && anArg == "-occlusiontexture" + && isImageFileExist (theArgVec[anArgIter + 1])) + { + aMatPbr.IsDefined = true; + aMatPbr.OcclusionTexture = new Image_Texture (theArgVec[++anArgIter]); + } + else if (anArg == "-emissivefactor" + && anArgIter + 4 < theNbArgs) + { + aMatPbr.IsDefined = true; + aMatPbr.EmissiveFactor.SetValues ((float )Draw::Atof (theArgVec[anArgIter + 1]), + (float )Draw::Atof (theArgVec[anArgIter + 2]), + (float )Draw::Atof (theArgVec[anArgIter + 3])); + anArgIter += 3; + } + else if (anArg == "-doublesided") + { + aMatPbr.IsDefined = true; + bool isDoubleSided = true; + if (anArgIter + 1 < theNbArgs + && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], isDoubleSided)) + { + ++anArgIter; + } + aMat->SetDoubleSided (isDoubleSided); + } + else if (anArgIter + 1 < theNbArgs + && anArg == "-metallic" + && parseNormalizedReal (theArgVec[anArgIter + 1], aMatPbr.Metallic)) + { + ++anArgIter; + aMatPbr.IsDefined = true; + } + else if (anArgIter + 1 < theNbArgs + && anArg == "-roughness" + && parseNormalizedReal (theArgVec[anArgIter + 1], aMatPbr.Roughness)) + { + ++anArgIter; + aMatPbr.IsDefined = true; + } + else + { + std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n"; + return 1; + } + } + + aMat->SetCommonMaterial (aMatCom); + aMat->SetPbrMaterial (aMatPbr); + return 0; +} + +// ================================================================ +// Function : XRemoveVisMaterial +// Purpose : +// ================================================================ +static Standard_Integer XRemoveVisMaterial (Draw_Interpretor& , Standard_Integer theNbArgs, const char** theArgVec) +{ + if (theNbArgs != 3) + { + std::cout << "Syntax error: wrong number of arguments\n"; + return 1; + } + + Handle(TDocStd_Document) aDoc; + DDocStd::GetDocument (theArgVec[1], aDoc); + if (aDoc.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n"; + return 1; + } + + TDF_Label aMatLab = findVisMaterial (aDoc, theArgVec[2]); + if (aMatLab.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[2] << " is not a material\n"; + return 1; + } + + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main()); + aMatTool->RemoveMaterial (aMatLab); + return 0; +} + +// ================================================================ +// Function : XSetVisMaterial +// Purpose : +// ================================================================ +static Standard_Integer XSetVisMaterial (Draw_Interpretor& , Standard_Integer theNbArgs, const char** theArgVec) +{ + if (theNbArgs != 3 && theNbArgs != 4) + { + std::cout << "Syntax error: wrong number of arguments\n"; + return 1; + } + + Handle(TDocStd_Document) aDoc; + TDF_Label aShapeLab; + DDocStd::GetDocument (theArgVec[1], aDoc); + if (aDoc.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[1] << " is not a document\n"; + return 1; + } + + TDF_Tool::Label (aDoc->GetData(), theArgVec[2], aShapeLab); + Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (aDoc->Main()); + if (aShapeLab.IsNull()) + { + // get label by shape + TopoDS_Shape aShape = DBRep::Get (theArgVec[2]); + if (!aShape.IsNull()) + { + aShapeLab = aColorTool->ShapeTool()->FindShape (aShape, Standard_True); + } + } + if (aShapeLab.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[2] << " is not a label not shape\n"; + return 1; + } + + TDF_Label aMatLab; + if (theNbArgs == 4) + { + aMatLab = findVisMaterial (aDoc, theArgVec[3]); + if (aMatLab.IsNull()) + { + std::cout << "Syntax error: " << theArgVec[3] << " is not a material\n"; + return 1; + } + } + + Handle(XCAFDoc_VisMaterialTool) aMatTool = XCAFDoc_DocumentTool::VisMaterialTool (aDoc->Main()); + aMatTool->SetShapeMaterial (aShapeLab, aMatLab); + return 0; +} + //======================================================================= //function : InitCommands //purpose : @@ -689,4 +1292,32 @@ void XDEDRAW_Colors::InitCommands(Draw_Interpretor& di) di.Add ("XSetInstanceColor","Doc Shape R G B [alpha] [{generic|surface|curve}=gen]" "\t: sets color for component of shape if SHUO structure exists already", __FILE__, setStyledcolor, g); + + di.Add ("XGetAllVisMaterials","Doc [{-names|-labels}=-names]" + "\t: Print all visualization materials defined in document", + __FILE__, XGetAllVisMaterials, g); + di.Add ("XGetVisMaterial","Doc {Material|Shape}" + "\t: Print visualization material properties", + __FILE__, XGetVisMaterial, g); + di.Add ("XAddVisMaterial", + "Doc Material" + "\n\t\t: [-transparency 0..1] [-alphaMode {Opaque|Mask|Blend|BlendAuto} CutOffValue]" + "\n\t\t: [-diffuse RGB] [-diffuseTexture ImagePath]" + "\n\t\t: [-specular RGB] [-ambient RGB] [-emissive RGB] [-shininess 0..1]" + "\n\t\t: [-baseColor RGB] [-baseColorTexture ImagePath]" + "\n\t\t: [-emissiveFactor RGB] [-emissiveTexture ImagePath]" + "\n\t\t: [-metallic 0..1] [-roughness 0..1] [-metallicRoughnessTexture ImagePath]" + "\n\t\t: [-occlusionTexture ImagePath] [-normalTexture ImagePath]" + "\n\t\t: [-doubleSided {0|1}]" + "\n\t\t: Add material into Document's material table.", + __FILE__, XAddVisMaterial, g); + di.Add ("XRemoveVisMaterial","Doc Material" + "\t: Remove material in document from material table", + __FILE__, XRemoveVisMaterial, g); + di.Add ("XSetVisMaterial", "Doc Shape Material" + "\t: Set material to shape", + __FILE__, XSetVisMaterial, g); + di.Add ("XUnsetVisMaterial", "Doc Shape" + "\t: Unset material from shape", + __FILE__, XSetVisMaterial, g); } diff --git a/src/XmlMXCAFDoc/FILES b/src/XmlMXCAFDoc/FILES index 965d5fbf55..2d1444cfa3 100644 --- a/src/XmlMXCAFDoc/FILES +++ b/src/XmlMXCAFDoc/FILES @@ -45,5 +45,9 @@ XmlMXCAFDoc_ShapeToolDriver.cxx XmlMXCAFDoc_ShapeToolDriver.hxx XmlMXCAFDoc_ViewToolDriver.cxx XmlMXCAFDoc_ViewToolDriver.hxx +XmlMXCAFDoc_VisMaterialDriver.cxx +XmlMXCAFDoc_VisMaterialDriver.hxx +XmlMXCAFDoc_VisMaterialToolDriver.cxx +XmlMXCAFDoc_VisMaterialToolDriver.hxx XmlMXCAFDoc_VolumeDriver.cxx XmlMXCAFDoc_VolumeDriver.hxx diff --git a/src/XmlMXCAFDoc/XmlMXCAFDoc.cxx b/src/XmlMXCAFDoc/XmlMXCAFDoc.cxx index 0ffa311b08..0d5b29725e 100644 --- a/src/XmlMXCAFDoc/XmlMXCAFDoc.cxx +++ b/src/XmlMXCAFDoc/XmlMXCAFDoc.cxx @@ -33,11 +33,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -72,6 +74,7 @@ void XmlMXCAFDoc::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable, aDriverTable -> AddDriver (new XmlMXCAFDoc_DatumDriver (anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_DimTolDriver (anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_MaterialDriver (anMsgDrv)); + aDriverTable -> AddDriver (new XmlMXCAFDoc_VisMaterialDriver(anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_NoteBalloonDriver(anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_NoteCommentDriver(anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_NoteBinDataDriver(anMsgDrv)); @@ -82,6 +85,7 @@ void XmlMXCAFDoc::AddDrivers (const Handle(XmlMDF_ADriverTable)& aDriverTable, aDriverTable -> AddDriver (new XmlMXCAFDoc_ShapeToolDriver (anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_DimTolToolDriver (anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_MaterialToolDriver (anMsgDrv)); + aDriverTable -> AddDriver (new XmlMXCAFDoc_VisMaterialToolDriver (anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_NotesToolDriver (anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_ViewToolDriver (anMsgDrv)); aDriverTable -> AddDriver (new XmlMXCAFDoc_ClippingPlaneToolDriver(anMsgDrv)); diff --git a/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.cxx b/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.cxx new file mode 100644 index 0000000000..687d1c5b2e --- /dev/null +++ b/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.cxx @@ -0,0 +1,319 @@ +// 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 + +#include +#include +#include +#include + +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); + } +} diff --git a/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.hxx b/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.hxx new file mode 100644 index 0000000000..f2bb61acaa --- /dev/null +++ b/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.hxx @@ -0,0 +1,51 @@ +// 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. + +#ifndef _XmlMXCAFDoc_VisMaterialDriver_HeaderFile +#define _XmlMXCAFDoc_VisMaterialDriver_HeaderFile + +#include +#include + +#include +#include +#include +#include + +DEFINE_STANDARD_HANDLE(XmlMXCAFDoc_VisMaterialDriver, XmlMDF_ADriver) + +//! Attribute Driver. +class XmlMXCAFDoc_VisMaterialDriver : public XmlMDF_ADriver +{ + DEFINE_STANDARD_RTTIEXT(XmlMXCAFDoc_VisMaterialDriver, XmlMDF_ADriver) +public: + + //! Main constructor. + Standard_EXPORT XmlMXCAFDoc_VisMaterialDriver (const Handle(Message_Messenger)& theMessageDriver); + + //! Create new instance of XCAFDoc_VisMaterial. + Standard_EXPORT Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE; + + //! Paste attribute from persistence into document. + Standard_EXPORT Standard_Boolean Paste (const XmlObjMgt_Persistent& theSource, + const Handle(TDF_Attribute)& theTarget, + XmlObjMgt_RRelocationTable& theRelocTable) const Standard_OVERRIDE; + + //! Paste attribute from document into persistence. + Standard_EXPORT void Paste (const Handle(TDF_Attribute)& theSource, + XmlObjMgt_Persistent& theTarget, + XmlObjMgt_SRelocationTable& theRelocTable) const Standard_OVERRIDE; + +}; + +#endif // _XmlMXCAFDoc_VisMaterialDriver_HeaderFile diff --git a/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialToolDriver.cxx b/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialToolDriver.cxx new file mode 100644 index 0000000000..d14e40314b --- /dev/null +++ b/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialToolDriver.cxx @@ -0,0 +1,61 @@ +// 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 + +#include +#include +#include + +IMPLEMENT_STANDARD_RTTIEXT(XmlMXCAFDoc_VisMaterialToolDriver, XmlMDF_ADriver) + +//======================================================================= +//function : XmlMXCAFDoc_VisMaterialToolDriver +//purpose : +//======================================================================= +XmlMXCAFDoc_VisMaterialToolDriver::XmlMXCAFDoc_VisMaterialToolDriver (const Handle(Message_Messenger)& theMsgDriver) +: XmlMDF_ADriver (theMsgDriver, "xcaf", "VisMaterialTool") +{ + // +} + +//======================================================================= +//function : NewEmpty +//purpose : +//======================================================================= +Handle(TDF_Attribute) XmlMXCAFDoc_VisMaterialToolDriver::NewEmpty() const +{ + return new XCAFDoc_VisMaterialTool(); +} + +//======================================================================= +//function : Paste +//purpose : +//======================================================================= +Standard_Boolean XmlMXCAFDoc_VisMaterialToolDriver::Paste (const XmlObjMgt_Persistent& , + const Handle(TDF_Attribute)& , + XmlObjMgt_RRelocationTable& ) const +{ + return Standard_True; +} + +//======================================================================= +//function : Paste +//purpose : +//======================================================================= +void XmlMXCAFDoc_VisMaterialToolDriver::Paste (const Handle(TDF_Attribute)& , + XmlObjMgt_Persistent& , + XmlObjMgt_SRelocationTable& ) const +{ + // +} diff --git a/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialToolDriver.hxx b/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialToolDriver.hxx new file mode 100644 index 0000000000..c4b11bb582 --- /dev/null +++ b/src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialToolDriver.hxx @@ -0,0 +1,45 @@ +// 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. + +#ifndef _XmlMXCAFDoc_VisMaterialToolDriver_HeaderFile +#define _XmlMXCAFDoc_VisMaterialToolDriver_HeaderFile + +#include + +DEFINE_STANDARD_HANDLE(XmlMXCAFDoc_VisMaterialToolDriver, XmlMDF_ADriver) + +//! XML persistence driver for XCAFDoc_VisMaterialTool. +class XmlMXCAFDoc_VisMaterialToolDriver : public XmlMDF_ADriver +{ + DEFINE_STANDARD_RTTIEXT(XmlMXCAFDoc_VisMaterialToolDriver, XmlMDF_ADriver) +public: + + //! Main constructor. + Standard_EXPORT XmlMXCAFDoc_VisMaterialToolDriver (const Handle(Message_Messenger)& theMsgDriver); + + //! Create new instance of XCAFDoc_VisMaterialTool. + Standard_EXPORT virtual Handle(TDF_Attribute) NewEmpty() const Standard_OVERRIDE; + + //! Paste attribute from persistence into document. + Standard_EXPORT virtual Standard_Boolean Paste (const XmlObjMgt_Persistent& theSource, + const Handle(TDF_Attribute)& theTarget, + XmlObjMgt_RRelocationTable& theRelocTable) const Standard_OVERRIDE; + + //! Paste attribute from document into persistence. + Standard_EXPORT virtual void Paste (const Handle(TDF_Attribute)& theSource, + XmlObjMgt_Persistent& theTarget, + XmlObjMgt_SRelocationTable& theRelocTable) const Standard_OVERRIDE; + +}; + +#endif // _XmlMXCAFDoc_VisMaterialToolDriver_HeaderFile