Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-16 09:18:24

0001 // Copyright (c) 2021 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef _RWMesh_TriangulationReader_HeaderFile
0015 #define _RWMesh_TriangulationReader_HeaderFile
0016 
0017 #include <Poly_Triangulation.hxx>
0018 #include <RWMesh_CoordinateSystemConverter.hxx>
0019 
0020 #include <mutex>
0021 
0022 class OSD_FileSystem;
0023 class RWMesh_TriangulationSource;
0024 
0025 //! Interface for reading primitive array from the buffer.
0026 class RWMesh_TriangulationReader : public Standard_Transient
0027 {
0028   DEFINE_STANDARD_RTTIEXT(RWMesh_TriangulationReader, Standard_Transient)
0029 public:
0030   struct LoadingStatistic
0031   {
0032     LoadingStatistic()
0033         : ExpectedNodesNb(0),
0034           LoadedNodesNb(0),
0035           ExpectedTrianglesNb(0),
0036           DegeneratedTrianglesNb(0),
0037           LoadedTrianglesNb(0)
0038     {
0039     }
0040 
0041     void Reset()
0042     {
0043       ExpectedNodesNb        = 0;
0044       LoadedNodesNb          = 0;
0045       ExpectedTrianglesNb    = 0;
0046       DegeneratedTrianglesNb = 0;
0047       LoadedTrianglesNb      = 0;
0048     }
0049 
0050     Standard_EXPORT void PrintStatistic(const TCollection_AsciiString& thePrefix = "") const;
0051 
0052     int ExpectedNodesNb;
0053     int LoadedNodesNb;
0054     int ExpectedTrianglesNb;
0055     int DegeneratedTrianglesNb;
0056     int LoadedTrianglesNb;
0057   };
0058 
0059   //! Constructor.
0060   Standard_EXPORT RWMesh_TriangulationReader();
0061 
0062   //! Destructor.
0063   Standard_EXPORT ~RWMesh_TriangulationReader() override;
0064 
0065   //! Returns file name for reporting issues.
0066   const TCollection_AsciiString& FileName() const { return myFileName; }
0067 
0068   //! Sets file name for reporting issues.
0069   void SetFileName(const TCollection_AsciiString& theFileName) { myFileName = theFileName; }
0070 
0071   //! Returns coordinate system converter using for correct data loading.
0072   const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const
0073   {
0074     return myCoordSysConverter;
0075   }
0076 
0077   //! Sets coordinate system converter.
0078   void SetCoordinateSystemConverter(const RWMesh_CoordinateSystemConverter& theConverter)
0079   {
0080     myCoordSysConverter = theConverter;
0081   }
0082 
0083   //! Returns flag to fill in triangulation using double or single precision; FALSE by default.
0084   bool IsDoublePrecision() const { return myIsDoublePrecision; }
0085 
0086   //! Sets flag to fill in triangulation using double or single precision.
0087   void SetDoublePrecision(bool theIsDouble) { myIsDoublePrecision = theIsDouble; }
0088 
0089   //! Returns TRUE if degenerated triangles should be skipped during mesh loading (only indexes will
0090   //! be checked).
0091   bool ToSkipDegenerates() const { return myToSkipDegenerateTris; }
0092 
0093   //! Sets flag to skip degenerated triangles during mesh loading (only indexes will be checked).
0094   void SetToSkipDegenerates(const bool theToSkip) { myToSkipDegenerateTris = theToSkip; }
0095 
0096   //! Returns TRUE if additional debug information should be print.
0097   bool ToPrintDebugMessages() const { return myToPrintDebugMessages; }
0098 
0099   //! Sets flag to print debug information.
0100   void SetToPrintDebugMessages(const bool theToPrint) { myToPrintDebugMessages = theToPrint; }
0101 
0102   //! Starts and reset internal object that accumulates nodes/triangles statistic during data
0103   //! reading.
0104   void StartStatistic()
0105   {
0106     if (myLoadingStatistic)
0107     {
0108       myLoadingStatistic->Reset();
0109     }
0110     else
0111     {
0112       myLoadingStatistic = new LoadingStatistic();
0113     }
0114   }
0115 
0116   //! Stops and nullify internal object that accumulates nodes/triangles statistic during data
0117   //! reading.
0118   void StopStatistic()
0119   {
0120     if (myLoadingStatistic)
0121     {
0122       delete myLoadingStatistic;
0123       myLoadingStatistic = nullptr;
0124     }
0125   }
0126 
0127   //! Prints loading statistic.
0128   //! This method should be used between StartStatistic() and StopStatistic() calls
0129   //! for correct results.
0130   void PrintStatistic() const
0131   {
0132     if (myLoadingStatistic)
0133     {
0134       myLoadingStatistic->PrintStatistic(TCollection_AsciiString("[Mesh reader. File '")
0135                                          + myFileName + "']. ");
0136     }
0137   }
0138 
0139   //! Loads primitive array.
0140   Standard_EXPORT bool Load(const occ::handle<RWMesh_TriangulationSource>& theSourceMesh,
0141                             const occ::handle<Poly_Triangulation>&         theDestMesh,
0142                             const occ::handle<OSD_FileSystem>&             theFileSystem) const;
0143 
0144 protected:
0145   //! Loads primitive array.
0146   Standard_EXPORT virtual bool load(const occ::handle<RWMesh_TriangulationSource>& theSourceMesh,
0147                                     const occ::handle<Poly_Triangulation>&         theDestMesh,
0148                                     const occ::handle<OSD_FileSystem>& theFileSystem) const = 0;
0149 
0150   //! Performs additional actions to finalize data loading.
0151   Standard_EXPORT virtual bool finalizeLoading(
0152     const occ::handle<RWMesh_TriangulationSource>& theSourceMesh,
0153     const occ::handle<Poly_Triangulation>&         theDestMesh) const;
0154 
0155 protected: //! @name interface for filling triangulation data
0156   //! Resizes array of position nodes to specified size.
0157   //! @param[in] theMesh  triangulation to be modified
0158   //! @param[in] theNbNodes  nodes number
0159   //! @param[in] theToCopyData  copy old nodes into new array
0160   //! @return TRUE in case of success operation
0161   virtual bool setNbPositionNodes(const occ::handle<Poly_Triangulation>& theMesh,
0162                                   int                                    theNbNodes,
0163                                   bool theToCopyData = false) const
0164   {
0165     if (theNbNodes <= 0)
0166     {
0167       return false;
0168     }
0169     theMesh->ResizeNodes(theNbNodes, theToCopyData);
0170     return true;
0171   }
0172 
0173   //! Sets node position.
0174   //! @param[in] theMesh  triangulation to be modified
0175   //! @param[in] theIndex  node index starting from 1
0176   //! @param[in] thePnt  node position
0177   virtual void setNodePosition(const occ::handle<Poly_Triangulation>& theMesh,
0178                                int                                    theIndex,
0179                                const gp_Pnt&                          thePnt) const
0180   {
0181     theMesh->SetNode(theIndex, thePnt);
0182   }
0183 
0184   //! Resizes array of UV nodes to specified size.
0185   //! @param[in] theMesh  triangulation to be modified
0186   //! @param[in] theNbNodes  nodes number
0187   //! @return TRUE in case of success operation
0188   virtual bool setNbUVNodes(const occ::handle<Poly_Triangulation>& theMesh, int theNbNodes) const
0189   {
0190     if (theNbNodes <= 0 || theMesh->NbNodes() != theNbNodes)
0191     {
0192       return false;
0193     }
0194     theMesh->AddUVNodes();
0195     return true;
0196   }
0197 
0198   //! Sets node UV texture coordinates.
0199   //! @param[in] theMesh  triangulation to be modified
0200   //! @param[in] theIndex  node index starting from 1
0201   //! @param[in] theUV  node UV coordinates
0202   virtual void setNodeUV(const occ::handle<Poly_Triangulation>& theMesh,
0203                          int                                    theIndex,
0204                          const gp_Pnt2d&                        theUV) const
0205   {
0206     theMesh->SetUVNode(theIndex, theUV);
0207   }
0208 
0209   //! Resizes array of nodes normals to specified size.
0210   //! @param[in] theMesh  triangulation to be modified
0211   //! @param[in] theNbNodes  nodes number
0212   //! @return TRUE in case of success operation
0213   virtual bool setNbNormalNodes(const occ::handle<Poly_Triangulation>& theMesh,
0214                                 int                                    theNbNodes) const
0215   {
0216     if (theNbNodes <= 0 || theMesh->NbNodes() != theNbNodes)
0217     {
0218       return false;
0219     }
0220     theMesh->AddNormals();
0221     return true;
0222   }
0223 
0224   //! Sets node normal.
0225   //! @param[in] theMesh  triangulation to be modified
0226   //! @param theIndex  node index starting from 1
0227   //! @param theNormal node normal vector
0228   virtual void setNodeNormal(const occ::handle<Poly_Triangulation>& theMesh,
0229                              int                                    theIndex,
0230                              const NCollection_Vec3<float>&         theNormal) const
0231   {
0232     theMesh->SetNormal(theIndex, theNormal);
0233   }
0234 
0235   //! Resizes array of triangles to specified size.
0236   //! @param[in] theMesh  triangulation to be modified
0237   //! @param[in] theNbTris  elements number
0238   //! @param[in] theToCopyData  copy old triangles into new array
0239   //! @return TRUE in case of success operation
0240   virtual bool setNbTriangles(const occ::handle<Poly_Triangulation>& theMesh,
0241                               int                                    theNbTris,
0242                               bool                                   theToCopyData = false) const
0243   {
0244     if (theNbTris >= 1)
0245     {
0246       theMesh->ResizeTriangles(theNbTris, theToCopyData);
0247       return true;
0248     }
0249     return false;
0250   }
0251 
0252   //! Adds triangle element.
0253   //! @param[in] theMesh  triangulation to be modified
0254   //! @param theIndex    triangle index starting from 1
0255   //! @param theTriangle triangle nodes starting from 1
0256   //! @return 0 if node indexes are out of range,
0257   //!        -1 if triangle is degenerated and should be skipped,
0258   //!         1 in case of success operation.
0259   virtual int setTriangle(const occ::handle<Poly_Triangulation>& theMesh,
0260                           int                                    theIndex,
0261                           const Poly_Triangle&                   theTriangle) const
0262   {
0263     if (theTriangle.Value(1) < 1 || theTriangle.Value(1) > theMesh->NbNodes()
0264         || theTriangle.Value(2) < 1 || theTriangle.Value(2) > theMesh->NbNodes()
0265         || theTriangle.Value(3) < 1 || theTriangle.Value(3) > theMesh->NbNodes())
0266     {
0267       return 0;
0268     }
0269     if (myToSkipDegenerateTris
0270         && (theTriangle.Value(1) == theTriangle.Value(2)
0271             || theTriangle.Value(1) == theTriangle.Value(3)
0272             || theTriangle.Value(2) == theTriangle.Value(3)))
0273     {
0274       return -1;
0275     }
0276     theMesh->SetTriangle(theIndex, theTriangle);
0277     return 1;
0278   }
0279 
0280   //! Resizes array of edges to specified size.
0281   //! @param[in] theMesh  triangulation source to be modified
0282   //! @param[in] theNbEdges  elements number
0283   //! @param[in] theToCopyData  copy old edges into new array
0284   //! @return TRUE in case of success operation
0285   Standard_EXPORT virtual bool setNbEdges(const occ::handle<Poly_Triangulation>& theMesh,
0286                                           const int                              theNbEdges,
0287                                           const bool theToCopyData = false) const;
0288 
0289   //! Adds edge element.
0290   //! @param[in] theMesh  triangulation source to be modified
0291   //! @param theIndex     edge index starting from 1
0292   //! @param theEdge      edge nodes starting from 1
0293   //! @return 0 if node indexes are out of range,
0294   //!         1 in case of success operation.
0295   Standard_EXPORT virtual int setEdge(const occ::handle<Poly_Triangulation>& theMesh,
0296                                       const int                              theIndex,
0297                                       const int                              theEdge) const;
0298 
0299 protected:
0300   RWMesh_CoordinateSystemConverter myCoordSysConverter; //!< coordinate system converter
0301   // clang-format off
0302   TCollection_AsciiString          myFileName;             //!< file name to use during message printing
0303   mutable std::mutex           myMutex;                //!< internal mutex to collect nodes/triangles statistic
0304   mutable LoadingStatistic*        myLoadingStatistic;     //!< statistic of loaded triangulation
0305   bool                 myIsDoublePrecision;    //!< flag to fill in triangulation using single or double precision
0306   bool                 myToSkipDegenerateTris; //!< flag to skip degenerate triangles during loading, FALSE by default
0307   bool                 myToPrintDebugMessages; //!< flag to print additional debug information
0308   // clang-format on
0309 };
0310 
0311 #endif // _RWMesh_TriangulationReader_HeaderFile