Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:03:14

0001 // Copyright (c) 2013-2014 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 _BRepMesh_Delaun_HeaderFile
0015 #define _BRepMesh_Delaun_HeaderFile
0016 
0017 #include <Standard.hxx>
0018 #include <Standard_DefineAlloc.hxx>
0019 #include <Standard_Macro.hxx>
0020 
0021 #include <BRepMesh_CircleTool.hxx>
0022 #include <BRepMesh_Triangle.hxx>
0023 #include <BRepMesh_Edge.hxx>
0024 #include <IMeshData_Types.hxx>
0025 #include <BRepMesh_DataStructureOfDelaun.hxx>
0026 #include <BRepMesh_GeomTool.hxx>
0027 #include <Message_ProgressRange.hxx>
0028 
0029 class Bnd_B2d;
0030 class Bnd_Box2d;
0031 class BRepMesh_Vertex;
0032 
0033 //! Compute the Delaunay's triangulation with the algorithm of Watson.
0034 class BRepMesh_Delaun
0035 {
0036 public:
0037 
0038   DEFINE_STANDARD_ALLOC
0039 
0040   //! Creates instance of triangulator, but do not run the algorithm automatically.
0041   Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
0042                                    const Standard_Integer                        theCellsCountU,
0043                                    const Standard_Integer                        theCellsCountV,
0044                                    const Standard_Boolean                        isFillCircles);
0045 
0046   //! Creates the triangulation with an empty Mesh data structure.
0047   Standard_EXPORT BRepMesh_Delaun (IMeshData::Array1OfVertexOfDelaun& theVertices);
0048 
0049   //! Creates the triangulation with an existent Mesh data structure.
0050   Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
0051                                    IMeshData::Array1OfVertexOfDelaun&            theVertices);
0052 
0053   //! Creates the triangulation with an existant Mesh data structure.
0054   Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
0055                                    IMeshData::VectorOfInteger&                   theVertexIndices);
0056 
0057   //! Creates the triangulation with an existant Mesh data structure.
0058   Standard_EXPORT BRepMesh_Delaun (const Handle (BRepMesh_DataStructureOfDelaun)& theOldMesh,
0059                                    IMeshData::VectorOfInteger&                    theVertexIndices,
0060                                    const Standard_Integer                         theCellsCountU,
0061                                    const Standard_Integer                         theCellsCountV);
0062 
0063   //! Initializes the triangulation with an array of vertices.
0064   Standard_EXPORT void Init (IMeshData::Array1OfVertexOfDelaun& theVertices);
0065 
0066   //! Forces initialization of circles cell filter using working structure.
0067   Standard_EXPORT void InitCirclesTool (const Standard_Integer theCellsCountU,
0068                                         const Standard_Integer theCellsCountV);
0069 
0070   //! Removes a vertex from the triangulation.
0071   Standard_EXPORT void RemoveVertex (const BRepMesh_Vertex& theVertex);
0072 
0073   //! Adds some vertices into the triangulation.
0074   Standard_EXPORT void AddVertices (IMeshData::VectorOfInteger&  theVerticesIndices,
0075                                     const Message_ProgressRange& theRange = Message_ProgressRange());
0076 
0077   //! Modify mesh to use the edge.
0078   //! @return True if done
0079   Standard_EXPORT Standard_Boolean UseEdge (const Standard_Integer theEdge);
0080 
0081   //! Gives the Mesh data structure.
0082   const Handle(BRepMesh_DataStructureOfDelaun)& Result() const
0083   {
0084     return myMeshData;
0085   }
0086 
0087   //! Forces insertion of constraint edges into the base triangulation. 
0088   void ProcessConstraints()
0089   {
0090     insertInternalEdges();
0091 
0092     // Adjustment of meshes to boundary edges
0093     frontierAdjust();
0094   }
0095 
0096   //! Gives the list of frontier edges.
0097   Handle(IMeshData::MapOfInteger) Frontier() const
0098   {
0099     return getEdgesByType (BRepMesh_Frontier);
0100   }
0101 
0102   //! Gives the list of internal edges.
0103   Handle(IMeshData::MapOfInteger) InternalEdges() const
0104   {
0105     return getEdgesByType (BRepMesh_Fixed);
0106   }
0107 
0108   //! Gives the list of free edges used only one time
0109   Handle(IMeshData::MapOfInteger) FreeEdges() const
0110   {
0111     return getEdgesByType (BRepMesh_Free);
0112   }
0113 
0114   //! Gives vertex with the given index
0115   const BRepMesh_Vertex& GetVertex (const Standard_Integer theIndex) const
0116   {
0117     return myMeshData->GetNode (theIndex);
0118   }
0119 
0120   //! Gives edge with the given index
0121   const BRepMesh_Edge& GetEdge (const Standard_Integer theIndex) const
0122   {
0123     return myMeshData->GetLink (theIndex);
0124   }
0125 
0126   //! Gives triangle with the given index
0127   const BRepMesh_Triangle& GetTriangle (const Standard_Integer theIndex) const
0128   {
0129     return myMeshData->GetElement (theIndex);
0130   }
0131 
0132   //! Returns tool used to build mesh consistent to Delaunay criteria.
0133   const BRepMesh_CircleTool& Circles() const
0134   {
0135     return myCircles;
0136   }
0137 
0138   //! Test is the given triangle contains the given vertex.
0139   //! @param theSqTolerance square tolerance to check closeness to some edge
0140   //! @param theEdgeOn If it is != 0 the vertex lies onto the edge index
0141   //!        returned through this parameter.
0142   Standard_EXPORT Standard_Boolean Contains (const Standard_Integer theTriangleId,
0143                                              const BRepMesh_Vertex& theVertex,
0144                                              const Standard_Real    theSqTolerance,
0145                                              Standard_Integer&      theEdgeOn) const;
0146 
0147   //! Explicitly sets ids of auxiliary vertices used to build mesh and used by 3rd-party algorithms.
0148   inline void SetAuxVertices (const IMeshData::VectorOfInteger& theSupVert)
0149   {
0150     mySupVert = theSupVert;
0151   }
0152 
0153   //! Destruction of auxiliary triangles containing the given vertices.
0154   //! Removes auxiliary vertices also.
0155   //! @param theAuxVertices auxiliary vertices to be cleaned up.
0156   Standard_EXPORT void RemoveAuxElements ();
0157 
0158 private:
0159 
0160   enum ReplaceFlag
0161   {
0162     Replace,
0163     InsertAfter,
0164     InsertBefore
0165   };
0166 
0167   typedef NCollection_DataMap<Standard_Integer, IMeshData::MapOfInteger> DataMapOfMap;
0168 
0169   //! Performs initialization of circles cell filter tool.
0170   void initCirclesTool (const Bnd_Box2d&       theBox,
0171                         const Standard_Integer theCellsCountU,
0172                         const Standard_Integer theCellsCountV);
0173 
0174   //! Add bounding box for edge defined by start & end point to
0175   //! the given vector of bounding boxes for triangulation edges.
0176   void fillBndBox (IMeshData::SequenceOfBndB2d&  theBoxes,
0177                    const BRepMesh_Vertex&        theV1,
0178                    const BRepMesh_Vertex&        theV2);
0179 
0180   //! Gives the list of edges with type defined by the input parameter.
0181   //! If the given type is BRepMesh_Free returns list of edges
0182   //! that have number of connected elements less or equal 1.
0183   Handle(IMeshData::MapOfInteger) getEdgesByType (const BRepMesh_DegreeOfFreedom theEdgeType) const;
0184 
0185   //! Run triangulation procedure.
0186   void perform (IMeshData::VectorOfInteger& theVertexIndices,
0187                 const Standard_Integer      theCellsCountU = -1,
0188                 const Standard_Integer      theCellsCountV = -1);
0189 
0190   //! Build the super mesh.
0191   void superMesh (const Bnd_Box2d& theBox);
0192 
0193   //! Computes the triangulation and adds the vertices,
0194   //! edges and triangles to the Mesh data structure.
0195   void compute (IMeshData::VectorOfInteger& theVertexIndices);
0196 
0197   //! Adjust the mesh on the frontier.
0198   void frontierAdjust();
0199 
0200   //! Find left polygon of the given edge and call meshPolygon.
0201   Standard_Boolean meshLeftPolygonOf(
0202     const Standard_Integer          theEdgeIndex,
0203     const Standard_Boolean          isForward,
0204     Handle(IMeshData::MapOfInteger) theSkipped = NULL);
0205 
0206   //! Find next link starting from the given node and has maximum
0207   //! angle respect the given reference link.
0208   //! Each time the next link is found other neighbor links at the pivot
0209   //! node are marked as leprous and will be excluded from consideration
0210   //! next time until a hanging end is occurred.
0211   Standard_Integer findNextPolygonLink (const Standard_Integer&               theFirstNode,
0212                                         const Standard_Integer&               thePivotNode,
0213                                         const BRepMesh_Vertex&                thePivotVertex,
0214                                         const gp_Vec2d&                       theRefLinkDir,
0215                                         const IMeshData::SequenceOfBndB2d&    theBoxes,
0216                                         const IMeshData::SequenceOfInteger&   thePolygon,
0217                                         const Handle(IMeshData::MapOfInteger)& theSkipped,
0218                                         const Standard_Boolean&               isSkipLeprous,
0219                                         IMeshData::MapOfInteger&              theLeprousLinks,
0220                                         IMeshData::MapOfInteger&              theDeadLinks,
0221                                         Standard_Integer&                     theNextPivotNode,
0222                                         gp_Vec2d&                             theNextLinkDir,
0223                                         Bnd_B2d&                              theNextLinkBndBox);
0224 
0225   //! Check is the given link intersects the polygon boundaries.
0226   //! Returns bounding box for the given link through the theLinkBndBox parameter.
0227   Standard_Boolean checkIntersection (const BRepMesh_Edge&                theLink,
0228                                       const IMeshData::SequenceOfInteger& thePolygon,
0229                                       const IMeshData::SequenceOfBndB2d&  thePolyBoxes,
0230                                       const Standard_Boolean              isConsiderEndPointTouch,
0231                                       const Standard_Boolean              isConsiderPointOnEdge,
0232                                       const Standard_Boolean              isSkipLastEdge,
0233                                       Bnd_B2d&                            theLinkBndBox) const;
0234 
0235   //! Triangulatiion of a closed polygon described by the list
0236   //! of indexes of its edges in the structure.
0237   //! (negative index means reversed edge)
0238   void meshPolygon (IMeshData::SequenceOfInteger&   thePolygon,
0239                     IMeshData::SequenceOfBndB2d&    thePolyBoxes,
0240                     Handle(IMeshData::MapOfInteger) theSkipped = NULL);
0241 
0242   //! Decomposes the given closed simple polygon (polygon without glued edges 
0243   //! and loops) on two simpler ones by adding new link at the most thin part 
0244   //! in respect to end point of the first link.
0245   //! In case if source polygon consists of three links, creates new triangle 
0246   //! and clears source container.
0247   //! @param thePolygon source polygon to be decomposed (first part of decomposition).
0248   //! @param thePolyBoxes bounding boxes corresponded to source polygon's links.
0249   //! @param thePolygonCut product of decomposition of source polygon (second part of decomposition).
0250   //! @param thePolyBoxesCut bounding boxes corresponded to resulting polygon's links.
0251   void decomposeSimplePolygon (
0252     IMeshData::SequenceOfInteger& thePolygon,
0253     IMeshData::SequenceOfBndB2d&  thePolyBoxes,
0254     IMeshData::SequenceOfInteger& thePolygonCut,
0255     IMeshData::SequenceOfBndB2d&  thePolyBoxesCut);
0256 
0257   //! Triangulation of closed polygon containing only three edges.
0258   Standard_Boolean meshElementaryPolygon (const IMeshData::SequenceOfInteger& thePolygon);
0259 
0260   //! Creates the triangles between the given node and the given polyline.
0261   void createTriangles (const Standard_Integer         theVertexIndex,
0262                         IMeshData::MapOfIntegerInteger& thePoly);
0263 
0264   //! Add a triangle based on the given oriented edges into mesh
0265   void addTriangle (const Standard_Integer (&theEdgesId)[3],
0266                     const Standard_Boolean (&theEdgesOri)[3],
0267                     const Standard_Integer (&theNodesId)[3]);
0268 
0269   //! Deletes the triangle with the given index and adds the free edges into the map.
0270   //! When an edge is suppressed more than one time it is destroyed.
0271   void deleteTriangle (const Standard_Integer         theIndex,
0272                        IMeshData::MapOfIntegerInteger& theLoopEdges);
0273 
0274   //! Returns start and end nodes of the given edge in respect to its orientation.
0275   void getOrientedNodes (const BRepMesh_Edge&   theEdge,
0276                          const Standard_Boolean isForward,
0277                          Standard_Integer*      theNodes) const;
0278 
0279   //! Processes loop within the given polygon formed by range of its
0280   //! links specified by start and end link indices.
0281   void processLoop (const Standard_Integer              theLinkFrom,
0282                     const Standard_Integer              theLinkTo,
0283                     const IMeshData::SequenceOfInteger& thePolygon,
0284                     const IMeshData::SequenceOfBndB2d&  thePolyBoxes);
0285 
0286   //! Creates new link based on the given nodes and updates the given polygon.
0287   Standard_Integer createAndReplacePolygonLink (const Standard_Integer        theNodes[],
0288                                                 const gp_Pnt2d                thePnts [],
0289                                                 const Standard_Integer        theRootIndex,
0290                                                 const ReplaceFlag             theReplaceFlag,
0291                                                 IMeshData::SequenceOfInteger& thePolygon,
0292                                                 IMeshData::SequenceOfBndB2d&  thePolyBoxes);
0293   
0294   //! Creates the triangles on new nodes.
0295   void createTrianglesOnNewVertices (IMeshData::VectorOfInteger&  theVertexIndices,
0296                                      const Message_ProgressRange& theRange);
0297 
0298   //! Cleanup mesh from the free triangles.
0299   void cleanupMesh();
0300 
0301   //! Goes through the neighbour triangles around the given node started
0302   //! from the given link, returns TRUE if some triangle has a bounding
0303   //! frontier edge or FALSE elsewhere.
0304   Standard_Boolean isBoundToFrontier (const Standard_Integer theRefNodeId,
0305                                       const Standard_Integer theRefLinkId);
0306 
0307   //! Remove internal triangles from the given polygon.
0308   void cleanupPolygon (const IMeshData::SequenceOfInteger& thePolygon,
0309                        const IMeshData::SequenceOfBndB2d&  thePolyBoxes);
0310 
0311   //! Checks is the given vertex lies inside the polygon.
0312   Standard_Boolean isVertexInsidePolygon (const Standard_Integer&           theVertexId,
0313                                           const IMeshData::VectorOfInteger& thePolygonVertices) const;
0314 
0315   //! Remove all triangles and edges that are placed inside the polygon or crossed it.
0316   void killTrianglesAroundVertex (const Standard_Integer              theZombieNodeId,
0317                                   const IMeshData::VectorOfInteger&   thePolyVertices,
0318                                   const IMeshData::MapOfInteger&      thePolyVerticesFindMap,
0319                                   const IMeshData::SequenceOfInteger& thePolygon,
0320                                   const IMeshData::SequenceOfBndB2d&  thePolyBoxes,
0321                                   IMeshData::MapOfInteger&            theSurvivedLinks,
0322                                   IMeshData::MapOfIntegerInteger&     theLoopEdges);
0323 
0324   //! Checks is the given link crosses the polygon boundary.
0325   //! If yes, kills its triangles and checks neighbor links on boundary intersection. Does nothing elsewhere.
0326   void killTrianglesOnIntersectingLinks (const Standard_Integer&              theLinkToCheckId,
0327                                          const BRepMesh_Edge&                 theLinkToCheck,
0328                                          const Standard_Integer&              theEndPoint,
0329                                          const IMeshData::SequenceOfInteger&  thePolygon,
0330                                          const IMeshData::SequenceOfBndB2d&   thePolyBoxes,
0331                                          IMeshData::MapOfInteger&             theSurvivedLinks,
0332                                          IMeshData::MapOfIntegerInteger&      theLoopEdges);
0333 
0334   //! Kill triangles bound to the given link.
0335   void killLinkTriangles (const Standard_Integer&         theLinkId,
0336                           IMeshData::MapOfIntegerInteger& theLoopEdges);
0337 
0338   //! Calculates distances between the given point and edges of triangle.
0339   Standard_Real calculateDist (const gp_XY            theVEdges[3],
0340                                const gp_XY            thePoints[3],
0341                                const BRepMesh_Vertex& theVertex,
0342                                Standard_Real          theDistance[3],
0343                                Standard_Real          theSqModulus[3],
0344                                Standard_Integer&      theEdgeOn) const;
0345 
0346   //! Checks intersection between the two segments.
0347   BRepMesh_GeomTool::IntFlag intSegSeg(
0348     const BRepMesh_Edge&   theEdge1,
0349     const BRepMesh_Edge&   theEdge2,
0350     const Standard_Boolean isConsiderEndPointTouch,
0351     const Standard_Boolean isConsiderPointOnEdge,
0352     gp_Pnt2d&              theIntPnt) const;
0353 
0354   //! Returns area of the loop of the given polygon defined by indices of its start and end links.
0355   Standard_Real polyArea (const IMeshData::SequenceOfInteger& thePolygon,
0356                           const Standard_Integer              theStartIndex,
0357                           const Standard_Integer              theEndIndex) const;
0358 
0359   //! Performs insertion of internal edges into mesh.
0360   void insertInternalEdges();
0361 
0362   //! Checks whether the given vertex id relates to super contour.
0363   Standard_Boolean isSupVertex (const Standard_Integer theVertexIdx) const
0364   {
0365     for (IMeshData::VectorOfInteger::Iterator aIt (mySupVert); aIt.More (); aIt.Next ())
0366     {
0367       if (theVertexIdx == aIt.Value ())
0368       {
0369         return Standard_True;
0370       }
0371     }
0372 
0373     return Standard_False;
0374   }
0375 
0376 private:
0377 
0378   Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
0379   BRepMesh_CircleTool                    myCircles;
0380   IMeshData::VectorOfInteger             mySupVert;
0381   Standard_Boolean                       myInitCircles;
0382   BRepMesh_Triangle                      mySupTrian;
0383 };
0384 
0385 #endif