--- /dev/null
+// Created on: 2013-05-20
+// Created by: Mikhail PONIKAROV
+// Copyright (c) 2003-2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _FILLETALGO_H_
+#define _FILLETALGO_H_
+
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Wire.hxx>
+#include <gp_Pnt.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom_Plane.hxx>
+#include <TColStd_ListOfReal.hxx>
+#include <TColStd_SequenceOfReal.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
+
+class FilletPoint;
+
+//! Algorithm that creates fillet edge: arc tangent to two edges in the start
+//! and in the end vertices. Initial edges must be located on the plane and
+//! must be connected by the end or start points (shared vertices are not
+//! obligatory). Created fillet arc is created with the given radius, that is
+//! useful in sketcher applications.
+//!
+//! The algorithm is iterative that allows to create fillet on any curves
+//! of initial edges, that supports projection of point and C2 continuous.
+//! Principles of algorithm can de reduced to the Newton method:
+//! 1. Splitting initial edge into N segments where probably only 1 root can be
+//! found. N depends on the complexity of the underlying curve.
+//! 2. On each segment compute value and derivative of the function:
+//! - argument of the function is the parameter on the curve
+//! - take point on the curve by the parameter: point of tangency
+//! - make center of fillet: perpendicular vector from the point of tagency
+//! - make projection from the center to the second curve
+//! - length of the projection minus radius of the fillet is result of the
+//! function
+//! - derivative of this function in the point is computed by value in
+//! point with small shift
+//! 3. Using Newton search method take the point on the segment where function
+//! value is most close to zero. If it is not enough close, step 2 and 3 are
+//! repeated taking as start or end point the found point.
+//! 4. If solution is found, result is created on point on root of the function
+//! (as a start point), point of the projection onto second curve (as an end
+//! point) and center of arc in found center. Initial edges are cutted by
+//! the start and end point of tangency.
+class ChFi2d_FilletAlgo
+{
+public:
+
+ //! An empty constructor of the fillet algorithm.
+ //! Call a method Init() to initialize the algorithm
+ //! before calling of a Perform() method.
+ Standard_EXPORT ChFi2d_FilletAlgo();
+
+ //! A constructor of a fillet algorithm: accepts a wire consisting of two edges in a plane.
+ Standard_EXPORT ChFi2d_FilletAlgo(const TopoDS_Wire& theWire,
+ const gp_Pln& thePlane);
+
+ //! A constructor of a fillet algorithm: accepts two edges in a plane.
+ Standard_EXPORT ChFi2d_FilletAlgo(const TopoDS_Edge& theEdge1,
+ const TopoDS_Edge& theEdge2,
+ const gp_Pln& thePlane);
+
+ //! Initializes a fillet algorithm: accepts a wire consisting of two edges in a plane.
+ Standard_EXPORT void Init(const TopoDS_Wire& theWire,
+ const gp_Pln& thePlane);
+
+ //! Initializes a fillet algorithm: accepts two edges in a plane.
+ Standard_EXPORT void Init(const TopoDS_Edge& theEdge1,
+ const TopoDS_Edge& theEdge2,
+ const gp_Pln& thePlane);
+
+ //! Constructs a fillet edge.
+ //! Returns true, if at least one result was found
+ Standard_EXPORT Standard_Boolean Perform(const Standard_Real theRadius);
+
+ //! Returns number of possible solutions.
+ //! <thePoint> chooses a particular fillet in case of several fillets
+ //! may be constructed (for example, a circle intersecting a segment in 2 points).
+ //! Put the intersecting (or common) point of the edges.
+ Standard_EXPORT Standard_Integer NbResults(const gp_Pnt& thePoint);
+
+ //! Returns result (fillet edge, modified edge1, modified edge2),
+ //! neares to the given point <thePoint> if iSolution == -1.
+ //! <thePoint> chooses a particular fillet in case of several fillets
+ //! may be constructed (for example, a circle intersecting a segment in 2 points).
+ //! Put the intersecting (or common) point of the edges.
+ Standard_EXPORT TopoDS_Edge Result(const gp_Pnt& thePoint,
+ TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2,
+ const Standard_Integer iSolution = -1);
+
+private:
+ //! Computes the value the function in the current point.
+ //! <theLimit> is end parameter of the segment
+ void FillPoint(FilletPoint*, const Standard_Real theLimit);
+ //! Computes the derivative value of the function in the current point.
+ //! <theDiffStep> is small step for approximate derivative computation
+ //! <theFront> is direction of the step: from or reverced
+ void FillDiff(FilletPoint*, Standard_Real theDiffStep, Standard_Boolean theFront);
+ //! Using Newton methods computes optimal point, that can be root of the
+ //! function taking into account two input points, functions value and derivatives.
+ //! Performs iteration until root is found or failed to find root.
+ //! Stores roots in myResultParams.
+ void PerformNewton(FilletPoint*, FilletPoint*);
+ //! Splits segment by the parameter and calls Newton method for both segments.
+ //! It supplies recursive iterations of the Newthon methods calls
+ //! (PerformNewton calls this function and this calls Netwton two times).
+ Standard_Boolean ProcessPoint(FilletPoint*, FilletPoint*, Standard_Real);
+
+ //! Initial edges where the fillet must be computed.
+ TopoDS_Edge myEdge1, myEdge2;
+ //! Plane where fillet arc must be created.
+ Handle(Geom_Plane) myPlane;
+ //! Underlying curves of the initial edges
+ Handle(Geom2d_Curve) myCurve1, myCurve2;
+ //! Start and end parameters of curves of initial edges.
+ Standard_Real myStart1, myEnd1, myStart2, myEnd2, myRadius;
+ //! List of params where roots were found.
+ TColStd_ListOfReal myResultParams;
+ //! sequence of 0 or 1: position of the fillet relatively to the first curve
+ TColStd_SequenceOfInteger myResultOrientation;
+ //! position of the fillet relatively to the first curve
+ Standard_Boolean myStartSide;
+ //! are initial edges where exchanged in the beginning: to make first edge
+ //! more simple and minimize number of iterations
+ Standard_Boolean myEdgesExchnged;
+ //! Number to avoid infinity recursion: indicates how deep the recursion is performed.
+ Standard_Integer myDegreeOfRecursion;
+};
+
+//! Private class. Corresponds to the point on the first curve, computed
+//! fillet function and derivative on it.
+class FilletPoint
+{
+public:
+ //! Creates a point on a first curve by parameter on this curve.
+ FilletPoint(Standard_Real theParam) {myParam = theParam;}
+
+ //! Changes the point position by changing point parameter on the first curve.
+ void setParam(Standard_Real theParam) {myParam = theParam;}
+ //! Returns the point parameter on the first curve.
+ Standard_Real getParam() const {return myParam;}
+
+ //! Returns number of found values of function in this point.
+ Standard_Integer getNBValues() {return myV.Length();}
+ //! Returns value of function in this point.
+ Standard_Real getValue(int theIndex) {return myV.Value(theIndex);}
+ //! Returns derivatives of function in this point.
+ Standard_Real getDiff(int theIndex) {return myD.Value(theIndex);}
+ //! Returns true if function is valid (rediuses vectors of fillet do not intersect any curve).
+ Standard_Boolean isValid(int theIndex) {return (Standard_Boolean)myValid.Value(theIndex);}
+ //! Returns the index of the nearest value
+ int getNear(int theIndex) {return myNear.Value(theIndex);}
+
+ //! Defines the parameter of the projected point on the second curve.
+ void setParam2(const Standard_Real theParam2) {myParam2 = theParam2;}
+ //! Returns the parameter of the projected point on the second curve.
+ Standard_Real getParam2() { return myParam2 ; }
+
+ //! Center of the fillet.
+ void setCenter(const gp_Pnt2d thePoint) {myCenter = thePoint;}
+ //! Center of the fillet.
+ const gp_Pnt2d getCenter() {return myCenter;}
+
+ //! Appends value of the function.
+ void appendValue(Standard_Real theValue, Standard_Boolean theValid);
+
+ //! Computes difference between this point and the given. Stores difference in myD.
+ Standard_Boolean calculateDiff(FilletPoint*);
+ //! Filters out the values and leaves the most optimal one.
+ void FilterPoints(FilletPoint*);
+
+ //! Returns a pointer to created copy of the point
+ //! warning: this is not the full copy! Copies only: myParam, myV, myD, myValid
+ FilletPoint* Copy();
+ //! Returns the index of the solution or zero if there is no solution
+ Standard_Integer hasSolution(Standard_Real theRadius);
+ //! For debug only
+ Standard_Real LowerValue()
+ {
+ Standard_Integer a, aResultIndex = 0;
+ Standard_Real aValue;
+ for(a = myV.Length(); a > 0; a--)
+ {
+ if (aResultIndex == 0 || Abs(aValue) > Abs(myV.Value(a)))
+ {
+ aResultIndex = a;
+ aValue = myV.Value(a);
+ }
+ }
+ return aValue;
+ }
+ //! Removes the found value by the given index.
+ void remove(Standard_Integer theIndex);
+
+private:
+ //! Parameter on the first curve (start fillet point).
+ Standard_Real myParam;
+ //! Parameter on the second curve (end fillet point).
+ Standard_Real myParam2;
+ //! Values and derivative values of the fillet function.
+ //! May be several if there are many projections on the second curve.
+ TColStd_SequenceOfReal myV, myD;
+ //! Center of the fillet arc.
+ gp_Pnt2d myCenter;
+ //! Flags for storage the validity of solutions. Indexes corresponds to indexes
+ //! in sequences myV, myD.
+ TColStd_SequenceOfInteger myValid, myNear;
+};
+
+#endif // _FILLETALGO_H_