// Function : performMesh
// Purpose :
//================================================================
-Standard_Boolean RWGltf_CafReader::performMesh (const TCollection_AsciiString& theFile,
+Standard_Boolean RWGltf_CafReader::performMesh (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe)
{
- Message_ProgressScope aPSentry (theProgress, "Reading glTF", 2);
+ Message_ProgressScope aPSentry(theProgress, "Reading glTF", 2);
aPSentry.Show();
- const Handle(OSD_FileSystem)& aFileSystem = OSD_FileSystem::DefaultFileSystem();
- std::shared_ptr<std::istream> aFile = aFileSystem->OpenIStream (theFile, std::ios::in | std::ios::binary);
- if (aFile.get() == NULL || !aFile->good())
+ if (!theStream.good())
{
Message::SendFail (TCollection_AsciiString ("File '") + theFile + "' is not found");
return false;
bool isBinaryFile = false;
char aGlbHeader[12] = {};
- aFile->read (aGlbHeader, sizeof (aGlbHeader));
+ theStream.read (aGlbHeader, sizeof (aGlbHeader));
int64_t aBinBodyOffset = 0;
int64_t aBinBodyLen = 0;
int64_t aJsonBodyOffset = 0;
}
char aHeader1[8] = {};
- aFile->read (aHeader1, sizeof (aHeader1));
+ theStream.read (aHeader1, sizeof (aHeader1));
const uint32_t* aSceneLen = (const uint32_t* )(aHeader1 + 0);
const uint32_t* aSceneFormat = (const uint32_t* )(aHeader1 + 4);
Message::SendWarning (TCollection_AsciiString ("File '") + theFile + "' is written using unknown version " + int(*aVer));
}
- for (int aChunkIter = 0; !aFile->eof() && aChunkIter < 2; ++aChunkIter)
+ for (int aChunkIter = 0; !theStream.eof() && aChunkIter < 2; ++aChunkIter)
{
char aChunkHeader2[8] = {};
- if (int64_t (aFile->tellg()) + int64_t (sizeof (aChunkHeader2)) > int64_t (*aLen))
+ if (int64_t (theStream.tellg()) + int64_t (sizeof (aChunkHeader2)) > int64_t (*aLen))
{
break;
}
- aFile->read (aChunkHeader2, sizeof (aChunkHeader2));
- if (!aFile->good())
+ theStream.read (aChunkHeader2, sizeof (aChunkHeader2));
+ if (!theStream.good())
{
Message::SendFail (TCollection_AsciiString ("File '") + theFile + "' is written using unsupported format");
return false;
const uint32_t* aChunkType = (const uint32_t* )(aChunkHeader2 + 4);
if (*aChunkType == 0x4E4F534A)
{
- aJsonBodyOffset = int64_t (aFile->tellg());
+ aJsonBodyOffset = int64_t (theStream.tellg());
aJsonBodyLen = int64_t (*aChunkLen);
}
else if (*aChunkType == 0x004E4942)
{
- aBinBodyOffset = int64_t (aFile->tellg());
+ aBinBodyOffset = int64_t (theStream.tellg());
aBinBodyLen = int64_t (*aChunkLen);
}
if (*aChunkLen != 0)
{
- aFile->seekg (*aChunkLen, std::ios_base::cur);
+ theStream.seekg (*aChunkLen, std::ios_base::cur);
}
}
- aFile->seekg ((std::streamoff )aJsonBodyOffset, std::ios_base::beg);
+ theStream.seekg ((std::streamoff )aJsonBodyOffset, std::ios_base::beg);
}
}
else
{
- aFile->seekg (0, std::ios_base::beg);
+ theStream.seekg (0, std::ios_base::beg);
}
TCollection_AsciiString anErrPrefix = TCollection_AsciiString ("File '") + theFile + "' defines invalid glTF!\n";
#ifdef HAVE_RAPIDJSON
rapidjson::ParseResult aRes;
- rapidjson::IStreamWrapper aFileStream (*aFile);
+ rapidjson::IStreamWrapper aFileStream (theStream);
if (isBinaryFile)
{
- aRes = aDoc.ParseStream<rapidjson::kParseStopWhenDoneFlag, rapidjson::UTF8<>, rapidjson::IStreamWrapper> (aFileStream);
+ aRes = aDoc.ParseStream<rapidjson::kParseStopWhenDoneFlag, rapidjson::UTF8<>, rapidjson::IStreamWrapper>(aFileStream);
}
else
{
protected:
//! Read the mesh from specified file.
- Standard_EXPORT virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile,
+ Standard_EXPORT virtual Standard_Boolean performMesh (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe) Standard_OVERRIDE;
Standard_Boolean RWMesh_CafReader::perform (const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe)
+{
+ std::ifstream aStream;
+ OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
+ return perform(aStream, theFile, theProgress, theToProbe);
+}
+
+// =======================================================================
+// function : perform
+// purpose :
+// =======================================================================
+Standard_Boolean RWMesh_CafReader::perform (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
+ const Message_ProgressRange& theProgress,
+ const Standard_Boolean theToProbe)
{
Standard_Integer aNewRootsLower = 1;
if (!myXdeDoc.IsNull())
OSD_Timer aLoadingTimer;
aLoadingTimer.Start();
- const Standard_Boolean isDone = performMesh (theFile, theProgress, theToProbe);
+ const Standard_Boolean isDone = performMesh (theStream, theFile, theProgress, theToProbe);
if (theToProbe || theProgress.UserBreak())
{
return isDone;
#define _RWMesh_CafReader_HeaderFile
#include <Message_ProgressRange.hxx>
+#include <OSD_OpenFile.hxx>
#include <RWMesh_CoordinateSystemConverter.hxx>
#include <RWMesh_NodeAttributes.hxx>
#include <TColStd_IndexedDataMapOfStringString.hxx>
public:
- //! Read the data from specified file.
+ //! Open stream and pass it to Perform method.
//! The Document instance should be set beforehand.
bool Perform (const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress)
{
- return perform (theFile, theProgress, Standard_False);
+ std::ifstream aStream;
+ OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
+ return Perform(aStream, theProgress, theFile);
+ }
+
+ //! Read the data from specified file.
+ bool Perform (std::istream& theStream,
+ const Message_ProgressRange& theProgress,
+ const TCollection_AsciiString& theFile = "")
+ {
+ return perform(theStream, theFile, theProgress, Standard_False);
}
//! Return extended status flags.
//! Return metadata map.
const TColStd_IndexedDataMapOfStringString& Metadata() const { return myMetadata; }
+ //! Open stream and pass it to ProbeHeader method.
+ Standard_Boolean ProbeHeader (const TCollection_AsciiString& theFile,
+ const Message_ProgressRange& theProgress = Message_ProgressRange())
+ {
+ std::ifstream aStream;
+ OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
+ return ProbeHeader (aStream, theFile, theProgress);
+ }
+
//! Read the header data from specified file without reading entire model.
//! The main purpose is collecting metadata and external references - for copying model into a new location, for example.
//! Can be NOT implemented (unsupported by format / reader).
- Standard_Boolean ProbeHeader (const TCollection_AsciiString& theFile,
+ Standard_Boolean ProbeHeader (std::istream& theStream,
+ const TCollection_AsciiString& theFile = "",
const Message_ProgressRange& theProgress = Message_ProgressRange())
{
- return perform (theFile, theProgress, Standard_True);
+ return perform(theStream, theFile, theProgress, Standard_True);
}
protected:
- //! Read the data from specified file.
- //! Default implementation calls performMesh() and fills XDE document from collected shapes.
+ //! Open stream and pass it to Perform method.
//! @param theFile file to read
//! @param optional progress indicator
//! @param theToProbe flag indicating that mesh data should be skipped and only basing information to be read
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe);
- //! Read the mesh from specified file - interface to be implemented by sub-classes.
+ //! Read the data from specified file.
+ //! Default implementation calls performMesh() and fills XDE document from collected shapes.
+ //! @param theStream input stream
+ //! @param theFile path of additional files
+ //! @param optional progress indicator
+ //! @param theToProbe flag indicating that mesh data should be skipped and only basing information to be read
+ Standard_EXPORT virtual Standard_Boolean perform (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
+ const Message_ProgressRange& theProgress,
+ const Standard_Boolean theToProbe);
+
+ //! Read the mesh from specified file
Standard_EXPORT virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile,
+ const Message_ProgressRange& theProgress,
+ const Standard_Boolean theToProbe)
+ {
+ std::ifstream aStream;
+ OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
+ return performMesh(aStream, theFile, theProgress, theToProbe);
+ }
+
+ //! Read the mesh from specified file - interface to be implemented by sub-classes.
+ Standard_EXPORT virtual Standard_Boolean performMesh (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe) = 0;
// Function : performMesh
// Purpose :
//================================================================
-Standard_Boolean RWObj_CafReader::performMesh (const TCollection_AsciiString& theFile,
+Standard_Boolean RWObj_CafReader::performMesh (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe)
{
Standard_Boolean isDone = Standard_False;
if (theToProbe)
{
- isDone = aCtx->Probe (theFile.ToCString(), theProgress);
+ isDone = aCtx->Probe (theStream, theFile, theProgress);
}
else
{
- isDone = aCtx->Read (theFile.ToCString(), theProgress);
+ isDone = aCtx->Read (theStream, theFile, theProgress);
}
if (!aCtx->FileComments().IsEmpty())
{
protected:
//! Read the mesh from specified file.
- Standard_EXPORT virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile,
+ Standard_EXPORT virtual Standard_Boolean performMesh (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe) Standard_OVERRIDE;
// The length of buffer to read (in bytes)
static const size_t THE_BUFFER_SIZE = 4 * 1024;
- //! Simple wrapper.
- struct RWObj_ReaderFile
- {
- FILE* File;
- int64_t FileLen;
-
- //! Constructor opening the file.
- RWObj_ReaderFile (const TCollection_AsciiString& theFile)
- : File (OSD_OpenFile (theFile.ToCString(), "rb")),
- FileLen (0)
- {
- if (this->File != NULL)
- {
- // determine length of file
- ::fseek64 (this->File, 0, SEEK_END);
- FileLen = ::ftell64 (this->File);
- ::fseek64 (this->File, 0, SEEK_SET);
- }
- }
-
- //! Destructor closing the file.
- ~RWObj_ReaderFile()
- {
- if (File != NULL)
- {
- ::fclose (File);
- }
- }
- };
//! Return TRUE if given polygon has clockwise node order.
static bool isClockwisePolygon (const Handle(BRepMesh_DataStructureOfDelaun)& theMesh,
// Function : read
// Purpose :
// ================================================================
-Standard_Boolean RWObj_Reader::read (const TCollection_AsciiString& theFile,
+Standard_Boolean RWObj_Reader::read (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe)
{
myCurrElem.resize (1024, -1);
Standard_CLocaleSentry aLocaleSentry;
- RWObj_ReaderFile aFile (theFile);
- if (aFile.File == NULL)
+ if (!theStream.good())
{
Message::SendFail (TCollection_AsciiString ("Error: file '") + theFile + "' is not found");
return Standard_False;
}
// determine length of file
- const int64_t aFileLen = aFile.FileLen;
+ theStream.seekg(0, theStream.end);
+ const int64_t aFileLen = theStream.tellg();
+ theStream.seekg(0, theStream.beg);
if (aFileLen <= 0L)
{
Message::SendFail (TCollection_AsciiString ("Error: file '") + theFile + "' is empty");
Standard_ReadLineBuffer aBuffer (THE_BUFFER_SIZE);
aBuffer.SetMultilineMode (true);
- const Standard_Integer aNbMiBTotal = Standard_Integer(aFileLen / (1024 * 1024));
+ const Standard_Integer aNbMiBTotal = Standard_Integer(aFileLen / (1024 * 1024));
Standard_Integer aNbMiBPassed = 0;
Message_ProgressScope aPS (theProgress, "Reading text OBJ file", aNbMiBTotal);
OSD_Timer aTimer;
aTimer.Start();
-
bool isStart = true;
int64_t aPosition = 0;
size_t aLineLen = 0;
const char* aLine = NULL;
for (;;)
{
- aLine = aBuffer.ReadLine (aFile.File, aLineLen, aReadBytes);
+ aLine = aBuffer.ReadLine (theStream, aLineLen, aReadBytes);
if (aLine == NULL)
{
break;
#include <NCollection_IndexedMap.hxx>
#include <NCollection_Vector.hxx>
#include <NCollection_Shared.hxx>
-
+#include <OSD_OpenFile.hxx>
#include <RWMesh_CoordinateSystemConverter.hxx>
#include <RWObj_Material.hxx>
#include <RWObj_SubMesh.hxx>
//! Empty constructor.
Standard_EXPORT RWObj_Reader();
+ //! Open stream and pass it to Read method
+ //! Returns true if success, false on error.
+ Standard_Boolean Read (const TCollection_AsciiString& theFile,
+ const Message_ProgressRange& theProgress)
+ {
+ std::ifstream aStream;
+ OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
+ return Read(aStream, theFile, theProgress);
+ }
+
//! Reads data from OBJ file.
//! Unicode paths can be given in UTF-8 encoding.
//! Returns true if success, false on error or user break.
- Standard_Boolean Read (const TCollection_AsciiString& theFile,
+ Standard_Boolean Read (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress)
{
- return read (theFile, theProgress, Standard_False);
+ return read(theStream, theFile, theProgress, Standard_False);
+ }
+
+ //! Open stream and pass it to Probe method.
+ //! @param theFile path to the file
+ //! @param theProgress progress indicator
+ //! @return TRUE if success, FALSE on error or user break.
+ //! @sa FileComments(), ExternalFiles(), NbProbeNodes(), NbProbeElems().
+ Standard_Boolean Probe (const TCollection_AsciiString& theFile,
+ const Message_ProgressRange& theProgress)
+ {
+ std::ifstream aStream;
+ OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
+ return Probe(aStream, theFile, theProgress);
}
//! Probe data from OBJ file (comments, external references) without actually reading mesh data.
//! Although mesh data will not be collected, the full file content will be parsed, due to OBJ format limitations.
+ //! @param theStream input stream
//! @param theFile path to the file
//! @param theProgress progress indicator
//! @return TRUE if success, FALSE on error or user break.
//! @sa FileComments(), ExternalFiles(), NbProbeNodes(), NbProbeElems().
- Standard_Boolean Probe (const TCollection_AsciiString& theFile,
+ Standard_Boolean Probe (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress)
{
- return read (theFile, theProgress, Standard_True);
+ return read(theStream, theFile, theProgress, Standard_True);
}
//! Returns file comments (lines starting with # at the beginning of file).
//! Reads data from OBJ file.
//! Unicode paths can be given in UTF-8 encoding.
//! Returns true if success, false on error or user break.
- Standard_EXPORT Standard_Boolean read (const TCollection_AsciiString& theFile,
+ Standard_EXPORT Standard_Boolean read (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe);
RWObj_SubMesh myActiveSubMesh; //!< active sub-mesh definition
std::vector<Standard_Integer> myCurrElem; //!< indices for the current element
-
};
#endif // _RWObj_Reader_HeaderFile
// function : performMesh
// purpose :
//=======================================================================
-bool VrmlAPI_CafReader::performMesh(const TCollection_AsciiString& theFile,
+bool VrmlAPI_CafReader::performMesh(std::istream& theStream,
+ const TCollection_AsciiString& theFile,
const Message_ProgressRange& theProgress,
const Standard_Boolean theToProbe)
{
(void)theProgress;
- Handle(OSD_FileSystem) aFile = OSD_FileSystem::DefaultFileSystem();
- std::shared_ptr<std::istream> aFileStream = aFile->OpenIStream(theFile, std::ios::in | std::ios::binary);
- if (aFileStream.get() == nullptr || !aFileStream->good())
+ if (!theStream.good())
{
Message::SendFail() << "Error in VrmlAPI_CafReader: file '" << theFile << "' is not found";
return false;
VrmlData_Scene aScene;
aScene.SetLinearScale(FileLengthUnit());
aScene.SetVrmlDir(aFolder);
- aScene << *aFileStream;
+ aScene << theStream;
VrmlData_DataMapOfShapeAppearance aShapeAppMap;
TopoDS_Shape aShape = aScene.GetShape(aShapeAppMap);
protected:
//! Read the mesh data from specified file.
- //! @param theFile file to read
+ //! @param theStream input stream
+ //! @param theFile path of additional files
//! @param theProgress progress indicator
//! @param theToProbe flag for probing file without complete reading. Not supported.
//! @return false when theToProbe is set to true or reading has completed with error.
- Standard_EXPORT virtual Standard_Boolean performMesh(const TCollection_AsciiString& theFile,
- const Message_ProgressRange& theProgress,
- const Standard_Boolean theToProbe) Standard_OVERRIDE;
+ Standard_EXPORT virtual Standard_Boolean performMesh (std::istream& theStream,
+ const TCollection_AsciiString& theFile,
+ const Message_ProgressRange& theProgress,
+ const Standard_Boolean theToProbe) Standard_OVERRIDE;
};
void VrmlData_Scene::SetVrmlDir (const TCollection_ExtendedString& theDir)
{
TCollection_ExtendedString& aDir = myVrmlDir.Append (theDir);
+ if (aDir.IsEmpty())
+ {
+ return;
+ }
const Standard_ExtCharacter aTerminator = aDir.Value(aDir.Length());
if (aTerminator != Standard_ExtCharacter('\\') &&
aTerminator != Standard_ExtCharacter('/'))