0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / ChFi2d / ChFi2d_ChamferAPI.cxx
1 // Copyright (c) 1999-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <ChFi2d_ChamferAPI.hxx>
15
16 #include <Precision.hxx>
17 #include <gp_Pnt.hxx>
18 #include <GC_MakeLine.hxx>
19 #include <Geom_Line.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepBuilderAPI_MakeEdge.hxx>
22 #include <TopoDS_Iterator.hxx>
23 #include <TopoDS.hxx>
24
25 // An empty constructor.
26 ChFi2d_ChamferAPI::ChFi2d_ChamferAPI()
27 : myStart1(0.0),
28   myEnd1  (0.0),
29   myStart2(0.0),
30   myEnd2  (0.0),
31   myCommonStart1(Standard_False),
32   myCommonStart2(Standard_False)
33 {
34 }
35
36 // A constructor accepting a wire consisting of two linear edges.
37 ChFi2d_ChamferAPI::ChFi2d_ChamferAPI(const TopoDS_Wire& theWire)
38 : myStart1(0.0),
39   myEnd1  (0.0),
40   myStart2(0.0),
41   myEnd2  (0.0),
42   myCommonStart1(Standard_False),
43   myCommonStart2(Standard_False)
44 {
45   Init(theWire);
46 }
47
48 // A constructor accepting two linear edges.
49 ChFi2d_ChamferAPI::ChFi2d_ChamferAPI(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
50 : myEdge1(theEdge1),
51   myEdge2(theEdge2),
52   myStart1(0.0),
53   myEnd1  (0.0),
54   myStart2(0.0),
55   myEnd2  (0.0),
56   myCommonStart1(Standard_False),
57   myCommonStart2(Standard_False)
58 {
59 }
60
61 // Initializes the class by a wire consisting of two libear edges.
62 void ChFi2d_ChamferAPI::Init(const TopoDS_Wire& theWire)
63 {
64   TopoDS_Edge E1, E2;
65   TopoDS_Iterator itr(theWire);
66   for (; itr.More(); itr.Next())
67   {
68     if (E1.IsNull())
69       E1 = TopoDS::Edge(itr.Value());
70     else if (E2.IsNull())
71       E2 = TopoDS::Edge(itr.Value());
72     else
73       break;
74   }
75   Init(E1, E2);
76 }
77
78 // Initializes the class by two linear edges.
79 void ChFi2d_ChamferAPI::Init(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
80 {
81   myEdge1 = theEdge1;
82   myEdge2 = theEdge2;
83 }
84
85 // Constructs a chamfer edge.
86 // Returns true if the edge is constructed.
87 Standard_Boolean ChFi2d_ChamferAPI::Perform()
88 {
89   myCurve1 = BRep_Tool::Curve(myEdge1, myStart1, myEnd1);
90   myCurve2 = BRep_Tool::Curve(myEdge2, myStart2, myEnd2);
91   // searching for common points
92   if (myCurve1->Value(myStart1).IsEqual(myCurve2->Value(myEnd2), Precision::Confusion())) 
93   {
94     myCommonStart1 = true;
95     myCommonStart2 = false;
96   } 
97   else 
98   {
99     if (myCurve1->Value(myEnd1).IsEqual(myCurve2->Value(myStart2), Precision::Confusion())) 
100     {
101       myCommonStart1 = false;
102       myCommonStart2 = true;
103     } 
104     else
105     {
106       if (myCurve1->Value(myEnd1).IsEqual(myCurve2->Value(myEnd2), Precision::Confusion())) 
107       {
108         myCommonStart1 = false;
109         myCommonStart2 = false;
110       } 
111       else 
112       {
113         myCommonStart1 = true;
114         myCommonStart2 = true;
115       }
116     }
117   }
118   return Standard_True;
119 }
120
121 // Returns the result (chamfer edge, modified edge1, modified edge2).
122 TopoDS_Edge ChFi2d_ChamferAPI::Result(TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2,
123                                       const Standard_Real theLength1, const Standard_Real theLength2) 
124 {
125   TopoDS_Edge aResult;
126   if (Abs(myEnd1 - myStart1) < theLength1) 
127     return aResult;
128   if (Abs(myEnd2 - myStart2) < theLength2) 
129     return aResult;
130
131   Standard_Real aCommon1 = (myCommonStart1?myStart1:myEnd1) + (((myStart1 > myEnd1)^myCommonStart1)?theLength1:-theLength1);
132   Standard_Real aCommon2 = (myCommonStart2?myStart2:myEnd2) + (((myStart2 > myEnd2)^myCommonStart2)?theLength2:-theLength2);
133
134   // make chamfer edge
135   GC_MakeLine aML(myCurve1->Value(aCommon1), myCurve2->Value(aCommon2));
136   BRepBuilderAPI_MakeEdge aBuilder(aML.Value(), myCurve1->Value(aCommon1), myCurve2->Value(aCommon2));
137   aResult = aBuilder.Edge();
138   // divide first edge
139   BRepBuilderAPI_MakeEdge aDivider1(myCurve1, aCommon1, (myCommonStart1?myEnd1:myStart1));
140   theEdge1 = aDivider1.Edge();
141   // divide second edge
142   BRepBuilderAPI_MakeEdge aDivider2(myCurve2, aCommon2, (myCommonStart2?myEnd2:myStart2));
143   theEdge2 = aDivider2.Edge();
144
145   return aResult;
146 }