From 48b9b87388eb6d041cf99adcdf4d0f13c83da359 Mon Sep 17 00:00:00 2001 From: ichesnok Date: Fri, 1 Sep 2023 08:42:26 +0100 Subject: [PATCH] 0033451: Saving texture to buffer New field was added in XCAFDoc_VisMaterialTool class for store texture in buffer or use file reading. User can change this parameter with XSetUseTextureBuffer command. --- src/Image/Image_Texture.cxx | 35 ++++++++++++ src/Image/Image_Texture.hxx | 4 ++ src/XCAFDoc/XCAFDoc_VisMaterialTool.cxx | 24 ++++++++- src/XCAFDoc/XCAFDoc_VisMaterialTool.hxx | 12 +++++ src/XDEDRAW/XDEDRAW.cxx | 72 +++++++++++++++++++++++++ tests/bugs/xde/bug33451_1 | 37 +++++++++++++ tests/bugs/xde/bug33451_2 | 38 +++++++++++++ tests/bugs/xde/bug33451_3 | 29 ++++++++++ tests/bugs/xde/bug33451_4 | 30 +++++++++++ 9 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 tests/bugs/xde/bug33451_1 create mode 100644 tests/bugs/xde/bug33451_2 create mode 100644 tests/bugs/xde/bug33451_3 create mode 100644 tests/bugs/xde/bug33451_4 diff --git a/src/Image/Image_Texture.cxx b/src/Image/Image_Texture.cxx index 34948c016a..a77df9b7a7 100644 --- a/src/Image/Image_Texture.cxx +++ b/src/Image/Image_Texture.cxx @@ -420,3 +420,38 @@ void Image_Texture::DumpJson (Standard_OStream& theOStream, Standard_Integer the OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOffset) OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myLength) } + +// ================================================================ +// Function : WriteToBuffer +// Purpose : +// ================================================================ +void Image_Texture::WriteToBuffer() +{ + if (this == nullptr || myImagePath.IsEmpty()) + { + return; + } + + const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem(); + std::shared_ptr aFileIn = aFileSystem->OpenIStream(myImagePath, std::ios::in | std::ios::binary); + if (aFileIn.get() == nullptr) + { + Message::SendFail(TCollection_AsciiString("Error: Unable to open file ") + myImagePath + "!"); + return; + } + + int64_t aLength = myLength; + if (myOffset == -1 && myLength == -1) + { + aFileIn->seekg(0, std::ios::end); + aLength = aFileIn->tellg(); + aFileIn->seekg(0, std::ios::beg); + } + else + { + aFileIn->seekg(myOffset); + } + myBuffer = new NCollection_Buffer(NCollection_BaseAllocator::CommonBaseAllocator(), aLength); + aFileIn->read((char*)myBuffer->ChangeData(), aLength); + myImagePath.Clear(); +} diff --git a/src/Image/Image_Texture.hxx b/src/Image/Image_Texture.hxx index 57575a5283..6e3ca865af 100644 --- a/src/Image/Image_Texture.hxx +++ b/src/Image/Image_Texture.hxx @@ -103,6 +103,10 @@ public: //! @name hasher interface //! Dumps the content of me into the stream Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const; + //! Write texture to buffer, if file path, offset and length are known + //! This function is use only when user has turn on parameter by XSetUseTextureBuffer function + Standard_EXPORT void WriteToBuffer(); + protected: //! Read image from normal image file. diff --git a/src/XCAFDoc/XCAFDoc_VisMaterialTool.cxx b/src/XCAFDoc/XCAFDoc_VisMaterialTool.cxx index af6e9b9113..2e40bcba1c 100644 --- a/src/XCAFDoc/XCAFDoc_VisMaterialTool.cxx +++ b/src/XCAFDoc/XCAFDoc_VisMaterialTool.cxx @@ -59,7 +59,7 @@ Handle(XCAFDoc_VisMaterialTool) XCAFDoc_VisMaterialTool::Set (const TDF_Label& t //======================================================================= XCAFDoc_VisMaterialTool::XCAFDoc_VisMaterialTool() { - // + myUseTextureBuffer = false; } //======================================================================= @@ -95,6 +95,8 @@ TDF_Label XCAFDoc_VisMaterialTool::AddMaterial (const Handle(XCAFDoc_VisMaterial { TDF_TagSource aTag; TDF_Label aLab = aTag.NewChild (Label()); + if (myUseTextureBuffer) + changeVisMaterial(theMat); aLab.AddAttribute (theMat); if (!theName.IsEmpty()) { @@ -283,3 +285,23 @@ Handle(XCAFDoc_VisMaterial) XCAFDoc_VisMaterialTool::GetShapeMaterial (const Top ? GetMaterial (aMatLabel) : Handle(XCAFDoc_VisMaterial)(); } + +//======================================================================= +//function : changeVisMaterial +//purpose : +//======================================================================= +void XCAFDoc_VisMaterialTool::changeVisMaterial(const Handle(XCAFDoc_VisMaterial)& theMat) const +{ + if (theMat->HasCommonMaterial()) + { + theMat->CommonMaterial().DiffuseTexture->WriteToBuffer(); + } + if (theMat->HasPbrMaterial()) + { + theMat->PbrMaterial().BaseColorTexture->WriteToBuffer(); + theMat->PbrMaterial().MetallicRoughnessTexture->WriteToBuffer(); + theMat->PbrMaterial().EmissiveTexture->WriteToBuffer(); + theMat->PbrMaterial().OcclusionTexture->WriteToBuffer(); + theMat->PbrMaterial().NormalTexture->WriteToBuffer(); + } +} diff --git a/src/XCAFDoc/XCAFDoc_VisMaterialTool.hxx b/src/XCAFDoc/XCAFDoc_VisMaterialTool.hxx index 6f76a94c04..f968ba82a9 100644 --- a/src/XCAFDoc/XCAFDoc_VisMaterialTool.hxx +++ b/src/XCAFDoc/XCAFDoc_VisMaterialTool.hxx @@ -113,6 +113,12 @@ public: //! Returns material assigned to shape or NULL if not assigned. Standard_EXPORT Handle(XCAFDoc_VisMaterial) GetShapeMaterial (const TopoDS_Shape& theShape); + //! Return parameter for use texture buffer + const Standard_Boolean GetUseTextureBuffer() { return myUseTextureBuffer; } + + //! Set parameter for use texture buffer + void SetUseTextureBuffer(const Standard_Boolean theUseBuffer) { myUseTextureBuffer = theUseBuffer; } + public: //! Returns GUID of this attribute type. @@ -128,8 +134,14 @@ public: virtual void Paste (const Handle(TDF_Attribute)& , const Handle(TDF_RelocationTable)& ) const Standard_OVERRIDE {} +protected: + + //! Reading a texture from file and save it to buffer + void changeVisMaterial(const Handle(XCAFDoc_VisMaterial)& theMat) const; + private: + Standard_Boolean myUseTextureBuffer; Handle(XCAFDoc_ShapeTool) myShapeTool; }; diff --git a/src/XDEDRAW/XDEDRAW.cxx b/src/XDEDRAW/XDEDRAW.cxx index 71561d359e..686aa1979e 100644 --- a/src/XDEDRAW/XDEDRAW.cxx +++ b/src/XDEDRAW/XDEDRAW.cxx @@ -98,6 +98,7 @@ #include #include #include +#include #include #include #include @@ -1721,6 +1722,69 @@ static Standard_Integer testDoc (Draw_Interpretor&, return 0; } +//======================================================================= +// function: XGetUseTextureBuffer +// purpose: return current value of parameter +//======================================================================= +static Standard_Integer XGetUseTextureBuffer(Draw_Interpretor& di, + Standard_Integer argc, + const char** argv) +{ + if (argc < 2) + { + return 1; + } + Handle(TDocStd_Document) aDoc; + if (!DDocStd::GetDocument(argv[1], aDoc)) + { + return 1; + } + + Handle(XCAFDoc_VisMaterialTool) aVisMatTool = XCAFDoc_DocumentTool::VisMaterialTool(aDoc->Main()); + if (aVisMatTool.IsNull()) + { + return 1; + } + const char* aStr = aVisMatTool->GetUseTextureBuffer() ? "on" : "off"; + di << "Current value is \"" << aStr << "\"" << "\n"; + + return 0; +} + +//======================================================================= +// function: XSetUseTextureBuffer +// purpose: change parameter for store texture (on/off), +// file path is use by default in case "off" +//======================================================================= +static Standard_Integer XSetUseTextureBuffer(Draw_Interpretor& di, + Standard_Integer argc, + const char** argv) +{ + if (argc < 3) + { + return 1; + } + Handle(TDocStd_Document) aDoc; + if (!DDocStd::GetDocument(argv[1], aDoc)) + { + return 1; + } + bool aBuffOn = false; + if (!Draw::ParseOnOff(argv[2], aBuffOn)) + { + return 1; + } + + Handle(XCAFDoc_VisMaterialTool) aVisMatTool = XCAFDoc_DocumentTool::VisMaterialTool(aDoc->Main()); + if (aVisMatTool.IsNull()) + { + return 1; + } + aVisMatTool->SetUseTextureBuffer(aBuffOn); + + (void)di; + return 0; +} //======================================================================= //function : Init @@ -1838,6 +1902,14 @@ void XDEDRAW::Init(Draw_Interpretor& di) di.Add("XRescaleGeometry", "Doc factor [-root label] [-force]: Applies geometrical scale to assembly", __FILE__, XRescaleGeometry, g); + di.Add("XGetUseTextureBuffer", + "Doc : return value of parameter for texture buffer usage", + __FILE__, XGetUseTextureBuffer, g); + di.Add("XSetUseTextureBuffer", + "Doc {on|off} : turns on/off texture buffer usage; \"off\" is use by default,\n" + "it means texture will store length, offset and will be read from file;\n" + "in case \"on\" texture data will be store in buffer", + __FILE__, XSetUseTextureBuffer, g); // Specialized commands XDEDRAW_Shapes::InitCommands ( di ); diff --git a/tests/bugs/xde/bug33451_1 b/tests/bugs/xde/bug33451_1 new file mode 100644 index 0000000000..784216c937 --- /dev/null +++ b/tests/bugs/xde/bug33451_1 @@ -0,0 +1,37 @@ +puts "========" +puts "0033451: Saving texture to buffer" +puts "Checks store texture in .xbf file" +puts "========" + +Close D -silent +XNewDoc D +XSetUseTextureBuffer D on +ReadGltf D [locate_data_file bug31706_launchvehicle.glb] -noCreateDoc + +set aTmpFile ${imagedir}/result.xbf +XSave D $aTmpFile +Close D +Open $aTmpFile D +set data1 [XGetVisMaterial D 0:1:10:1] +set data2 [XGetVisMaterial D 0:1:10:5] + +if {[string first "PBR.BaseColorTexture" $data1] == -1 + || [string first "PBR.EmissiveTexture" $data1] == -1} { + puts "Error: Texture is not found" +} +if {[string first "PBR.BaseColorTexture" $data2] == -1 + || [string first "PBR.MetallicRoughnessTexture" $data2] == -1 + || [string first "PBR.OcclusionTexture" $data2] == -1 + || [string first "PBR.NormalTexture" $data2] == -1} { + puts "Error: Texture is not found" +} + +vinit View1 +XDisplay -dispMode 1 D +vfit +if { [vreadpixel 50 300 rgb name] != "WHITE" || [vreadpixel 120 250 rgb name] != "LEMONCHIFFON1" } { + puts "Error: color not match" +} + +Close D +file delete -force $aTmpFile diff --git a/tests/bugs/xde/bug33451_2 b/tests/bugs/xde/bug33451_2 new file mode 100644 index 0000000000..37d31275cc --- /dev/null +++ b/tests/bugs/xde/bug33451_2 @@ -0,0 +1,38 @@ +puts "========" +puts "0033451: Saving texture to buffer" +puts "Checks store texture in .xml file" +puts "========" + +Close D -silent +XNewDoc D +#XSetUseTextureBuffer D on +ReadGltf D [locate_data_file bug31706_launchvehicle.glb] -noCreateDoc + +set aTmpFile ${imagedir}/res.xml +Format D XmlXCAF +XSave D $aTmpFile +Close D +XOpen $aTmpFile D +set data1 [XGetVisMaterial D 0:1:10:1] +set data2 [XGetVisMaterial D 0:1:10:5] + +if {[string first "PBR.BaseColorTexture" $data1] == -1 + || [string first "PBR.EmissiveTexture" $data1] == -1} { + puts "Error: Texture is not found" +} +if {[string first "PBR.BaseColorTexture" $data2] == -1 + || [string first "PBR.MetallicRoughnessTexture" $data2] == -1 + || [string first "PBR.OcclusionTexture" $data2] == -1 + || [string first "PBR.NormalTexture" $data2] == -1} { + puts "Error: Texture is not found" +} + +vinit View1 +XDisplay -dispMode 1 D +vfit +if { [vreadpixel 50 300 rgb name] != "WHITE" || [vreadpixel 120 250 rgb name] != "LEMONCHIFFON1" } { + puts "Error: color not match" +} + +Close D +file delete -force $aTmpFile diff --git a/tests/bugs/xde/bug33451_3 b/tests/bugs/xde/bug33451_3 new file mode 100644 index 0000000000..858b126749 --- /dev/null +++ b/tests/bugs/xde/bug33451_3 @@ -0,0 +1,29 @@ +puts "========" +puts "0033451: Saving texture to buffer" +puts "Checks store texture in .xbf file" +puts "========" + +Close D -silent +XNewDoc D +XSetUseTextureBuffer D on +ReadObj D [locate_data_file ship_boat.obj] -noCreateDoc + +set aTmpFile ${imagedir}/result.xbf +XSave D $aTmpFile +Close D +Open $aTmpFile D +set data [XGetVisMaterial D 0:1:10:3] + +if {[string first "Common.DiffuseTexture" $data] == -1} { + puts "Error: Texture is not found" +} + +vinit View1 +XDisplay -dispMode 1 D +vfit +if { [vreadpixel 130 300 rgb name] != "ROSYBROWN" } { puts "Error: color not match" } +if { [vreadpixel 150 250 rgb name] != "ORANGE2" } { puts "Error: color not match" } +if { [vreadpixel 250 250 rgb name] != "GRAY43" } { puts "Error: color not match" } + +Close D +file delete -force $aTmpFile diff --git a/tests/bugs/xde/bug33451_4 b/tests/bugs/xde/bug33451_4 new file mode 100644 index 0000000000..894a4f9814 --- /dev/null +++ b/tests/bugs/xde/bug33451_4 @@ -0,0 +1,30 @@ +puts "========" +puts "0033451: Saving texture to buffer" +puts "Checks store texture in .xbf file" +puts "========" + +Close D -silent +XNewDoc D +#XSetUseTextureBuffer D on +ReadObj D [locate_data_file ship_boat.obj] -noCreateDoc + +set aTmpFile ${imagedir}/result.xml +Format D XmlXCAF +XSave D $aTmpFile +Close D +XOpen $aTmpFile D +set data [XGetVisMaterial D 0:1:10:3] + +if {[string first "Common.DiffuseTexture" $data] == -1} { + puts "Error: Texture is not found" +} + +vinit View1 +XDisplay -dispMode 1 D +vfit +if { [vreadpixel 130 300 rgb name] != "ROSYBROWN" } { puts "Error: color not match" } +if { [vreadpixel 150 250 rgb name] != "ORANGE2" } { puts "Error: color not match" } +if { [vreadpixel 250 250 rgb name] != "GRAY43" } { puts "Error: color not match" } + +Close D +file delete -force $aTmpFile -- 2.39.5