1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0030692: Data Exchange - introduce base framework RWMesh for importing mesh data formats into XDE document

RWMesh_CafReader - added new interface class for common workflow for reading mesh data files into XDE document.

OSD_Path - added auxiliary methods splitting path into folder+file pair
and checking relative/absolute path semantically:
OSD_Path::FolderAndFileFromPath(), ::IsRelativePath(), ::IsAbsolutePath().

V3d_TypeOfOrientation enumeration has been extended with aliases
(like front/left) for Z-up and Y-up conventions.
V3d_View::SetProj() now accepts argument for asking Y-up instead of Z-up.

Added command vviewproj defining standard camera direction.
Commands vaxo, vleft, vright, vtop, vbottom, vfront, vbottom now redirect to vviewproj.

TCollection_AsciiString::SubString() now uses Standard_OutOfRange_Always_Raise_if() to suppress GCC warning.

Eliminated gcc 4.4 compilation errors within Standard_OutOfRange_Raise_if,Standard_RangeError_Raise_if.
This commit is contained in:
kgv
2019-05-03 17:50:28 +03:00
committed by bugmaster
parent 5771d380b1
commit fc552d842e
39 changed files with 3116 additions and 176 deletions

View File

@@ -1,4 +1,6 @@
FILES
FSD_Base64Decoder.cxx
FSD_Base64Decoder.hxx
FSD_BinaryFile.cxx
FSD_BinaryFile.hxx
FSD_BStream.hxx

View File

@@ -0,0 +1,87 @@
// Author: Kirill Gavrilov
// Copyright (c) 2016-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 <FSD_Base64Decoder.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
// =======================================================================
// function : Decode
// purpose :
// =======================================================================
Handle(NCollection_Buffer) FSD_Base64Decoder::Decode (const Standard_Byte* theStr,
const Standard_Size theLen)
{
//! Look-up table for decoding base64 stream.
static const Standard_Byte THE_BASE64_FROM[128] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 62, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 0, 255, 255, 255,
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255
};
Handle(NCollection_Buffer) aData = new NCollection_Buffer (NCollection_BaseAllocator::CommonBaseAllocator());
if (!aData->Allocate (3 * theLen / 4))
{
Message::DefaultMessenger()->Send ("Fail to allocate memory.", Message_Fail);
return Handle(NCollection_Buffer)();
}
Standard_Byte* aDataPtr = aData->ChangeData();
const Standard_Byte* anEnd = theStr + theLen;
for (const Standard_Byte* aByteIter = theStr; aByteIter < anEnd; aByteIter += 4)
{
// get values for each group of four base 64 characters
const Standard_Byte b4[4] =
{
aByteIter + 0 < anEnd && aByteIter[0] <= 'z' ? THE_BASE64_FROM[aByteIter[0]] : Standard_Byte(0xFF),
aByteIter + 1 < anEnd && aByteIter[1] <= 'z' ? THE_BASE64_FROM[aByteIter[1]] : Standard_Byte(0xFF),
aByteIter + 2 < anEnd && aByteIter[2] <= 'z' ? THE_BASE64_FROM[aByteIter[2]] : Standard_Byte(0xFF),
aByteIter + 3 < anEnd && aByteIter[3] <= 'z' ? THE_BASE64_FROM[aByteIter[3]] : Standard_Byte(0xFF)
};
// transform into a group of three bytes
const Standard_Byte b3[3] =
{
Standard_Byte(((b4[0] & 0x3F) << 2) + ((b4[1] & 0x30) >> 4)),
Standard_Byte(((b4[1] & 0x0F) << 4) + ((b4[2] & 0x3C) >> 2)),
Standard_Byte(((b4[2] & 0x03) << 6) + ((b4[3] & 0x3F) >> 0))
};
// add the byte to the return value if it isn't part of an '=' character (indicated by 0xFF)
if (b4[1] != 0xFF)
{
*aDataPtr = b3[0];
++aDataPtr;
}
if (b4[2] != 0xFF)
{
*aDataPtr = b3[1];
++aDataPtr;
}
if (b4[3] != 0xFF)
{
*aDataPtr = b3[2];
++aDataPtr;
}
}
return aData;
}

View File

@@ -0,0 +1,30 @@
// Author: Kirill Gavrilov
// Copyright (c) 2016-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 _FSD_Base64Decoder_HeaderFile
#define _FSD_Base64Decoder_HeaderFile
#include <NCollection_Buffer.hxx>
//! Tool decoding base64 stream.
class FSD_Base64Decoder
{
public:
//! Function decoding base64 stream.
Standard_EXPORT static Handle(NCollection_Buffer) Decode (const Standard_Byte* theStr,
const Standard_Size theLen);
};
#endif // _FSD_Base64Decoder_HeaderFile

View File

@@ -8,5 +8,7 @@ Image_PixMap.cxx
Image_PixMap.hxx
Image_PixMapData.hxx
Image_PixMapTypedData.hxx
Image_Texture.cxx
Image_Texture.hxx
Image_VideoRecorder.cxx
Image_VideoRecorder.hxx

304
src/Image/Image_Texture.cxx Normal file
View File

@@ -0,0 +1,304 @@
// Author: Kirill Gavrilov
// Copyright (c) 2015-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 <Image_Texture.hxx>
#include <Image_AlienPixMap.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <OSD_OpenFile.hxx>
IMPLEMENT_STANDARD_RTTIEXT(Image_Texture, Standard_Transient)
// ================================================================
// Function : Image_Texture
// Purpose :
// ================================================================
Image_Texture::Image_Texture (const TCollection_AsciiString& theFileName)
: myImagePath (theFileName),
myOffset (-1),
myLength (-1)
{
// share textures with unique file paths
if (!theFileName.IsEmpty())
{
myTextureId = TCollection_AsciiString ("texture://") + theFileName;
}
}
// ================================================================
// Function : Image_Texture
// Purpose :
// ================================================================
Image_Texture::Image_Texture (const TCollection_AsciiString& theFileName,
int64_t theOffset,
int64_t theLength)
: myImagePath (theFileName),
myOffset (theOffset),
myLength (theLength)
{
// share textures with unique file paths
if (!theFileName.IsEmpty())
{
char aBuff[60];
Sprintf (aBuff, ";%" PRId64 ",%" PRId64, theOffset, theLength);
myTextureId = TCollection_AsciiString ("texture://") + theFileName + aBuff;
}
}
// ================================================================
// Function : Image_Texture
// Purpose :
// ================================================================
Image_Texture::Image_Texture (const Handle(NCollection_Buffer)& theBuffer,
const TCollection_AsciiString& theId)
: myBuffer (theBuffer),
myOffset (-1),
myLength (-1)
{
if (!theId.IsEmpty())
{
myTextureId = TCollection_AsciiString ("texturebuf://") + theId;
}
}
// ================================================================
// Function : ReadImage
// Purpose :
// ================================================================
Handle(Image_PixMap) Image_Texture::ReadImage() const
{
Handle(Image_PixMap) anImage;
if (!myBuffer.IsNull())
{
anImage = loadImageBuffer (myBuffer, myTextureId);
}
else if (myOffset >= 0)
{
anImage = loadImageOffset (myImagePath, myOffset, myLength);
}
else
{
anImage = loadImageFile (myImagePath);
}
if (anImage.IsNull())
{
return Handle(Image_PixMap)();
}
return anImage;
}
// ================================================================
// Function : loadImageFile
// Purpose :
// ================================================================
Handle(Image_PixMap) Image_Texture::loadImageFile (const TCollection_AsciiString& thePath) const
{
Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
if (!anImage->Load (thePath))
{
return Handle(Image_PixMap)();
}
return anImage;
}
// ================================================================
// Function : loadImageBuffer
// Purpose :
// ================================================================
Handle(Image_PixMap) Image_Texture::loadImageBuffer (const Handle(NCollection_Buffer)& theBuffer,
const TCollection_AsciiString& theId) const
{
if (theBuffer.IsNull())
{
return Handle(Image_PixMap)();
}
else if (theBuffer->Size() > (Standard_Size )IntegerLast())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Image file size is too big '") + theId + "'.", Message_Fail);
return Handle(Image_PixMap)();
}
Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
if (!anImage->Load (theBuffer->Data(), (int )theBuffer->Size(), theId))
{
return Handle(Image_PixMap)();
}
return anImage;
}
// ================================================================
// Function : loadImageOffset
// Purpose :
// ================================================================
Handle(Image_PixMap) Image_Texture::loadImageOffset (const TCollection_AsciiString& thePath,
int64_t theOffset,
int64_t theLength) const
{
if (theLength > IntegerLast())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Image file size is too big '") + thePath + "'.", Message_Fail);
return Handle(Image_PixMap)();
}
std::ifstream aFile;
OSD_OpenStream (aFile, thePath.ToCString(), std::ios::in | std::ios::binary);
if (!aFile)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Image file '") + thePath + "' cannot be opened.", Message_Fail);
return Handle(Image_PixMap)();
}
aFile.seekg ((std::streamoff )theOffset, std::ios_base::beg);
if (!aFile.good())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Image is defined with invalid file offset '") + thePath + "'.", Message_Fail);
return Handle(Image_PixMap)();
}
Handle(Image_AlienPixMap) anImage = new Image_AlienPixMap();
if (!anImage->Load (aFile, thePath))
{
return Handle(Image_PixMap)();
}
return anImage;
}
// ================================================================
// Function : ProbeImageFileFormat
// Purpose :
// ================================================================
TCollection_AsciiString Image_Texture::ProbeImageFileFormat() const
{
static const int THE_PROBE_SIZE = 20;
char aBuffer[THE_PROBE_SIZE];
if (!myBuffer.IsNull())
{
memcpy (aBuffer, myBuffer->Data(), myBuffer->Size() < THE_PROBE_SIZE ? myBuffer->Size() : THE_PROBE_SIZE);
}
else
{
std::ifstream aFileIn;
OSD_OpenStream (aFileIn, myImagePath.ToCString(), std::ios::in | std::ios::binary);
if (!aFileIn)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Unable to open file ") + myImagePath + "!", Message_Fail);
return false;
}
if (myOffset >= 0)
{
aFileIn.seekg ((std::streamoff )myOffset, std::ios_base::beg);
if (!aFileIn.good())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Image is defined with invalid file offset '") + myImagePath + "'.", Message_Fail);
return false;
}
}
if (!aFileIn.read (aBuffer, THE_PROBE_SIZE))
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: unable to read image file '") + myImagePath + "'", Message_Fail);
return false;
}
}
if (memcmp (aBuffer, "\x89" "PNG\r\n" "\x1A" "\n", 8) == 0)
{
return "png";
}
else if (memcmp (aBuffer, "\xFF\xD8\xFF", 3) == 0)
{
return "jpg";
}
else if (memcmp (aBuffer, "GIF87a", 6) == 0
|| memcmp (aBuffer, "GIF89a", 6) == 0)
{
return "gif";
}
else if (memcmp (aBuffer, "II\x2A\x00", 4) == 0
|| memcmp (aBuffer, "MM\x00\x2A", 4) == 0)
{
return "tiff";
}
else if (memcmp (aBuffer, "BM", 2) == 0)
{
return "bmp";
}
else if (memcmp (aBuffer, "RIFF", 4) == 0
&& memcmp (aBuffer + 8, "WEBP", 4) == 0)
{
return "webp";
}
return "";
}
// ================================================================
// Function : WriteImage
// Purpose :
// ================================================================
Standard_Boolean Image_Texture::WriteImage (const TCollection_AsciiString& theFile)
{
Handle(NCollection_Buffer) aBuffer = myBuffer;
if (myBuffer.IsNull())
{
std::ifstream aFileIn;
OSD_OpenStream (aFileIn, myImagePath.ToCString(), std::ios::in | std::ios::binary);
if (!aFileIn)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Unable to open file ") + myImagePath + "!", Message_Fail);
return Standard_False;
}
Standard_Size aLen = (Standard_Size )myLength;
if (myOffset >= 0)
{
aFileIn.seekg ((std::streamoff )myOffset, std::ios_base::beg);
if (!aFileIn.good())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Image is defined with invalid file offset '") + myImagePath + "'.", Message_Fail);
return Standard_False;
}
}
else
{
aFileIn.seekg (0, std::ios_base::end);
aLen = (Standard_Size )aFileIn.tellg();
aFileIn.seekg (0, std::ios_base::beg);
}
aBuffer = new NCollection_Buffer (NCollection_BaseAllocator::CommonBaseAllocator(), aLen);
if (!aFileIn.read ((char* )aBuffer->ChangeData(), aBuffer->Size()))
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: unable to read image file '") + myImagePath + "'", Message_Fail);
return Standard_False;
}
}
std::ofstream aFileOut;
OSD_OpenStream (aFileOut, theFile.ToCString(), std::ios::out | std::ios::binary | std::ios::trunc);
if (!aFileOut)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Unable to create file ") + theFile + "!", Message_Fail);
return Standard_False;
}
aFileOut.write ((const char* )aBuffer->Data(), aBuffer->Size());
aFileOut.close();
if (!aFileOut.good())
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Error: Unable to write file ") + theFile + "!", Message_Fail);
return Standard_False;
}
return Standard_True;
}

115
src/Image/Image_Texture.hxx Normal file
View File

@@ -0,0 +1,115 @@
// Author: Kirill Gavrilov
// Copyright (c) 2015-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 _Image_Texture_HeaderFile
#define _Image_Texture_HeaderFile
#include <NCollection_Buffer.hxx>
#include <TCollection_AsciiString.hxx>
class Image_PixMap;
//! Texture image definition.
//! The image can be stored as path to image file, as file path with the given offset and as a data buffer of encoded image.
class Image_Texture : public Standard_Transient
{
DEFINE_STANDARD_RTTIEXT(Image_Texture, Standard_Transient)
public:
//! Constructor pointing to file location.
Standard_EXPORT explicit Image_Texture (const TCollection_AsciiString& theFileName);
//! Constructor pointing to file part.
Standard_EXPORT explicit Image_Texture (const TCollection_AsciiString& theFileName,
int64_t theOffset,
int64_t theLength);
//! Constructor pointing to buffer.
Standard_EXPORT explicit Image_Texture (const Handle(NCollection_Buffer)& theBuffer,
const TCollection_AsciiString& theId);
//! Return generated texture id.
const TCollection_AsciiString& TextureId() const { return myTextureId; }
//! Return image file path.
const TCollection_AsciiString& FilePath() const { return myImagePath; }
//! Return offset within file.
int64_t FileOffset() const { return myOffset; }
//! Return length of image data within the file after offset.
int64_t FileLength() const { return myLength; }
//! Return buffer holding encoded image content.
const Handle(NCollection_Buffer)& DataBuffer() const { return myBuffer; }
//! Return image file format.
Standard_EXPORT TCollection_AsciiString ProbeImageFileFormat() const;
//! Image reader.
Standard_EXPORT virtual Handle(Image_PixMap) ReadImage() const;
//! Write image to specified file without decoding data.
Standard_EXPORT virtual Standard_Boolean WriteImage (const TCollection_AsciiString& theFile);
public: //! @name hasher interface
//! Hash value, for Map interface.
static int HashCode (const Handle(Image_Texture)& theTexture, const int theUpper)
{
return !theTexture.IsNull()
? TCollection_AsciiString::HashCode (theTexture->myTextureId, theUpper)
: 0;
}
//! Matching two instances, for Map interface.
static Standard_Boolean IsEqual (const Handle(Image_Texture)& theTex1,
const Handle(Image_Texture)& theTex2)
{
if (theTex1.IsNull() != theTex2.IsNull())
{
return Standard_False;
}
else if (theTex1.IsNull())
{
return Standard_True;
}
return theTex1->myTextureId.IsEqual (theTex2->myTextureId);
}
protected:
//! Read image from normal image file.
Standard_EXPORT virtual Handle(Image_PixMap) loadImageFile (const TCollection_AsciiString& thePath) const;
//! Read image from file with some offset.
Standard_EXPORT virtual Handle(Image_PixMap) loadImageOffset (const TCollection_AsciiString& thePath,
int64_t theOffset,
int64_t theLength) const;
//! Read image from buffer.
Standard_EXPORT virtual Handle(Image_PixMap) loadImageBuffer (const Handle(NCollection_Buffer)& theBuffer,
const TCollection_AsciiString& theId) const;
protected:
TCollection_AsciiString myTextureId; //!< generated texture id
TCollection_AsciiString myImagePath; //!< image file path
Handle(NCollection_Buffer) myBuffer; //!< image buffer
int64_t myOffset; //!< offset within file
int64_t myLength; //!< length within file
};
#endif // _Image_Texture_HeaderFile

View File

@@ -17,7 +17,7 @@
proc DataExchange:toolkits { } {
return [list TKXSBase TKSTEPBase TKSTEPAttr TKSTEP209 TKSTEP TKIGES \
TKXCAF TKXDEIGES TKXDESTEP \
TKSTL TKVRML TKXmlXCAF TKBinXCAF]
TKSTL TKVRML TKXmlXCAF TKBinXCAF TKRWMesh]
}
;#
;# Autres UDs a prendre.

View File

@@ -1635,3 +1635,40 @@ Standard_Boolean LocateExecFile(OSD_Path& )
{
return Standard_False ;
}
// =======================================================================
// function : FolderAndFileFromPath
// purpose :
// =======================================================================
void OSD_Path::FolderAndFileFromPath (const TCollection_AsciiString& theFilePath,
TCollection_AsciiString& theFolder,
TCollection_AsciiString& theFileName)
{
Standard_Integer aLastSplit = -1;
Standard_CString aString = theFilePath.ToCString();
for (Standard_Integer anIter = 0; anIter < theFilePath.Length(); ++anIter)
{
if (aString[anIter] == '/'
|| aString[anIter] == '\\')
{
aLastSplit = anIter;
}
}
if (aLastSplit == -1)
{
theFolder.Clear();
theFileName = theFilePath;
return;
}
theFolder = theFilePath.SubString (1, aLastSplit + 1);
if (aLastSplit + 2 <= theFilePath.Length())
{
theFileName = theFilePath.SubString (aLastSplit + 2, theFilePath.Length());
}
else
{
theFileName.Clear();
}
}

View File

@@ -20,27 +20,14 @@
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <TCollection_AsciiString.hxx>
#include <Standard_Boolean.hxx>
#include <OSD_SysType.hxx>
#include <Standard_Integer.hxx>
class Standard_ConstructionError;
class Standard_NullObject;
class OSD_OSDError;
class Standard_NumericError;
class Standard_ProgramError;
class TCollection_AsciiString;
class OSD_Path
{
public:
DEFINE_STANDARD_ALLOC
//! Creates a Path object initialized to an empty string.
//! i.e. current directory.
Standard_EXPORT OSD_Path();
@@ -199,10 +186,12 @@ public:
//! "which" Unix utility. Uses the path environment variable.
//! Returns False if executable file not found.
Standard_EXPORT Standard_Boolean LocateExecFile (OSD_Path& aPath);
public:
//! Returns the relative file path between the absolute directory
//! path <DirPath> and the absolute file path <AbsFilePath>.
//! If <DirPath> starts with "/", pathes are handled as
//! If <DirPath> starts with "/", paths are handled as
//! on Unix, if it starts with a letter followed by ":", as on
//! WNT. In particular on WNT directory names are not key sensitive.
//! If handling fails, an empty string is returned.
@@ -215,19 +204,109 @@ public:
//! If handling fails, an empty string is returned.
Standard_EXPORT static TCollection_AsciiString AbsolutePath (const TCollection_AsciiString& DirPath, const TCollection_AsciiString& RelFilePath);
//! Split absolute filepath into folder path and file name.
//! Example: IN theFilePath ='/media/cdrom/image.jpg'
//! OUT theFolder ='/media/cdrom/'
//! OUT theFileName ='image.jpg'
//! @param theFilePath [in] file path
//! @param theFolder [out] folder path (with trailing separator)
//! @param theFileName [out] file name
Standard_EXPORT static void FolderAndFileFromPath (const TCollection_AsciiString& theFilePath,
TCollection_AsciiString& theFolder,
TCollection_AsciiString& theFileName);
//! Detect absolute DOS-path also used in Windows.
//! The total path length is limited to 256 characters.
//! Sample path:
//! C:\folder\file
//! @return true if DOS path syntax detected.
static Standard_Boolean IsDosPath (const char* thePath) { return thePath[0] != '\0' && thePath[1] == ':'; }
//! Detect extended-length NT path (can be only absolute).
//! Approximate maximum path is 32767 characters.
//! Sample path:
//! \\?\D:\very long path
//! File I/O functions in the Windows API convert "/" to "\" as part of converting the name to an NT-style name, except when using the "\\?\" prefix.
//! @return true if extended-length NT path syntax detected.
static Standard_Boolean IsNtExtendedPath (const char* thePath) { return ::memcmp (thePath, "\\\\?\\", 4) == 0; }
protected:
//! UNC is a naming convention used primarily to specify and map network drives in Microsoft Windows.
//! Sample path:
//! \\server\share\file
//! @return true if UNC path syntax detected.
static Standard_Boolean IsUncPath (const char* thePath)
{
if (::memcmp (thePath, "\\\\", 2) == 0)
{
return thePath[2] != '?'
|| IsUncExtendedPath (thePath);
}
return ::memcmp (thePath, "//", 2) == 0;
}
//! Detect extended-length UNC path.
//! Sample path:
//! \\?\UNC\server\share
//! @return true if extended-length UNC path syntax detected.
static Standard_Boolean IsUncExtendedPath (const char* thePath) { return ::memcmp (thePath, "\\\\?\\UNC\\", 8) == 0; }
//! Detect absolute UNIX-path.
//! Sample path:
//! /media/cdrom/file
//! @return true if UNIX path syntax detected.
static Standard_Boolean IsUnixPath (const char* thePath) { return thePath[0] == '/' && thePath[1] != '/'; }
//! Detect special URLs on Android platform.
//! Sample path:
//! content://filename
//! @return true if content path syntax detected
static Standard_Boolean IsContentProtocolPath (const char* thePath) { return ::memcmp (thePath, "content://", 10) == 0; }
//! Detect remote protocol path (http / ftp / ...).
//! Actually shouldn't be remote...
//! Sample path:
//! http://domain/path/file
//! @return true if remote protocol path syntax detected.
static Standard_Boolean IsRemoteProtocolPath (const char* thePath)
{
const char* anIter = thePath;
if (*anIter == ':')
{
return false;
}
for (; *anIter != '\0'; ++anIter)
{
if (*anIter == ':')
{
return *(++anIter) == '/'
&& *(++anIter) == '/';
}
}
return false;
}
//! Method to recognize path is absolute or not.
//! Detection is based on path syntax - no any filesystem / network access performed.
//! @return true if path is incomplete (relative).
static Standard_Boolean IsRelativePath (const char* thePath)
{
return !IsUncPath (thePath)
&& !IsDosPath (thePath)
&& !IsNtExtendedPath (thePath)
&& !IsUnixPath (thePath)
&& !IsRemoteProtocolPath (thePath);
}
//! Method to recognize path is absolute or not.
//! Detection is based on path syntax - no any filesystem / network access performed.
//! @return true if path is complete (absolute)
static Standard_Boolean IsAbsolutePath (const char* thePath)
{
return !IsRelativePath (thePath);
}
private:
TCollection_AsciiString myNode;
TCollection_AsciiString myUserName;
TCollection_AsciiString myPassword;
@@ -238,13 +317,6 @@ private:
Standard_Boolean myUNCFlag;
OSD_SysType mySysDep;
};
#endif // _OSD_Path_HeaderFile

View File

@@ -21,6 +21,7 @@
#include <gp_Pnt.hxx>
#include <OSD_Path.hxx>
#include <Precision.hxx>
#include <Standard_Overflow.hxx>
@@ -1224,6 +1225,114 @@ static Standard_Integer QANColTestVec4 (Draw_Interpretor& theDI, Standard_Intege
return 0;
}
//! Print file path flags deduced from path string.
static Standard_Integer QAOsdPathType (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
{
if (theNbArgs != 2)
{
std::cout << "Syntax error: wrong number of arguments\n";
return 1;
}
TCollection_AsciiString aPath (theArgVec[1]);
if (OSD_Path::IsAbsolutePath (aPath.ToCString()))
{
theDI << "absolute ";
}
if (OSD_Path::IsRelativePath (aPath.ToCString()))
{
theDI << "relative ";
}
if (OSD_Path::IsUnixPath (aPath.ToCString()))
{
theDI << "unix ";
}
if (OSD_Path::IsDosPath (aPath.ToCString()))
{
theDI << "dos ";
}
if (OSD_Path::IsUncPath (aPath.ToCString()))
{
theDI << "unc ";
}
if (OSD_Path::IsNtExtendedPath (aPath.ToCString()))
{
theDI << "ntextended ";
}
if (OSD_Path::IsUncExtendedPath (aPath.ToCString()))
{
theDI << "uncextended ";
}
if (OSD_Path::IsRemoteProtocolPath (aPath.ToCString()))
{
theDI << "protocol ";
}
if (OSD_Path::IsContentProtocolPath (aPath.ToCString()))
{
theDI << "content ";
}
return 0;
}
//! Print file path part deduced from path string.
static Standard_Integer QAOsdPathPart (Draw_Interpretor& theDI, Standard_Integer theNbArgs, const char** theArgVec)
{
TCollection_AsciiString aPath;
enum PathPart
{
PathPart_NONE,
PathPart_Folder,
PathPart_FileName,
};
PathPart aPart = PathPart_NONE;
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
anArgCase.LowerCase();
if (aPart == PathPart_NONE
&& anArgCase == "-folder")
{
aPart = PathPart_Folder;
}
else if (aPart == PathPart_NONE
&& anArgCase == "-filename")
{
aPart = PathPart_FileName;
}
else if (aPath.IsEmpty())
{
aPath = theArgVec[anArgIter];
}
else
{
std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
return 1;
}
}
if (aPath.IsEmpty()
|| aPart == PathPart_NONE)
{
std::cout << "Syntax error: wrong number of arguments\n";
return 1;
}
TCollection_AsciiString aFolder, aFileName;
OSD_Path::FolderAndFileFromPath (aPath, aFolder, aFileName);
switch (aPart)
{
case PathPart_Folder:
theDI << aFolder;
return 0;
case PathPart_FileName:
theDI << aFileName;
return 0;
case PathPart_NONE:
default:
return 1;
}
}
void QANCollection::CommandsTest(Draw_Interpretor& theCommands) {
const char *group = "QANCollection";
@@ -1242,4 +1351,6 @@ void QANCollection::CommandsTest(Draw_Interpretor& theCommands) {
theCommands.Add("QANColTestArrayMove", "QANColTestArrayMove (is expected to give error)", __FILE__, QANColTestArrayMove, group);
theCommands.Add("QANColTestVec4", "QANColTestVec4 test Vec4 implementation", __FILE__, QANColTestVec4, group);
theCommands.Add("QATestAtof", "QATestAtof [nbvalues [nbdigits [min [max]]]]", __FILE__, QATestAtof, group);
theCommands.Add("QAOsdPathType", "QAOsdPathType path : Print file path flags deduced from path string", __FILE__, QAOsdPathType, group);
theCommands.Add("QAOsdPathPart", "QAOsdPathPart path [-folder][-fileName] : Print file path part", __FILE__, QAOsdPathPart, group);
}

6
src/RWMesh/FILES Normal file
View File

@@ -0,0 +1,6 @@
RWMesh_CoordinateSystem.hxx
RWMesh_CoordinateSystemConverter.cxx
RWMesh_CoordinateSystemConverter.hxx
RWMesh_CafReader.cxx
RWMesh_CafReader.hxx
RWMesh_NodeAttributes.hxx

View File

@@ -0,0 +1,387 @@
// Author: Kirill Gavrilov
// Copyright (c) 2016-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 <RWMesh_CafReader.hxx>
#include <XCAFPrs_DocumentExplorer.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
#include <Message_ProgressIndicator.hxx>
#include <BRep_Builder.hxx>
#include <OSD_Path.hxx>
#include <OSD_Timer.hxx>
#include <TDataStd_Name.hxx>
#include <TDocStd_Document.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
#include <XCAFDoc_ColorTool.hxx>
#include <XCAFDoc_ColorType.hxx>
#include <XCAFDoc_DocumentTool.hxx>
#include <XCAFDoc_ShapeMapTool.hxx>
#include <XCAFDoc_ShapeTool.hxx>
IMPLEMENT_STANDARD_RTTIEXT(RWMesh_CafReader, Standard_Transient)
// =======================================================================
// function : RWMesh_CafReader
// purpose :
// =======================================================================
RWMesh_CafReader::RWMesh_CafReader()
: myToFillDoc (Standard_True),
myToFillIncomplete (Standard_True),
myMemoryLimitMiB (-1),
myExtraStatus (RWMesh_CafReaderStatusEx_NONE)
{
//
}
// =======================================================================
// function : ~RWMesh_CafReader
// purpose :
// =======================================================================
RWMesh_CafReader::~RWMesh_CafReader()
{
//
}
// =======================================================================
// function : SingleShape
// purpose :
// =======================================================================
TopoDS_Shape RWMesh_CafReader::SingleShape() const
{
if (myRootShapes.Size() > 1)
{
BRep_Builder aBuilder;
TopoDS_Compound aCompound;
aBuilder.MakeCompound (aCompound);
for (TopTools_SequenceOfShape::Iterator aRootIter (myRootShapes); aRootIter.More(); aRootIter.Next())
{
aBuilder.Add (aCompound, aRootIter.Value());
}
return aCompound;
}
else if (!myRootShapes.IsEmpty())
{
return myRootShapes.First();
}
return TopoDS_Shape();
}
// =======================================================================
// function : perform
// purpose :
// =======================================================================
Standard_Boolean RWMesh_CafReader::perform (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Boolean theToProbe)
{
Standard_Integer aNewRootsLower = 1;
Handle(XCAFDoc_ShapeTool) aShapeTool = !myXdeDoc.IsNull()
? XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main())
: Handle(XCAFDoc_ShapeTool)();
if (!myXdeDoc.IsNull())
{
TDF_LabelSequence aRootLabels;
aShapeTool->GetFreeShapes (aRootLabels);
aNewRootsLower = aRootLabels.Upper() + 1;
}
OSD_Timer aLoadingTimer;
aLoadingTimer.Start();
const Standard_Boolean isDone = performMesh (theFile, theProgress, theToProbe);
if (theToProbe
|| (!theProgress.IsNull() && theProgress->UserBreak()))
{
return isDone;
}
else if (!isDone)
{
if (!myToFillIncomplete)
{
return Standard_False;
}
myExtraStatus |= RWMesh_CafReaderStatusEx_Partial;
}
BRep_Builder aBuilder;
TopoDS_Shape aShape;
if (myRootShapes.Size() > 1)
{
TopoDS_Compound aCompound;
aBuilder.MakeCompound (aCompound);
for (TopTools_SequenceOfShape::Iterator aRootIter (myRootShapes); aRootIter.More(); aRootIter.Next())
{
aBuilder.Add (aCompound, aRootIter.Value());
}
aShape = aCompound;
}
else if (!myRootShapes.IsEmpty())
{
aShape = myRootShapes.First();
}
Standard_Integer aNbNodes = 0, aNbElems = 0, aNbFaces = 0;
if (!aShape.IsNull())
{
TopLoc_Location aDummyLoc;
for (TopExp_Explorer aFaceIter (aShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
{
const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
if (const Handle(Poly_Triangulation)& aPolyTri = BRep_Tool::Triangulation (aFace, aDummyLoc))
{
++aNbFaces;
aNbNodes += aPolyTri->NbNodes();
aNbElems += aPolyTri->NbTriangles();
}
}
}
if (!isDone && aNbElems < 100)
{
return Standard_False;
}
if (myToFillDoc
&& !myXdeDoc.IsNull())
{
const Standard_Boolean wasAutoNaming = aShapeTool->AutoNaming();
aShapeTool->SetAutoNaming (Standard_False);
const TCollection_AsciiString aRootName; // = generateRootName (theFile);
for (TopTools_SequenceOfShape::Iterator aRootIter (myRootShapes); aRootIter.More(); aRootIter.Next())
{
addShapeIntoDoc (aRootIter.Value(), TDF_Label(), aRootName);
}
aShapeTool->UpdateAssemblies();
aShapeTool->SetAutoNaming (wasAutoNaming);
}
if (!myXdeDoc.IsNull())
{
generateNames (theFile, aNewRootsLower, Standard_False);
}
aLoadingTimer.Stop();
TCollection_AsciiString aStats = TCollection_AsciiString("[") + aNbNodes + " nodes] [" + aNbElems + " 2d elements]";
if (!isDone)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Mesh ") + theFile
+ "\n" + aStats
+ "\n[PARTIALLY read in " + aLoadingTimer.ElapsedTime() + " s]", Message_Info);
}
else
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Mesh ") + theFile
+ "\n" + aStats
+ "\n[read in " + aLoadingTimer.ElapsedTime() + " s]", Message_Info);
}
return Standard_True;
}
// =======================================================================
// function : addShapeIntoDoc
// purpose :
// =======================================================================
Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (const TopoDS_Shape& theShape,
const TDF_Label& theLabel,
const TCollection_AsciiString& theParentName)
{
if (theShape.IsNull()
|| myXdeDoc.IsNull())
{
return Standard_False;
}
Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main());
TopLoc_Location aDummyLoc;
const TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
TopoDS_Shape aShapeToAdd = theShape;
Standard_Boolean toMakeAssembly = Standard_False;
if (theShape.ShapeType() == TopAbs_COMPOUND)
{
TCollection_AsciiString aFirstName;
RWMesh_NodeAttributes aSubFaceAttribs;
for (TopoDS_Iterator aSubShapeIter (theShape, Standard_True, Standard_False); !toMakeAssembly && aSubShapeIter.More(); aSubShapeIter.Next())
{
if (aSubShapeIter.Value().ShapeType() != TopAbs_FACE)
{
toMakeAssembly = Standard_True;
break;
}
const TopoDS_Face& aFace = TopoDS::Face (aSubShapeIter.Value());
toMakeAssembly = toMakeAssembly
|| (myAttribMap.Find (aFace, aSubFaceAttribs) && !aSubFaceAttribs.Name.IsEmpty());
}
// create empty compound to add as assembly
if (toMakeAssembly)
{
TopoDS_Compound aCompound;
BRep_Builder aBuilder;
aBuilder.MakeCompound (aCompound);
aCompound.Location (theShape.Location());
aShapeToAdd = aCompound;
}
}
TDF_Label aNewLabel;
if (theLabel.IsNull())
{
// add new shape
aNewLabel = aShapeTool->AddShape (aShapeToAdd, toMakeAssembly);
}
else if (aShapeTool->IsAssembly (theLabel))
{
// add shape as component
aNewLabel = aShapeTool->AddComponent (theLabel, aShapeToAdd, toMakeAssembly);
}
else
{
// add shape as sub-shape
aNewLabel = aShapeTool->AddSubShape (theLabel, theShape);
if (!aNewLabel.IsNull())
{
Handle(XCAFDoc_ShapeMapTool) aShapeMapTool = XCAFDoc_ShapeMapTool::Set (aNewLabel);
aShapeMapTool->SetShape (theShape);
}
}
if (aNewLabel.IsNull())
{
return Standard_False;
}
// if new label is a reference get referred shape
TDF_Label aNewRefLabel = aNewLabel;
aShapeTool->GetReferredShape (aNewLabel, aNewRefLabel);
// store name
RWMesh_NodeAttributes aShapeAttribs;
myAttribMap.Find (theShape, aShapeAttribs);
if (aShapeAttribs.Name.IsEmpty())
{
if (theLabel.IsNull())
{
aShapeAttribs.Name = theParentName;
}
if (aShapeAttribs.Name.IsEmpty()
&& !theLabel.IsNull())
{
aShapeAttribs.Name = shapeTypeToString (aShapeType);
}
}
if (!aShapeAttribs.Name.IsEmpty())
{
TDataStd_Name::Set (aNewRefLabel, aShapeAttribs.Name);
}
// store color
Handle(XCAFDoc_ColorTool) aColorTool = XCAFDoc_DocumentTool::ColorTool (myXdeDoc->Main());
if (aShapeAttribs.Style.IsSetColorSurf())
{
aColorTool->SetColor (aNewRefLabel, aShapeAttribs.Style.GetColorSurfRGBA(), XCAFDoc_ColorSurf);
}
if (aShapeAttribs.Style.IsSetColorCurv())
{
aColorTool->SetColor (aNewRefLabel, aShapeAttribs.Style.GetColorCurv(), XCAFDoc_ColorCurv);
}
// store sub-shapes (iterator is set to ignore Location)
TCollection_AsciiString aDummyName;
for (TopoDS_Iterator aSubShapeIter (theShape, Standard_True, Standard_False); aSubShapeIter.More(); aSubShapeIter.Next())
{
addShapeIntoDoc (aSubShapeIter.Value(), aNewRefLabel, aDummyName);
}
return Standard_True;
}
// =======================================================================
// function : generateNames
// purpose :
// =======================================================================
void RWMesh_CafReader::generateNames (const TCollection_AsciiString& theFile,
const Standard_Integer theRootLower,
const Standard_Boolean theWithSubLabels)
{
if (myXdeDoc.IsNull())
{
return;
}
TCollection_AsciiString aDummyFolder, aFileName;
OSD_Path::FolderAndFileFromPath (theFile, aDummyFolder, aFileName);
const TCollection_AsciiString aRootName = myRootPrefix + aFileName;
Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main());
TDF_LabelSequence aRootLabels;
aShapeTool->GetFreeShapes (aRootLabels);
if (aRootLabels.Upper() < theRootLower)
{
return;
}
// replace empty names
Handle(TDataStd_Name) aNodeName;
Standard_Integer aRootIndex = aRootLabels.Lower();
TDF_LabelSequence aNewRootLabels;
for (TDF_LabelSequence::Iterator aRootIter (aRootLabels); aRootIter.More(); ++aRootIndex, aRootIter.Next())
{
if (aRootIndex < theRootLower)
{
continue;
}
else if (theWithSubLabels)
{
aNewRootLabels.Append (aRootIter.Value());
}
const TDF_Label aLabel = aRootIter.Value();
TDF_Label aRefLab = aLabel;
XCAFDoc_ShapeTool::GetReferredShape (aLabel, aRefLab);
if (!aRefLab.FindAttribute (TDataStd_Name::GetID(), aNodeName))
{
TDataStd_Name::Set (aRefLab, aRootName);
}
if (aLabel != aRefLab
&& !aLabel.FindAttribute (TDataStd_Name::GetID(), aNodeName))
{
TDataStd_Name::Set (aLabel, aRootName);
}
}
if (theWithSubLabels)
{
for (XCAFPrs_DocumentExplorer aDocIter (myXdeDoc,
aNewRootLabels,
XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes | XCAFPrs_DocumentExplorerFlags_NoStyle);
aDocIter.More(); aDocIter.Next())
{
if (aDocIter.CurrentDepth() == 0
|| aDocIter.Current().RefLabel.FindAttribute (TDataStd_Name::GetID(), aNodeName))
{
continue;
}
const TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape (aDocIter.Current().RefLabel);
if (!aShape.IsNull())
{
TDataStd_Name::Set (aDocIter.Current().RefLabel, shapeTypeToString (aShape.ShapeType()));
}
}
}
}

View File

@@ -0,0 +1,228 @@
// Author: Kirill Gavrilov
// Copyright (c) 2016-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 _RWMesh_CafReader_HeaderFile
#define _RWMesh_CafReader_HeaderFile
#include <NCollection_IndexedMap.hxx>
#include <RWMesh_CoordinateSystemConverter.hxx>
#include <RWMesh_NodeAttributes.hxx>
#include <TColStd_IndexedDataMapOfStringString.hxx>
#include <TDF_Label.hxx>
#include <TopTools_SequenceOfShape.hxx>
class Message_ProgressIndicator;
class TDocStd_Document;
//! Extended status bits.
enum RWMesh_CafReaderStatusEx
{
RWMesh_CafReaderStatusEx_NONE = 0, //!< empty status
RWMesh_CafReaderStatusEx_Partial = 0x01, //!< partial read (due to unexpected EOF, syntax error, memory limit)
};
//! The general interface for importing mesh data into XDE document.
//!
//! The tool implements auxiliary structures for creating an XDE document in two steps:
//! 1) Creating TopoDS_Shape hierarchy (myRootShapes)
//! and Shape attributes (myAttribMap) separately within performMesh().
//! Attributes include names and styles.
//! 2) Filling XDE document from these auxiliary structures.
//! Named elements are expanded within document structure, while Compounds having no named children will remain collapsed.
//! In addition, unnamed nodes can be filled with generated names like "Face", "Compound" via generateNames() method,
//! and the very root unnamed node can be filled from file name like "MyModel.obj".
class RWMesh_CafReader : public Standard_Transient
{
DEFINE_STANDARD_RTTIEXT(RWMesh_CafReader, Standard_Transient)
public:
//! Empty constructor.
Standard_EXPORT RWMesh_CafReader();
//! Destructor.
Standard_EXPORT virtual ~RWMesh_CafReader();
//! Return target document.
const Handle(TDocStd_Document)& Document() const { return myXdeDoc; }
//! Set target document.
void SetDocument (const Handle(TDocStd_Document)& theDoc) { myXdeDoc = theDoc; }
//! Return prefix for generating root labels names.
const TCollection_AsciiString& RootPrefix() const { return myRootPrefix; }
//! Set prefix for generating root labels names
void SetRootPrefix (const TCollection_AsciiString& theRootPrefix) { myRootPrefix = theRootPrefix; }
//! Flag indicating if partially read file content should be put into the XDE document, TRUE by default.
//!
//! Partial read means unexpected end of file, critical parsing syntax errors in the middle of file, or reached memory limit
//! indicated by performMesh() returning FALSE.
//! Partial read allows importing a model even in case of formal reading failure,
//! so that it will be up to user to decide if processed data has any value.
//!
//! In case of partial read (performMesh() returns FALSE, but there are some data that could be put into document),
//! Perform() will return TRUE and result flag will have failure bit set.
//! @sa MemoryLimitMiB(), ExtraStatus().
Standard_Boolean ToFillIncompleteDocument() const { return myToFillIncomplete; }
//! Set flag allowing partially read file content to be put into the XDE document.
void SetFillIncompleteDocument (Standard_Boolean theToFillIncomplete) { myToFillIncomplete = theToFillIncomplete; }
//! Return memory usage limit in MiB, -1 by default which means no limit.
Standard_Integer MemoryLimitMiB() const { return myMemoryLimitMiB; }
//! Set memory usage limit in MiB; can be ignored by reader implementation!
void SetMemoryLimitMiB (Standard_Integer theLimitMiB) { myMemoryLimitMiB = theLimitMiB; }
public:
//! Return coordinate system converter.
const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCoordSysConverter; }
//! Set coordinate system converter.
void SetCoordinateSystemConverter (const RWMesh_CoordinateSystemConverter& theConverter) { myCoordSysConverter = theConverter; }
//! Return the length unit to convert into while reading the file, defined as scale factor for m (meters);
//! -1.0 by default, which means that NO conversion will be applied.
Standard_Real SystemLengthUnit() const { return myCoordSysConverter.OutputLengthUnit(); }
//! Set system length units to convert into while reading the file, defined as scale factor for m (meters).
void SetSystemLengthUnit (Standard_Real theUnits) { myCoordSysConverter.SetOutputLengthUnit (theUnits); }
//! Return TRUE if system coordinate system has been defined; FALSE by default.
Standard_Boolean HasSystemCoordinateSystem() const { return myCoordSysConverter.HasOutputCoordinateSystem(); }
//! Return system coordinate system; UNDEFINED by default, which means that no conversion will be done.
const gp_Ax3& SystemCoordinateSystem() const { return myCoordSysConverter.OutputCoordinateSystem(); }
//! Set system origin coordinate system to perform conversion into during read.
void SetSystemCoordinateSystem (const gp_Ax3& theCS) { myCoordSysConverter.SetOutputCoordinateSystem (theCS); }
//! Set system origin coordinate system to perform conversion into during read.
void SetSystemCoordinateSystem (RWMesh_CoordinateSystem theCS) { myCoordSysConverter.SetOutputCoordinateSystem (theCS); }
//! Return the length unit to convert from while reading the file, defined as scale factor for m (meters).
//! Can be undefined (-1.0) if file format is unitless.
Standard_Real FileLengthUnit() const { return myCoordSysConverter.InputLengthUnit(); }
//! Set (override) file length units to convert from while reading the file, defined as scale factor for m (meters).
void SetFileLengthUnit (Standard_Real theUnits) { myCoordSysConverter.SetInputLengthUnit (theUnits); }
//! Return TRUE if file origin coordinate system has been defined.
Standard_Boolean HasFileCoordinateSystem() const { return myCoordSysConverter.HasInputCoordinateSystem(); }
//! Return file origin coordinate system; can be UNDEFINED, which means no conversion will be done.
const gp_Ax3& FileCoordinateSystem() const { return myCoordSysConverter.InputCoordinateSystem(); }
//! Set (override) file origin coordinate system to perform conversion during read.
void SetFileCoordinateSystem (const gp_Ax3& theCS) { myCoordSysConverter.SetInputCoordinateSystem (theCS); }
//! Set (override) file origin coordinate system to perform conversion during read.
void SetFileCoordinateSystem (RWMesh_CoordinateSystem theCS) { myCoordSysConverter.SetInputCoordinateSystem (theCS); }
public:
//! Read the data from specified file.
//! The Document instance should be set beforehand.
bool Perform (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress)
{
return perform (theFile, theProgress, Standard_False);
}
//! Return extended status flags.
//! @sa RWMesh_CafReaderStatusEx enumeration.
Standard_Integer ExtraStatus() const { return myExtraStatus; }
public:
//! Return result as a single shape.
Standard_EXPORT TopoDS_Shape SingleShape() const;
//! Return the list of complementary files - external references (textures, data, etc.).
const NCollection_IndexedMap<TCollection_AsciiString>& ExternalFiles() const { return myExternalFiles; }
//! Return metadata map.
const TColStd_IndexedDataMapOfStringString& Metadata() const { return myMetadata; }
//! 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,
const Handle(Message_ProgressIndicator)& theProgress = Handle(Message_ProgressIndicator)())
{
return perform (theFile, theProgress, Standard_True);
}
protected:
//! Read the data from specified file.
//! Default implementation calls performMesh() and fills XDE document from collected shapes.
//! @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
virtual Standard_Boolean perform (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Boolean theToProbe);
//! Read the mesh from specified file - interface to be implemented by sub-classes.
virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Boolean theToProbe) = 0;
//! @name tools for filling XDE document
protected:
//! Append new shape into the document (recursively).
Standard_EXPORT Standard_Boolean addShapeIntoDoc (const TopoDS_Shape& theShape,
const TDF_Label& theLabel,
const TCollection_AsciiString& theParentName);
//! Generate names for root labels starting from specified index.
Standard_EXPORT void generateNames (const TCollection_AsciiString& theFile,
const Standard_Integer theRootLower,
const Standard_Boolean theWithSubLabels);
//! Return shape type as string.
//! @sa TopAbs::ShapeTypeToString()
static TCollection_AsciiString shapeTypeToString (TopAbs_ShapeEnum theType)
{
TCollection_AsciiString aString = TopAbs::ShapeTypeToString (theType);
aString.Capitalize();
return aString;
}
protected:
Handle(TDocStd_Document) myXdeDoc; //!< target document
TColStd_IndexedDataMapOfStringString
myMetadata; //!< metadata map
NCollection_IndexedMap<TCollection_AsciiString>
myExternalFiles; //!< the list of complementary files - external references (textures, data, etc.)
TCollection_AsciiString myRootPrefix; //!< root folder for generating root labels names
TopTools_SequenceOfShape myRootShapes; //!< sequence of result root shapes
RWMesh_NodeAttributeMap myAttribMap; //!< map of per-shape attributes
RWMesh_CoordinateSystemConverter
myCoordSysConverter; //!< coordinate system converter
Standard_Boolean myToFillDoc; //!< fill document from shape sequence
Standard_Boolean myToFillIncomplete; //!< fill the document with partially retrieved data even if reader has failed with error
Standard_Integer myMemoryLimitMiB; //!< memory usage limit
Standard_Integer myExtraStatus; //!< extra status bitmask
};
#endif // _RWMesh_CafReader_HeaderFile

View File

@@ -0,0 +1,34 @@
// Author: Kirill Gavrilov
// Copyright: Open CASCADE 2015-2019
//
// 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 _RWMesh_CoordinateSystem_HeaderFile
#define _RWMesh_CoordinateSystem_HeaderFile
//! Standard coordinate system definition.
//! Open CASCADE does not force application using specific coordinate system,
//! although Draw Harness and samples define +Z-up +Y-forward coordinate system for camera view manipulation.
//! This enumeration defines two commonly used conventions - Z-up and Y-up..
enum RWMesh_CoordinateSystem
{
RWMesh_CoordinateSystem_Undefined = -1, //!< undefined
RWMesh_CoordinateSystem_posYfwd_posZup = 0, //!< +YForward+Zup+Xright
RWMesh_CoordinateSystem_negZfwd_posYup, //!< -ZForward+Yup+Xright
RWMesh_CoordinateSystem_Blender = RWMesh_CoordinateSystem_posYfwd_posZup, //!< coordinate system used by Blender (+YForward+Zup+Xright)
RWMesh_CoordinateSystem_glTF = RWMesh_CoordinateSystem_negZfwd_posYup, //!< coordinate system used by glTF (-ZForward+Yup+Xright)
RWMesh_CoordinateSystem_Zup = RWMesh_CoordinateSystem_Blender, //!< Z-up coordinate system (+YForward+Zup+Xright)
RWMesh_CoordinateSystem_Yup = RWMesh_CoordinateSystem_glTF, //!< Y-up coordinate system (-ZForward+Yup+Xright)
};
#endif // _RWMesh_CoordinateSystem_HeaderFile

View File

@@ -0,0 +1,77 @@
// Author: Kirill Gavrilov
// Copyright (c) 2015-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 <RWMesh_CoordinateSystemConverter.hxx>
#include <gp_Quaternion.hxx>
// ================================================================
// Function : RWMesh_CoordinateSystemConverter
// Purpose :
// ================================================================
RWMesh_CoordinateSystemConverter::RWMesh_CoordinateSystemConverter()
: myInputLengthUnit (-1.0),
myOutputLengthUnit(-1.0),
myHasInputAx3 (Standard_False),
myHasOutputAx3(Standard_False),
//
myUnitFactor (1),
myHasScale (Standard_False),
myIsEmpty (Standard_True)
{
//
}
// ================================================================
// Function : Init
// Purpose :
// ================================================================
void RWMesh_CoordinateSystemConverter::Init (const gp_Ax3& theInputSystem,
Standard_Real theInputLengthUnit,
const gp_Ax3& theOutputSystem,
Standard_Real theOutputLengthUnit)
{
myInputLengthUnit = theInputLengthUnit;
myOutputLengthUnit = theOutputLengthUnit;
myInputAx3 = theInputSystem;
myOutputAx3 = theOutputSystem;
if (theInputLengthUnit > 0.0
&& theOutputLengthUnit > 0.0)
{
myUnitFactor = theInputLengthUnit / theOutputLengthUnit;
myHasScale = Abs(myUnitFactor - 1.0) > gp::Resolution();
}
else
{
myUnitFactor = 1.0;
myHasScale = Standard_False;
}
gp_Trsf aTrsf;
if (myHasInputAx3
&& myHasOutputAx3)
{
aTrsf.SetTransformation (theOutputSystem, theInputSystem);
if (aTrsf.TranslationPart().IsEqual (gp_XYZ (0.0, 0.0, 0.0), gp::Resolution())
&& aTrsf.GetRotation().IsEqual (gp_Quaternion()))
{
aTrsf = gp_Trsf();
}
}
myTrsf = aTrsf;
myTrsfInv = aTrsf.Inverted();
myTrsf.GetMat4 (myNormTrsf);
myIsEmpty = !myHasScale && myTrsf.Form() == gp_Identity;
}

View File

@@ -0,0 +1,196 @@
// Author: Kirill Gavrilov
// Copyright: Open CASCADE 2015-2019
//
// 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 _RWMesh_CoordinateSystemConverter_HeaderFile
#define _RWMesh_CoordinateSystemConverter_HeaderFile
#include <RWMesh_CoordinateSystem.hxx>
#include <gp.hxx>
#include <gp_Ax3.hxx>
#include <gp_XYZ.hxx>
#include <gp_Trsf.hxx>
#include <Graphic3d_Mat4.hxx>
#include <Graphic3d_Vec.hxx>
//! Coordinate system converter defining the following tools:
//! - Initialization for commonly used coordinate systems Z-up and Y-up.
//! - Perform length unit conversion (scaling).
//! - Conversion of three basic elements:
//! a) mesh node Positions,
//! b) mesh node Normals,
//! c) model nodes Transformations (locations).
//!
//! RWMesh_CoordinateSystem enumeration is used for convenient conversion between two commonly
//! used coordinate systems, to make sure that imported model is oriented up.
//! But gp_Ax3 can be used instead for defining a conversion between arbitrary systems (e.g. including non-zero origin).
//!
//! The converter requires defining explicitly both input and output systems,
//! so that if either input or output is undefined, then conversion will be skipped.
//! Length units conversion and coordinate system conversion are decomposed,
//! so that application might specify no length units conversion but Y-up to Z-up coordinate system conversion.
//!
//! Class defines dedicated methods for parameters of input and output systems.
//! This allows passing tool through several initialization steps,
//! so that a reader can initialize input length units (only if file format defines such information),
//! while application specifies output length units, and conversion will be done only when both defined.
class RWMesh_CoordinateSystemConverter
{
public:
//! Return a standard coordinate system definition.
static gp_Ax3 StandardCoordinateSystem (RWMesh_CoordinateSystem theSys)
{
switch (theSys)
{
case RWMesh_CoordinateSystem_posYfwd_posZup: return gp_Ax3 (gp::Origin(), gp::DZ(), gp::DX());
case RWMesh_CoordinateSystem_negZfwd_posYup: return gp_Ax3 (gp::Origin(), gp::DY(), gp::DX());
case RWMesh_CoordinateSystem_Undefined: break;
}
return gp_Ax3();
}
public:
//! Empty constructor.
Standard_EXPORT RWMesh_CoordinateSystemConverter();
//! Return TRUE if there is no transformation (target and current coordinates systems are same).
Standard_Boolean IsEmpty() const { return myIsEmpty; }
//! Return source length units, defined as scale factor to m (meters).
//! -1.0 by default, which means that NO conversion will be applied (regardless output length unit).
Standard_Real InputLengthUnit() const { return myInputLengthUnit; }
//! Set source length units as scale factor to m (meters).
void SetInputLengthUnit (Standard_Real theInputScale)
{
Init (myInputAx3, theInputScale, myOutputAx3, myOutputLengthUnit);
}
//! Return destination length units, defined as scale factor to m (meters).
//! -1.0 by default, which means that NO conversion will be applied (regardless input length unit).
Standard_Real OutputLengthUnit() const { return myOutputLengthUnit; }
//! Set destination length units as scale factor to m (meters).
void SetOutputLengthUnit (Standard_Real theOutputScale)
{
Init (myInputAx3, myInputLengthUnit, myOutputAx3, theOutputScale);
}
//! Return TRUE if source coordinate system has been set; FALSE by default.
Standard_Boolean HasInputCoordinateSystem() const { return myHasInputAx3; }
//! Source coordinate system; UNDEFINED by default.
const gp_Ax3& InputCoordinateSystem() const { return myInputAx3; }
//! Set source coordinate system.
void SetInputCoordinateSystem (const gp_Ax3& theSysFrom)
{
myHasInputAx3 = Standard_True;
Init (theSysFrom, myInputLengthUnit, myOutputAx3, myOutputLengthUnit);
}
//! Set source coordinate system.
void SetInputCoordinateSystem (RWMesh_CoordinateSystem theSysFrom)
{
myHasInputAx3 = theSysFrom != RWMesh_CoordinateSystem_Undefined;
Init (StandardCoordinateSystem (theSysFrom), myInputLengthUnit, myOutputAx3, myOutputLengthUnit);
}
//! Return TRUE if destination coordinate system has been set; FALSE by default.
Standard_Boolean HasOutputCoordinateSystem() const { return myHasOutputAx3; }
//! Destination coordinate system; UNDEFINED by default.
const gp_Ax3& OutputCoordinateSystem() const { return myOutputAx3; }
//! Set destination coordinate system.
void SetOutputCoordinateSystem (const gp_Ax3& theSysTo)
{
myHasOutputAx3 = Standard_True;
Init (myInputAx3, myInputLengthUnit, theSysTo, myOutputLengthUnit);
}
//! Set destination coordinate system.
void SetOutputCoordinateSystem (RWMesh_CoordinateSystem theSysTo)
{
myHasOutputAx3 = theSysTo != RWMesh_CoordinateSystem_Undefined;
Init (myInputAx3, myInputLengthUnit, StandardCoordinateSystem (theSysTo), myOutputLengthUnit);
}
//! Initialize transformation.
Standard_EXPORT void Init (const gp_Ax3& theInputSystem,
Standard_Real theInputLengthUnit,
const gp_Ax3& theOutputSystem,
Standard_Real theOutputLengthUnit);
public:
//! Transform transformation.
void TransformTransformation (gp_Trsf& theTrsf) const
{
if (myHasScale)
{
gp_XYZ aTransPart = theTrsf.TranslationPart();
aTransPart *= myUnitFactor;
theTrsf.SetTranslationPart (aTransPart);
}
if (myTrsf.Form() != gp_Identity)
{
theTrsf = myTrsf * theTrsf * myTrsfInv;
}
}
//! Transform position.
void TransformPosition (gp_XYZ& thePos) const
{
if (myHasScale)
{
thePos *= myUnitFactor;
}
if (myTrsf.Form() != gp_Identity)
{
myTrsf.Transforms (thePos);
}
}
//! Transform normal (e.g. exclude translation/scale part of transformation).
void TransformNormal (Graphic3d_Vec3& theNorm) const
{
if (myTrsf.Form() != gp_Identity)
{
const Graphic3d_Vec4 aNorm = myNormTrsf * Graphic3d_Vec4 (theNorm, 0.0f);
theNorm = aNorm.xyz();
}
}
private:
gp_Ax3 myInputAx3; //!< source coordinate system
gp_Ax3 myOutputAx3; //!< destination coordinate system
Standard_Real myInputLengthUnit; //!< source length units, defined as scale factor to m (meters); -1.0 by default which means UNDEFINED
Standard_Real myOutputLengthUnit; //!< destination length units, defined as scale factor to m (meters); -1.0 by default which means UNDEFINED
Standard_Boolean myHasInputAx3; //!< flag indicating if source coordinate system is defined or not
Standard_Boolean myHasOutputAx3; //!< flag indicating if destination coordinate system is defined or not
gp_Trsf myTrsf; //!< transformation from input Ax3 to output Ax3
gp_Trsf myTrsfInv; //!< inversed transformation from input Ax3 to output Ax3
Graphic3d_Mat4 myNormTrsf; //!< transformation 4x4 matrix from input Ax3 to output Ax3
Standard_Real myUnitFactor; //!< unit scale factor
Standard_Boolean myHasScale; //!< flag indicating that length unit transformation should be performed
Standard_Boolean myIsEmpty; //!< flag indicating that transformation is empty
};
#endif // _RWMesh_CoordinateSystemConverter_HeaderFile

View File

@@ -0,0 +1,32 @@
// Author: Kirill Gavrilov
// Copyright (c) 2016-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 _RWMesh_NodeAttributes_HeaderFile
#define _RWMesh_NodeAttributes_HeaderFile
#include <NCollection_DataMap.hxx>
#include <TCollection_AsciiString.hxx>
#include <TopTools_ShapeMapHasher.hxx>
#include <XCAFPrs_Style.hxx>
//! Attributes of the node.
struct RWMesh_NodeAttributes
{
TCollection_AsciiString Name; //!< name for the user
TCollection_AsciiString RawName; //!< name within low-level format structure
XCAFPrs_Style Style; //!< presentation style
};
typedef NCollection_DataMap<TopoDS_Shape, RWMesh_NodeAttributes, TopTools_ShapeMapHasher> RWMesh_NodeAttributeMap;
#endif // _RWMesh_NodeAttributes_HeaderFile

View File

@@ -76,6 +76,7 @@ Standard_PExtCharacter.hxx
Standard_PrimitiveTypes.hxx
Standard_ProgramError.hxx
Standard_RangeError.hxx
Standard_ReadBuffer.hxx
Standard_Real.cxx
Standard_Real.hxx
Standard_ShortReal.cxx

View File

@@ -25,18 +25,20 @@
class Standard_OutOfRange;
DEFINE_STANDARD_HANDLE(Standard_OutOfRange, Standard_RangeError)
#if !defined No_Exception && !defined No_Standard_OutOfRange
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
#if (defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
// suppress false-positive warnings produced by GCC optimizer
#define Standard_OutOfRange_Raise_if(CONDITION, MESSAGE) \
#define Standard_OutOfRange_Always_Raise_if(CONDITION, MESSAGE) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wstrict-overflow\"") \
if (CONDITION) throw Standard_OutOfRange(MESSAGE); \
_Pragma("GCC diagnostic pop")
#else
#define Standard_OutOfRange_Raise_if(CONDITION, MESSAGE) \
#define Standard_OutOfRange_Always_Raise_if(CONDITION, MESSAGE) \
if (CONDITION) throw Standard_OutOfRange(MESSAGE);
#endif
#if !defined No_Exception && !defined No_Standard_OutOfRange
#define Standard_OutOfRange_Raise_if(CONDITION, MESSAGE) Standard_OutOfRange_Always_Raise_if(CONDITION, MESSAGE)
#else
#define Standard_OutOfRange_Raise_if(CONDITION, MESSAGE)
#endif

View File

@@ -26,7 +26,7 @@ class Standard_RangeError;
DEFINE_STANDARD_HANDLE(Standard_RangeError, Standard_DomainError)
#if !defined No_Exception && !defined No_Standard_RangeError
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
#if (defined(__GNUC__) && __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
// suppress false-positive warnings produced by GCC optimizer
#define Standard_RangeError_Raise_if(CONDITION, MESSAGE) \
_Pragma("GCC diagnostic push") \

View File

@@ -0,0 +1,145 @@
// Copyright (c) 2017-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 _Standard_ReadBuffer_HeaderFile
#define _Standard_ReadBuffer_HeaderFile
#include <Standard_ProgramError.hxx>
#include <iostream>
//! Auxiliary tool for buffered reading from input stream within chunks of constant size.
class Standard_ReadBuffer
{
public:
//! Constructor with initialization.
Standard_ReadBuffer (int64_t theDataLen,
size_t theChunkLen)
: myBufferPtr(NULL),
myBufferEnd(NULL),
myDataLen (0),
myDataRead (0),
myChunkLen (0),
myNbChunks (0),
myBufferLen(0)
{
Init (theDataLen, theChunkLen);
}
//! Initialize the buffer.
//! @param theDataLen the full length of input data to read from stream.
//! @param theChunkLen the length of single chunk to read
void Init (int64_t theDataLen,
size_t theChunkLen)
{
myDataRead = 0;
myDataLen = theDataLen - theDataLen % int64_t(theChunkLen);
myChunkLen = theChunkLen;
myNbChunks = sizeof(myBuffer) / theChunkLen;
myBufferLen = theChunkLen * myNbChunks;
myBufferEnd = myBuffer + sizeof(myBuffer);
myBufferPtr = myBuffer + sizeof(myBuffer);
memset (myBuffer, 0, sizeof(myBuffer));
if (theChunkLen > sizeof(myBuffer))
{
Standard_ProgramError::Raise ("Internal error - chunk size is greater then preallocated buffer");
}
}
//! Return TRUE if amount of read bytes is equal to requested length of entire data.
bool IsDone() const
{
return myDataRead == myDataLen;
}
//! Read next chunk.
//! @return pointer to the chunk or NULL on error / end of reading buffer
template<typename Chunk_T, typename Stream_T>
Chunk_T* ReadChunk (Stream_T& theStream)
{
return reinterpret_cast<Chunk_T*> (readRawDataChunk (theStream));
}
//! Read next chunk.
//! @return pointer to the chunk or NULL on error / end of reading buffer
template<typename Stream_T>
char* ReadDataChunk (Stream_T& theStream)
{
return readRawDataChunk (theStream);
}
private:
//! Read next chunk.
//! @return pointer to the chunk or NULL on error / end of reading buffer
template<typename Stream_T>
char* readRawDataChunk (Stream_T& theStream)
{
myBufferPtr += myChunkLen;
if (myBufferPtr < myBufferEnd)
{
return myBufferPtr;
}
const int64_t aDataLeft = myDataLen - myDataRead;
if (aDataLeft == 0) // myDataLen should be multiple of myChunkLen
{
myBufferPtr = NULL;
return NULL;
}
const size_t aDataToRead = int64_t(myBufferLen) > aDataLeft ? size_t(aDataLeft) : myBufferLen;
if (!readStream (theStream, aDataToRead))
{
myBufferPtr = NULL;
return NULL;
}
myBufferPtr = myBuffer;
myBufferEnd = myBuffer + aDataToRead;
myDataRead += aDataToRead;
return myBufferPtr;
}
//! Read from stl stream.
bool readStream (std::istream& theStream,
size_t theLen)
{
theStream.read (myBuffer, theLen);
return theStream.good();
}
//! Read from FILE stream.
bool readStream (FILE* theStream,
size_t theLen)
{
return ::fread (myBuffer, 1, theLen, theStream) == theLen;
}
private:
char myBuffer[4096]; //!< data cache
char* myBufferPtr; //!< current position within the buffer
const char* myBufferEnd; //!< end of the buffer
int64_t myDataLen; //!< length of entire data to read
int64_t myDataRead; //!< amount of data already processed
size_t myChunkLen; //!< length of single chunk that caller would like to read (e.g. iterator increment)
size_t myNbChunks; //!< number of cached chunks
size_t myBufferLen; //!< effective length of the buffer to be read at once (multiple of chunk length)
};
#endif // _Standard_ReadBuffer_HeaderFile

View File

@@ -114,9 +114,9 @@ inline Standard_Boolean TCollection_AsciiString::IsEqual(const TCollection_Ascii
inline TCollection_AsciiString TCollection_AsciiString::SubString(const Standard_Integer FromIndex,
const Standard_Integer ToIndex) const
{
if (ToIndex > mylength || FromIndex <= 0 || FromIndex > ToIndex ) throw Standard_OutOfRange();
// note the we are doing here weird casts just to suppress annoying and meaningless warning -Wstrict-overflow
Standard_OutOfRange_Always_Raise_if(FromIndex <= 0 || ToIndex <= 0 || (unsigned int)ToIndex > (unsigned int)mylength || (unsigned int)FromIndex > (unsigned int)ToIndex,
"TCollection_AsciiString::SubString() out of range");
return TCollection_AsciiString( &mystring [ FromIndex - 1 ] ,
ToIndex - FromIndex + 1 ) ;
}

View File

@@ -0,0 +1,3 @@
project(TKRWMesh)
OCCT_INCLUDE_CMAKE_FILE (adm/cmake/occt_toolkit)

9
src/TKRWMesh/EXTERNLIB Normal file
View File

@@ -0,0 +1,9 @@
TKernel
TKMath
TKMesh
TKXCAF
TKLCAF
TKV3d
TKBRep
TKG3d
TKService

2
src/TKRWMesh/FILES Normal file
View File

@@ -0,0 +1,2 @@
EXTERNLIB
PACKAGES

1
src/TKRWMesh/PACKAGES Normal file
View File

@@ -0,0 +1 @@
RWMesh

View File

@@ -19,3 +19,5 @@ TKIGES
TKSTL
TKVRML
TKLCAF
TKDCAF
TKRWMesh

View File

@@ -17,35 +17,64 @@
#ifndef _V3d_TypeOfOrientation_HeaderFile
#define _V3d_TypeOfOrientation_HeaderFile
//! Determines the type of orientation.
//! Determines the type of orientation as a combination of standard DX/DY/DZ directions.
//! This enumeration defines a model orientation looking towards the user's eye, which is an opposition to Camera main direction.
//! For example, V3d_Xneg defines +X Camera main direction.
//!
//! This enumeration defines only main Camera direction, so that the Camera up direction should be defined elsewhere for unambiguous Camera definition.
//! Open CASCADE does not force application using specific coordinate system, although Draw Harness and samples define +Z-up +Y-forward coordinate system for camera view manipulation.
//! Therefore, this enumeration also defines V3d_TypeOfOrientation_Zup_* aliases defining front/back/left/top camera orientations for +Z-up convention
//! as well as V3d_TypeOfOrientation_Yup_* aliases for another commonly used in other systems +Y-up convention.
//! Applications using other coordinate system can define their own enumeration, when found suitable.
enum V3d_TypeOfOrientation
{
V3d_Xpos,
V3d_Ypos,
V3d_Zpos,
V3d_Xneg,
V3d_Yneg,
V3d_Zneg,
V3d_XposYpos,
V3d_XposZpos,
V3d_YposZpos,
V3d_XnegYneg,
V3d_XnegYpos,
V3d_XnegZneg,
V3d_XnegZpos,
V3d_YnegZneg,
V3d_YnegZpos,
V3d_XposYneg,
V3d_XposZneg,
V3d_YposZneg,
V3d_XposYposZpos,
V3d_XposYnegZpos,
V3d_XposYposZneg,
V3d_XnegYposZpos,
V3d_XposYnegZneg,
V3d_XnegYposZneg,
V3d_XnegYnegZpos,
V3d_XnegYnegZneg
V3d_Xpos, //!< (+Y+Z) view
V3d_Ypos, //!< (-X+Z) view
V3d_Zpos, //!< (+X+Y) view
V3d_Xneg, //!< (-Y+Z) view
V3d_Yneg, //!< (+X+Z) view
V3d_Zneg, //!< (+X-Y) view
V3d_XposYpos,
V3d_XposZpos,
V3d_YposZpos,
V3d_XnegYneg,
V3d_XnegYpos,
V3d_XnegZneg,
V3d_XnegZpos,
V3d_YnegZneg,
V3d_YnegZpos,
V3d_XposYneg,
V3d_XposZneg,
V3d_YposZneg,
V3d_XposYposZpos,
V3d_XposYnegZpos,
V3d_XposYposZneg,
V3d_XnegYposZpos,
V3d_XposYnegZneg,
V3d_XnegYposZneg,
V3d_XnegYnegZpos,
V3d_XnegYnegZneg,
// +Z-up +Y-forward convention
V3d_TypeOfOrientation_Zup_AxoLeft = V3d_XnegYnegZpos, //!< +Z-up +Y-forward Left +Front+Top
V3d_TypeOfOrientation_Zup_AxoRight = V3d_XposYnegZpos, //!< +Z-up +Y-forward Right+Front+Top
V3d_TypeOfOrientation_Zup_Front = V3d_Yneg, //!< +Z-up +Y-forward Front (+X+Z) view
V3d_TypeOfOrientation_Zup_Back = V3d_Ypos, //!< +Z-up +Y-forward Back (-X+Z) view
V3d_TypeOfOrientation_Zup_Top = V3d_Zpos, //!< +Z-up +Y-forward Top (+X+Y) view
V3d_TypeOfOrientation_Zup_Bottom = V3d_Zneg, //!< +Z-up +Y-forward Bottom (+X-Y) view
V3d_TypeOfOrientation_Zup_Left = V3d_Xneg, //!< +Z-up +Y-forward Left (-Y+Z) view
V3d_TypeOfOrientation_Zup_Right = V3d_Xpos, //!< +Z-up +Y-forward Right (+Y+Z) view
// +Y-up -Z-forward convention
V3d_TypeOfOrientation_Yup_AxoLeft = V3d_XnegYposZpos, //!< +Y-up -Z-forward Left +Front+Top
V3d_TypeOfOrientation_Yup_AxoRight = V3d_XposYposZpos, //!< +Y-up -Z-forward Right+Front+Top
V3d_TypeOfOrientation_Yup_Front = V3d_Zpos, //!< +Y-up -Z-forward Front (+X+Y) view
V3d_TypeOfOrientation_Yup_Back = V3d_Zneg, //!< +Y-up -Z-forward Back (-X+Y) view
V3d_TypeOfOrientation_Yup_Top = V3d_Ypos, //!< +Y-up -Z-forward Top (+X-Z) view
V3d_TypeOfOrientation_Yup_Bottom = V3d_Yneg, //!< +Y-up -Z-forward Bottom (-X-Z) view
V3d_TypeOfOrientation_Yup_Left = V3d_Xpos, //!< +Y-up -Z-forward Left (-Z+Y) view
V3d_TypeOfOrientation_Yup_Right = V3d_Xneg, //!< +Y-up -Z-forward Right (+Z+Y) view
};
#endif // _V3d_TypeOfOrientation_HeaderFile

View File

@@ -1019,38 +1019,42 @@ void V3d_View::SetProj( const Standard_Real Vx,const Standard_Real Vy, const Sta
//function : SetProj
//purpose :
//=============================================================================
void V3d_View::SetProj( const V3d_TypeOfOrientation Orientation )
void V3d_View::SetProj (const V3d_TypeOfOrientation theOrientation,
const Standard_Boolean theIsYup)
{
Standard_Real Xpn=0;
Standard_Real Ypn=0;
Standard_Real Zpn=0;
switch (Orientation) {
case V3d_Zpos :
Ypn = 1.;
break;
case V3d_Zneg :
Ypn = -1.;
break;
default:
Zpn = 1.;
Graphic3d_Vec3d anUp = theIsYup ? Graphic3d_Vec3d (0.0, 1.0, 0.0) : Graphic3d_Vec3d (0.0, 0.0, 1.0);
if (theIsYup)
{
if (theOrientation == V3d_Ypos
|| theOrientation == V3d_Yneg)
{
anUp.SetValues (0.0, 0.0, -1.0);
}
}
else
{
if (theOrientation == V3d_Zpos)
{
anUp.SetValues (0.0, 1.0, 0.0);
}
else if (theOrientation == V3d_Zneg)
{
anUp.SetValues (0.0, -1.0, 0.0);
}
}
const gp_Dir aBck = V3d::GetProjAxis (Orientation);
const gp_Dir aBck = V3d::GetProjAxis (theOrientation);
// retain camera panning from origin when switching projection
Handle(Graphic3d_Camera) aCamera = Camera();
gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
Standard_Real aPanX = anOriginVCS.X();
Standard_Real aPanY = anOriginVCS.Y();
const Handle(Graphic3d_Camera)& aCamera = Camera();
const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
aCamera->SetCenter (gp_Pnt (0, 0, 0));
aCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed());
aCamera->SetUp (gp_Dir (Xpn, Ypn, Zpn));
aCamera->SetUp (gp_Dir (anUp.x(), anUp.y(), anUp.z()));
aCamera->OrthogonalizeUp();
Panning (aPanX, aPanY);
Panning (anOriginVCS.X(), anOriginVCS.Y());
AutoZFit();

View File

@@ -410,7 +410,10 @@ public:
Standard_EXPORT void SetProj (const Standard_Real Vx, const Standard_Real Vy, const Standard_Real Vz);
//! Defines the orientation of the projection .
Standard_EXPORT void SetProj (const V3d_TypeOfOrientation Orientation);
//! @param theOrientation camera direction
//! @param theIsYup flag indicating Y-up (TRUE) or Z-up (FALSE) convention
Standard_EXPORT void SetProj (const V3d_TypeOfOrientation theOrientation,
const Standard_Boolean theIsYup = Standard_False);
//! Defines the position of the view point.
Standard_EXPORT void SetAt (const Standard_Real X, const Standard_Real Y, const Standard_Real Z);

View File

@@ -3180,99 +3180,309 @@ void ViewerTest::GetMousePosition(Standard_Integer& Xpix,Standard_Integer& Ypix)
}
//==============================================================================
//function : ViewProject: implements VAxo, VTop, VLeft, ...
//purpose : Switches to an axonometric, top, left and other views
//function : VViewProj
//purpose : Switch view projection
//==============================================================================
static int ViewProject(Draw_Interpretor& di, const V3d_TypeOfOrientation ori)
static int VViewProj (Draw_Interpretor& ,
Standard_Integer theNbArgs,
const char** theArgVec)
{
if ( ViewerTest::CurrentView().IsNull() )
static Standard_Boolean isYup = Standard_False;
const Handle(V3d_View)& aView = ViewerTest::CurrentView();
if (aView.IsNull())
{
di<<"Call vinit before this command, please\n";
std::cout << "Error: no active view\n";
return 1;
}
ViewerTest::CurrentView()->SetProj(ori);
TCollection_AsciiString aCmdName (theArgVec[0]);
Standard_Boolean isGeneralCmd = Standard_False;
if (aCmdName == "vfront")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
}
else if (aCmdName == "vback")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
}
else if (aCmdName == "vtop")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
}
else if (aCmdName == "vbottom")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
}
else if (aCmdName == "vleft")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
}
else if (aCmdName == "vright")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
}
else if (aCmdName == "vaxo")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
}
else
{
isGeneralCmd = Standard_True;
for (Standard_Integer anArgIter = 1; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArgCase (theArgVec[anArgIter]);
anArgCase.LowerCase();
if (anArgCase == "-zup")
{
isYup = Standard_False;
}
else if (anArgCase == "-yup")
{
isYup = Standard_True;
}
else if (anArgCase == "-front"
|| anArgCase == "front"
|| anArgCase == "-f"
|| anArgCase == "f")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Front : V3d_TypeOfOrientation_Zup_Front, isYup);
}
else if (anArgCase == "-back"
|| anArgCase == "back"
|| anArgCase == "-b"
|| anArgCase == "b")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Back : V3d_TypeOfOrientation_Zup_Back, isYup);
}
else if (anArgCase == "-top"
|| anArgCase == "top"
|| anArgCase == "-t"
|| anArgCase == "t")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Top : V3d_TypeOfOrientation_Zup_Top, isYup);
}
else if (anArgCase == "-bottom"
|| anArgCase == "bottom"
|| anArgCase == "-bot"
|| anArgCase == "bot"
|| anArgCase == "-b"
|| anArgCase == "b")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Bottom : V3d_TypeOfOrientation_Zup_Bottom, isYup);
}
else if (anArgCase == "-left"
|| anArgCase == "left"
|| anArgCase == "-l"
|| anArgCase == "l")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Left : V3d_TypeOfOrientation_Zup_Left, isYup);
}
else if (anArgCase == "-right"
|| anArgCase == "right"
|| anArgCase == "-r"
|| anArgCase == "r")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_Right : V3d_TypeOfOrientation_Zup_Right, isYup);
}
else if (anArgCase == "-axoleft"
|| anArgCase == "-leftaxo"
|| anArgCase == "axoleft"
|| anArgCase == "leftaxo")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoLeft : V3d_TypeOfOrientation_Zup_AxoLeft, isYup);
}
else if (anArgCase == "-axo"
|| anArgCase == "axo"
|| anArgCase == "-a"
|| anArgCase == "a"
|| anArgCase == "-axoright"
|| anArgCase == "-rightaxo"
|| anArgCase == "axoright"
|| anArgCase == "rightaxo")
{
aView->SetProj (isYup ? V3d_TypeOfOrientation_Yup_AxoRight : V3d_TypeOfOrientation_Zup_AxoRight, isYup);
}
else if (anArgCase == "+x")
{
aView->SetProj (V3d_Xpos, isYup);
}
else if (anArgCase == "-x")
{
aView->SetProj (V3d_Xneg, isYup);
}
else if (anArgCase == "+y")
{
aView->SetProj (V3d_Ypos, isYup);
}
else if (anArgCase == "-y")
{
aView->SetProj (V3d_Yneg, isYup);
}
else if (anArgCase == "+z")
{
aView->SetProj (V3d_Zpos, isYup);
}
else if (anArgCase == "-z")
{
aView->SetProj (V3d_Zneg, isYup);
}
else if (anArgCase == "+x+y+z")
{
aView->SetProj (V3d_XposYposZpos, isYup);
}
else if (anArgCase == "+x+y-z")
{
aView->SetProj (V3d_XposYposZneg, isYup);
}
else if (anArgCase == "+x-y+z")
{
aView->SetProj (V3d_XposYnegZpos, isYup);
}
else if (anArgCase == "+x-y-z")
{
aView->SetProj (V3d_XposYnegZneg, isYup);
}
else if (anArgCase == "-x+y+z")
{
aView->SetProj (V3d_XnegYposZpos, isYup);
}
else if (anArgCase == "-x+y-z")
{
aView->SetProj (V3d_XnegYposZneg, isYup);
}
else if (anArgCase == "-x-y+z")
{
aView->SetProj (V3d_XnegYnegZpos, isYup);
}
else if (anArgCase == "-x-y-z")
{
aView->SetProj (V3d_XnegYnegZneg, isYup);
}
else if (anArgCase == "+x+y")
{
aView->SetProj (V3d_XposYpos, isYup);
}
else if (anArgCase == "+x-y")
{
aView->SetProj (V3d_XposYneg, isYup);
}
else if (anArgCase == "-x+y")
{
aView->SetProj (V3d_XnegYpos, isYup);
}
else if (anArgCase == "-x-y")
{
aView->SetProj (V3d_XnegYneg, isYup);
}
else if (anArgCase == "+x+z")
{
aView->SetProj (V3d_XposZpos, isYup);
}
else if (anArgCase == "+x-z")
{
aView->SetProj (V3d_XposZneg, isYup);
}
else if (anArgCase == "-x+z")
{
aView->SetProj (V3d_XnegZpos, isYup);
}
else if (anArgCase == "-x-z")
{
aView->SetProj (V3d_XnegZneg, isYup);
}
else if (anArgCase == "+y+z")
{
aView->SetProj (V3d_YposZpos, isYup);
}
else if (anArgCase == "+y-z")
{
aView->SetProj (V3d_YposZneg, isYup);
}
else if (anArgCase == "-y+z")
{
aView->SetProj (V3d_YnegZpos, isYup);
}
else if (anArgCase == "-y-z")
{
aView->SetProj (V3d_YnegZneg, isYup);
}
else if (anArgIter + 1 < theNbArgs
&& anArgCase == "-frame"
&& TCollection_AsciiString (theArgVec[anArgIter + 1]).Length() == 4)
{
TCollection_AsciiString aFrameDef (theArgVec[++anArgIter]);
aFrameDef.LowerCase();
gp_Dir aRight, anUp;
if (aFrameDef.Value (2) == aFrameDef.Value (4))
{
std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
return 1;
}
if (aFrameDef.Value (2) == 'x')
{
aRight = aFrameDef.Value (1) == '+' ? gp::DX() : -gp::DX();
}
else if (aFrameDef.Value (2) == 'y')
{
aRight = aFrameDef.Value (1) == '+' ? gp::DY() : -gp::DY();
}
else if (aFrameDef.Value (2) == 'z')
{
aRight = aFrameDef.Value (1) == '+' ? gp::DZ() : -gp::DZ();
}
else
{
std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
return 1;
}
if (aFrameDef.Value (4) == 'x')
{
anUp = aFrameDef.Value (3) == '+' ? gp::DX() : -gp::DX();
}
else if (aFrameDef.Value (4) == 'y')
{
anUp = aFrameDef.Value (3) == '+' ? gp::DY() : -gp::DY();
}
else if (aFrameDef.Value (4) == 'z')
{
anUp = aFrameDef.Value (3) == '+' ? gp::DZ() : -gp::DZ();
}
else
{
std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
return 1;
}
const Handle(Graphic3d_Camera)& aCamera = aView->Camera();
const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin());
const gp_Dir aDir = anUp.Crossed (aRight);
aCamera->SetCenter (gp_Pnt (0, 0, 0));
aCamera->SetDirection (aDir);
aCamera->SetUp (anUp);
aCamera->OrthogonalizeUp();
aView->Panning (anOriginVCS.X(), anOriginVCS.Y());
aView->Update();
}
else
{
std::cout << "Syntax error at '" << theArgVec[anArgIter] << "'\n";
return 1;
}
}
}
if (!isGeneralCmd
&& theNbArgs != 1)
{
std::cout << "Syntax error: wrong number of arguments\n";
return 1;
}
return 0;
}
//==============================================================================
//function : VAxo
//purpose : Switch to an Axonometric view
//Draw arg : No args
//==============================================================================
static int VAxo(Draw_Interpretor& di, Standard_Integer , const char** )
{
return ViewProject(di, V3d_XposYnegZpos);
}
//==============================================================================
//function : VTop
//purpose : Switch to a Top View
//Draw arg : No args
//==============================================================================
static int VTop(Draw_Interpretor& di, Standard_Integer , const char** )
{
return ViewProject(di, V3d_Zpos);
}
//==============================================================================
//function : VBottom
//purpose : Switch to a Bottom View
//Draw arg : No args
//==============================================================================
static int VBottom(Draw_Interpretor& di, Standard_Integer , const char** )
{
return ViewProject(di, V3d_Zneg);
}
//==============================================================================
//function : VLeft
//purpose : Switch to a Left View
//Draw arg : No args
//==============================================================================
static int VLeft(Draw_Interpretor& di, Standard_Integer , const char** )
{
return ViewProject(di, V3d_Xneg);
}
//==============================================================================
//function : VRight
//purpose : Switch to a Right View
//Draw arg : No args
//==============================================================================
static int VRight(Draw_Interpretor& di, Standard_Integer , const char** )
{
return ViewProject(di, V3d_Xpos);
}
//==============================================================================
//function : VFront
//purpose : Switch to a Front View
//Draw arg : No args
//==============================================================================
static int VFront(Draw_Interpretor& di, Standard_Integer , const char** )
{
return ViewProject(di, V3d_Yneg);
}
//==============================================================================
//function : VBack
//purpose : Switch to a Back View
//Draw arg : No args
//==============================================================================
static int VBack(Draw_Interpretor& di, Standard_Integer , const char** )
{
return ViewProject(di, V3d_Ypos);
}
//==============================================================================
//function : VHelp
//purpose : Dsiplay help on viewer Keyboead and mouse commands
@@ -13543,27 +13753,38 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
theCommands.Add("vhelp" ,
"vhelp : display help on the viewer commands",
__FILE__,VHelp,group);
theCommands.Add("vviewproj",
"vviewproj [top|bottom|left|right|front|back|axoLeft|axoRight]"
"\n\t\t: [+-X+-Y+-Z] [-Zup|-Yup] [-frame +-X+-Y]"
"\n\t\t: Setup view direction"
"\n\t\t: -Yup use Y-up convention instead of Zup (which is default)."
"\n\t\t: +-X+-Y+-Z define direction as combination of DX, DY and DZ;"
"\n\t\t: for example '+Z' will show front of the model,"
"\n\t\t: '-X-Y+Z' will define left axonometrical view."
"\n\t\t: -frame define camera Up and Right directions (regardless Up convention);"
"\n\t\t: for example '+X+Z' will show front of the model with Z-up."
__FILE__,VViewProj,group);
theCommands.Add("vtop" ,
"vtop or <T> : Top view. Orientation +X+Y" ,
__FILE__,VTop,group);
__FILE__,VViewProj,group);
theCommands.Add("vbottom" ,
"vbottom : Bottom view. Orientation +X-Y" ,
__FILE__,VBottom,group);
__FILE__,VViewProj,group);
theCommands.Add("vleft" ,
"vleft : Left view. Orientation -Y+Z" ,
__FILE__,VLeft,group);
__FILE__,VViewProj,group);
theCommands.Add("vright" ,
"vright : Right view. Orientation +Y+Z" ,
__FILE__,VRight,group);
__FILE__,VViewProj,group);
theCommands.Add("vaxo" ,
" vaxo or <A> : Axonometric view. Orientation +X-Y+Z",
__FILE__,VAxo,group);
__FILE__,VViewProj,group);
theCommands.Add("vfront" ,
"vfront : Front view. Orientation +X+Z" ,
__FILE__,VFront,group);
__FILE__,VViewProj,group);
theCommands.Add("vback" ,
"vback : Back view. Orientation -X+Z" ,
__FILE__,VBack,group);
__FILE__,VViewProj,group);
theCommands.Add("vpick" ,
"vpick : vpick X Y Z [shape subshape] ( all variables as string )",
VPick,group);

View File

@@ -8,6 +8,10 @@ XCAFPrs_DataMapIteratorOfDataMapOfStyleTransient.hxx
XCAFPrs_IndexedDataMapOfShapeStyle.hxx
XCAFPrs_DataMapOfStyleShape.hxx
XCAFPrs_DataMapOfStyleTransient.hxx
XCAFPrs_DocumentExplorer.cxx
XCAFPrs_DocumentExplorer.hxx
XCAFPrs_DocumentIdIterator.hxx
XCAFPrs_DocumentNode.hxx
XCAFPrs_Driver.cxx
XCAFPrs_Driver.hxx
XCAFPrs_Style.cxx

View File

@@ -0,0 +1,441 @@
// Author: Kirill Gavrilov
// Copyright (c) 2017-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 <XCAFPrs_DocumentExplorer.hxx>
#include <TDF_Tool.hxx>
#include <TDocStd_Document.hxx>
#include <XCAFDoc_ColorTool.hxx>
#include <XCAFDoc_DocumentTool.hxx>
#include <XCAFDoc_ShapeTool.hxx>
#include <XCAFPrs_DocumentIdIterator.hxx>
namespace
{
//! Return merged style for the child node.
static XCAFPrs_Style mergedStyle (const Handle(XCAFDoc_ColorTool)& theColorTool,
const XCAFPrs_Style& theParenStyle,
const TDF_Label& theLabel,
const TDF_Label& theRefLabel)
{
if (theColorTool.IsNull())
{
return theParenStyle;
}
XCAFPrs_Style aStyle = theParenStyle;
Quantity_ColorRGBA aColor;
if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorGen, aColor))
{
aStyle.SetColorCurv (aColor.GetRGB());
aStyle.SetColorSurf (aColor);
}
if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorSurf, aColor))
{
aStyle.SetColorSurf (aColor);
}
if (theColorTool->GetColor (theRefLabel, XCAFDoc_ColorCurv, aColor))
{
aStyle.SetColorCurv (aColor.GetRGB());
}
if (theLabel != theRefLabel)
{
// override Reference style with Instance style when defined (bad model?)
if (theColorTool->GetColor (theLabel, XCAFDoc_ColorGen, aColor))
{
aStyle.SetColorCurv (aColor.GetRGB());
aStyle.SetColorSurf (aColor);
}
if (theColorTool->GetColor (theLabel, XCAFDoc_ColorSurf, aColor))
{
aStyle.SetColorSurf (aColor);
}
if (theColorTool->GetColor (theLabel, XCAFDoc_ColorCurv, aColor))
{
aStyle.SetColorCurv (aColor.GetRGB());
}
}
return aStyle;
}
}
// =======================================================================
// function : DefineChildId
// purpose :
// =======================================================================
TCollection_AsciiString XCAFPrs_DocumentExplorer::DefineChildId (const TDF_Label& theLabel,
const TCollection_AsciiString& theParentId)
{
TCollection_AsciiString anEntryId;
TDF_Tool::Entry (theLabel, anEntryId);
return !theParentId.IsEmpty()
? theParentId + "/" + anEntryId + "."
: anEntryId + ".";
}
// =======================================================================
// function : FindLabelFromPathId
// purpose :
// =======================================================================
TDF_Label XCAFPrs_DocumentExplorer::FindLabelFromPathId (const Handle(TDocStd_Document)& theDocument,
const TCollection_AsciiString& theId,
TopLoc_Location& theParentLocation,
TopLoc_Location& theLocation)
{
theParentLocation = TopLoc_Location();
theLocation = TopLoc_Location();
TDF_Label anInstanceLabel;
for (XCAFPrs_DocumentIdIterator anPathIter (theId); anPathIter.More();)
{
TDF_Label aSubLabel;
{
const TCollection_AsciiString& anOcafId = anPathIter.Value();
TDF_Tool::Label (theDocument->Main().Data(), anOcafId, aSubLabel);
if (aSubLabel.IsNull())
{
return TDF_Label();
}
}
anPathIter.Next();
if (!anPathIter.More())
{
theParentLocation = theLocation;
}
TopLoc_Location aLocTrsf = XCAFDoc_ShapeTool::GetLocation (aSubLabel);
theLocation = theLocation * aLocTrsf;
anInstanceLabel = aSubLabel;
}
return anInstanceLabel;
}
// =======================================================================
// function : FindShapeFromPathId
// purpose :
// =======================================================================
TopoDS_Shape XCAFPrs_DocumentExplorer::FindShapeFromPathId (const Handle(TDocStd_Document)& theDocument,
const TCollection_AsciiString& theId)
{
TopLoc_Location aLocation;
TDF_Label anInstanceLabel = FindLabelFromPathId (theDocument, theId, aLocation);
if (anInstanceLabel.IsNull())
{
return TopoDS_Shape();
}
TDF_Label aRefLabel = anInstanceLabel;
XCAFDoc_ShapeTool::GetReferredShape (anInstanceLabel, aRefLabel);
if (aRefLabel.IsNull())
{
return TopoDS_Shape();
}
TopoDS_Shape aShape = XCAFDoc_ShapeTool::GetShape (aRefLabel);
if (aShape.IsNull())
{
return TopoDS_Shape();
}
aShape.Location (aLocation);
return aShape;
}
// =======================================================================
// function : XCAFPrs_DocumentExplorer
// purpose :
// =======================================================================
XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer()
: myTop (-1),
myHasMore (Standard_False),
myFlags (XCAFPrs_DocumentExplorerFlags_None)
{
//
}
// =======================================================================
// function : XCAFPrs_DocumentExplorer
// purpose :
// =======================================================================
XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
const XCAFPrs_DocumentExplorerFlags theFlags,
const XCAFPrs_Style& theDefStyle)
: myTop (-1),
myHasMore (Standard_False),
myFlags (XCAFPrs_DocumentExplorerFlags_None)
{
Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (theDocument->Main());
TDF_LabelSequence aRootLabels;
aShapeTool->GetFreeShapes (aRootLabels);
Init (theDocument, aRootLabels, theFlags, theDefStyle);
}
// =======================================================================
// function : XCAFPrs_DocumentExplorer
// purpose :
// =======================================================================
XCAFPrs_DocumentExplorer::XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
const TDF_LabelSequence& theRoots,
const XCAFPrs_DocumentExplorerFlags theFlags,
const XCAFPrs_Style& theDefStyle)
: myTop (-1),
myHasMore (Standard_False),
myFlags (XCAFPrs_DocumentExplorerFlags_None)
{
Init (theDocument, theRoots, theFlags, theDefStyle);
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
void XCAFPrs_DocumentExplorer::Init (const Handle(TDocStd_Document)& theDocument,
const TDF_Label& theRoot,
const XCAFPrs_DocumentExplorerFlags theFlags,
const XCAFPrs_Style& theDefStyle)
{
TDF_LabelSequence aSeq;
aSeq.Append (theRoot);
Init (theDocument, aSeq, theFlags, theDefStyle);
}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
void XCAFPrs_DocumentExplorer::Init (const Handle(TDocStd_Document)& theDocument,
const TDF_LabelSequence& theRoots,
const XCAFPrs_DocumentExplorerFlags theFlags,
const XCAFPrs_Style& theDefStyle)
{
if ((theFlags & XCAFPrs_DocumentExplorerFlags_NoStyle) != 0)
{
myColorTool = XCAFDoc_DocumentTool::ColorTool (theDocument->Main());
}
else
{
myColorTool.Nullify();
}
///myColorTool = theColorTool;
myDefStyle = theDefStyle;
myRoots = theRoots;
myRootIter = TDF_LabelSequence::Iterator (myRoots);
myFlags = theFlags;
initRoot();
}
// =======================================================================
// function : initRoot
// purpose :
// =======================================================================
void XCAFPrs_DocumentExplorer::initRoot()
{
for (;;)
{
// reset the stack
for (Standard_Integer aStackIter = 0; aStackIter <= myTop; ++aStackIter)
{
myNodeStack.SetValue (aStackIter, XCAFPrs_DocumentNode());
}
myTop = -1;
if (!myRootIter.More())
{
myHasMore = Standard_False;
initCurrent (Standard_False);
return;
}
const TDF_Label& aRootLab = myRootIter.Value();
if (aRootLab.IsNull())
{
// assert - invalid input
//Standard_ProgramError::Raise ("CadDocumentExplorer - NULL label in the input");
myRootIter.Next();
continue;
}
myHasMore = Standard_True;
TDF_Label aRefLabel = aRootLab;
XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
if (XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
{
Next();
}
else
{
initCurrent (Standard_False);
}
return;
}
}
// =======================================================================
// function : initCurrent
// purpose :
// =======================================================================
void XCAFPrs_DocumentExplorer::initCurrent (Standard_Boolean theIsAssmebly)
{
myCurrent = XCAFPrs_DocumentNode();
if (theIsAssmebly)
{
if (myTop < 0)
{
Standard_ProgramError::Raise ("CadDocumentExplorer - internal error");
}
myCurrent = myNodeStack.Value (myTop);
}
else if (myTop < 0)
{
if (!myRootIter.More())
{
return;
}
myCurrent.Label = myRootIter.Value();
myCurrent.RefLabel = myCurrent.Label;
XCAFDoc_ShapeTool::GetReferredShape (myCurrent.Label, myCurrent.RefLabel);
myCurrent.LocalTrsf= XCAFDoc_ShapeTool::GetLocation (myCurrent.Label);
myCurrent.Location = myCurrent.LocalTrsf;
myCurrent.Style = mergedStyle (myColorTool, myDefStyle, myCurrent.Label, myCurrent.RefLabel);
myCurrent.Id = DefineChildId (myCurrent.Label, TCollection_AsciiString());
}
else
{
const XCAFPrs_DocumentNode& aTopNodeInStack = myNodeStack.Value (myTop);
myCurrent.Label = aTopNodeInStack.ChildIter.Value();
myCurrent.RefLabel = myCurrent.Label;
XCAFDoc_ShapeTool::GetReferredShape (myCurrent.Label, myCurrent.RefLabel);
myCurrent.LocalTrsf= XCAFDoc_ShapeTool::GetLocation (myCurrent.Label);
myCurrent.Location = aTopNodeInStack.Location * myCurrent.LocalTrsf;
myCurrent.Style = mergedStyle (myColorTool, aTopNodeInStack.Style, myCurrent.Label, myCurrent.RefLabel);
myCurrent.Id = DefineChildId (myCurrent.Label, aTopNodeInStack.Id);
}
}
// =======================================================================
// function : Next
// purpose :
// =======================================================================
void XCAFPrs_DocumentExplorer::Next()
{
if (!myHasMore)
{
Standard_ProgramError::Raise ("CadDocumentExplorer::Next() - out of range");
return; // assert
}
if (myTop < 0)
{
const TDF_Label& aRootLab = myRootIter.Value();
TDF_Label aRefLabel = aRootLab;
XCAFDoc_ShapeTool::GetReferredShape (aRootLab, aRefLabel);
if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
{
// already visited once
myRootIter.Next();
initRoot();
return;
}
// push and try to find
myTop = 0;
XCAFPrs_DocumentNode aNodeInStack;
aNodeInStack.IsAssembly = Standard_True;
aNodeInStack.Label = aRootLab;
aNodeInStack.RefLabel = aRefLabel;
aNodeInStack.ChildIter = TDF_ChildIterator (aNodeInStack.RefLabel);
aNodeInStack.LocalTrsf = XCAFDoc_ShapeTool::GetLocation (aNodeInStack.Label);
aNodeInStack.Location = aNodeInStack.LocalTrsf;
aNodeInStack.Style = mergedStyle (myColorTool, myDefStyle, aNodeInStack.Label, aNodeInStack.RefLabel);
aNodeInStack.Id = DefineChildId (aNodeInStack.Label, TCollection_AsciiString());
myNodeStack.SetValue (0, aNodeInStack);
if ((myFlags & XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes) == 0)
{
initCurrent (Standard_True);
return;
}
}
else
{
if (!myCurrent.IsAssembly)
{
myNodeStack.ChangeValue (myTop).ChildIter.Next();
}
}
for (;;)
{
if (myNodeStack.Value (myTop).ChildIter.More())
{
const TDF_Label& aNodeTop = myNodeStack.Value (myTop).ChildIter.Value();
if (aNodeTop.IsNull()
|| (!aNodeTop.HasChild() && !aNodeTop.HasAttribute()))
{
myNodeStack.ChangeValue (myTop).ChildIter.Next();
continue;
}
TDF_Label aRefLabel = aNodeTop;
XCAFDoc_ShapeTool::GetReferredShape (aNodeTop, aRefLabel);
if (!XCAFDoc_ShapeTool::IsAssembly (aRefLabel))
{
myHasMore = Standard_True;
initCurrent (Standard_False);
return;
}
else if (aRefLabel.HasAttribute()
|| aRefLabel.HasChild())
{
const XCAFPrs_DocumentNode& aParent = myNodeStack.Value (myTop);
++myTop;
XCAFPrs_DocumentNode aNodeInStack;
aNodeInStack.IsAssembly = Standard_True;
aNodeInStack.Label = aNodeTop;
aNodeInStack.RefLabel = aRefLabel;
aNodeInStack.LocalTrsf = XCAFDoc_ShapeTool::GetLocation (aNodeInStack.Label);
aNodeInStack.Location = aParent.Location * aNodeInStack.LocalTrsf;
aNodeInStack.Style = mergedStyle (myColorTool, aParent.Style, aNodeInStack.Label, aNodeInStack.RefLabel);
aNodeInStack.Id = DefineChildId (aNodeInStack.Label, aParent.Id);
aNodeInStack.ChildIter = TDF_ChildIterator (aNodeInStack.RefLabel);
myNodeStack.SetValue (myTop, aNodeInStack);
if ((myFlags & XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes) == 0)
{
initCurrent (Standard_True);
return;
}
}
else
{
myNodeStack.ChangeValue (myTop).ChildIter.Next();
}
}
else
{
myNodeStack.SetValue (myTop, XCAFPrs_DocumentNode());
--myTop;
if (myTop < 0)
{
myRootIter.Next();
initRoot();
return;
}
myNodeStack.ChangeValue (myTop).ChildIter.Next();
}
}
}

View File

@@ -0,0 +1,174 @@
// Author: Kirill Gavrilov
// Copyright (c) 2017-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 _XCAFPrs_DocumentExplorer_HeaderFile
#define _XCAFPrs_DocumentExplorer_HeaderFile
#include <NCollection_Vector.hxx>
#include <NCollection_Sequence.hxx>
#include <XCAFPrs_DocumentNode.hxx>
#include <TDF_LabelSequence.hxx>
#include <TopoDS_Shape.hxx>
class TDocStd_Document;
class XCAFDoc_ShapeTool;
class XCAFDoc_ColorTool;
typedef Standard_Integer XCAFPrs_DocumentExplorerFlags;
//! Document explorer flags.
enum
{
XCAFPrs_DocumentExplorerFlags_None = 0x00, //!< no flags
XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes = 0x01, //!< explore only leaf nodes (skip assembly nodes)
XCAFPrs_DocumentExplorerFlags_NoStyle = 0x02, //!< do not fetch styles
};
//! Document iterator through shape nodes.
class XCAFPrs_DocumentExplorer
{
public: //! @name string identification tools
//! Construct a unique string identifier for the given label.
//! The identifier is a concatenation of label entries (TDF_Tool::Entry() with tailing '.') of hierarchy from parent to child
//! joined via '/' and looking like this:
//! @code
//! 0:1:1:1./0:1:1:1:9./0:1:1:5:7.
//! @endcode
//! This generation scheme also allows finding originating labels using TDF_Tool::Label().
//! The tailing dot simplifies parent equality check.
//! @param theLabel child label to define id
//! @param theParentId parent string identifier defined by this method
Standard_EXPORT static TCollection_AsciiString DefineChildId (const TDF_Label& theLabel,
const TCollection_AsciiString& theParentId);
//! Find a shape entity based on a text identifier constructed from OCAF labels defining full path.
//! @sa DefineChildId()
Standard_EXPORT static TDF_Label FindLabelFromPathId (const Handle(TDocStd_Document)& theDocument,
const TCollection_AsciiString& theId,
TopLoc_Location& theParentLocation,
TopLoc_Location& theLocation);
//! Find a shape entity based on a text identifier constructed from OCAF labels defining full path.
//! @sa DefineChildId()
static TDF_Label FindLabelFromPathId (const Handle(TDocStd_Document)& theDocument,
const TCollection_AsciiString& theId,
TopLoc_Location& theLocation)
{
TopLoc_Location aDummy;
return FindLabelFromPathId (theDocument, theId, aDummy, theLocation);
}
//! Find a shape entity based on a text identifier constructed from OCAF labels defining full path.
//! @sa DefineChildId()
Standard_EXPORT static TopoDS_Shape FindShapeFromPathId (const Handle(TDocStd_Document)& theDocument,
const TCollection_AsciiString& theId);
public:
//! Empty constructor.
Standard_EXPORT XCAFPrs_DocumentExplorer();
//! Constructor for exploring the whole document.
//! @param theDocument document to explore
//! @param theFlags iteration flags
//! @param theDefStyle default style for nodes with undefined style
Standard_EXPORT XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
const XCAFPrs_DocumentExplorerFlags theFlags,
const XCAFPrs_Style& theDefStyle = XCAFPrs_Style());
//! Constructor for exploring specified list of root shapes in the document.
//! @param theDocument document to explore
//! @param theRoots root labels to explore within specified document
//! @param theFlags iteration flags
//! @param theDefStyle default style for nodes with undefined style
Standard_EXPORT XCAFPrs_DocumentExplorer (const Handle(TDocStd_Document)& theDocument,
const TDF_LabelSequence& theRoots,
const XCAFPrs_DocumentExplorerFlags theFlags,
const XCAFPrs_Style& theDefStyle = XCAFPrs_Style());
//! Initialize the iterator from a single root shape in the document.
//! @param theDocument document to explore
//! @param theRoot single root label to explore within specified document
//! @param theFlags iteration flags
//! @param theDefStyle default style for nodes with undefined style
Standard_EXPORT void Init (const Handle(TDocStd_Document)& theDocument,
const TDF_Label& theRoot,
const XCAFPrs_DocumentExplorerFlags theFlags,
const XCAFPrs_Style& theDefStyle = XCAFPrs_Style());
//! Initialize the iterator from the list of root shapes in the document.
//! @param theDocument document to explore
//! @param theRoots root labels to explore within specified document
//! @param theFlags iteration flags
//! @param theDefStyle default style for nodes with undefined style
Standard_EXPORT void Init (const Handle(TDocStd_Document)& theDocument,
const TDF_LabelSequence& theRoots,
const XCAFPrs_DocumentExplorerFlags theFlags,
const XCAFPrs_Style& theDefStyle = XCAFPrs_Style());
//! Return TRUE if iterator points to the valid node.
Standard_Boolean More() const { return myHasMore; }
//! Return current position.
const XCAFPrs_DocumentNode& Current() const { return myCurrent; }
//! Return current position.
XCAFPrs_DocumentNode& ChangeCurrent() { return myCurrent; }
//! Return current position within specified assembly depth.
const XCAFPrs_DocumentNode& Current (Standard_Integer theDepth) const
{
const Standard_Integer aCurrDepth = CurrentDepth();
if (theDepth == aCurrDepth)
{
return myCurrent;
}
Standard_OutOfRange_Raise_if (theDepth < 0 || theDepth > myTop,
"XCAFPrs_DocumentExplorer::Current() out of range");
return myNodeStack.Value (theDepth);
}
//! Return depth of the current node in hierarchy, starting from 0.
//! Zero means Root label.
Standard_Integer CurrentDepth() const { return myCurrent.IsAssembly ? myTop : myTop + 1; }
//! Go to the next node.
Standard_EXPORT void Next();
protected:
//! Initialize root label.
Standard_EXPORT void initRoot();
//! Initialize properties for a current label.
Standard_EXPORT void initCurrent (Standard_Boolean theIsAssmebly);
protected:
Handle(XCAFDoc_ColorTool) myColorTool; //!< color tool
TDF_LabelSequence myRoots; //!< sequence of root labels
TDF_LabelSequence::Iterator myRootIter; //!< current root label
NCollection_Vector<XCAFPrs_DocumentNode>
myNodeStack; //!< node stack
Standard_Integer myTop; //!< top position in the node stack
Standard_Boolean myHasMore; //!< global flag indicating that iterator points to the label
XCAFPrs_Style myDefStyle; //!< default style
XCAFPrs_DocumentNode myCurrent; //!< current label info
XCAFPrs_DocumentExplorerFlags myFlags; //!< iteration flags
};
#endif // _XCAFPrs_DocumentExplorer_HeaderFile

View File

@@ -0,0 +1,90 @@
// Author: Kirill Gavrilov
// Copyright (c) 2017-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 _XCAFPrs_DocumentIdIterator_HeaderFile
#define _XCAFPrs_DocumentIdIterator_HeaderFile
#include <XCAFPrs_Style.hxx>
#include <TDF_ChildIterator.hxx>
#include <TDF_Label.hxx>
#include <TopLoc_Location.hxx>
//! Auxiliary tool for iterating through Path identification string.
class XCAFPrs_DocumentIdIterator
{
public:
//! Main constructor.
XCAFPrs_DocumentIdIterator (const TCollection_AsciiString& thePath)
: myPath (thePath), myPosition (0)
{
Next();
}
//! Return TRUE if iterator points to a value.
bool More() const { return !mySubId.IsEmpty(); }
//! Return current value.
const TCollection_AsciiString& Value() const { return mySubId; }
//! Find the next value.
void Next();
private:
// Disable assignment operator.
XCAFPrs_DocumentIdIterator& operator= (const XCAFPrs_DocumentIdIterator& );
private:
const TCollection_AsciiString& myPath; //!< full path
TCollection_AsciiString mySubId; //!< current value
Standard_Integer myPosition; //!< last processed new-line symbol
};
// =======================================================================
// function : Next
// purpose :
// =======================================================================
inline void XCAFPrs_DocumentIdIterator::Next()
{
for (Standard_Integer aCharIndex = myPosition + 1; aCharIndex <= myPath.Length(); ++aCharIndex)
{
if (myPath.Value (aCharIndex) == '/')
{
// intermediate items have trailing dot and separator before the next item
const Standard_Integer aLen = aCharIndex - myPosition - 2;
if (aLen < 1)
{
return; // assert - should never happen for valid IDs!
}
mySubId = myPath.SubString (myPosition + 1, aCharIndex - 2);
myPosition = aCharIndex;
return;
}
}
if (myPosition < myPath.Length())
{
// last item has only trailing dot
mySubId = myPath.SubString (myPosition + 1, myPath.Length() - 1);
myPosition = myPath.Length();
}
else
{
mySubId.Clear();
myPosition = myPath.Length();
}
}
#endif // _XCAFPrs_DocumentIdIterator_HeaderFile

View File

@@ -0,0 +1,39 @@
// Author: Kirill Gavrilov
// Copyright (c) 2017-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 _XCAFPrs_DocumentNode_HeaderFile
#define _XCAFPrs_DocumentNode_HeaderFile
#include <XCAFPrs_Style.hxx>
#include <TDF_ChildIterator.hxx>
#include <TDF_Label.hxx>
#include <TopLoc_Location.hxx>
//! Structure defining document node.
struct XCAFPrs_DocumentNode
{
TCollection_AsciiString Id; //!< string identifier
TDF_Label Label; //!< label in the document
TDF_Label RefLabel; //!< reference label in the document
XCAFPrs_Style Style; //!< node style
TopLoc_Location Location; //!< node global transformation
TopLoc_Location LocalTrsf; //!< node transformation relative to parent
TDF_ChildIterator ChildIter; //!< child iterator
Standard_Boolean IsAssembly; //!< flag indicating that this label is assembly
XCAFPrs_DocumentNode() : IsAssembly (Standard_False) {}
};
#endif // _XCAFPrs_DocumentNode_HeaderFile