1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

2 Commits

Author SHA1 Message Date
ichesnok
48b9b87388 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.
2023-09-01 12:27:21 +01:00
ichesnok
351f09c8bb 0033183: Data Exchange - Lose texture after saving XBF file
Texture reading and writing changed in VisMaterial drivers
2023-08-31 15:56:33 +01:00
14 changed files with 429 additions and 18 deletions

View File

@@ -126,23 +126,68 @@ static void readColor (const BinObjMgt_Persistent& theSource,
static void writeTexture (BinObjMgt_Persistent& theTarget,
const Handle(Image_Texture)& theImage)
{
theTarget.PutAsciiString (!theImage.IsNull()
&& !theImage->FilePath().IsEmpty()
&& theImage->FileOffset() == -1
? theImage->FilePath()
: "");
if (theImage.IsNull())
{
theTarget.PutAsciiString("");
return;
}
if (theImage->DataBuffer().IsNull())
{
theTarget.PutAsciiString(theImage->FilePath());
theTarget.PutBoolean(false);
if (theImage->FileOffset() == -1 || theImage->FileLength() == -1)
{
theTarget.PutBoolean(true);
return;
}
theTarget.PutBoolean(false);
theTarget.PutInteger(static_cast<int>(theImage->FileOffset()));
theTarget.PutInteger(static_cast<int>(theImage->FileLength()));
return;
}
theTarget.PutAsciiString(theImage->TextureId());
theTarget.PutBoolean(true);
theTarget.PutInteger(static_cast<int>(theImage->DataBuffer()->Size()));
theTarget.PutByteArray((Standard_Byte*)theImage->DataBuffer()->Data(),
static_cast<int>(theImage->DataBuffer()->Size()));
}
//! Decode texture path.
static void readTexture (const BinObjMgt_Persistent& theSource,
Handle(Image_Texture)& theTexture)
{
TCollection_AsciiString aPath;
theSource.GetAsciiString (aPath);
if (!aPath.IsEmpty())
TCollection_AsciiString aStr;
theSource.GetAsciiString(aStr);
if (aStr.IsEmpty())
{
theTexture = new Image_Texture (aPath);
return;
}
Standard_Boolean anUseBuffer;
if (!theSource.GetBoolean(anUseBuffer).IsOK())
{
theTexture = new Image_Texture(aStr);
return;
}
Standard_Integer anOffset = -1, aLength = -1;
if (!anUseBuffer)
{
Standard_Boolean isOnlyFilePath;
theSource.GetBoolean(isOnlyFilePath);
if (isOnlyFilePath)
{
theTexture = new Image_Texture(aStr);
return;
}
theSource.GetInteger(anOffset);
theSource.GetInteger(aLength);
theTexture = new Image_Texture(aStr, anOffset, aLength);
return;
}
theSource.GetInteger(aLength);
Handle(NCollection_Buffer) aBuff =
new NCollection_Buffer(NCollection_BaseAllocator::CommonBaseAllocator(), aLength);
theSource.GetByteArray(aBuff->ChangeData(), aLength);
theTexture = new Image_Texture(aBuff, aStr);
}
//=======================================================================

View File

@@ -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<std::istream> 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();
}

View File

@@ -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.

View File

@@ -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();
}
}

View File

@@ -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;
};

View File

@@ -98,6 +98,7 @@
#include <XCAFDoc_LayerTool.hxx>
#include <XCAFDoc_Material.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include <XCAFDoc_VisMaterialTool.hxx>
#include <XCAFDoc_Volume.hxx>
#include <XCAFPrs.hxx>
#include <XCAFPrs_AISObject.hxx>
@@ -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 );

View File

@@ -13,9 +13,11 @@
#include <XmlMXCAFDoc_VisMaterialDriver.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <XCAFDoc_VisMaterial.hxx>
#include <XmlObjMgt.hxx>
#include <XmlObjMgt_Document.hxx>
#include <XmlObjMgt_Persistent.hxx>
IMPLEMENT_STANDARD_RTTIEXT(XmlMXCAFDoc_VisMaterialDriver, XmlMDF_ADriver)
@@ -42,6 +44,10 @@ IMPLEMENT_DOMSTRING(EmissiveColor, "emissive_color")
IMPLEMENT_DOMSTRING(Shininess, "shininess")
IMPLEMENT_DOMSTRING(Transparency, "transparency")
IMPLEMENT_DOMSTRING(DiffuseTexture, "diffuse_texture")
IMPLEMENT_DOMSTRING(FilePath, "file_path")
IMPLEMENT_DOMSTRING(TextureId, "texture_id")
IMPLEMENT_DOMSTRING(Offset, "offset")
IMPLEMENT_DOMSTRING(Length, "length")
//! Encode alpha mode into character.
static const char* alphaModeToString (Graphic3d_AlphaMode theMode)
@@ -202,11 +208,26 @@ static void writeTexture (XmlObjMgt_Persistent& theTarget,
const XmlObjMgt_DOMString& theName,
const Handle(Image_Texture)& theImage)
{
if (!theImage.IsNull()
&& !theImage->FilePath().IsEmpty()
&& theImage->FileOffset() == -1)
if (theImage.IsNull())
{
theTarget.Element().setAttribute (theName, theImage->FilePath().ToCString());
return;
}
XmlObjMgt_Document aDoc(theTarget.Element().getOwnerDocument());
XmlObjMgt_Element aCurTarget = aDoc.createElement(theName);
theTarget.Element().appendChild(aCurTarget);
if (theImage->DataBuffer().IsNull())
{
aCurTarget.setAttribute(::FilePath(), theImage->FilePath().ToCString());
if (theImage->FileOffset() == -1 || theImage->FileLength() == -1)
{
return;
}
aCurTarget.setAttribute(::Offset(), static_cast<int>(theImage->FileOffset()));
aCurTarget.setAttribute(::Length(), static_cast<int>(theImage->FileLength()));
}
else
{
Message::SendWarning(TCollection_AsciiString("Can't write a texture to buffer."));
}
}
@@ -215,10 +236,34 @@ 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())
TCollection_AsciiString aStr(theElement.getAttribute(theName).GetString());
if (!aStr.IsEmpty())
{
theImage = new Image_Texture (aPath);
theImage = new Image_Texture(aStr);
return;
}
LDOM_Element anElement = theElement.GetChildByTagName(theName);
if (anElement.isNull())
{
return;
}
TCollection_AsciiString aFilePath(anElement.getAttribute(::FilePath()).GetString());
TCollection_AsciiString anId(anElement.getAttribute(::TextureId()).GetString());
Standard_Integer anOffset = -1, aLength = -1;
if (!aFilePath.IsEmpty())
{
anElement.getAttribute(::Offset()).GetInteger(anOffset);
anElement.getAttribute(::Length()).GetInteger(aLength);
if (anOffset == -1 || aLength == -1)
{
theImage = new Image_Texture(aFilePath);
return;
}
theImage = new Image_Texture(aFilePath, anOffset, aLength);
}
else if (!anId.IsEmpty())
{
Message::SendWarning(TCollection_AsciiString("Can't read a texture from buffer."));
}
}

View File

@@ -1,3 +1,3 @@
pload XDE
pload XDE OCAF VISUALISATION
set subgroup xde

21
tests/bugs/xde/bug33183_1 Normal file
View File

@@ -0,0 +1,21 @@
puts "========"
puts "0033183: Data Exchange - Lose texture after saving XBF file"
puts "Checking saving of textures for the previous version"
puts "========"
Close D -silent
XOpen [locate_data_file bug33183_ship_boat.xbf] 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

21
tests/bugs/xde/bug33183_2 Normal file
View File

@@ -0,0 +1,21 @@
puts "========"
puts "0033183: Data Exchange - Lose texture after saving XBF file"
puts "Checking saving of textures for the previous version"
puts "========"
Close D -silent
XOpen [locate_data_file bug33183_ship_boat.xml] 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

37
tests/bugs/xde/bug33451_1 Normal file
View File

@@ -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

38
tests/bugs/xde/bug33451_2 Normal file
View File

@@ -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

29
tests/bugs/xde/bug33451_3 Normal file
View File

@@ -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

30
tests/bugs/xde/bug33451_4 Normal file
View File

@@ -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