0027490: BRepMesh: Reduce number of memory allocations
[occt.git] / src / BRepMesh / BRepMesh_FastDiscretFace.hxx
1 // Copyright (c) 2013 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #ifndef _BRepMesh_FastDiscretFace_HeaderFile
15 #define _BRepMesh_FastDiscretFace_HeaderFile
16
17 #include <Standard.hxx>
18 #include <Standard_Type.hxx>
19 #include <BRepMesh_FastDiscretFace.hxx>
20 #include <BRepMesh_DataStructureOfDelaun.hxx>
21 #include <BRepMesh.hxx>
22 #include <BRepMesh_FaceAttribute.hxx>
23 #include <Standard_Transient.hxx>
24 #include <TopTools_MutexForShapeProvider.hxx>
25 #include <TopTools_DataMapOfShapeReal.hxx>
26 #include <BRepMesh_Delaun.hxx>
27 #include <BRepMesh_Triangle.hxx>
28 #include <BRepMesh_Classifier.hxx>
29 #include <ElSLib.hxx>
30
31 class BRepMesh_DataStructureOfDelaun;
32 class BRepMesh_FaceAttribute;
33 class TopoDS_Face;
34 class TopoDS_Vertex;
35 class BRepAdaptor_HSurface;
36 class TopoDS_Edge;
37 class Poly_Triangulation;
38 class TopLoc_Location;
39 class gp_XY;
40 class gp_Pnt2d;
41 class BRepMesh_Edge;
42 class BRepMesh_Vertex;
43 class gp_Pnt;
44
45 //! Algorithm to mesh a face with respect of the frontier 
46 //! the deflection and by option the shared components.
47 class BRepMesh_FastDiscretFace : public Standard_Transient 
48 {
49 public:
50   
51   //! Constructor.
52   //! @param theAngle deviation angle to be used for surface tessellation.
53   //! @param isInternalVerticesMode flag enabling/disabling internal 
54   //! vertices mode.
55   //! @param isControlSurfaceDeflection enables/disables adaptive 
56   //! reconfiguration of mesh.
57   Standard_EXPORT BRepMesh_FastDiscretFace(
58     const Standard_Real    theAngle,
59     const Standard_Real    theMinSize,
60     const Standard_Boolean isInternalVerticesMode,
61     const Standard_Boolean isControlSurfaceDeflection);
62
63   Standard_EXPORT void Perform(const Handle(BRepMesh_FaceAttribute)& theAttribute);
64
65   DEFINE_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient)
66
67 private:
68
69   void add(const Handle(BRepMesh_FaceAttribute)& theAttribute);
70   void add(const TopoDS_Vertex& theVertex);
71
72   Standard_Real control(BRepMesh::ListOfVertex&  theNewVertices,
73                         BRepMesh_Delaun&         theMeshBuilder,
74                         const Standard_Boolean   theIsFirst);
75
76   //! Registers the given nodes in mesh data structure and
77   //! performs refinement of existing mesh.
78   //! @param theVertices nodes to be inserted.
79   //! @param theMeshBuilder initialized tool refining mesh 
80   //! in respect to inserting nodes.
81   //! @return TRUE if vertices were been inserted, FALSE elewhere.
82   Standard_Boolean addVerticesToMesh(
83     const BRepMesh::ListOfVertex& theVertices,
84     BRepMesh_Delaun&              theMeshBuilder);
85
86   //! Calculates nodes lying on face's surface and inserts them to a mesh.
87   //! @param theNewVertices list of vertices to be extended and added to mesh.
88   //! @param theMeshBuilder initialized tool refining mesh 
89   //! in respect to inserting nodes.
90   void insertInternalVertices(BRepMesh::ListOfVertex&  theNewVertices,
91                               BRepMesh_Delaun&         theMeshBuilder);
92
93   //! Calculates nodes lying on spherical surface.
94   //! @param theNewVertices list of vertices to be extended and added to mesh.
95   void insertInternalVerticesSphere(BRepMesh::ListOfVertex& theNewVertices);
96
97   //! Calculates nodes lying on cylindrical surface.
98   //! @param theNewVertices list of vertices to be extended and added to mesh.
99   void insertInternalVerticesCylinder(BRepMesh::ListOfVertex& theNewVertices);
100
101   //! Calculates nodes lying on conical surface.
102   //! @param theNewVertices list of vertices to be extended and added to mesh.
103   void insertInternalVerticesCone(BRepMesh::ListOfVertex& theNewVertices);
104
105   //! Calculates nodes lying on toroidal surface.
106   //! @param theNewVertices list of vertices to be extended and added to mesh.
107   void insertInternalVerticesTorus(BRepMesh::ListOfVertex& theNewVertices);
108
109   //! Calculates nodes lying on custom-type surface.
110   //! @param theNewVertices list of vertices to be extended and added to mesh.
111   void insertInternalVerticesOther(BRepMesh::ListOfVertex& theNewVertices);
112   
113   //! Template method trying to insert new internal vertex corresponded to
114   //! the given 2d point. Calculates 3d position analytically using the given
115   //! surface.
116   //! @param thePnt2d 2d point to be inserted to the list.
117   //! @param theAnalyticSurface analytic surface to calculate 3d point.
118   //! @param[out] theVertices list of vertices to be updated.
119   template<class AnalyticSurface>
120   void tryToInsertAnalyticVertex(const gp_Pnt2d&         thePnt2d,
121                                  const AnalyticSurface&  theAnalyticSurface,
122                                  BRepMesh::ListOfVertex& theVertices)
123   {
124     const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier();
125     if (aClassifier->Perform(thePnt2d) != TopAbs_IN)
126       return;
127
128     gp_Pnt aPnt;
129     ElSLib::D0(thePnt2d.X(), thePnt2d.Y(), theAnalyticSurface, aPnt);
130     insertVertex(aPnt, thePnt2d.Coord(), theVertices);
131   }
132
133   //! Creates new vertex with the given parameters.
134   //! @param thePnt3d 3d point corresponded to the vertex.
135   //! @param theUV UV point corresponded to the vertex.
136   //! @param[out] theVertices list of vertices to be updated.
137   void insertVertex(const gp_Pnt&           thePnt3d,
138                     const gp_XY&            theUV,
139                     BRepMesh::ListOfVertex& theVertices);
140
141   //! Stores mesh into the face (without internal edges).
142   void commitSurfaceTriangulation();
143
144   //! Performs initialization of data structure using existing data.
145   void initDataStructure();
146
147   //! Adds new link to the mesh data structure.
148   //! Movability of the link and order of nodes depend on orientation parameter.
149   void addLinkToMesh(const Standard_Integer   theFirstNodeId,
150                      const Standard_Integer   theLastNodeId,
151                      const TopAbs_Orientation theOrientation);
152
153   //! Inserts new node into a mesh in case if smoothed region build 
154   //! using the given node has better deflection metrics than source state.
155   //! @param thePnt3d 3d point corresponded to the vertex.
156   //! @param theUV UV point corresponded to the vertex.
157   //! @param isDeflectionCheckOnly if TRUE new node will not be added to a mesh
158   //! even if deflection parameter is better.
159   //! @param theTriangleDeflection deflection of a triangle from real geometry.
160   //! @param theFaceDeflection deflection to be achieved.
161   //! @param theCircleTool tool used for fast extraction of triangles 
162   //! touched by the given point.
163   //! @param[out] theVertices list of vertices to be updated.
164   //! @param[in out] theMaxTriangleDeflection maximal deflection of a mesh.
165   //! @return TRUE in case if the given deflection of triangle is fine and
166   //! there is no necessity to insert new node or new node was being inserted
167   //! successfully, FALSE in case if new configuration is better but 
168   //! isDeflectionCheckOnly flag is set.
169   Standard_Boolean checkDeflectionAndInsert(
170     const gp_Pnt&              thePnt3d,
171     const gp_XY&               theUV,
172     const Standard_Boolean     isDeflectionCheckOnly,
173     const Standard_Real        theTriangleDeflection,
174     const Standard_Real        theFaceDeflection,
175     const BRepMesh_CircleTool& theCircleTool,
176     BRepMesh::ListOfVertex&    theVertices,
177     Standard_Real&             theMaxTriangleDeflection,
178     const Handle(NCollection_IncAllocator)& theTempAlloc);
179
180 private:
181
182   Standard_Real                          myAngle;
183   Standard_Boolean                       myInternalVerticesMode;
184   BRepMesh::IMapOfReal                   myUParam;
185   BRepMesh::IMapOfReal                   myVParam;
186
187   // Fast access to attributes of current face
188   Handle(BRepMesh_FaceAttribute)         myAttribute;
189   Handle(BRepMesh_DataStructureOfDelaun) myStructure;
190
191   Standard_Real                          myMinSize;
192   Standard_Boolean                       myIsControlSurfaceDeflection;
193 };
194
195 DEFINE_STANDARD_HANDLE (BRepMesh_FastDiscretFace, Standard_Transient)
196
197 #endif