0025113: Mesh - Progress indication and user break functionality for BRepMesh component
[occt.git] / src / BRepMesh / BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx
1 // Created on: 2016-07-07
2 // Copyright (c) 2016 OPEN CASCADE SAS
3 // Created by: Oleg AGASHIN
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #ifndef _BRepMesh_DelaunayNodeInsertionMeshAlgo_HeaderFile
17 #define _BRepMesh_DelaunayNodeInsertionMeshAlgo_HeaderFile
18
19 #include <BRepMesh_NodeInsertionMeshAlgo.hxx>
20 #include <BRepMesh_GeomTool.hxx>
21
22 //! Extends base Delaunay meshing algo in order to enable possibility 
23 //! of addition of free vertices and internal nodes into the mesh.
24 template<class RangeSplitter, class BaseAlgo>
25 class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
26 {
27 private:
28   // Typedef for OCCT RTTI
29   typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> InsertionBaseClass;
30
31 public:
32
33   //! Constructor.
34   BRepMesh_DelaunayNodeInsertionMeshAlgo()
35     : myIsPreProcessSurfaceNodes (Standard_False)
36   {
37   }
38
39   //! Destructor.
40   virtual ~BRepMesh_DelaunayNodeInsertionMeshAlgo()
41   {
42   }
43
44   //! Returns PreProcessSurfaceNodes flag. 
45   inline Standard_Boolean IsPreProcessSurfaceNodes () const
46   {
47     return myIsPreProcessSurfaceNodes;
48   }
49
50   //! Sets PreProcessSurfaceNodes flag.
51   //! If TRUE, registers surface nodes before generation of base mesh.
52   //! If FALSE, inserts surface nodes after generation of base mesh. 
53   inline void SetPreProcessSurfaceNodes (const Standard_Boolean isPreProcessSurfaceNodes)
54   {
55     myIsPreProcessSurfaceNodes = isPreProcessSurfaceNodes;
56   }
57
58 protected:
59
60   //! Performs initialization of data structure using existing model data.
61   virtual Standard_Boolean initDataStructure() Standard_OVERRIDE
62   {
63     if (!InsertionBaseClass::initDataStructure())
64     {
65       return Standard_False;
66     }
67
68     if (myIsPreProcessSurfaceNodes)
69     {
70       const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
71         this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
72
73       registerSurfaceNodes (aSurfaceNodes);
74     }
75
76     return Standard_True;
77   }
78
79   //! Returns size of cell to be used by acceleration circles grid structure.
80   virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer theVerticesNb) Standard_OVERRIDE
81   {
82     return BRepMesh_GeomTool::CellsCount (this->getDFace()->GetSurface(), theVerticesNb,
83                                           this->getDFace()->GetDeflection(),
84                                           &this->getRangeSplitter());
85   }
86
87   //! Perfroms processing of generated mesh. Generates surface nodes and inserts them into structure.
88   virtual void postProcessMesh (BRepMesh_Delaun& theMesher,
89                                 const Message_ProgressRange& theRange) Standard_OVERRIDE
90   {
91     if (!theRange.More())
92     {
93       return;
94     }
95     InsertionBaseClass::postProcessMesh (theMesher, Message_ProgressRange()); // shouldn't be range passed here?
96
97     if (!myIsPreProcessSurfaceNodes)
98     {
99       const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
100         this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
101
102       insertNodes(aSurfaceNodes, theMesher, theRange);
103     }
104   }
105
106   //! Inserts nodes into mesh.
107   Standard_Boolean insertNodes(
108     const Handle(IMeshData::ListOfPnt2d)& theNodes,
109     BRepMesh_Delaun&                      theMesher,
110     const Message_ProgressRange&          theRange)
111   {
112     if (theNodes.IsNull() || theNodes->IsEmpty())
113     {
114       return Standard_False;
115     }
116
117     IMeshData::VectorOfInteger aVertexIndexes(theNodes->Size(), this->getAllocator());
118     IMeshData::ListOfPnt2d::Iterator aNodesIt(*theNodes);
119     for (Standard_Integer aNodeIt = 1; aNodesIt.More(); aNodesIt.Next(), ++aNodeIt)
120     {
121       const gp_Pnt2d& aPnt2d = aNodesIt.Value();
122       if (this->getClassifier()->Perform(aPnt2d) == TopAbs_IN)
123       {
124         aVertexIndexes.Append(this->registerNode(this->getRangeSplitter().Point(aPnt2d),
125                                                  aPnt2d, BRepMesh_Free, Standard_False));
126       }
127     }
128
129     theMesher.AddVertices (aVertexIndexes, theRange);
130     if (!theRange.More())
131     {
132       return Standard_False;
133     }
134     return !aVertexIndexes.IsEmpty();
135   }
136
137 private:
138   
139   //! Registers surface nodes in data structure.
140   Standard_Boolean registerSurfaceNodes(
141     const Handle(IMeshData::ListOfPnt2d)& theNodes)
142   {
143     if (theNodes.IsNull() || theNodes->IsEmpty())
144     {
145       return Standard_False;
146     }
147
148     Standard_Boolean isAdded = Standard_False;
149     IMeshData::ListOfPnt2d::Iterator aNodesIt(*theNodes);
150     for (Standard_Integer aNodeIt = 1; aNodesIt.More(); aNodesIt.Next(), ++aNodeIt)
151     {
152       const gp_Pnt2d& aPnt2d = aNodesIt.Value();
153       if (this->getClassifier()->Perform(aPnt2d) == TopAbs_IN)
154       {
155         isAdded = Standard_True;
156         this->registerNode(this->getRangeSplitter().Point(aPnt2d),
157                            aPnt2d, BRepMesh_Free, Standard_False);
158       }
159     }
160
161     return isAdded;
162   }
163
164 private:
165
166   Standard_Boolean myIsPreProcessSurfaceNodes;
167 };
168
169 #endif