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 myState(TopAbs_UNKNOWN), // skv OCC12627
41 myIsHeadOrEnd(Standard_False) // skv OCC12627
45 //=======================================================================
48 //=======================================================================
50 void TopClass_Classifier2d::Reset(const gp_Lin2d& L,
51 const Standard_Real P,
52 const Standard_Real Tol)
57 myState = TopAbs_UNKNOWN;
58 myFirstCompare = Standard_True;
59 myFirstTrans = Standard_True;
61 myIsSet = Standard_True;
62 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
63 myIsHeadOrEnd = Standard_False;
64 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
67 //=======================================================================
70 //=======================================================================
72 void TopClass_Classifier2d::Compare(const TheEdge& E,
73 const TopAbs_Orientation Or)
75 // intersect the edge and the segment
77 myIntersector.Perform(myLin,myParam,myTolerance,E);
78 if (!myIntersector.IsDone()) return;
79 if ((myIntersector.NbPoints() == 0)&&
80 (myIntersector.NbSegments() == 0)) return;
82 // find the closest point
83 Standard_Integer iPoint, iSegment, nbPoints, nbSegments;
85 const IntRes2d_IntersectionPoint *PClosest = NULL;
87 Standard_Real dMin = RealLast();
88 nbPoints = myIntersector.NbPoints();
89 for (iPoint = 1; iPoint <= nbPoints; iPoint++) {
90 const IntRes2d_IntersectionPoint& PInter = myIntersector.Point(iPoint);
92 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
97 Standard_Real paramfirst = PInter.ParamOnFirst();
98 if (paramfirst < dMin) {
105 // for the segments we only test the first point
106 nbSegments = myIntersector.NbSegments();
107 for (iSegment = 1; iSegment <= nbSegments; iSegment++) {
108 const IntRes2d_IntersectionSegment& SegInter =
109 myIntersector.Segment(iSegment);
110 const IntRes2d_IntersectionPoint& PInter = SegInter.FirstPoint();
111 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
112 myClosest = nbPoints + iSegment+ iSegment - 1;
116 Standard_Real paramfirst = PInter.ParamOnFirst();
117 if (paramfirst < dMin) {
118 myClosest = nbPoints + iSegment+iSegment - 1;
124 // if no point was found return
125 if (myClosest == 0) return;
127 // if the Edge is INTERNAL or EXTERNAL, no problem
128 if (Or == TopAbs_INTERNAL) {
132 else if (Or == TopAbs_EXTERNAL) {
133 myState = TopAbs_OUT;
138 if ( ! myFirstCompare ) {
139 Standard_Boolean b = (dMin > myParam);
141 // dMin > myParam : le point le plus proche (dMin) trouve dans CETTE
142 // intersection ligne,arete n'est pas le plus proche
143 // de TOUS les points d'intersection avec les autres aretes (myParam).
148 // process the closest point PClosest, found at dMin on line.
149 myFirstCompare = Standard_False;
151 if(myParam > dMin) { //-- lbr le 13 mai 96
152 myFirstTrans = Standard_True;
156 const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
157 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
158 // Standard_Boolean isHeadorEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
159 // (T2.PositionOnCurve() == IntRes2d_End);
160 myIsHeadOrEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
161 (T2.PositionOnCurve() == IntRes2d_End);
162 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
164 // transition on the segment
166 TopAbs_Orientation SegTrans = TopAbs_FORWARD;
168 const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
169 switch (T1.TransitionType()) {
171 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_REVERSED;
172 else SegTrans = TopAbs_FORWARD;
175 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_FORWARD;
176 else SegTrans = TopAbs_REVERSED;
178 case IntRes2d_Touch :
179 switch (T1.Situation()) {
180 case IntRes2d_Inside :
181 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_EXTERNAL;
182 else SegTrans = TopAbs_INTERNAL;
184 case IntRes2d_Outside :
185 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
186 else SegTrans = TopAbs_EXTERNAL;
188 case IntRes2d_Unknown : return;
191 case IntRes2d_Undecided : return;
194 // are we inside the Edge ?
195 // const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
196 if ( ! myIsHeadOrEnd ) {
197 // PClosest is inside the edge
200 case TopAbs_FORWARD :
201 case TopAbs_EXTERNAL :
202 myState = TopAbs_OUT;
205 case TopAbs_REVERSED :
206 case TopAbs_INTERNAL :
212 // PClosest is Head or End of the edge : update the complex transition
213 gp_Dir2d Tang2d,Norm2d;
215 myIntersector.LocalGeometry
216 (E,PClosest->ParamOnSecond(),Tang2d,Norm2d,Curv);
217 gp_Dir Tang(Tang2d.X(),Tang2d.Y(),0.);
218 gp_Dir Norm(Norm2d.X(),Norm2d.Y(),0.);
220 gp_Dir D(myLin.Direction().X(),myLin.Direction().Y(),0.);
222 myFirstTrans = Standard_False;
225 TopAbs_Orientation Ort;
226 if (T2.PositionOnCurve() == IntRes2d_Head) Ort = TopAbs_FORWARD;
227 else Ort = TopAbs_REVERSED;
228 myTrans.Compare(RealEpsilon(), Tang, Norm, Curv, SegTrans, Ort);
229 myState = myTrans.StateBefore();