1 // File: TopClass_Classifier2d.gxx
2 // Created: Tue Nov 17 17:47:02 1992
3 // Author: Remi LEQUETTE
6 // Modified: Mon May 13 15:20:43 1996
7 // Author: Laurent BUCHARD
9 //-- Reinitialisation des transitions complexes
11 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627
14 #include <IntRes2d_IntersectionSegment.hxx>
15 #include <IntRes2d_IntersectionPoint.hxx>
16 #include <gp_Vec2d.hxx>
18 //=======================================================================
19 //function : TopClass_Classifier2d
21 //=======================================================================
23 TopClass_Classifier2d::TopClass_Classifier2d() :
24 myIsSet(Standard_False),
25 myFirstCompare(Standard_True),
26 myIsHeadOrEnd(Standard_False), // skv OCC12627
27 myState(TopAbs_UNKNOWN) // skv OCC12627
32 //=======================================================================
35 //=======================================================================
37 void TopClass_Classifier2d::Reset(const gp_Lin2d& L,
38 const Standard_Real P,
39 const Standard_Real Tol)
44 myState = TopAbs_UNKNOWN;
45 myFirstCompare = Standard_True;
46 myFirstTrans = Standard_True;
48 myIsSet = Standard_True;
49 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
50 myIsHeadOrEnd = Standard_False;
51 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
54 //=======================================================================
57 //=======================================================================
59 void TopClass_Classifier2d::Compare(const TheEdge& E,
60 const TopAbs_Orientation Or)
62 // intersect the edge and the segment
64 myIntersector.Perform(myLin,myParam,myTolerance,E);
65 if (!myIntersector.IsDone()) return;
66 if ((myIntersector.NbPoints() == 0)&&
67 (myIntersector.NbSegments() == 0)) return;
69 // find the closest point
70 Standard_Integer iPoint, iSegment, nbPoints, nbSegments;
72 const IntRes2d_IntersectionPoint *PClosest = NULL;
74 const IntRes2d_IntersectionPoint *PClosest;
76 Standard_Real dMin = RealLast();
77 nbPoints = myIntersector.NbPoints();
78 for (iPoint = 1; iPoint <= nbPoints; iPoint++) {
79 const IntRes2d_IntersectionPoint& PInter = myIntersector.Point(iPoint);
81 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
86 Standard_Real paramfirst = PInter.ParamOnFirst();
87 if (paramfirst < dMin) {
94 // for the segments we only test the first point
95 nbSegments = myIntersector.NbSegments();
96 for (iSegment = 1; iSegment <= nbSegments; iSegment++) {
97 const IntRes2d_IntersectionSegment& SegInter =
98 myIntersector.Segment(iSegment);
99 const IntRes2d_IntersectionPoint& PInter = SegInter.FirstPoint();
100 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
101 myClosest = nbPoints + iSegment+ iSegment - 1;
105 Standard_Real paramfirst = PInter.ParamOnFirst();
106 if (paramfirst < dMin) {
107 myClosest = nbPoints + iSegment+iSegment - 1;
113 // if no point was found return
114 if (myClosest == 0) return;
116 // if the Edge is INTERNAL or EXTERNAL, no problem
117 if (Or == TopAbs_INTERNAL) {
121 else if (Or == TopAbs_EXTERNAL) {
122 myState = TopAbs_OUT;
127 if ( ! myFirstCompare ) {
128 Standard_Boolean b = (dMin > myParam);
130 // dMin > myParam : le point le plus proche (dMin) trouve dans CETTE
131 // intersection ligne,arete n'est pas le plus proche
132 // de TOUS les points d'intersection avec les autres aretes (myParam).
137 // process the closest point PClosest, found at dMin on line.
138 myFirstCompare = Standard_False;
140 if(myParam > dMin) { //-- lbr le 13 mai 96
141 myFirstTrans = Standard_True;
145 const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
146 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
147 // Standard_Boolean isHeadorEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
148 // (T2.PositionOnCurve() == IntRes2d_End);
149 myIsHeadOrEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
150 (T2.PositionOnCurve() == IntRes2d_End);
151 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
153 // transition on the segment
155 TopAbs_Orientation SegTrans = TopAbs_FORWARD;
157 TopAbs_Orientation SegTrans;
159 const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
160 switch (T1.TransitionType()) {
162 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_REVERSED;
163 else SegTrans = TopAbs_FORWARD;
166 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_FORWARD;
167 else SegTrans = TopAbs_REVERSED;
169 case IntRes2d_Touch :
170 switch (T1.Situation()) {
171 case IntRes2d_Inside :
172 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_EXTERNAL;
173 else SegTrans = TopAbs_INTERNAL;
175 case IntRes2d_Outside :
176 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
177 else SegTrans = TopAbs_EXTERNAL;
179 case IntRes2d_Unknown : return;
182 case IntRes2d_Undecided : return;
185 // are we inside the Edge ?
186 // const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
187 if ( ! myIsHeadOrEnd ) {
188 // PClosest is inside the edge
191 case TopAbs_FORWARD :
192 case TopAbs_EXTERNAL :
193 myState = TopAbs_OUT;
196 case TopAbs_REVERSED :
197 case TopAbs_INTERNAL :
203 // PClosest is Head or End of the edge : update the complex transition
204 gp_Dir2d Tang2d,Norm2d;
206 myIntersector.LocalGeometry
207 (E,PClosest->ParamOnSecond(),Tang2d,Norm2d,Curv);
208 gp_Dir Tang(Tang2d.X(),Tang2d.Y(),0.);
209 gp_Dir Norm(Norm2d.X(),Norm2d.Y(),0.);
211 gp_Dir D(myLin.Direction().X(),myLin.Direction().Y(),0.);
213 myFirstTrans = Standard_False;
216 TopAbs_Orientation Ort;
217 if (T2.PositionOnCurve() == IntRes2d_Head) Ort = TopAbs_FORWARD;
218 else Ort = TopAbs_REVERSED;
219 myTrans.Compare(RealEpsilon(), Tang, Norm, Curv, SegTrans, Ort);
220 myState = myTrans.StateBefore();