973c2be1 |
1 | // Created on: 2013-06-06 |
2 | // Created by: Vlad ROMASHKO |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
4 | // |
5 | // This file is part of Open CASCADE Technology software library. |
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. |
12 | // |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
15 | |
8b7c5e47 |
16 | #include <ChFi2d_FilletAPI.hxx> |
17 | #include <BRepAdaptor_Curve.hxx> |
18 | #include <TopoDS_Iterator.hxx> |
19 | #include <TopoDS.hxx> |
20 | |
21 | // An empty constructor of the fillet algorithm. |
22 | // Call a method Init() to initialize the algorithm |
23 | // before calling of a Perform() method. |
24 | ChFi2d_FilletAPI::ChFi2d_FilletAPI():myIsAnalytical(Standard_False) |
25 | { |
26 | |
27 | } |
28 | |
29 | // A constructor of a fillet algorithm: accepts a wire consisting of two edges in a plane. |
30 | ChFi2d_FilletAPI::ChFi2d_FilletAPI(const TopoDS_Wire& theWire, |
31 | const gp_Pln& thePlane):myIsAnalytical(Standard_False) |
32 | { |
33 | Init(theWire, thePlane); |
34 | } |
35 | |
36 | // A constructor of a fillet algorithm: accepts two edges in a plane. |
37 | ChFi2d_FilletAPI::ChFi2d_FilletAPI(const TopoDS_Edge& theEdge1, |
38 | const TopoDS_Edge& theEdge2, |
39 | const gp_Pln& thePlane):myIsAnalytical(Standard_False) |
40 | { |
41 | Init(theEdge1, theEdge2, thePlane); |
42 | } |
43 | |
44 | // Initializes a fillet algorithm: accepts a wire consisting of two edges in a plane. |
45 | void ChFi2d_FilletAPI::Init(const TopoDS_Wire& theWire, |
46 | const gp_Pln& thePlane) |
47 | { |
48 | // Decide whether we may apply an analytical solution. |
49 | TopoDS_Edge E1, E2; |
50 | TopoDS_Iterator itr(theWire); |
51 | for (; itr.More(); itr.Next()) |
52 | { |
53 | if (E1.IsNull()) |
54 | E1 = TopoDS::Edge(itr.Value()); |
55 | else if (E2.IsNull()) |
56 | E2 = TopoDS::Edge(itr.Value()); |
57 | else |
58 | break; |
59 | } |
60 | if (!E1.IsNull() && !E2.IsNull()) |
61 | myIsAnalytical = IsAnalytical(E1, E2); |
62 | |
63 | // Initialize the algorithm. |
64 | myIsAnalytical ? myAnaFilletAlgo.Init(theWire, thePlane) : |
65 | myFilletAlgo.Init(theWire, thePlane); |
66 | } |
67 | |
68 | // Initializes a fillet algorithm: accepts two edges in a plane. |
69 | void ChFi2d_FilletAPI::Init(const TopoDS_Edge& theEdge1, |
70 | const TopoDS_Edge& theEdge2, |
71 | const gp_Pln& thePlane) |
72 | { |
73 | // Decide whether we may apply an analytical solution. |
74 | myIsAnalytical = IsAnalytical(theEdge1, theEdge2); |
75 | |
76 | // Initialize the algorithm. |
77 | myIsAnalytical ? myAnaFilletAlgo.Init(theEdge1, theEdge2, thePlane) : |
78 | myFilletAlgo.Init(theEdge1, theEdge2, thePlane); |
79 | } |
80 | |
81 | // Returns true, if at least one result was found. |
82 | Standard_Boolean ChFi2d_FilletAPI::Perform(const Standard_Real theRadius) |
83 | { |
84 | return myIsAnalytical ? myAnaFilletAlgo.Perform(theRadius) : |
85 | myFilletAlgo.Perform(theRadius); |
86 | } |
87 | |
88 | // Returns number of possible solutions. |
89 | Standard_Integer ChFi2d_FilletAPI::NbResults(const gp_Pnt& thePoint) |
90 | { |
91 | return myIsAnalytical ? 1 : myFilletAlgo.NbResults(thePoint); |
92 | } |
93 | |
94 | // Returns result (fillet edge, modified edge1, modified edge2), |
95 | // nearest to the given point <thePoint> if iSolution == -1 |
96 | TopoDS_Edge ChFi2d_FilletAPI::Result(const gp_Pnt& thePoint, |
97 | TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2, |
98 | const Standard_Integer iSolution) |
99 | { |
100 | return myIsAnalytical ? myAnaFilletAlgo.Result(theEdge1, theEdge2) : |
101 | myFilletAlgo.Result(thePoint, theEdge1, theEdge2, iSolution); |
102 | } |
103 | |
104 | // Decides whether the input parameters may use an analytical algorithm |
105 | // for calculation of the fillets, or an iteration-recursive method is needed. |
106 | // The analytical solution is applicable for linear and circular edges having a common point. |
107 | Standard_Boolean ChFi2d_FilletAPI::IsAnalytical(const TopoDS_Edge& theEdge1, |
108 | const TopoDS_Edge& theEdge2) |
109 | { |
110 | Standard_Boolean ret(Standard_False); |
111 | BRepAdaptor_Curve AC1(theEdge1), AC2(theEdge2); |
112 | if ((AC1.GetType() == GeomAbs_Line || AC1.GetType() == GeomAbs_Circle) && |
113 | (AC2.GetType() == GeomAbs_Line || AC2.GetType() == GeomAbs_Circle)) |
114 | { |
115 | // The edges are lines or arcs of circle. |
116 | // Now check wether they have a common point. |
117 | gp_Pnt p11 = AC1.Value(AC1.FirstParameter()); |
118 | gp_Pnt p12 = AC1.Value(AC1.LastParameter()); |
119 | gp_Pnt p21 = AC2.Value(AC2.FirstParameter()); |
120 | gp_Pnt p22 = AC2.Value(AC2.LastParameter()); |
121 | if (p11.SquareDistance(p21) < Precision::SquareConfusion() || |
122 | p11.SquareDistance(p22) < Precision::SquareConfusion() || |
123 | p12.SquareDistance(p21) < Precision::SquareConfusion() || |
124 | p12.SquareDistance(p22) < Precision::SquareConfusion()) |
125 | { |
126 | ret = Standard_True; |
127 | } |
128 | } |
129 | return ret; |
130 | } |