0026106: BRepMesh - revision of data model
[occt.git] / src / BRepMesh / BRepMesh_GeomTool.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_GeomTool_HeaderFile
15 #define _BRepMesh_GeomTool_HeaderFile
16
17 #include <Standard.hxx>
18 #include <Standard_DefineAlloc.hxx>
19 #include <Standard_Macro.hxx>
20 #include <GCPnts_TangentialDeflection.hxx>
21 #include <GeomAbs_IsoType.hxx>
22 #include <TopoDS_Edge.hxx>
23 #include <Precision.hxx>
24
25 class BRepAdaptor_Curve;
26 class BRepAdaptor_HSurface;
27 class gp_Pnt;
28 class gp_Pnt2d;
29 class gp_Dir;
30 class BRepMesh_DefaultRangeSplitter;
31 class Adaptor3d_HSurface;
32
33 //! Tool class accumulating common geometrical functions as well as 
34 //! functionality using shape geometry to produce data necessary for 
35 //! tessellation.
36 //! General aim is to calculate discretization points for the given
37 //! curve or iso curve of surface according to the specified parameters.
38 class BRepMesh_GeomTool
39 {
40 public:
41
42   //! Enumerates states of segments intersection check.
43   enum IntFlag
44   {
45     NoIntersection,
46     Cross,
47     EndPointTouch,
48     PointOnSegment,
49     Glued,
50     Same
51   };
52
53 public:
54
55   DEFINE_STANDARD_ALLOC
56   
57   //! Constructor.
58   //! Initiates discretization of the given geometric curve.
59   //! @param theCurve curve to be discretized.
60   //! @param theFirstParam first parameter of the curve.
61   //! @param theLastParam last parameter of the curve.
62   //! @param theLinDeflection linear deflection.
63   //! @param theAngDeflection angular deflection.
64   //! @param theMinPointsNb minimum nuber of points to be produced.
65   Standard_EXPORT BRepMesh_GeomTool(
66     const BRepAdaptor_Curve& theCurve,
67     const Standard_Real      theFirstParam,
68     const Standard_Real      theLastParam,
69     const Standard_Real      theLinDeflection,
70     const Standard_Real      theAngDeflection,
71     const Standard_Integer   theMinPointsNb = 2,
72     const Standard_Real      theMinSize = Precision::Confusion());
73   
74   //! Constructor.
75   //! Initiates discretization of geometric curve corresponding 
76   //! to iso curve of the given surface.
77   //! @param theSurface surface the iso curve to be taken from.
78   //! @param theIsoType type of iso curve to be used, U or V.
79   //! @param theParamIso parameter on the surface specifying the iso curve.
80   //! @param theFirstParam first parameter of the curve.
81   //! @param theLastParam last parameter of the curve.
82   //! @param theLinDeflection linear deflection.
83   //! @param theAngDeflection angular deflection.
84   //! @param theMinPointsNb minimum nuber of points to be produced.
85   Standard_EXPORT BRepMesh_GeomTool(
86     const Handle(BRepAdaptor_HSurface)& theSurface,
87     const GeomAbs_IsoType               theIsoType,
88     const Standard_Real                 theParamIso,
89     const Standard_Real                 theFirstParam,
90     const Standard_Real                 theLastParam,
91     const Standard_Real                 theLinDeflection,
92     const Standard_Real                 theAngDeflection,
93     const Standard_Integer              theMinPointsNb = 2,
94     const Standard_Real                 theMinSize = Precision::Confusion());
95
96   //! Adds point to already calculated points (or replaces existing).
97   //! @param thePoint point to be added.
98   //! @param theParam parameter on the curve corresponding to the given point.
99   //! @param theIsReplace if TRUE replaces existing point lying within 
100   //! parameteric tolerance of the given point.
101   //! @return index of new added point or found with parametric tolerance
102   inline Standard_Integer AddPoint(const gp_Pnt&           thePoint,
103                                    const Standard_Real     theParam,
104                                    const Standard_Boolean  theIsReplace = Standard_True)
105   {
106     return myDiscretTool.AddPoint(thePoint, theParam, theIsReplace);
107   }
108   
109   //! Returns number of discretization points.
110   inline Standard_Integer NbPoints() const
111   {
112     return myDiscretTool.NbPoints();
113   }
114   
115   //! Gets parameters of discretization point with the given index.
116   //! @param theIndex index of discretization point.
117   //! @param theIsoParam parameter on surface to be used as second coordinate 
118   //! of resulting 2d point.
119   //! @param theParam[out] parameter of the point on the iso curve.
120   //! @param thePoint[out] discretization point.
121   //! @param theUV[out] discretization point in parametric space of the surface.
122   //! @return TRUE on success, FALSE elsewhere.
123   Standard_EXPORT Standard_Boolean Value(const Standard_Integer theIndex,
124                                          const Standard_Real    theIsoParam,
125                                          Standard_Real&         theParam,
126                                          gp_Pnt&                thePoint,
127                                          gp_Pnt2d&              theUV) const;
128   
129   //! Gets parameters of discretization point with the given index.
130   //! @param theIndex index of discretization point.
131   //! @param theSurface surface the curve is lying onto.
132   //! @param theParam[out] parameter of the point on the curve.
133   //! @param thePoint[out] discretization point.
134   //! @param theUV[out] discretization point in parametric space of the surface.
135   //! @return TRUE on success, FALSE elsewhere.
136   Standard_EXPORT Standard_Boolean Value(const Standard_Integer              theIndex,
137                                          const Handle(BRepAdaptor_HSurface)& theSurface,
138                                          Standard_Real&                      theParam,
139                                          gp_Pnt&                             thePoint,
140                                          gp_Pnt2d&                           theUV) const;
141   
142 public: //! @name static API
143
144   //! Computes normal to the given surface at the specified
145   //! position in parametric space.
146   //! @param theSurface surface the normal should be found for.
147   //! @param theParamU U parameter in parametric space of the surface.
148   //! @param theParamV V parameter in parametric space of the surface.
149   //! @param[out] thePoint 3d point corresponding to the given parameters.
150   //! @param[out] theNormal normal vector at the point specified by the parameters.
151   //! @return FALSE if the normal can not be computed, TRUE elsewhere.
152   Standard_EXPORT static Standard_Boolean Normal(
153     const Handle(BRepAdaptor_HSurface)& theSurface,
154     const Standard_Real                 theParamU,
155     const Standard_Real                 theParamV,
156     gp_Pnt&                             thePoint,
157     gp_Dir&                             theNormal);
158
159   //! Checks intersection between two lines defined by two points.
160   //! @param theStartPnt1 start point of first line.
161   //! @param theEndPnt1 end point of first line.
162   //! @param theStartPnt2 start point of second line.
163   //! @param theEndPnt2 end point of second line.
164   //! @param[out] theIntPnt point of intersection.
165   //! @param[out] theParamOnSegment parameters of intersection point 
166   //! corresponding to first and second segment.
167   //! @return status of intersection check.
168   Standard_EXPORT static IntFlag IntLinLin(
169     const gp_XY&  theStartPnt1,
170     const gp_XY&  theEndPnt1,
171     const gp_XY&  theStartPnt2,
172     const gp_XY&  theEndPnt2,
173     gp_XY&        theIntPnt,
174     Standard_Real (&theParamOnSegment)[2]);
175
176   //! Checks intersection between the two segments. 
177   //! Checks that intersection point lies within ranges of both segments.
178   //! @param theStartPnt1 start point of first segment.
179   //! @param theEndPnt1 end point of first segment.
180   //! @param theStartPnt2 start point of second segment.
181   //! @param theEndPnt2 end point of second segment.
182   //! @param isConsiderEndPointTouch if TRUE EndPointTouch status will be
183   //! returned in case if segments are touching by end points, if FALSE
184   //! returns NoIntersection flag.
185   //! @param isConsiderPointOnSegment if TRUE PointOnSegment status will be
186   //! returned in case if end point of one segment lies onto another one, 
187   //! if FALSE returns NoIntersection flag.
188   //! @param[out] theIntPnt point of intersection.
189   //! @return status of intersection check.
190   Standard_EXPORT static IntFlag IntSegSeg(
191     const gp_XY&           theStartPnt1,
192     const gp_XY&           theEndPnt1,
193     const gp_XY&           theStartPnt2,
194     const gp_XY&           theEndPnt2,
195     const Standard_Boolean isConsiderEndPointTouch,
196     const Standard_Boolean isConsiderPointOnSegment,
197     gp_Pnt2d&              theIntPnt);
198
199   //! Compute deflection of the given segment.
200   static Standard_Real SquareDeflectionOfSegment(
201     const gp_Pnt& theFirstPoint,
202     const gp_Pnt& theLastPoint,
203     const gp_Pnt& theMidPoint)
204   {
205     // 23.03.2010 skl for OCC21645 - change precision for comparison
206     if (theFirstPoint.SquareDistance(theLastPoint) > Precision::SquareConfusion())
207     {
208       gp_Lin aLin(theFirstPoint, gp_Dir(gp_Vec(theFirstPoint, theLastPoint)));
209       return aLin.SquareDistance(theMidPoint);
210     }
211
212     return theFirstPoint.SquareDistance(theMidPoint);
213   }
214
215   // For better meshing performance we try to estimate the acceleration circles grid structure sizes:
216   // For each parametric direction (U, V) we estimate firstly an approximate distance between the future points -
217   // this estimation takes into account the required face deflection and the complexity of the face.
218   // Particularly, the complexity of the faces based on BSpline curves and surfaces requires much more points.
219   // At the same time, for planar faces and linear parts of the arbitrary surfaces usually no intermediate points
220   // are necessary.
221   // The general idea for each parametric direction:
222   // cells_count = 2 ^ log10 ( estimated_points_count )
223   // For linear parametric direction we fall back to the initial vertex count:
224   // cells_count = 2 ^ log10 ( initial_vertex_count )
225   Standard_EXPORT static std::pair<Standard_Integer, Standard_Integer> CellsCount (
226     const Handle (Adaptor3d_HSurface)&   theSurface,
227     const Standard_Integer               theVerticesNb,
228     const Standard_Real                  theDeflection,
229     const BRepMesh_DefaultRangeSplitter* theRangeSplitter);
230
231 private:
232
233   //! Classifies the point in case of coincidence of two vectors.
234   //! @param thePoint1 the start point of a segment (base point).
235   //! @param thePoint2 the end point of a segment.
236   //! @param thePointToCheck the point to classify.
237   //! @return zero value if point is out of segment and non zero value 
238   //! if point is between the first and the second point of segment.
239   static Standard_Integer classifyPoint (const gp_XY& thePoint1,
240                                          const gp_XY& thePoint2,
241                                          const gp_XY& thePointToCheck);
242
243 private:
244
245   const TopoDS_Edge*                  myEdge;
246   GCPnts_TangentialDeflection         myDiscretTool;
247   GeomAbs_IsoType                     myIsoType;
248 };
249
250 #endif