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 Standard_Real dMin = RealLast();
89 nbPoints = myIntersector.NbPoints();
90 for (iPoint = 1; iPoint <= nbPoints; iPoint++) {
91 const IntRes2d_IntersectionPoint& PInter = myIntersector.Point(iPoint);
93 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
98 Standard_Real paramfirst = PInter.ParamOnFirst();
99 if (paramfirst < dMin) {
106 // for the segments we only test the first point
107 nbSegments = myIntersector.NbSegments();
108 for (iSegment = 1; iSegment <= nbSegments; iSegment++) {
109 const IntRes2d_IntersectionSegment& SegInter =
110 myIntersector.Segment(iSegment);
111 const IntRes2d_IntersectionPoint& PInter = SegInter.FirstPoint();
112 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
113 myClosest = nbPoints + iSegment+ iSegment - 1;
117 Standard_Real paramfirst = PInter.ParamOnFirst();
118 if (paramfirst < dMin) {
119 myClosest = nbPoints + iSegment+iSegment - 1;
125 // if no point was found return
126 if (myClosest == 0) return;
128 // if the Edge is INTERNAL or EXTERNAL, no problem
129 if (Or == TopAbs_INTERNAL) {
133 else if (Or == TopAbs_EXTERNAL) {
134 myState = TopAbs_OUT;
139 if ( ! myFirstCompare ) {
140 Standard_Boolean b = (dMin > myParam);
142 // dMin > myParam : le point le plus proche (dMin) trouve dans CETTE
143 // intersection ligne,arete n'est pas le plus proche
144 // de TOUS les points d'intersection avec les autres aretes (myParam).
149 // process the closest point PClosest, found at dMin on line.
150 myFirstCompare = Standard_False;
152 if(myParam > dMin) { //-- lbr le 13 mai 96
153 myFirstTrans = Standard_True;
157 const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
158 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
159 // Standard_Boolean isHeadorEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
160 // (T2.PositionOnCurve() == IntRes2d_End);
161 myIsHeadOrEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
162 (T2.PositionOnCurve() == IntRes2d_End);
163 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
165 // transition on the segment
167 TopAbs_Orientation SegTrans = TopAbs_FORWARD;
169 const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
170 switch (T1.TransitionType()) {
172 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_REVERSED;
173 else SegTrans = TopAbs_FORWARD;
176 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_FORWARD;
177 else SegTrans = TopAbs_REVERSED;
179 case IntRes2d_Touch :
180 switch (T1.Situation()) {
181 case IntRes2d_Inside :
182 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_EXTERNAL;
183 else SegTrans = TopAbs_INTERNAL;
185 case IntRes2d_Outside :
186 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
187 else SegTrans = TopAbs_EXTERNAL;
189 case IntRes2d_Unknown : return;
192 case IntRes2d_Undecided : return;
195 // are we inside the Edge ?
196 // const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
197 if ( ! myIsHeadOrEnd ) {
198 // PClosest is inside the edge
201 case TopAbs_FORWARD :
202 case TopAbs_EXTERNAL :
203 myState = TopAbs_OUT;
206 case TopAbs_REVERSED :
207 case TopAbs_INTERNAL :
213 // PClosest is Head or End of the edge : update the complex transition
214 gp_Dir2d Tang2d,Norm2d;
216 myIntersector.LocalGeometry
217 (E,PClosest->ParamOnSecond(),Tang2d,Norm2d,Curv);
218 gp_Dir Tang(Tang2d.X(),Tang2d.Y(),0.);
219 gp_Dir Norm(Norm2d.X(),Norm2d.Y(),0.);
221 gp_Dir D(myLin.Direction().X(),myLin.Direction().Y(),0.);
223 myFirstTrans = Standard_False;
226 TopAbs_Orientation Ort;
227 if (T2.PositionOnCurve() == IntRes2d_Head) Ort = TopAbs_FORWARD;
228 else Ort = TopAbs_REVERSED;
229 myTrans.Compare(RealEpsilon(), Tang, Norm, Curv, SegTrans, Ort);
230 myState = myTrans.StateBefore();