0023024: Update headers of OCCT files
[occt.git] / src / TopClass / TopClass_Classifier2d.gxx
1 // Created on: 1992-11-17
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 // Modified:    Mon May 13 15:20:43 1996
23 //-- Reinitialisation des transitions complexes
24
25 //  Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627
26
27
28 #include <IntRes2d_IntersectionSegment.hxx>
29 #include <IntRes2d_IntersectionPoint.hxx>
30 #include <gp_Vec2d.hxx>
31
32 //=======================================================================
33 //function : TopClass_Classifier2d
34 //purpose  : 
35 //=======================================================================
36
37 TopClass_Classifier2d::TopClass_Classifier2d() :
38        myIsSet(Standard_False),
39        myFirstCompare(Standard_True),
40        myIsHeadOrEnd(Standard_False), // skv OCC12627
41        myState(TopAbs_UNKNOWN)        // skv OCC12627
42
43 {
44 }
45
46 //=======================================================================
47 //function : Reset
48 //purpose  : 
49 //=======================================================================
50
51 void TopClass_Classifier2d::Reset(const gp_Lin2d& L,  
52                                   const Standard_Real P,
53                                   const Standard_Real Tol)
54 {
55   myLin = L;
56   myParam = P;
57   myTolerance = Tol;
58   myState = TopAbs_UNKNOWN;
59   myFirstCompare = Standard_True;
60   myFirstTrans = Standard_True;
61   myClosest = 0;
62   myIsSet = Standard_True;
63 //  Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
64   myIsHeadOrEnd = Standard_False;
65 //  Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
66 }
67
68 //=======================================================================
69 //function : Compare
70 //purpose  : 
71 //=======================================================================
72
73 void TopClass_Classifier2d::Compare(const TheEdge& E,
74                                     const TopAbs_Orientation Or)
75 {
76   // intersect the edge and the segment
77   myClosest = 0;
78   myIntersector.Perform(myLin,myParam,myTolerance,E);
79   if (!myIntersector.IsDone()) return;
80   if ((myIntersector.NbPoints()   == 0)&&
81       (myIntersector.NbSegments() == 0)) return;
82
83   // find the closest point
84   Standard_Integer iPoint, iSegment, nbPoints, nbSegments;
85 #ifndef DEB
86   const IntRes2d_IntersectionPoint *PClosest = NULL;
87 #else 
88   const IntRes2d_IntersectionPoint *PClosest;
89 #endif
90   Standard_Real dMin = RealLast();
91   nbPoints = myIntersector.NbPoints();
92   for (iPoint = 1; iPoint <= nbPoints;  iPoint++)  {
93     const IntRes2d_IntersectionPoint& PInter = myIntersector.Point(iPoint);
94     // test for ON
95     if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
96       myClosest = iPoint;
97       myState = TopAbs_ON;
98       return;
99     }
100     Standard_Real paramfirst = PInter.ParamOnFirst();
101     if (paramfirst <  dMin) {
102       myClosest = iPoint;
103       PClosest = &PInter;
104       dMin = paramfirst;
105     }
106   }
107
108   // for the segments we only test the first point
109   nbSegments = myIntersector.NbSegments();
110   for (iSegment = 1; iSegment <= nbSegments;  iSegment++)  {
111     const IntRes2d_IntersectionSegment& SegInter = 
112       myIntersector.Segment(iSegment);
113     const IntRes2d_IntersectionPoint& PInter = SegInter.FirstPoint();
114     if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
115       myClosest = nbPoints + iSegment+  iSegment - 1;
116       myState = TopAbs_ON;
117       return;
118     }
119     Standard_Real paramfirst = PInter.ParamOnFirst();
120     if (paramfirst <  dMin) {
121       myClosest = nbPoints + iSegment+iSegment - 1;
122       PClosest = &PInter;
123       dMin = paramfirst;
124     }
125   }
126
127   // if no point was found return
128   if (myClosest == 0) return;
129
130   // if the Edge is INTERNAL or EXTERNAL, no problem
131   if (Or == TopAbs_INTERNAL) {
132     myState = TopAbs_IN;
133     return;
134   }
135   else if (Or == TopAbs_EXTERNAL) {
136     myState = TopAbs_OUT;
137     return;
138   }
139
140
141   if ( ! myFirstCompare ) {
142     Standard_Boolean b = (dMin > myParam);
143     if (b) {
144       // dMin > myParam : le point le plus proche (dMin) trouve dans CETTE
145       // intersection ligne,arete n'est pas le plus proche
146       // de TOUS les points d'intersection avec les autres aretes (myParam).
147       return;
148     }
149   }
150   
151   // process the closest point PClosest, found at dMin on line.
152   myFirstCompare = Standard_False;
153
154   if(myParam > dMin) {  //-- lbr le 13 mai 96 
155     myFirstTrans = Standard_True; 
156   } 
157   
158   myParam = dMin;
159   const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
160 //  Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
161 //   Standard_Boolean isHeadorEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
162 //                                  (T2.PositionOnCurve() == IntRes2d_End);
163   myIsHeadOrEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
164                   (T2.PositionOnCurve() == IntRes2d_End);
165 //  Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
166   
167   // transition on the segment
168 #ifndef DEB
169   TopAbs_Orientation SegTrans = TopAbs_FORWARD;
170 #else
171   TopAbs_Orientation SegTrans;
172 #endif
173   const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
174   switch (T1.TransitionType()) {
175   case IntRes2d_In :
176     if (Or == TopAbs_REVERSED)   SegTrans = TopAbs_REVERSED;
177     else                         SegTrans = TopAbs_FORWARD;
178     break;
179   case IntRes2d_Out :
180     if (Or == TopAbs_REVERSED)   SegTrans = TopAbs_FORWARD;
181     else                         SegTrans = TopAbs_REVERSED;
182     break;
183   case IntRes2d_Touch :
184     switch (T1.Situation()) {
185     case IntRes2d_Inside :
186       if (Or == TopAbs_REVERSED) SegTrans = TopAbs_EXTERNAL;
187       else                       SegTrans = TopAbs_INTERNAL;
188       break;
189     case IntRes2d_Outside :
190       if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
191       else                       SegTrans = TopAbs_EXTERNAL;
192       break;
193     case IntRes2d_Unknown :      return;
194     }
195     break;
196   case IntRes2d_Undecided :      return;
197   }
198
199   // are we inside the Edge ?
200   //  const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
201   if ( ! myIsHeadOrEnd ) {
202     // PClosest is inside the edge
203     switch (SegTrans) {
204
205     case TopAbs_FORWARD :
206     case TopAbs_EXTERNAL :
207       myState = TopAbs_OUT;
208       break;
209
210     case TopAbs_REVERSED :
211     case TopAbs_INTERNAL :
212       myState = TopAbs_IN;
213       break;
214     }
215   }
216   else {
217     // PClosest is Head or End of the edge : update the complex transition
218     gp_Dir2d Tang2d,Norm2d;
219     Standard_Real Curv;
220     myIntersector.LocalGeometry
221       (E,PClosest->ParamOnSecond(),Tang2d,Norm2d,Curv);
222     gp_Dir Tang(Tang2d.X(),Tang2d.Y(),0.);
223     gp_Dir Norm(Norm2d.X(),Norm2d.Y(),0.);
224     if (myFirstTrans) {
225       gp_Dir D(myLin.Direction().X(),myLin.Direction().Y(),0.);
226       myTrans.Reset(D);
227       myFirstTrans = Standard_False;
228     }
229     
230     TopAbs_Orientation Ort;
231     if (T2.PositionOnCurve() == IntRes2d_Head) Ort = TopAbs_FORWARD;
232     else                                       Ort = TopAbs_REVERSED;
233     myTrans.Compare(RealEpsilon(), Tang, Norm,  Curv, SegTrans, Ort);
234     myState = myTrans.StateBefore();
235   }
236 }
237
238
239
240
241
242
243
244
245
246
247