0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / TopClass / TopClass_FaceClassifier.gxx
1 // Created on: 1992-11-18
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 18:00:34 2006 OCC12627
18 // The method Perform is totally rewroted.
19
20 #include <IntRes2d_IntersectionSegment.hxx>
21 #include <IntRes2d_IntersectionPoint.hxx>
22
23 //=======================================================================
24 //function : TopClass_FaceClassifier
25 //purpose  : 
26 //=======================================================================
27
28 TopClass_FaceClassifier::TopClass_FaceClassifier() :
29 myEdgeParameter(0.0),
30 rejected(Standard_False),
31 nowires(Standard_True)
32 {
33 }
34
35 //=======================================================================
36 //function : TopClass_FaceClassifier
37 //purpose  : 
38 //=======================================================================
39
40 TopClass_FaceClassifier::TopClass_FaceClassifier(TheFaceExplorer& FExp,
41                                                  const gp_Pnt2d& P,
42                                                  const Standard_Real Tol) :
43 myEdgeParameter(0.0),
44 rejected(Standard_False),
45 nowires(Standard_True)
46 {
47   Perform(FExp,P,Tol);
48 }
49
50 //=======================================================================
51 //function : Perform
52 //purpose  : 
53 //=======================================================================
54
55 void TopClass_FaceClassifier::Perform(TheFaceExplorer& Fexp,
56                                       const gp_Pnt2d& P,
57                                       const Standard_Real Tol)
58 {
59   gp_Pnt2d aPoint(P);
60   Standard_Boolean aResOfPointCheck = Standard_False;
61   while (aResOfPointCheck == Standard_False)
62   {
63     aResOfPointCheck = Fexp.CheckPoint(aPoint);
64   }
65
66   // Test for rejection.
67   rejected = Fexp.Reject(aPoint);
68
69   if (rejected)
70     return;
71
72   gp_Lin2d                   aLine;
73   Standard_Real              aParam;
74   Standard_Boolean           IsValidSegment = Fexp.Segment(aPoint, aLine, aParam);
75   TheEdge                    anEdge;
76   TopAbs_Orientation         anEdgeOri;
77   Standard_Integer           aClosestInd;
78   IntRes2d_IntersectionPoint aPInter;
79   TopAbs_State               aState = TopAbs_UNKNOWN;
80   Standard_Boolean           IsWReject;
81   Standard_Boolean           IsEReject;
82
83   nowires = Standard_True;
84
85   while (IsValidSegment) {
86     myClassifier.Reset(aLine, aParam, Tol);
87
88     for (Fexp.InitWires(); Fexp.MoreWires(); Fexp.NextWire()) {
89       nowires   = Standard_False;
90       IsWReject = Fexp.RejectWire(aLine, myClassifier.Parameter());
91
92       if (!IsWReject) {
93         // test this wire
94         for (Fexp.InitEdges(); Fexp.MoreEdges(); Fexp.NextEdge()) {
95           IsEReject = Fexp.RejectEdge(aLine, myClassifier.Parameter());
96
97           if (!IsEReject) {
98             // test this edge
99             Fexp.CurrentEdge(anEdge, anEdgeOri);
100
101             if (anEdgeOri == TopAbs_FORWARD || anEdgeOri == TopAbs_REVERSED) {
102               myClassifier.Compare(anEdge, anEdgeOri);
103               aClosestInd = myClassifier.ClosestIntersection();
104
105               if (aClosestInd != 0) {
106                 // save the closest edge
107                 TheIntersection2d &anIntersector = myClassifier.Intersector();
108                 Standard_Integer   aNbPnts       = anIntersector.NbPoints();
109
110                 myEdge = anEdge;
111
112                 if (aClosestInd <= aNbPnts) {
113                   aPInter = anIntersector.Point(aClosestInd);
114                 } else {
115                   aClosestInd -= aNbPnts;
116
117                   if (aClosestInd&1) {
118                     aPInter =  anIntersector.
119                       Segment((aClosestInd + 1)/2).FirstPoint();
120                   } else {
121                     aPInter =  anIntersector.
122                       Segment((aClosestInd + 1)/2).LastPoint();
123                   }
124                 }
125
126                 myPosition      = aPInter.
127                                   TransitionOfSecond().PositionOnCurve();
128                 myEdgeParameter = aPInter.ParamOnSecond();
129               }
130               // if we are ON, we stop
131               aState = myClassifier.State();
132             
133               if (aState == TopAbs_ON)
134                 return;
135             }
136           }
137         }
138
139         // if we are out of the wire we stop
140         aState = myClassifier.State();
141
142         if (aState == TopAbs_OUT)
143           return;
144       }
145     }
146
147     if (!myClassifier.IsHeadOrEnd() && aState != TopAbs_UNKNOWN)
148       break;
149
150     // Bad case for classification. Trying to get another segment.
151     IsValidSegment = Fexp.OtherSegment(aPoint, aLine, aParam);
152   }
153 }
154
155 //=======================================================================
156 //function : State
157 //purpose  : 
158 //=======================================================================
159
160 TopAbs_State TopClass_FaceClassifier::State() const
161 {
162   if (rejected)     return TopAbs_OUT;
163   else if (nowires) return TopAbs_IN;
164   else              return  myClassifier.State();
165 }
166
167 //=======================================================================
168 //function : Edge
169 //purpose  : 
170 //=======================================================================
171
172 const TheEdge& TopClass_FaceClassifier::Edge() const
173 {
174   Standard_DomainError_Raise_if(rejected,
175                                 "TopClass_FaceClassifier::Edge:rejected");
176   return myEdge;
177 }
178
179
180 //=======================================================================
181 //function : EdgeParameter
182 //purpose  : 
183 //=======================================================================
184
185 Standard_Real TopClass_FaceClassifier::EdgeParameter() const
186 {
187   Standard_DomainError_Raise_if(rejected,
188                                 "TopClass_FaceClassifier::EdgeParameter:rejected");
189   return myEdgeParameter;
190 }
191