Warning, /include/opencascade/TopClass_Classifier2d.gxx is written in an unsupported language. File is not indexed.
0001 // Created on: 1992-11-17
0002 // Created by: Laurent BUCHARD
0003 // Copyright (c) 1992-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016
0017 // Modified: Mon May 13 15:20:43 1996
0018 //-- Reinitialisation des transitions complexes
0019
0020 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627
0021
0022
0023 #include <IntRes2d_IntersectionSegment.hxx>
0024 #include <IntRes2d_IntersectionPoint.hxx>
0025 #include <gp_Vec2d.hxx>
0026
0027 //=======================================================================
0028 //function : TopClass_Classifier2d
0029 //purpose :
0030 //=======================================================================
0031
0032 TopClass_Classifier2d::TopClass_Classifier2d() :
0033 myIsSet(Standard_False),
0034 myFirstCompare(Standard_True),
0035 myFirstTrans(Standard_True),
0036 myParam(0.0),
0037 myTolerance(0.0),
0038 myClosest(0),
0039 myState(TopAbs_UNKNOWN), // skv OCC12627
0040 myIsHeadOrEnd(Standard_False) // skv OCC12627
0041 {
0042 }
0043
0044 //=======================================================================
0045 //function : Reset
0046 //purpose :
0047 //=======================================================================
0048
0049 void TopClass_Classifier2d::Reset(const gp_Lin2d& L,
0050 const Standard_Real P,
0051 const Standard_Real Tol)
0052 {
0053 myLin = L;
0054 myParam = P;
0055 myTolerance = Tol;
0056 myState = TopAbs_UNKNOWN;
0057 myFirstCompare = Standard_True;
0058 myFirstTrans = Standard_True;
0059 myClosest = 0;
0060 myIsSet = Standard_True;
0061 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
0062 myIsHeadOrEnd = Standard_False;
0063 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
0064 }
0065
0066 //=======================================================================
0067 //function : Compare
0068 //purpose :
0069 //=======================================================================
0070
0071 void TopClass_Classifier2d::Compare(const TheEdge& E,
0072 const TopAbs_Orientation Or)
0073 {
0074 // intersect the edge and the segment
0075 myClosest = 0;
0076 myIntersector.Perform(myLin,myParam,myTolerance,E);
0077 if (!myIntersector.IsDone()) return;
0078 if ((myIntersector.NbPoints() == 0)&&
0079 (myIntersector.NbSegments() == 0)) return;
0080
0081 // find the closest point
0082 Standard_Integer iPoint, iSegment, nbPoints, nbSegments;
0083
0084 const IntRes2d_IntersectionPoint *PClosest = NULL;
0085
0086 Standard_Real dMin = RealLast();
0087 nbPoints = myIntersector.NbPoints();
0088 for (iPoint = 1; iPoint <= nbPoints; iPoint++) {
0089 const IntRes2d_IntersectionPoint& PInter = myIntersector.Point(iPoint);
0090 // test for ON
0091 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
0092 myClosest = iPoint;
0093 myState = TopAbs_ON;
0094 return;
0095 }
0096 Standard_Real paramfirst = PInter.ParamOnFirst();
0097 if (paramfirst < dMin) {
0098 myClosest = iPoint;
0099 PClosest = &PInter;
0100 dMin = paramfirst;
0101 }
0102 }
0103
0104 // for the segments we only test the first point
0105 nbSegments = myIntersector.NbSegments();
0106 for (iSegment = 1; iSegment <= nbSegments; iSegment++) {
0107 const IntRes2d_IntersectionSegment& SegInter =
0108 myIntersector.Segment(iSegment);
0109 const IntRes2d_IntersectionPoint& PInter = SegInter.FirstPoint();
0110 if (PInter.TransitionOfFirst().PositionOnCurve() == IntRes2d_Head) {
0111 myClosest = nbPoints + iSegment+ iSegment - 1;
0112 myState = TopAbs_ON;
0113 return;
0114 }
0115 Standard_Real paramfirst = PInter.ParamOnFirst();
0116 if (paramfirst < dMin) {
0117 myClosest = nbPoints + iSegment+iSegment - 1;
0118 PClosest = &PInter;
0119 dMin = paramfirst;
0120 }
0121 }
0122
0123 // if no point was found return
0124 if (myClosest == 0) return;
0125
0126 // if the Edge is INTERNAL or EXTERNAL, no problem
0127 if (Or == TopAbs_INTERNAL) {
0128 myState = TopAbs_IN;
0129 return;
0130 }
0131 else if (Or == TopAbs_EXTERNAL) {
0132 myState = TopAbs_OUT;
0133 return;
0134 }
0135
0136
0137 if ( ! myFirstCompare ) {
0138 Standard_Boolean b = (dMin > myParam);
0139 if (b) {
0140 // dMin > myParam : le point le plus proche (dMin) trouve dans CETTE
0141 // intersection ligne,arete n'est pas le plus proche
0142 // de TOUS les points d'intersection avec les autres aretes (myParam).
0143 return;
0144 }
0145 }
0146
0147 // process the closest point PClosest, found at dMin on line.
0148 myFirstCompare = Standard_False;
0149
0150 if(myParam > dMin) { //-- lbr le 13 mai 96
0151 myFirstTrans = Standard_True;
0152 }
0153
0154 myParam = dMin;
0155 const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
0156 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 Begin
0157 // Standard_Boolean isHeadorEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
0158 // (T2.PositionOnCurve() == IntRes2d_End);
0159 myIsHeadOrEnd = (T2.PositionOnCurve() == IntRes2d_Head) ||
0160 (T2.PositionOnCurve() == IntRes2d_End);
0161 // Modified by skv - Wed Jul 12 15:20:58 2006 OCC12627 End
0162
0163 // transition on the segment
0164
0165 TopAbs_Orientation SegTrans = TopAbs_FORWARD;
0166
0167 const IntRes2d_Transition& T1 = PClosest->TransitionOfFirst();
0168 switch (T1.TransitionType()) {
0169 case IntRes2d_In :
0170 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_REVERSED;
0171 else SegTrans = TopAbs_FORWARD;
0172 break;
0173 case IntRes2d_Out :
0174 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_FORWARD;
0175 else SegTrans = TopAbs_REVERSED;
0176 break;
0177 case IntRes2d_Touch :
0178 switch (T1.Situation()) {
0179 case IntRes2d_Inside :
0180 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_EXTERNAL;
0181 else SegTrans = TopAbs_INTERNAL;
0182 break;
0183 case IntRes2d_Outside :
0184 if (Or == TopAbs_REVERSED) SegTrans = TopAbs_INTERNAL;
0185 else SegTrans = TopAbs_EXTERNAL;
0186 break;
0187 case IntRes2d_Unknown : return;
0188 }
0189 break;
0190 case IntRes2d_Undecided : return;
0191 }
0192
0193 // are we inside the Edge ?
0194 // const IntRes2d_Transition& T2 = PClosest->TransitionOfSecond();
0195 if ( ! myIsHeadOrEnd ) {
0196 // PClosest is inside the edge
0197 switch (SegTrans) {
0198
0199 case TopAbs_FORWARD :
0200 case TopAbs_EXTERNAL :
0201 myState = TopAbs_OUT;
0202 break;
0203
0204 case TopAbs_REVERSED :
0205 case TopAbs_INTERNAL :
0206 myState = TopAbs_IN;
0207 break;
0208 }
0209 }
0210 else {
0211 // PClosest is Head or End of the edge : update the complex transition
0212 gp_Dir2d Tang2d,Norm2d;
0213 Standard_Real Curv;
0214 myIntersector.LocalGeometry
0215 (E,PClosest->ParamOnSecond(),Tang2d,Norm2d,Curv);
0216 gp_Dir Tang(Tang2d.X(),Tang2d.Y(),0.);
0217 gp_Dir Norm(Norm2d.X(),Norm2d.Y(),0.);
0218 if (myFirstTrans) {
0219 gp_Dir D(myLin.Direction().X(),myLin.Direction().Y(),0.);
0220 myTrans.Reset(D);
0221 myFirstTrans = Standard_False;
0222 }
0223
0224 TopAbs_Orientation Ort;
0225 if (T2.PositionOnCurve() == IntRes2d_Head) Ort = TopAbs_FORWARD;
0226 else Ort = TopAbs_REVERSED;
0227 myTrans.Compare(RealEpsilon(), Tang, Norm, Curv, SegTrans, Ort);
0228 myState = myTrans.StateBefore();
0229 }
0230 }