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> |
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. |
cbff1e55 |
148 | FilletPoint(const Standard_Real theParam); |
8b7c5e47 |
149 | |
150 | //! Changes the point position by changing point parameter on the first curve. |
151 | void setParam(Standard_Real theParam) {myParam = theParam;} |
cbff1e55 |
152 | |
8b7c5e47 |
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();} |
cbff1e55 |
158 | |
8b7c5e47 |
159 | //! Returns value of function in this point. |
160 | Standard_Real getValue(int theIndex) {return myV.Value(theIndex);} |
cbff1e55 |
161 | |
8b7c5e47 |
162 | //! Returns derivatives of function in this point. |
163 | Standard_Real getDiff(int theIndex) {return myD.Value(theIndex);} |
cbff1e55 |
164 | |
8b7c5e47 |
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);} |
cbff1e55 |
167 | |
8b7c5e47 |
168 | //! Returns the index of the nearest value |
169 | int getNear(int theIndex) {return myNear.Value(theIndex);} |
170 | |
171 | //! Defines the parameter of the projected point on the second curve. |
172 | void setParam2(const Standard_Real theParam2) {myParam2 = theParam2;} |
cbff1e55 |
173 | |
8b7c5e47 |
174 | //! Returns the parameter of the projected point on the second curve. |
175 | Standard_Real getParam2() { return myParam2 ; } |
176 | |
177 | //! Center of the fillet. |
178 | void setCenter(const gp_Pnt2d thePoint) {myCenter = thePoint;} |
179 | //! Center of the fillet. |
180 | const gp_Pnt2d getCenter() {return myCenter;} |
181 | |
182 | //! Appends value of the function. |
183 | void appendValue(Standard_Real theValue, Standard_Boolean theValid); |
184 | |
185 | //! Computes difference between this point and the given. Stores difference in myD. |
186 | Standard_Boolean calculateDiff(FilletPoint*); |
cbff1e55 |
187 | |
8b7c5e47 |
188 | //! Filters out the values and leaves the most optimal one. |
189 | void FilterPoints(FilletPoint*); |
190 | |
191 | //! Returns a pointer to created copy of the point |
192 | //! warning: this is not the full copy! Copies only: myParam, myV, myD, myValid |
cbff1e55 |
193 | FilletPoint* Copy(); |
194 | |
8b7c5e47 |
195 | //! Returns the index of the solution or zero if there is no solution |
196 | Standard_Integer hasSolution(Standard_Real theRadius); |
cbff1e55 |
197 | |
8b7c5e47 |
198 | //! For debug only |
199 | Standard_Real LowerValue() |
200 | { |
201 | Standard_Integer a, aResultIndex = 0; |
202 | Standard_Real aValue; |
203 | for(a = myV.Length(); a > 0; a--) |
204 | { |
205 | if (aResultIndex == 0 || Abs(aValue) > Abs(myV.Value(a))) |
206 | { |
207 | aResultIndex = a; |
208 | aValue = myV.Value(a); |
209 | } |
210 | } |
211 | return aValue; |
212 | } |
213 | //! Removes the found value by the given index. |
214 | void remove(Standard_Integer theIndex); |
215 | |
216 | private: |
217 | //! Parameter on the first curve (start fillet point). |
218 | Standard_Real myParam; |
219 | //! Parameter on the second curve (end fillet point). |
220 | Standard_Real myParam2; |
221 | //! Values and derivative values of the fillet function. |
222 | //! May be several if there are many projections on the second curve. |
223 | TColStd_SequenceOfReal myV, myD; |
224 | //! Center of the fillet arc. |
225 | gp_Pnt2d myCenter; |
226 | //! Flags for storage the validity of solutions. Indexes corresponds to indexes |
227 | //! in sequences myV, myD. |
228 | TColStd_SequenceOfInteger myValid, myNear; |
229 | }; |
230 | |
231 | #endif // _FILLETALGO_H_ |