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
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.
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.
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.
22 // Modified: Mon May 13 15:20:43 1996
23 //-- Reinitialisation des transitions complexes
25 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627
28 #include <IntRes2d_IntersectionSegment.hxx>
29 #include <IntRes2d_IntersectionPoint.hxx>
30 #include <gp_Vec2d.hxx>
32 //=======================================================================
33 //function : TopClass_Classifier2d
35 //=======================================================================
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
46 //=======================================================================
49 //=======================================================================
51 void TopClass_Classifier2d::Reset(const gp_Lin2d& L,
52 const Standard_Real P,
53 const Standard_Real Tol)
58 myState = TopAbs_UNKNOWN;
59 myFirstCompare = Standard_True;
60 myFirstTrans = Standard_True;
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
68 //=======================================================================
71 //=======================================================================
73 void TopClass_Classifier2d::Compare(const TheEdge& E,
74 const TopAbs_Orientation Or)
76 // intersect the edge and the segment
78 myIntersector.Perform(myLin,myParam,myTolerance,E);
79 if (!myIntersector.IsDone()) return;
80 if ((myIntersector.NbPoints() == 0)&&
81 (myIntersector.NbSegments() == 0)) return;
83 // find the closest point
84 Standard_Integer iPoint, iSegment, nbPoints, nbSegments;
86 const IntRes2d_IntersectionPoint *PClosest = NULL;
88 const IntRes2d_IntersectionPoint *PClosest;
90 Standard_Real dMin = RealLast();
91 nbPoints = myIntersector.NbPoints();
92 for (iPoint = 1; iPoint <= nbPoints; iPoint++) {
93 const IntRes2d_IntersectionPoint& PInter = myIntersector.Point(iPoint);
95 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
100 Standard_Real paramfirst = PInter.ParamOnFirst();
101 if (paramfirst < dMin) {
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;
119 Standard_Real paramfirst = PInter.ParamOnFirst();
120 if (paramfirst < dMin) {
121 myClosest = nbPoints + iSegment+iSegment - 1;
127 // if no point was found return
128 if (myClosest == 0) return;
130 // if the Edge is INTERNAL or EXTERNAL, no problem
131 if (Or == TopAbs_INTERNAL) {
135 else if (Or == TopAbs_EXTERNAL) {
136 myState = TopAbs_OUT;
141 if ( ! myFirstCompare ) {
142 Standard_Boolean b = (dMin > myParam);
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).
151 // process the closest point PClosest, found at dMin on line.
152 myFirstCompare = Standard_False;
154 if(myParam > dMin) { //-- lbr le 13 mai 96
155 myFirstTrans = Standard_True;
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
167 // transition on the segment
169 TopAbs_Orientation SegTrans = TopAbs_FORWARD;
171 TopAbs_Orientation SegTrans;
173 const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
174 switch (T1.TransitionType()) {
176 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_REVERSED;
177 else SegTrans = TopAbs_FORWARD;
180 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_FORWARD;
181 else SegTrans = TopAbs_REVERSED;
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;
189 case IntRes2d_Outside :
190 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
191 else SegTrans = TopAbs_EXTERNAL;
193 case IntRes2d_Unknown : return;
196 case IntRes2d_Undecided : return;
199 // are we inside the Edge ?
200 // const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
201 if ( ! myIsHeadOrEnd ) {
202 // PClosest is inside the edge
205 case TopAbs_FORWARD :
206 case TopAbs_EXTERNAL :
207 myState = TopAbs_OUT;
210 case TopAbs_REVERSED :
211 case TopAbs_INTERNAL :
217 // PClosest is Head or End of the edge : update the complex transition
218 gp_Dir2d Tang2d,Norm2d;
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.);
225 gp_Dir D(myLin.Direction().X(),myLin.Direction().Y(),0.);
227 myFirstTrans = Standard_False;
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();