0022048: Visualization, AIS_InteractiveContext - single object selection should alway...
[occt.git] / src / TopClass / TopClass_Classifier2d.gxx
CommitLineData
b311480e 1// Created on: 1992-11-17
2// Created by: Laurent BUCHARD
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17// Modified: Mon May 13 15:20:43 1996
7fd59977 18//-- Reinitialisation des transitions complexes
19
20// Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627
21
22
23#include <IntRes2d_IntersectionSegment.hxx>
24#include <IntRes2d_IntersectionPoint.hxx>
25#include <gp_Vec2d.hxx>
26
27//=======================================================================
28//function : TopClass_Classifier2d
29//purpose :
30//=======================================================================
31
32TopClass_Classifier2d::TopClass_Classifier2d() :
33 myIsSet(Standard_False),
34 myFirstCompare(Standard_True),
eafb234b 35 myState(TopAbs_UNKNOWN), // skv OCC12627
36 myIsHeadOrEnd(Standard_False) // skv OCC12627
7fd59977 37{
38}
39
40//=======================================================================
41//function : Reset
42//purpose :
43//=======================================================================
44
45void TopClass_Classifier2d::Reset(const gp_Lin2d& L,
46 const Standard_Real P,
47 const Standard_Real Tol)
48{
49 myLin = L;
50 myParam = P;
51 myTolerance = Tol;
52 myState = TopAbs_UNKNOWN;
53 myFirstCompare = Standard_True;
54 myFirstTrans = Standard_True;
55 myClosest = 0;
56 myIsSet = Standard_True;
57// Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
58 myIsHeadOrEnd = Standard_False;
59// Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
60}
61
62//=======================================================================
63//function : Compare
64//purpose :
65//=======================================================================
66
67void TopClass_Classifier2d::Compare(const TheEdge& E,
68 const TopAbs_Orientation Or)
69{
70 // intersect the edge and the segment
71 myClosest = 0;
72 myIntersector.Perform(myLin,myParam,myTolerance,E);
73 if (!myIntersector.IsDone()) return;
74 if ((myIntersector.NbPoints() == 0)&&
75 (myIntersector.NbSegments() == 0)) return;
76
77 // find the closest point
78 Standard_Integer iPoint, iSegment, nbPoints, nbSegments;
1d47d8d0 79
7fd59977 80 const IntRes2d_IntersectionPoint *PClosest = NULL;
1d47d8d0 81
7fd59977 82 Standard_Real dMin = RealLast();
83 nbPoints = myIntersector.NbPoints();
84 for (iPoint = 1; iPoint <= nbPoints; iPoint++) {
85 const IntRes2d_IntersectionPoint& PInter = myIntersector.Point(iPoint);
86 // test for ON
87 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
88 myClosest = iPoint;
89 myState = TopAbs_ON;
90 return;
91 }
92 Standard_Real paramfirst = PInter.ParamOnFirst();
93 if (paramfirst < dMin) {
94 myClosest = iPoint;
95 PClosest = &PInter;
96 dMin = paramfirst;
97 }
98 }
99
100 // for the segments we only test the first point
101 nbSegments = myIntersector.NbSegments();
102 for (iSegment = 1; iSegment <= nbSegments; iSegment++) {
103 const IntRes2d_IntersectionSegment& SegInter =
104 myIntersector.Segment(iSegment);
105 const IntRes2d_IntersectionPoint& PInter = SegInter.FirstPoint();
106 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
107 myClosest = nbPoints + iSegment+ iSegment - 1;
108 myState = TopAbs_ON;
109 return;
110 }
111 Standard_Real paramfirst = PInter.ParamOnFirst();
112 if (paramfirst < dMin) {
113 myClosest = nbPoints + iSegment+iSegment - 1;
114 PClosest = &PInter;
115 dMin = paramfirst;
116 }
117 }
118
119 // if no point was found return
120 if (myClosest == 0) return;
121
122 // if the Edge is INTERNAL or EXTERNAL, no problem
123 if (Or == TopAbs_INTERNAL) {
124 myState = TopAbs_IN;
125 return;
126 }
127 else if (Or == TopAbs_EXTERNAL) {
128 myState = TopAbs_OUT;
129 return;
130 }
131
132
133 if ( ! myFirstCompare ) {
134 Standard_Boolean b = (dMin > myParam);
135 if (b) {
136 // dMin > myParam : le point le plus proche (dMin) trouve dans CETTE
137 // intersection ligne,arete n'est pas le plus proche
138 // de TOUS les points d'intersection avec les autres aretes (myParam).
139 return;
140 }
141 }
142
143 // process the closest point PClosest, found at dMin on line.
144 myFirstCompare = Standard_False;
145
146 if(myParam > dMin) { //-- lbr le 13 mai 96
147 myFirstTrans = Standard_True;
148 }
149
150 myParam = dMin;
151 const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
152// Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
153// Standard_Boolean isHeadorEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
154// (T2.PositionOnCurve() == IntRes2d_End);
155 myIsHeadOrEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
156 (T2.PositionOnCurve() == IntRes2d_End);
157// Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
158
159 // transition on the segment
1d47d8d0 160
7fd59977 161 TopAbs_Orientation SegTrans = TopAbs_FORWARD;
1d47d8d0 162
7fd59977 163 const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
164 switch (T1.TransitionType()) {
165 case IntRes2d_In :
166 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_REVERSED;
167 else SegTrans = TopAbs_FORWARD;
168 break;
169 case IntRes2d_Out :
170 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_FORWARD;
171 else SegTrans = TopAbs_REVERSED;
172 break;
173 case IntRes2d_Touch :
174 switch (T1.Situation()) {
175 case IntRes2d_Inside :
176 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_EXTERNAL;
177 else SegTrans = TopAbs_INTERNAL;
178 break;
179 case IntRes2d_Outside :
180 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
181 else SegTrans = TopAbs_EXTERNAL;
182 break;
183 case IntRes2d_Unknown : return;
184 }
185 break;
186 case IntRes2d_Undecided : return;
187 }
188
189 // are we inside the Edge ?
190 // const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
191 if ( ! myIsHeadOrEnd ) {
192 // PClosest is inside the edge
193 switch (SegTrans) {
194
195 case TopAbs_FORWARD :
196 case TopAbs_EXTERNAL :
197 myState = TopAbs_OUT;
198 break;
199
200 case TopAbs_REVERSED :
201 case TopAbs_INTERNAL :
202 myState = TopAbs_IN;
203 break;
204 }
205 }
206 else {
207 // PClosest is Head or End of the edge : update the complex transition
208 gp_Dir2d Tang2d,Norm2d;
209 Standard_Real Curv;
210 myIntersector.LocalGeometry
211 (E,PClosest->ParamOnSecond(),Tang2d,Norm2d,Curv);
212 gp_Dir Tang(Tang2d.X(),Tang2d.Y(),0.);
213 gp_Dir Norm(Norm2d.X(),Norm2d.Y(),0.);
214 if (myFirstTrans) {
215 gp_Dir D(myLin.Direction().X(),myLin.Direction().Y(),0.);
216 myTrans.Reset(D);
217 myFirstTrans = Standard_False;
218 }
219
220 TopAbs_Orientation Ort;
221 if (T2.PositionOnCurve() == IntRes2d_Head) Ort = TopAbs_FORWARD;
222 else Ort = TopAbs_REVERSED;
223 myTrans.Compare(RealEpsilon(), Tang, Norm, Curv, SegTrans, Ort);
224 myState = myTrans.StateBefore();
225 }
226}