]> OCCT Git - occt.git/commitdiff
0033183: Data Exchange - Lose texture after saving XBF file
authorichesnok <ichesnok@opencascade.com>
Thu, 31 Aug 2023 14:56:33 +0000 (15:56 +0100)
committervglukhik <vglukhik@opencascade.com>
Fri, 8 Sep 2023 10:28:27 +0000 (11:28 +0100)
Texture reading and writing changed in VisMaterial drivers

src/BinMXCAFDoc/BinMXCAFDoc_VisMaterialDriver.cxx
src/XmlMXCAFDoc/XmlMXCAFDoc_VisMaterialDriver.cxx
tests/bugs/xde/bug33183_1 [new file with mode: 0644]
tests/bugs/xde/bug33183_2 [new file with mode: 0644]
tests/bugs/xde/bug33183_3 [new file with mode: 0644]

index b6f80319786dc78c892e433f800254abb9b0d441..f7f183ebab21a7d09f70741c280694f8c3598514 100644 (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);
 }
 
 //=======================================================================
index 257620e455714e9b5b89fda11d1849d0b2c9febb..4a8bd4c623d87648c9fb09ea122c0ae3f7eb7ac4 100644 (file)
 
 #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() << "Warning: XmlMXCAFDoc_VisMaterialDriver : 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(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())
   {
-    theImage = new Image_Texture (aPath);
+    Message::SendWarning() << "Warning: XmlMXCAFDoc_VisMaterialDriver : Can't write a texture to buffer.";
   }
 }
 
diff --git a/tests/bugs/xde/bug33183_1 b/tests/bugs/xde/bug33183_1
new file mode 100644 (file)
index 0000000..580fba0
--- /dev/null
@@ -0,0 +1,37 @@
+puts "========"
+puts "0033183: Data Exchange - Lose texture after saving XBF file"
+puts "Checking saving of textures for the previous version"
+puts "========"
+
+pload OCAF
+
+Close D -silent
+XOpen [locate_data_file bug33183.xbf] D
+
+set ref {
+Label:                  0:1:10:3
+Name:                   boat1
+AlphaMode:              BlendAuto
+AlphaCutOff:            0.5
+IsDoubleSided:          Auto
+Common.Ambient:         0.21404114365577698 0.21404114365577698 0.21404114365577698
+Common.Diffuse:         0.21404114365577698 0.21404114365577698 0.21404114365577698
+Common.DiffuseTexture:  texture://C:/Work/Projects/OpenCASCADE/testfiles/ship_boat.jpg
+Common.Specular:        0 0 0
+Common.Emissive:        0 0 0
+Common.Shininess:       0.0099999997764825821
+Common.Transparency:    0
+}
+
+set data [XGetVisMaterial D 0:1:10:3]
+
+for {set i 1} {$i <= 12} {incr i} {
+  set data_str [lindex $data $i-1]
+  set ref_str  [lindex $ref  $i-1]
+  if { $data_str != $ref_str } {
+     puts "Error: Data is not equal"
+     break
+  }
+}
+
+Close D
diff --git a/tests/bugs/xde/bug33183_2 b/tests/bugs/xde/bug33183_2
new file mode 100644 (file)
index 0000000..cce5530
--- /dev/null
@@ -0,0 +1,37 @@
+puts "========"
+puts "0033183: Data Exchange - Lose texture after saving XBF file"
+puts "Checking saving of textures for the previous version"
+puts "========"
+
+pload OCAF
+
+Close D -silent
+XOpen [locate_data_file bug33183.xml] D
+
+set ref {
+Label:                  0:1:10:3
+Name:                   boat1
+AlphaMode:              BlendAuto
+AlphaCutOff:            0.5
+IsDoubleSided:          Auto
+Common.Ambient:         0.21404099464416504 0.21404099464416504 0.21404099464416504
+Common.Diffuse:         0.21404099464416504 0.21404099464416504 0.21404099464416504
+Common.DiffuseTexture:  texture://C:/Work/Projects/OpenCASCADE/testfiles/ship_boat.jpg
+Common.Specular:        0 0 0
+Common.Emissive:        0 0 0
+Common.Shininess:       0.0099999997764825821
+Common.Transparency:    0
+}
+
+set data [XGetVisMaterial D 0:1:10:3]
+
+for {set i 1} {$i <= 12} {incr i} {
+  set data_str [lindex $data $i-1]
+  set ref_str  [lindex $ref  $i-1]
+  if { $data_str != $ref_str } {
+     puts "Error: Data is not equal"
+     break
+  }
+}
+
+Close D
diff --git a/tests/bugs/xde/bug33183_3 b/tests/bugs/xde/bug33183_3
new file mode 100644 (file)
index 0000000..3e806d5
--- /dev/null
@@ -0,0 +1,42 @@
+puts "========"
+puts "0033183: Data Exchange - Lose texture after saving XBF file"
+puts "Checking saving of textures for the previous version"
+puts "========"
+
+pload OCAF
+
+Close D -silent
+ReadGltf D [locate_data_file bug31706_launchvehicle.glb]
+
+set ref_1 [XGetVisMaterial D 0:1:10:1]
+set ref_2 [XGetVisMaterial D 0:1:10:7]
+
+set aTmpFile ${imagedir}/result.xbf
+XSave D $aTmpFile
+Close D
+XOpen $aTmpFile D
+
+set cur_1 [XGetVisMaterial D 0:1:10:1]
+set cur_2 [XGetVisMaterial D 0:1:10:7]
+
+for {set i 1} {$i <= 12} {incr i} {
+  set ref_1_str [lindex $ref_1 $i-1]
+  set ref_2_str  [lindex $ref_2  $i-1]
+  set cur_1_str [lindex $cur_1 $i-1]
+  set cur_2_str  [lindex $cur_2  $i-1]
+  if { $ref_1_str != $cur_1_str ||
+    $ref_2_str != $cur_2_str} {
+    puts "Error: Data is not equal"
+    break
+  }
+}
+
+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