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 under 8 // the terms of the GNU Lesser General Public License 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 ChFi2d_FilletAlgo_HeaderFile 17 #define ChFi2d_FilletAlgo_HeaderFile 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_SequenceOfBoolean.hxx> 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 (as a start point), 55 //! point of the projection onto second curve (as an end point) and center of arc in found center. 56 //! Initial edges are cut by 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 //! nearest 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 reversed 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 Newton 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(const Standard_Real theParam); 149 150 //! Changes the point position by changing point parameter on the first curve. setParam(Standard_Real theParam)151 void setParam(Standard_Real theParam) {myParam = theParam;} 152 153 //! Returns the point parameter on the first curve. getParam() const154 Standard_Real getParam() const {return myParam;} 155 156 //! Returns number of found values of function in this point. getNBValues()157 Standard_Integer getNBValues() {return myV.Length();} 158 159 //! Returns value of function in this point. getValue(int theIndex)160 Standard_Real getValue(int theIndex) {return myV.Value(theIndex);} 161 162 //! Returns derivatives of function in this point. getDiff(int theIndex)163 Standard_Real getDiff(int theIndex) {return myD.Value(theIndex);} 164 165 //! Returns true if function is valid (rediuses vectors of fillet do not intersect any curve). isValid(int theIndex)166 Standard_Boolean isValid(int theIndex) {return myValid.Value(theIndex);} 167 168 //! Returns the index of the nearest value getNear(int theIndex)169 int getNear(int theIndex) {return myNear.Value(theIndex);} 170 171 //! Defines the parameter of the projected point on the second curve. setParam2(const Standard_Real theParam2)172 void setParam2(const Standard_Real theParam2) {myParam2 = theParam2;} 173 174 //! Returns the parameter of the projected point on the second curve. getParam2()175 Standard_Real getParam2() { return myParam2 ; } 176 177 //! Center of the fillet. setCenter(const gp_Pnt2d thePoint)178 void setCenter(const gp_Pnt2d thePoint) {myCenter = thePoint;} 179 //! Center of the fillet. getCenter()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*); 187 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 193 FilletPoint* Copy(); 194 195 //! Returns the index of the solution or zero if there is no solution 196 Standard_Integer hasSolution(Standard_Real theRadius); 197 198 //! For debug only LowerValue()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_SequenceOfBoolean myValid; 229 TColStd_SequenceOfInteger myNear; 230 }; 231 232 #endif // _FILLETALGO_H_ 233