0024002: Overall code and build procedure refactoring -- automatic
[occt.git] / src / BRepClass / BRepClass_FaceExplorer.cxx
1 // Created on: 1992-11-19
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //  Modified by skv - Thu Jul 13 17:42:58 2006 OCC12627
18 //  Total rewriting of the method Segment; add the method OtherSegment.
19
20 #include <BRep_Tool.hxx>
21 #include <BRepClass_Edge.hxx>
22 #include <BRepClass_FaceExplorer.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <gp_Lin2d.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <Precision.hxx>
27 #include <TopoDS.hxx>
28 #include <TopoDS_Face.hxx>
29
30 static const Standard_Real Probing_Start = 0.123;
31 static const Standard_Real Probing_End = 0.7;
32 static const Standard_Real Probing_Step = 0.2111;
33
34 //=======================================================================
35 //function : BRepClass_FaceExplorer
36 //purpose  : 
37 //=======================================================================
38
39 BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
40        myFace(F),
41        myCurEdgeInd(1),
42        myCurEdgePar(Probing_Start)
43 {
44   myFace.Orientation(TopAbs_FORWARD);
45 }
46
47 //=======================================================================
48 //function : Reject
49 //purpose  : 
50 //=======================================================================
51
52 Standard_Boolean  BRepClass_FaceExplorer::Reject(const gp_Pnt2d&)const 
53 {
54   return Standard_False;
55 }
56
57 //=======================================================================
58 //function : Segment
59 //purpose  : 
60 //=======================================================================
61
62 Standard_Boolean BRepClass_FaceExplorer::Segment(const gp_Pnt2d& P, 
63                                                  gp_Lin2d& L,
64                                                  Standard_Real& Par)
65 {
66   myCurEdgeInd = 1;
67   myCurEdgePar = Probing_Start;
68
69   return OtherSegment(P, L, Par);
70 }
71
72 //=======================================================================
73 //function : OtherSegment
74 //purpose  : 
75 //=======================================================================
76
77 Standard_Boolean BRepClass_FaceExplorer::OtherSegment(const gp_Pnt2d& P, 
78                                                       gp_Lin2d& L,
79                                                       Standard_Real& Par)
80 {
81   TopExp_Explorer      anExpF(myFace,TopAbs_EDGE);
82   Standard_Integer     i;
83   Standard_Real        aFPar;
84   Standard_Real        aLPar;
85   Handle(Geom2d_Curve) aC2d;
86   Standard_Real        aTolParConf2 = Precision::PConfusion() * Precision::PConfusion();
87   gp_Pnt2d             aPOnC;
88   Standard_Real        aParamIn;
89
90   for (i = 1; anExpF.More(); anExpF.Next(), i++) {
91     if (i != myCurEdgeInd)
92       continue;
93
94     const TopoDS_Shape       &aLocalShape   = anExpF.Current();
95     const TopAbs_Orientation  anOrientation = aLocalShape.Orientation();
96
97     if (anOrientation == TopAbs_FORWARD || anOrientation == TopAbs_REVERSED) {
98       const TopoDS_Edge &anEdge = TopoDS::Edge(aLocalShape);
99
100       aC2d = BRep_Tool::CurveOnSurface(anEdge, myFace, aFPar, aLPar);
101
102       if (!aC2d.IsNull()) {
103         // Treatment of infinite cases.
104         if (Precision::IsNegativeInfinite(aFPar)) {
105           if (Precision::IsPositiveInfinite(aLPar)) {
106             aFPar = -1.;
107             aLPar =  1.;
108           } else {
109             aFPar = aLPar - 1.;
110           }
111         } else if (Precision::IsPositiveInfinite(aLPar))
112           aLPar = aFPar + 1.;
113
114         for (; myCurEdgePar < Probing_End ;myCurEdgePar += Probing_Step) {
115           aParamIn = myCurEdgePar*aFPar + (1. - myCurEdgePar)*aLPar;
116
117           gp_Vec2d aTanVec;
118           aC2d->D1(aParamIn, aPOnC, aTanVec);
119           Par = aPOnC.SquareDistance(P);
120
121           if (Par > aTolParConf2) {
122             gp_Vec2d aLinVec(P, aPOnC);
123             gp_Dir2d aLinDir(aLinVec);
124
125             Standard_Real aTanMod = aTanVec.SquareMagnitude();
126             if (aTanMod < aTolParConf2)
127               continue;
128             aTanVec /= Sqrt(aTanMod);
129             Standard_Real aSinA = aTanVec.Crossed(aLinDir.XY());
130             const Standard_Real SmallAngle = 0.001;
131             if (Abs(aSinA) < SmallAngle)
132             {
133               // The line from the input point P to the current point on edge
134               // is tangent to the edge curve. This condition is bad for classification.
135               // Therefore try to go to another point in the hope that there will be 
136               // no tangent. If there tangent is preserved then leave the last point in 
137               // order to get this edge chanse to participate in classification.
138               if (myCurEdgePar + Probing_Step < Probing_End)
139                 continue;
140             }
141
142             L = gp_Lin2d(P, aLinDir);
143
144             // Check if ends of a curve lie on a line.
145             aC2d->D0(aFPar, aPOnC);
146
147             if (L.SquareDistance(aPOnC) > aTolParConf2) {
148               aC2d->D0(aLPar, aPOnC);
149
150               if (L.SquareDistance(aPOnC) > aTolParConf2) {
151                 myCurEdgePar += Probing_Step;
152
153                 if (myCurEdgePar >= Probing_End) {
154                   myCurEdgeInd++;
155                   myCurEdgePar = Probing_Start;
156                 }
157
158                 Par = Sqrt(Par);
159                 return Standard_True;
160               }
161             }
162           }
163         }
164       } // if (!aC2d.IsNull()) {
165     } // if (anOrientation == TopAbs_FORWARD ...
166
167     // This curve is not valid for line construction. Go to another edge.
168     myCurEdgeInd++;
169     myCurEdgePar = Probing_Start;
170   }
171
172   // nothing found, return an horizontal line
173   Par = RealLast();
174   L   = gp_Lin2d(P,gp_Dir2d(1,0));
175
176   return Standard_False;
177 }
178
179 //=======================================================================
180 //function : InitWires
181 //purpose  : 
182 //=======================================================================
183
184 void  BRepClass_FaceExplorer::InitWires()
185 {
186   myWExplorer.Init(myFace,TopAbs_WIRE);
187 }
188
189 //=======================================================================
190 //function : RejectWire NYI
191 //purpose  : 
192 //=======================================================================
193
194 Standard_Boolean  BRepClass_FaceExplorer::RejectWire
195   (const gp_Lin2d& , 
196    const Standard_Real)const 
197 {
198   return Standard_False;
199 }
200
201 //=======================================================================
202 //function : InitEdges
203 //purpose  : 
204 //=======================================================================
205
206 void  BRepClass_FaceExplorer::InitEdges()
207 {
208   myEExplorer.Init(myWExplorer.Current(),TopAbs_EDGE);
209 }
210
211 //=======================================================================
212 //function : RejectEdge NYI
213 //purpose  : 
214 //=======================================================================
215
216 Standard_Boolean  BRepClass_FaceExplorer::RejectEdge
217   (const gp_Lin2d& , 
218    const Standard_Real )const 
219 {
220   return Standard_False;
221 }
222
223
224 //=======================================================================
225 //function : CurrentEdge
226 //purpose  : 
227 //=======================================================================
228
229 void  BRepClass_FaceExplorer::CurrentEdge(BRepClass_Edge& E, 
230                                           TopAbs_Orientation& Or) const 
231 {
232   E.Edge() = TopoDS::Edge(myEExplorer.Current());
233   E.Face() = myFace;
234   Or = E.Edge().Orientation();
235 }
236