0024428: Implementation of LGPL license
[occt.git] / src / ChFi2d / ChFi2d_FilletAlgo.hxx
1 // Created on: 2013-05-20
2 // Created by: Mikhail PONIKAROV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
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
8 // under the terms of the GNU Lesser General Public 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 _FILLETALGO_H_
17 #define _FILLETALGO_H_
18
19 #include <TopoDS_Edge.hxx>
20 #include <TopoDS_Wire.hxx>
21 #include <gp_Pnt.hxx>
22 #include <Geom2d_Curve.hxx>
23 #include <Geom_Plane.hxx>
24 #include <TColStd_ListOfReal.hxx>
25 #include <TColStd_SequenceOfReal.hxx>
26 #include <TColStd_SequenceOfInteger.hxx>
27
28 class FilletPoint;
29
30 //! Algorithm that creates fillet edge: arc tangent to two edges in the start
31 //! and in the end vertices. Initial edges must be located on the plane and 
32 //! must be connected by the end or start points (shared vertices are not 
33 //! obligatory). Created fillet arc is created with the given radius, that is
34 //! useful in sketcher applications.
35 //! 
36 //! The algorithm is iterative that allows to create fillet on any curves
37 //! of initial edges, that supports projection of point and C2 continuous.
38 //! Principles of algorithm can de reduced to the Newton method:
39 //! 1. Splitting initial edge into N segments where probably only 1 root can be
40 //!    found. N depends on the complexity of the underlying curve.
41 //! 2. On each segment compute value and derivative of the function:
42 //!    - argument of the function is the parameter on the curve
43 //!    - take point on the curve by the parameter: point of tangency
44 //!    - make center of fillet: perpendicular vector from the point of tagency
45 //!    - make projection from the center to the second curve
46 //!    - length of the projection minus radius of the fillet is result of the 
47 //!      function
48 //!    - derivative of this function in the point is computed by value in 
49 //!      point with small shift
50 //! 3. Using Newton search method take the point on the segment where function
51 //!    value is most close to zero. If it is not enough close, step 2 and 3 are
52 //!    repeated taking as start or end point the found point.
53 //! 4. If solution is found, result is created on point on root of the function
54 //!    (as a start point), point of the projection onto second curve (as an end 
55 //!    point) and center of arc in found center. Initial edges are cutted by
56 //!    the start and end point of tangency.
57 class ChFi2d_FilletAlgo 
58 {
59 public:
60
61   //! An empty constructor of the fillet algorithm.
62   //! Call a method Init() to initialize the algorithm
63   //! before calling of a Perform() method.
64   Standard_EXPORT ChFi2d_FilletAlgo();
65
66   //! A constructor of a fillet algorithm: accepts a wire consisting of two edges in a plane.
67   Standard_EXPORT ChFi2d_FilletAlgo(const TopoDS_Wire& theWire, 
68                                     const gp_Pln& thePlane);
69
70   //! A constructor of a fillet algorithm: accepts two edges in a plane.
71   Standard_EXPORT ChFi2d_FilletAlgo(const TopoDS_Edge& theEdge1, 
72                                     const TopoDS_Edge& theEdge2, 
73                                     const gp_Pln& thePlane);
74
75   //! Initializes a fillet algorithm: accepts a wire consisting of two edges in a plane.
76   Standard_EXPORT void Init(const TopoDS_Wire& theWire, 
77                             const gp_Pln& thePlane);
78
79   //! Initializes a fillet algorithm: accepts two edges in a plane.
80   Standard_EXPORT void Init(const TopoDS_Edge& theEdge1, 
81                             const TopoDS_Edge& theEdge2, 
82                             const gp_Pln& thePlane);
83
84   //! Constructs a fillet edge.
85   //! Returns true, if at least one result was found
86   Standard_EXPORT Standard_Boolean Perform(const Standard_Real theRadius);
87
88   //! Returns number of possible solutions.
89   //! <thePoint> chooses a particular fillet in case of several fillets 
90   //! may be constructed (for example, a circle intersecting a segment in 2 points).
91   //! Put the intersecting (or common) point of the edges.
92   Standard_EXPORT Standard_Integer NbResults(const gp_Pnt& thePoint);
93
94   //! Returns result (fillet edge, modified edge1, modified edge2), 
95   //! neares to the given point <thePoint> if iSolution == -1.
96   //! <thePoint> chooses a particular fillet in case of several fillets 
97   //! may be constructed (for example, a circle intersecting a segment in 2 points).
98   //! Put the intersecting (or common) point of the edges.
99   Standard_EXPORT TopoDS_Edge Result(const gp_Pnt& thePoint, 
100                                      TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2, 
101                                      const Standard_Integer iSolution = -1);
102
103 private:
104   //! Computes the value the function in the current point.
105   //! <theLimit> is end parameter of the segment
106   void FillPoint(FilletPoint*, const Standard_Real theLimit);
107   //! Computes the derivative value of the function in the current point.
108   //! <theDiffStep> is small step for approximate derivative computation
109   //! <theFront> is direction of the step: from or reverced
110   void FillDiff(FilletPoint*, Standard_Real theDiffStep, Standard_Boolean theFront);
111   //! Using Newton methods computes optimal point, that can be root of the
112   //! function taking into account two input points, functions value and derivatives.
113   //! Performs iteration until root is found or failed to find root.
114   //! Stores roots in myResultParams.
115   void PerformNewton(FilletPoint*, FilletPoint*);
116   //! Splits segment by the parameter and calls Newton method for both segments.
117   //! It supplies recursive iterations of the Newthon methods calls 
118   //! (PerformNewton calls this function and this calls Netwton two times).
119   Standard_Boolean ProcessPoint(FilletPoint*, FilletPoint*, Standard_Real);
120
121   //! Initial edges where the fillet must be computed.
122   TopoDS_Edge myEdge1, myEdge2;
123   //! Plane where fillet arc must be created.
124   Handle(Geom_Plane) myPlane;
125   //! Underlying curves of the initial edges
126   Handle(Geom2d_Curve) myCurve1, myCurve2;
127   //! Start and end parameters of curves of initial edges.
128   Standard_Real myStart1, myEnd1, myStart2, myEnd2, myRadius;
129   //! List of params where roots were found.
130   TColStd_ListOfReal myResultParams;
131   //! sequence of 0 or 1: position of the fillet relatively to the first curve
132   TColStd_SequenceOfInteger myResultOrientation;
133   //! position of the fillet relatively to the first curve
134   Standard_Boolean myStartSide;
135   //! are initial edges where exchanged in the beginning: to make first edge 
136   //! more simple and minimize number of iterations
137   Standard_Boolean myEdgesExchnged;
138   //! Number to avoid infinity recursion: indicates how deep the recursion is performed.
139   Standard_Integer myDegreeOfRecursion;
140 };
141
142 //! Private class. Corresponds to the point on the first curve, computed
143 //! fillet function and derivative on it.
144 class FilletPoint 
145 {
146 public:
147   //! Creates a point on a first curve by parameter on this curve.
148   FilletPoint(Standard_Real theParam) : myParam2(0.)
149         {myParam = theParam;}
150
151   //! Changes the point position by changing point parameter on the first curve.
152   void setParam(Standard_Real theParam) {myParam = theParam;}
153   //! Returns the point parameter on the first curve.
154   Standard_Real getParam() const {return myParam;}
155
156   //! Returns number of found values of function in this point.
157   Standard_Integer getNBValues() {return myV.Length();}
158   //! Returns value of function in this point.
159   Standard_Real getValue(int theIndex) {return myV.Value(theIndex);}
160   //! Returns derivatives of function in this point.
161   Standard_Real getDiff(int theIndex) {return myD.Value(theIndex);}
162   //! Returns true if function is valid (rediuses vectors of fillet do not intersect any curve).
163   Standard_Boolean isValid(int theIndex) {return (Standard_Boolean)myValid.Value(theIndex);}
164   //! Returns the index of the nearest value
165   int getNear(int theIndex) {return myNear.Value(theIndex);}
166
167   //! Defines the parameter of the projected point on the second curve.
168   void setParam2(const Standard_Real theParam2) {myParam2 = theParam2;}
169   //! Returns the parameter of the projected point on the second curve.
170   Standard_Real getParam2() { return myParam2 ; }
171
172   //! Center of the fillet.
173   void setCenter(const gp_Pnt2d thePoint) {myCenter = thePoint;}
174   //! Center of the fillet.
175   const gp_Pnt2d getCenter() {return myCenter;}
176
177   //! Appends value of the function.
178   void appendValue(Standard_Real theValue, Standard_Boolean theValid);
179
180   //! Computes difference between this point and the given. Stores difference in myD.
181   Standard_Boolean calculateDiff(FilletPoint*);
182   //! Filters out the values and leaves the most optimal one.
183   void FilterPoints(FilletPoint*);
184
185   //! Returns a pointer to created copy of the point
186   //! warning: this is not the full copy! Copies only: myParam, myV, myD, myValid
187   FilletPoint* Copy(); 
188   //! Returns the index of the solution or zero if there is no solution
189   Standard_Integer hasSolution(Standard_Real theRadius);
190   //! For debug only
191   Standard_Real LowerValue() 
192   {
193     Standard_Integer a, aResultIndex = 0;
194     Standard_Real aValue;
195     for(a = myV.Length(); a > 0; a--) 
196     {
197       if (aResultIndex == 0 || Abs(aValue) > Abs(myV.Value(a))) 
198       {
199         aResultIndex = a;
200         aValue = myV.Value(a);
201       }
202     }
203     return aValue;
204   }
205   //! Removes the found value by the given index.
206   void remove(Standard_Integer theIndex);
207
208 private:
209   //! Parameter on the first curve (start fillet point).
210   Standard_Real myParam;
211   //! Parameter on the second curve (end fillet point).
212   Standard_Real myParam2;
213   //! Values and derivative values of the fillet function.
214   //! May be several if there are many projections on the second curve.
215   TColStd_SequenceOfReal myV, myD;
216   //! Center of the fillet arc.
217   gp_Pnt2d myCenter;
218   //! Flags for storage the validity of solutions. Indexes corresponds to indexes
219   //! in sequences myV, myD.
220   TColStd_SequenceOfInteger myValid, myNear;
221 };
222
223 #endif // _FILLETALGO_H_