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 | |
32 | TopClass_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 | |
45 | void 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 | |
67 | void 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 | } |