// Copyright (c) 2021 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_TriangulationReader_HeaderFile #define _RWMesh_TriangulationReader_HeaderFile #include #include #include class OSD_FileSystem; class RWMesh_TriangulationSource; //! Interface for reading primitive array from the buffer. class RWMesh_TriangulationReader : public Standard_Transient { DEFINE_STANDARD_RTTIEXT(RWMesh_TriangulationReader, Standard_Transient) public: struct LoadingStatistic { LoadingStatistic() : ExpectedNodesNb(0), LoadedNodesNb(0), ExpectedTrianglesNb(0), DegeneratedTrianglesNb(0), LoadedTrianglesNb(0) {} void Reset() { ExpectedNodesNb = 0; LoadedNodesNb = 0; ExpectedTrianglesNb = 0; DegeneratedTrianglesNb = 0; LoadedTrianglesNb = 0; } Standard_EXPORT void PrintStatistic (const TCollection_AsciiString& thePrefix = "") const; Standard_Integer ExpectedNodesNb; Standard_Integer LoadedNodesNb; Standard_Integer ExpectedTrianglesNb; Standard_Integer DegeneratedTrianglesNb; Standard_Integer LoadedTrianglesNb; }; //! Constructor. Standard_EXPORT RWMesh_TriangulationReader(); //! Destructor. Standard_EXPORT virtual ~RWMesh_TriangulationReader(); //! Returns file name for reporting issues. const TCollection_AsciiString& FileName() const { return myFileName; } //! Sets file name for reporting issues. void SetFileName(const TCollection_AsciiString& theFileName) { myFileName = theFileName; } //! Returns coordinate system converter using for correct data loading. const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCoordSysConverter; } //! Sets coordinate system converter. void SetCoordinateSystemConverter (const RWMesh_CoordinateSystemConverter& theConverter) { myCoordSysConverter = theConverter; } //! Returns flag to fill in triangulation using double or single precision; FALSE by default. bool IsDoublePrecision() const { return myIsDoublePrecision; } //! Sets flag to fill in triangulation using double or single precision. void SetDoublePrecision (bool theIsDouble) { myIsDoublePrecision = theIsDouble; } //! Returns TRUE if degenerated triangles should be skipped during mesh loading (only indexes will be checked). Standard_Boolean ToSkipDegenerates() const { return myToSkipDegenerateTris; } //! Sets flag to skip degenerated triangles during mesh loading (only indexes will be checked). void SetToSkipDegenerates (const Standard_Boolean theToSkip) { myToSkipDegenerateTris = theToSkip; } //! Returns TRUE if additional debug information should be print. Standard_Boolean ToPrintDebugMessages() const { return myToPrintDebugMessages; } //! Sets flag to print debug information. void SetToPrintDebugMessages (const Standard_Boolean theToPrint) { myToPrintDebugMessages = theToPrint; } //! Starts and reset internal object that accumulates nodes/triangles statistic during data reading. void StartStatistic() { if (myLoadingStatistic) { myLoadingStatistic->Reset(); } else { myLoadingStatistic = new LoadingStatistic(); } } //! Stops and nullify internal object that accumulates nodes/triangles statistic during data reading. void StopStatistic() { if (myLoadingStatistic) { delete myLoadingStatistic; myLoadingStatistic = NULL; } } //! Prints loading statistic. //! This method should be used between StartStatistic() and StopStatistic() calls //! for correct results. void PrintStatistic() const { if (myLoadingStatistic) { myLoadingStatistic->PrintStatistic (TCollection_AsciiString("[Mesh reader. File '") + myFileName + "']. "); } } //! Loads primitive array. Standard_EXPORT bool Load (const Handle(RWMesh_TriangulationSource)& theSourceMesh, const Handle(Poly_Triangulation)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const; protected: //! Loads primitive array. Standard_EXPORT virtual bool load (const Handle(RWMesh_TriangulationSource)& theSourceMesh, const Handle(Poly_Triangulation)& theDestMesh, const Handle(OSD_FileSystem)& theFileSystem) const = 0; //! Performs additional actions to finalize data loading. Standard_EXPORT virtual bool finalizeLoading (const Handle(RWMesh_TriangulationSource)& theSourceMesh, const Handle(Poly_Triangulation)& theDestMesh) const; protected: //! @name interface for filling triangulation data //! Resizes array of position nodes to specified size. //! @param theMesh [in] triangulation to be modified //! @param theNbNodes [in] nodes number //! @param theToCopyData [in] copy old nodes into new array //! @return TRUE in case of success operation virtual bool setNbPositionNodes (const Handle(Poly_Triangulation)& theMesh, Standard_Integer theNbNodes, Standard_Boolean theToCopyData = false) const { if (theNbNodes <= 0) { return false; } theMesh->ResizeNodes (theNbNodes, theToCopyData); return true; } //! Sets node position. //! @param theMesh [in] triangulation to be modified //! @param theIndex [in] node index starting from 1 //! @param thePnt [in] node position virtual void setNodePosition (const Handle(Poly_Triangulation)& theMesh, Standard_Integer theIndex, const gp_Pnt& thePnt) const { theMesh->SetNode (theIndex, thePnt); } //! Resizes array of UV nodes to specified size. //! @param theMesh [in] triangulation to be modified //! @param theNbNodes [in] nodes number //! @return TRUE in case of success operation virtual bool setNbUVNodes (const Handle(Poly_Triangulation)& theMesh, Standard_Integer theNbNodes) const { if (theNbNodes <= 0 || theMesh->NbNodes() != theNbNodes) { return false; } theMesh->AddUVNodes(); return true; } //! Sets node UV texture coordinates. //! @param theMesh [in] triangulation to be modified //! @param theIndex [in] node index starting from 1 //! @param theUV [in] node UV coordinates virtual void setNodeUV (const Handle(Poly_Triangulation)& theMesh, Standard_Integer theIndex, const gp_Pnt2d& theUV) const { theMesh->SetUVNode (theIndex, theUV); } //! Resizes array of nodes normals to specified size. //! @param theMesh [in] triangulation to be modified //! @param theNbNodes [in] nodes number //! @return TRUE in case of success operation virtual bool setNbNormalNodes (const Handle(Poly_Triangulation)& theMesh, Standard_Integer theNbNodes) const { if (theNbNodes <= 0 || theMesh->NbNodes() != theNbNodes) { return false; } theMesh->AddNormals(); return true; } //! Sets node normal. //! @param theMesh [in] triangulation to be modified //! @param theIndex node index starting from 1 //! @param theNormal node normal vector virtual void setNodeNormal (const Handle(Poly_Triangulation)& theMesh, Standard_Integer theIndex, const gp_Vec3f& theNormal) const { theMesh->SetNormal (theIndex, theNormal); } //! Resizes array of triangles to specified size. //! @param theMesh [in] triangulation to be modified //! @param theNbTris [in] elements number //! @param theToCopyData [in] copy old triangles into new array //! @return TRUE in case of success operation virtual bool setNbTriangles (const Handle(Poly_Triangulation)& theMesh, Standard_Integer theNbTris, Standard_Boolean theToCopyData = false) const { if (theNbTris >= 1) { theMesh->ResizeTriangles (theNbTris, theToCopyData); return true; } return false; } //! Adds triangle element. //! @param theMesh [in] triangulation to be modified //! @param theIndex triangle index starting from 1 //! @param theTriangle triangle nodes starting from 1 //! @return 0 if node indexes are out of range, //! -1 if triangle is degenerated and should be skipped, //! 1 in case of success operation. virtual Standard_Integer setTriangle (const Handle(Poly_Triangulation)& theMesh, Standard_Integer theIndex, const Poly_Triangle& theTriangle) const { if (theTriangle.Value (1) < 1 || theTriangle.Value (1) > theMesh->NbNodes() || theTriangle.Value (2) < 1 || theTriangle.Value (2) > theMesh->NbNodes() || theTriangle.Value (3) < 1 || theTriangle.Value (3) > theMesh->NbNodes()) { return 0; } if (myToSkipDegenerateTris && (theTriangle.Value (1) == theTriangle.Value (2) || theTriangle.Value (1) == theTriangle.Value (3) || theTriangle.Value (2) == theTriangle.Value (3))) { return -1; } theMesh->SetTriangle (theIndex, theTriangle); return 1; } protected: RWMesh_CoordinateSystemConverter myCoordSysConverter; //!< coordinate system converter TCollection_AsciiString myFileName; //!< file name to use during message printing mutable Standard_Mutex myMutex; //!< internal mutex to collect nodes/triangles statistic mutable LoadingStatistic* myLoadingStatistic; //!< statistic of loaded triangulation Standard_Boolean myIsDoublePrecision; //!< flag to fill in triangulation using single or double precision Standard_Boolean myToSkipDegenerateTris; //!< flag to skip degenerate triangles during loading, FALSE by default Standard_Boolean myToPrintDebugMessages; //!< flag to print additional debug information }; #endif // _RWMesh_TriangulationReader_HeaderFile