1 // Created on: 1992-11-17
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified: Mon May 13 15:20:43 1996
18 //-- Reinitialisation des transitions complexes
20 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627
23 #include <IntRes2d_IntersectionSegment.hxx>
24 #include <IntRes2d_IntersectionPoint.hxx>
25 #include <gp_Vec2d.hxx>
27 //=======================================================================
28 //function : TopClass_Classifier2d
30 //=======================================================================
32 TopClass_Classifier2d::TopClass_Classifier2d() :
33 myIsSet(Standard_False),
34 myFirstCompare(Standard_True),
35 myFirstTrans(Standard_True),
39 myState(TopAbs_UNKNOWN), // skv OCC12627
40 myIsHeadOrEnd(Standard_False) // skv OCC12627
44 //=======================================================================
47 //=======================================================================
49 void TopClass_Classifier2d::Reset(const gp_Lin2d& L,
50 const Standard_Real P,
51 const Standard_Real Tol)
56 myState = TopAbs_UNKNOWN;
57 myFirstCompare = Standard_True;
58 myFirstTrans = Standard_True;
60 myIsSet = Standard_True;
61 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
62 myIsHeadOrEnd = Standard_False;
63 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
66 //=======================================================================
69 //=======================================================================
71 void TopClass_Classifier2d::Compare(const TheEdge& E,
72 const TopAbs_Orientation Or)
74 // intersect the edge and the segment
76 myIntersector.Perform(myLin,myParam,myTolerance,E);
77 if (!myIntersector.IsDone()) return;
78 if ((myIntersector.NbPoints() == 0)&&
79 (myIntersector.NbSegments() == 0)) return;
81 // find the closest point
82 Standard_Integer iPoint, iSegment, nbPoints, nbSegments;
84 const IntRes2d_IntersectionPoint *PClosest = NULL;
86 Standard_Real dMin = RealLast();
87 nbPoints = myIntersector.NbPoints();
88 for (iPoint = 1; iPoint <= nbPoints; iPoint++) {
89 const IntRes2d_IntersectionPoint& PInter = myIntersector.Point(iPoint);
91 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
96 Standard_Real paramfirst = PInter.ParamOnFirst();
97 if (paramfirst < dMin) {
104 // for the segments we only test the first point
105 nbSegments = myIntersector.NbSegments();
106 for (iSegment = 1; iSegment <= nbSegments; iSegment++) {
107 const IntRes2d_IntersectionSegment& SegInter =
108 myIntersector.Segment(iSegment);
109 const IntRes2d_IntersectionPoint& PInter = SegInter.FirstPoint();
110 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
111 myClosest = nbPoints + iSegment+ iSegment - 1;
115 Standard_Real paramfirst = PInter.ParamOnFirst();
116 if (paramfirst < dMin) {
117 myClosest = nbPoints + iSegment+iSegment - 1;
123 // if no point was found return
124 if (myClosest == 0) return;
126 // if the Edge is INTERNAL or EXTERNAL, no problem
127 if (Or == TopAbs_INTERNAL) {
131 else if (Or == TopAbs_EXTERNAL) {
132 myState = TopAbs_OUT;
137 if ( ! myFirstCompare ) {
138 Standard_Boolean b = (dMin > myParam);
140 // dMin > myParam : le point le plus proche (dMin) trouve dans CETTE
141 // intersection ligne,arete n'est pas le plus proche
142 // de TOUS les points d'intersection avec les autres aretes (myParam).
147 // process the closest point PClosest, found at dMin on line.
148 myFirstCompare = Standard_False;
150 if(myParam > dMin) { //-- lbr le 13 mai 96
151 myFirstTrans = Standard_True;
155 const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
156 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
157 // Standard_Boolean isHeadorEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
158 // (T2.PositionOnCurve() == IntRes2d_End);
159 myIsHeadOrEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
160 (T2.PositionOnCurve() == IntRes2d_End);
161 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
163 // transition on the segment
165 TopAbs_Orientation SegTrans = TopAbs_FORWARD;
167 const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
168 switch (T1.TransitionType()) {
170 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_REVERSED;
171 else SegTrans = TopAbs_FORWARD;
174 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_FORWARD;
175 else SegTrans = TopAbs_REVERSED;
177 case IntRes2d_Touch :
178 switch (T1.Situation()) {
179 case IntRes2d_Inside :
180 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_EXTERNAL;
181 else SegTrans = TopAbs_INTERNAL;
183 case IntRes2d_Outside :
184 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
185 else SegTrans = TopAbs_EXTERNAL;
187 case IntRes2d_Unknown : return;
190 case IntRes2d_Undecided : return;
193 // are we inside the Edge ?
194 // const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
195 if ( ! myIsHeadOrEnd ) {
196 // PClosest is inside the edge
199 case TopAbs_FORWARD :
200 case TopAbs_EXTERNAL :
201 myState = TopAbs_OUT;
204 case TopAbs_REVERSED :
205 case TopAbs_INTERNAL :
211 // PClosest is Head or End of the edge : update the complex transition
212 gp_Dir2d Tang2d,Norm2d;
214 myIntersector.LocalGeometry
215 (E,PClosest->ParamOnSecond(),Tang2d,Norm2d,Curv);
216 gp_Dir Tang(Tang2d.X(),Tang2d.Y(),0.);
217 gp_Dir Norm(Norm2d.X(),Norm2d.Y(),0.);
219 gp_Dir D(myLin.Direction().X(),myLin.Direction().Y(),0.);
221 myFirstTrans = Standard_False;
224 TopAbs_Orientation Ort;
225 if (T2.PositionOnCurve() == IntRes2d_Head) Ort = TopAbs_FORWARD;
226 else Ort = TopAbs_REVERSED;
227 myTrans.Compare(RealEpsilon(), Tang, Norm, Curv, SegTrans, Ort);
228 myState = myTrans.StateBefore();