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