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