Warning, /include/opencascade/IntCurve_IntPolyPolyGen.gxx is written in an unsupported language. File is not indexed.
0001 // Created on: 1992-10-13
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 by skv - Tue Mar 1 14:22:09 2005 OCC8169
0018
0019
0020 #ifndef OCCT_DEBUG
0021 #define No_Standard_RangeError
0022 #define No_Standard_OutOfRange
0023 #endif
0024
0025
0026 #include <Standard_ConstructionError.hxx>
0027
0028 #include <IntRes2d_Domain.hxx>
0029 #include <IntRes2d_Position.hxx>
0030 #include <IntRes2d_Transition.hxx>
0031 #include <IntRes2d_IntersectionPoint.hxx>
0032 #include <IntRes2d_IntersectionSegment.hxx>
0033
0034
0035 #include <IntImpParGen.hxx>
0036
0037 #include <Intf_SectionPoint.hxx>
0038 #include <Intf_SectionLine.hxx>
0039 #include <Intf_TangentZone.hxx>
0040 #include <Intf_InterferencePolygon2d.hxx>
0041
0042 #include <gp_Vec2d.hxx>
0043
0044 #include <math_Vector.hxx>
0045 #include <math_FunctionSetRoot.hxx>
0046 #include <math_NewtonFunctionSetRoot.hxx>
0047 #include <NCollection_Handle.hxx>
0048 #include <Bnd_Box2d.hxx>
0049 #include <Precision.hxx>
0050
0051 //======================================================================
0052
0053 #define NBITER_MAX_POLYGON 10
0054 #define TOL_CONF_MINI 0.0000000001
0055 #define TOL_MINI 0.0000000001
0056
0057 //----------------------------------------------------------------------
0058
0059
0060 void GetIntersection(const TheCurve& theC1, const Standard_Real theT1f, const Standard_Real theT1l,
0061 const TheCurve& theC2, const Standard_Real theT2f, const Standard_Real theT2l,
0062 const Standard_Real theTolConf,
0063 const Standard_Integer theMaxCount,
0064 IntRes2d_IntersectionPoint& thePInt, Standard_Real& theDist,
0065 Standard_Integer& theCount);
0066
0067
0068 Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1
0069 ,const TheCurve& C1
0070 ,const Standard_Real u
0071 ,const IntRes2d_Domain& D2
0072 ,const TheCurve& C2
0073 ,const Standard_Real v
0074 ,const Standard_Real TolConf
0075 ,IntRes2d_IntersectionPoint& IntPt
0076 ,Standard_Boolean& HeadOn1
0077 ,Standard_Boolean& HeadOn2
0078 ,Standard_Boolean& EndOn1
0079 ,Standard_Boolean& EndOn2
0080 ,Standard_Integer PosSegment);
0081
0082
0083 //======================================================================
0084 IntCurve_IntPolyPolyGen::IntCurve_IntPolyPolyGen()
0085 {
0086 const Standard_Integer aMinPntNb = 20; // Minimum number of samples.
0087 myMinPntNb = aMinPntNb;
0088 done = Standard_False;
0089 }
0090 //======================================================================
0091 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
0092 ,const IntRes2d_Domain& D1
0093 ,const TheCurve& C2
0094 ,const IntRes2d_Domain& D2
0095 ,const Standard_Real TheTolConf
0096 ,const Standard_Real TheTol)
0097 {
0098 this->ResetFields();
0099 DomainOnCurve1=D1;
0100 DomainOnCurve2=D2;
0101 Standard_Real DU = D1.LastParameter()-D1.FirstParameter();
0102 Standard_Real DV = D2.LastParameter()-D2.FirstParameter();
0103 Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol;
0104 Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
0105 Perform(C1,D1,C2,D2,TlConf,Tl,0,DU,DV);
0106 //----------------------------------------------------------------------
0107 //-- Processing of end points
0108 //----------------------------------------------------------------------
0109 Standard_Boolean HeadOn1 = Standard_False;
0110 Standard_Boolean HeadOn2 = Standard_False;
0111 Standard_Boolean EndOn1 = Standard_False;
0112 Standard_Boolean EndOn2 = Standard_False;
0113 Standard_Integer i;
0114 Standard_Integer n=this->NbPoints();
0115
0116
0117 //--------------------------------------------------------------------
0118 //-- The points Head Head ... End End are not rejected if
0119 //-- they are already present at the end of segment
0120 //-- ( It is not possible to test the equities on the parameters)
0121 //-- ( these points are not found at EpsX precision )
0122 //-- PosSegment = 1 if Head Head
0123 //-- 2 if Head End
0124 //-- 4 if End Head
0125 //-- 8 if End End
0126 //--------------------------------------------------------------------
0127 Standard_Integer PosSegment = 0;
0128
0129 for(i=1;i<=n;i++) {
0130 IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
0131 if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True;
0132 else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True;
0133
0134 IntRes2d_Position Pos2 = this->Point(i).TransitionOfSecond().PositionOnCurve();
0135 if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True;
0136 else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True;
0137
0138 if(Pos1 == IntRes2d_Head) {
0139 if(Pos2 == IntRes2d_Head) PosSegment|=1;
0140 else if(Pos2 == IntRes2d_End) PosSegment|=2;
0141 }
0142 else if(Pos1 == IntRes2d_End) {
0143 if(Pos2 == IntRes2d_Head) PosSegment|=4;
0144 else if(Pos2 == IntRes2d_End) PosSegment|=8;
0145 }
0146 }
0147
0148 n=this->NbSegments();
0149 for(i=1;i<=n;i++) {
0150 IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
0151 if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True;
0152 else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True;
0153
0154 IntRes2d_Position Pos2 = this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
0155 if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True;
0156 else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True;
0157
0158 if(Pos1 == IntRes2d_Head) {
0159 if(Pos2 == IntRes2d_Head) PosSegment|=1;
0160 else if(Pos2 == IntRes2d_End) PosSegment|=2;
0161 }
0162 else if(Pos1 == IntRes2d_End) {
0163 if(Pos2 == IntRes2d_Head) PosSegment|=4;
0164 else if(Pos2 == IntRes2d_End) PosSegment|=8;
0165 }
0166
0167 Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
0168 if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True;
0169 else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True;
0170
0171 Pos2 = this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
0172 if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True;
0173 else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True;
0174
0175 if(Pos1 == IntRes2d_Head) {
0176 if(Pos2 == IntRes2d_Head) PosSegment|=1;
0177 else if(Pos2 == IntRes2d_End) PosSegment|=2;
0178 }
0179 else if(Pos1 == IntRes2d_End) {
0180 if(Pos2 == IntRes2d_Head) PosSegment|=4;
0181 else if(Pos2 == IntRes2d_End) PosSegment|=8;
0182 }
0183 }
0184
0185 Standard_Real U0 = D1.FirstParameter();
0186 Standard_Real U1 = D1.LastParameter();
0187 Standard_Real V0 = D2.FirstParameter();
0188 Standard_Real V1 = D2.LastParameter();
0189 IntRes2d_IntersectionPoint IntPt;
0190
0191 if(D1.FirstTolerance() || D2.FirstTolerance()) {
0192 if(HeadOrEndPoint(D1,C1,U0,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
0193 this->Insert(IntPt);
0194 }
0195 if(D1.FirstTolerance() || D2.LastTolerance()) {
0196 if(HeadOrEndPoint(D1,C1,U0,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
0197 this->Insert(IntPt);
0198 }
0199 if(D1.LastTolerance() || D2.FirstTolerance()) {
0200 if(HeadOrEndPoint(D1,C1,U1,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
0201 this->Insert(IntPt);
0202 }
0203 if(D1.LastTolerance() || D2.LastTolerance()) {
0204 if(HeadOrEndPoint(D1,C1,U1,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
0205 this->Insert(IntPt);
0206 }
0207 }
0208
0209
0210 //======================================================================
0211 //== A u t o I n t e r s e c t i o n
0212 //======================================================================
0213 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
0214 ,const IntRes2d_Domain& D1
0215 ,const Standard_Real TheTolConf
0216 ,const Standard_Real TheTol)
0217 {
0218
0219 this->ResetFields();
0220 DomainOnCurve1=D1;
0221 DomainOnCurve2=D1;
0222 Standard_Real DU = D1.LastParameter()-D1.FirstParameter();
0223 Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol;
0224 Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
0225 Perform(C1,D1,TlConf,Tl,0,DU,DU);
0226 Standard_Integer i;
0227 Standard_Integer n=this->NbPoints();
0228
0229 //--------------------------------------------------------------------
0230 //-- The points Head Head ... End End are not rejected if
0231 //-- they are already present at the end of segment
0232 //-- ( It is not possible to test the equities on the parameters)
0233 //-- ( these points are not found at EpsX precision )
0234 //-- PosSegment = 1 if Head Head
0235 //-- 2 if Head End
0236 //-- 4 if End Head
0237 //-- 8 if End End
0238 //--------------------------------------------------------------------
0239 Standard_Integer PosSegment = 0;
0240
0241 for(i=1;i<=n;i++) {
0242 IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
0243 IntRes2d_Position Pos2 = this->Point(i).TransitionOfSecond().PositionOnCurve();
0244
0245 if(Pos1 == IntRes2d_Head) {
0246 if(Pos2 == IntRes2d_Head) PosSegment|=1;
0247 else if(Pos2 == IntRes2d_End) PosSegment|=2;
0248 }
0249 else if(Pos1 == IntRes2d_End) {
0250 if(Pos2 == IntRes2d_Head) PosSegment|=4;
0251 else if(Pos2 == IntRes2d_End) PosSegment|=8;
0252 }
0253 }
0254
0255 n=this->NbSegments();
0256 for(i=1;i<=n;i++) {
0257 IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
0258 IntRes2d_Position Pos2 = this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
0259
0260 if(Pos1 == IntRes2d_Head) {
0261 if(Pos2 == IntRes2d_Head) PosSegment|=1;
0262 else if(Pos2 == IntRes2d_End) PosSegment|=2;
0263 }
0264 else if(Pos1 == IntRes2d_End) {
0265 if(Pos2 == IntRes2d_Head) PosSegment|=4;
0266 else if(Pos2 == IntRes2d_End) PosSegment|=8;
0267 }
0268
0269 Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
0270 Pos2 = this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
0271
0272 if(Pos1 == IntRes2d_Head) {
0273 if(Pos2 == IntRes2d_Head) PosSegment|=1;
0274 else if(Pos2 == IntRes2d_End) PosSegment|=2;
0275 }
0276 else if(Pos1 == IntRes2d_End) {
0277 if(Pos2 == IntRes2d_Head) PosSegment|=4;
0278 else if(Pos2 == IntRes2d_End) PosSegment|=8;
0279 }
0280 }
0281 (void )PosSegment;
0282 }
0283 //======================================================================
0284
0285 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
0286 ,const IntRes2d_Domain& D1
0287 ,const Standard_Real TolConf
0288 ,const Standard_Real Tol
0289 ,const Standard_Integer NbIter
0290 ,const Standard_Real /*DeltaU*/
0291 ,const Standard_Real) {
0292
0293 gp_Vec2d Tan1,Tan2,Norm1,Norm2;
0294 gp_Pnt2d P1,P2;
0295 Standard_Integer nbsamples;
0296 done = Standard_False;
0297
0298 nbsamples = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
0299
0300 if(NbIter>3 || (NbIter>2 && nbsamples>100)) return;
0301
0302 nbsamples*=2; //--- We take systematically two times more points
0303 //-- than on a normal curve.
0304 //-- Auto-intersecting curves often produce
0305 //-- polygons rather far from the curve with parameter ct.
0306
0307 if(NbIter>0) {
0308 nbsamples=(3*(nbsamples*NbIter))/2;
0309 }
0310 IntCurve_ThePolygon2d Poly1(C1,nbsamples,D1,Tol);
0311 if(!Poly1.AutoIntersectionIsPossible()) {
0312 done = Standard_True;
0313 return;
0314 }
0315 //-- Poly1.Dump();
0316 //----------------------------------------------------------------------
0317 //-- If the deflection is less than the Tolerance of Confusion
0318 //-- then the deflection of the polygon is set in TolConf
0319 //-- (Detection of Tangency Zones)
0320 //----------------------------------------------------------------------
0321 if(Poly1.DeflectionOverEstimation() < TolConf) {
0322 Poly1.SetDeflectionOverEstimation(TolConf);
0323 }
0324
0325 Intf_InterferencePolygon2d InterPP(Poly1);
0326 IntCurve_ExactIntersectionPoint EIP(C1,C1,TolConf);
0327 Standard_Real U,V;
0328
0329 //----------------------------------------------------------------------
0330 //-- Processing of SectionPoint
0331 //----------------------------------------------------------------------
0332 Standard_Integer Nbsp = InterPP.NbSectionPoints();
0333 if(Nbsp>=1) {
0334
0335 //-- ---------------------------------------------------------------------
0336 //-- filtering, filtering, filtering ...
0337 //--
0338 Standard_Integer* TriIndex = new Standard_Integer [Nbsp+1];
0339 Standard_Integer* PtrSegIndex1 = new Standard_Integer [Nbsp+1];
0340 Standard_Integer* PtrSegIndex2 = new Standard_Integer [Nbsp+1];
0341 Standard_Boolean Triok;
0342 Standard_Integer SegIndex1,SegIndex2,SegIndex_1,SegIndex_2;
0343 // Standard_Real ParamOn1,ParamOn2,ParamOn_1,ParamOn_2;
0344 Standard_Real ParamOn1,ParamOn2;
0345 Intf_PIType Type;
0346 Standard_Integer i ;
0347 for( i=1;i<=Nbsp;i++) {
0348 TriIndex[i]=i;
0349 const Intf_SectionPoint& SPnt1 = InterPP.PntValue(i);
0350 SPnt1.InfoFirst(Type,PtrSegIndex1[i],ParamOn1);
0351 SPnt1.InfoSecond(Type,PtrSegIndex2[i],ParamOn2);
0352 }
0353
0354
0355 do {
0356 Triok=Standard_True;
0357
0358 for(Standard_Integer tr=1;tr<Nbsp;tr++) {
0359 SegIndex1=PtrSegIndex1[TriIndex[tr]];
0360 SegIndex_1=PtrSegIndex1[TriIndex[tr+1]];
0361
0362 SegIndex2=PtrSegIndex2[TriIndex[tr]];
0363 SegIndex_2=PtrSegIndex2[TriIndex[tr+1]];
0364
0365 if(SegIndex1 > SegIndex_1) {
0366 Standard_Integer q=TriIndex[tr];
0367 TriIndex[tr]=TriIndex[tr+1];
0368 TriIndex[tr+1]=q;
0369 Triok=Standard_False;
0370 }
0371 else if(SegIndex1 == SegIndex_1) {
0372 if(SegIndex2 > SegIndex_2) {
0373 Standard_Integer q=TriIndex[tr];
0374 TriIndex[tr]=TriIndex[tr+1];
0375 TriIndex[tr+1]=q;
0376 Triok=Standard_False;
0377 }
0378 }
0379 }
0380 }
0381 while(Triok==Standard_False);
0382
0383 //-- supression des doublons Si Si !
0384 for(i=1; i<Nbsp;i++) {
0385 if( (PtrSegIndex1[TriIndex[i]] == PtrSegIndex1[TriIndex[i+1]])
0386 && (PtrSegIndex2[TriIndex[i]] == PtrSegIndex2[TriIndex[i+1]])) {
0387 TriIndex[i]=-i;
0388 }
0389 }
0390
0391 for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
0392 if(TriIndex[sp]>0) {
0393 const Intf_SectionPoint& SPnt = InterPP.PntValue(TriIndex[sp]);
0394
0395 SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
0396 SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
0397
0398 if(Abs(SegIndex1-SegIndex2)>1) {
0399
0400 EIP.Perform(Poly1,Poly1,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
0401 if(EIP.NbRoots()>=1) {
0402 //--------------------------------------------------------------------
0403 //-- It is checked if the found point is a root
0404 //--------------------------------------------------------------------
0405 EIP.Roots(U,V);
0406
0407 TheCurveTool::D1(C1,U,P1,Tan1);
0408 TheCurveTool::D1(C1,V,P2,Tan2);
0409 Standard_Real Dist = P1.Distance(P2);
0410 Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1);
0411
0412 if(Abs(U-V)<=EpsX1) {
0413 //-----------------------------------------
0414 //-- Solution not valid
0415 //-- The maths should have converged in a
0416 //-- trivial solution ( point U = V )
0417 //-----------------------------------------
0418 Dist = TolConf+1.0;
0419 }
0420
0421 //-----------------------------------------------------------------
0422 //-- It is checked if the point (u,v) already exists
0423 //--
0424 done = Standard_True;
0425 Standard_Integer nbp=NbPoints();
0426
0427 for(Standard_Integer p=1; p<=nbp; p++) {
0428 const IntRes2d_IntersectionPoint& P=Point(p);
0429 if(Abs(U-P.ParamOnFirst()) <= EpsX1) {
0430 if(Abs(V-P.ParamOnSecond()) <= EpsX1) {
0431 Dist = TolConf+1.0; p+=nbp;
0432 }
0433 }
0434 }
0435
0436 if(Dist <= TolConf) { //-- Or the point is already present
0437 IntRes2d_Position Pos1 = IntRes2d_Middle;
0438 IntRes2d_Position Pos2 = IntRes2d_Middle;
0439 IntRes2d_Transition Trans1,Trans2;
0440 //-----------------------------------------------------------------
0441 //-- Calculate Positions of Points on the curve
0442 //--
0443 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())
0444 Pos1 = IntRes2d_Head;
0445 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance())
0446 Pos1 = IntRes2d_End;
0447
0448 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())
0449 Pos2 = IntRes2d_Head;
0450 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance())
0451 Pos2 = IntRes2d_End;
0452 //-----------------------------------------------------------------
0453 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1
0454 ,Pos2,Tan2,Trans2
0455 ,TolConf) == Standard_False)
0456 {
0457 TheCurveTool::D2(C1,U,P1,Tan1,Norm1);
0458 TheCurveTool::D2(C1,V,P2,Tan2,Norm2);
0459 IntImpParGen::DetermineTransition( Pos1,Tan1,Norm1,Trans1
0460 ,Pos2,Tan2,Norm2,Trans2
0461 ,TolConf);
0462 }
0463 IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
0464 Insert(IP);
0465 }
0466 }
0467 }
0468 }
0469 }
0470 delete [] TriIndex;
0471 delete [] PtrSegIndex1;
0472 delete [] PtrSegIndex2;
0473 }
0474
0475 //----------------------------------------------------------------------
0476 //-- Processing of TangentZone
0477 //----------------------------------------------------------------------
0478 Standard_Integer Nbtz = InterPP.NbTangentZones();
0479 for(Standard_Integer tz=1; tz <= Nbtz; tz++) {
0480 Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
0481 //====================================================================
0482 //== Find the first and the last point in the tangency zone.
0483 //====================================================================
0484 Standard_Real ParamSupOnCurve2,ParamInfOnCurve2;
0485 Standard_Real ParamSupOnCurve1,ParamInfOnCurve1;
0486 // Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
0487 Standard_Integer SegIndex1onP1,SegIndex1onP2;
0488 Intf_PIType Type;
0489 Standard_Real ParamOnLine;
0490 Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup;
0491 ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast();
0492 ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast();
0493 for(Standard_Integer qq=1;qq<=NbPnts;qq++) {
0494 const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
0495 //====================================================================
0496 //== The zones of tangency are discretized
0497 //== Test of stop : Check if
0498 //== (Deflection < Tolerance)
0499 //== Or (Sample < EpsX) (normally the first condition is
0500 //== more strict)
0501 //====================================================================
0502 // Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
0503 Standard_Real _PolyUInf,_PolyVInf;
0504
0505 SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine);
0506 if(SegIndex1onP1 > Poly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
0507 if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; }
0508 _PolyUInf = Poly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
0509
0510 SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine);
0511 if(SegIndex1onP2 > Poly1.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
0512 if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; }
0513 _PolyVInf = Poly1.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
0514
0515 //----------------------------------------------------------------------
0516
0517 if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf;
0518 if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf;
0519
0520 if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf;
0521 if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf;
0522 }
0523
0524 PolyUInf= ParamInfOnCurve1;
0525 PolyUSup= ParamSupOnCurve1;
0526 PolyVInf= ParamInfOnCurve2;
0527 PolyVSup= ParamSupOnCurve2;
0528
0529 TheCurveTool::D0(C1,PolyUInf,P1);
0530 TheCurveTool::D0(C1,PolyVInf,P2);
0531 Standard_Real distmemesens = P1.SquareDistance(P2);
0532 TheCurveTool::D0(C1,PolyVSup,P2);
0533 Standard_Real distdiffsens = P1.SquareDistance(P2);
0534 if(distmemesens > distdiffsens) {
0535 Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty;
0536 }
0537
0538 //-----------------------------------------------------------------
0539 //-- Calculate Positions of Points on the curve and
0540 //-- Transitions on each limit of the segment
0541
0542 IntRes2d_Position Pos1 = IntRes2d_Middle;
0543 IntRes2d_Position Pos2 = IntRes2d_Middle;
0544 IntRes2d_Transition Trans1,Trans2;
0545
0546 TheCurveTool::D1(C1,PolyUInf,P1,Tan1);
0547 TheCurveTool::D1(C1,PolyVInf,P2,Tan2);
0548
0549 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
0550 Pos1 = IntRes2d_Head;
0551 }
0552 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
0553 Pos1 = IntRes2d_End;
0554 }
0555 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
0556 Pos2 = IntRes2d_Head;
0557 }
0558 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
0559 Pos2 = IntRes2d_End;
0560 }
0561
0562 if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
0563 PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0564 }
0565 else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
0566 PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0567 }
0568 else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
0569 PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0570 }
0571 else {
0572 PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0573 }
0574
0575
0576
0577 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
0578 == Standard_False)
0579 {
0580 TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1);
0581 TheCurveTool::D2(C1,PolyVInf,P2,Tan2,Norm2);
0582 IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
0583 Pos2,Tan2,Norm2,Trans2,TolConf);
0584 }
0585 IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf
0586 ,Trans1,Trans2,Standard_False);
0587 //----------------------------------------------------------------------
0588
0589 if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1)) ||
0590 (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C1)))
0591 {
0592 //bad segment
0593 }
0594 else
0595 {
0596 TheCurveTool::D1(C1,PolyUSup,P1,Tan1);
0597 TheCurveTool::D1(C1,PolyVSup,P2,Tan2);
0598 Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle;
0599
0600 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
0601 Pos1 = IntRes2d_Head;
0602 }
0603 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
0604 Pos1 = IntRes2d_End;
0605 }
0606 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
0607 Pos2 = IntRes2d_Head;
0608 }
0609 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
0610 Pos2 = IntRes2d_End;
0611 }
0612
0613
0614 if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
0615 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0616 }
0617 else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
0618 PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0619 }
0620 else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
0621 PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0622 }
0623 else {
0624 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0625 }
0626
0627 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
0628 ==Standard_False) {
0629 TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1);
0630 TheCurveTool::D2(C1,PolyVSup,P2,Tan2,Norm2);
0631 IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
0632 Pos2,Tan2,Norm2,Trans2,TolConf);
0633 }
0634 IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup
0635 ,Trans1,Trans2,Standard_False);
0636
0637 Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True;
0638 if(ParamInfOnCurve1 > ParamSupOnCurve1) {
0639 IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False);
0640 Append(Seg);
0641 }
0642 else {
0643 IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False);
0644 Append(Seg);
0645 }
0646 }
0647 } //end of processing of TangentZone
0648
0649 done = Standard_True;
0650 }
0651
0652
0653 Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1
0654 ,const TheCurve& C1
0655 ,const Standard_Real tu
0656 ,const IntRes2d_Domain& D2
0657 ,const TheCurve& C2
0658 ,const Standard_Real tv
0659 ,const Standard_Real TolConf
0660 ,IntRes2d_IntersectionPoint& IntPt
0661 ,Standard_Boolean& HeadOn1
0662 ,Standard_Boolean& HeadOn2
0663 ,Standard_Boolean& EndOn1
0664 ,Standard_Boolean& EndOn2
0665 ,Standard_Integer PosSegment) {
0666
0667 gp_Pnt2d P1,P2,SP1,SP2;
0668 gp_Vec2d T1,T2,N1,N2;
0669 Standard_Real u=tu;
0670 Standard_Real v=tv;
0671 Standard_Real svu = u;
0672 Standard_Real svv = v;
0673
0674 TheCurveTool::D1(C1,u,P1,T1);
0675 TheCurveTool::D1(C2,v,P2,T2);
0676
0677 IntRes2d_Position Pos1 = IntRes2d_Middle;
0678 IntRes2d_Position Pos2 = IntRes2d_Middle;
0679 IntRes2d_Transition Trans1,Trans2;
0680
0681 //----------------------------------------------------------------------
0682 //-- Head On 1 : Head1 <-> P2
0683 if(P2.Distance(D1.FirstPoint())<=D1.FirstTolerance()) {
0684 Pos1 = IntRes2d_Head;
0685 HeadOn1 = Standard_True;
0686 SP1 = D1.FirstPoint();
0687 u = D1.FirstParameter();
0688 }
0689 //----------------------------------------------------------------------
0690 //-- End On 1 : End1 <-> P2
0691 else if(P2.Distance(D1.LastPoint())<=D1.LastTolerance()) {
0692 Pos1 = IntRes2d_End;
0693 EndOn1 = Standard_True;
0694 SP1 = D1.LastPoint();
0695 u = D1.LastParameter();
0696 }
0697
0698 //----------------------------------------------------------------------
0699 //-- Head On 2 : Head2 <-> P1
0700 else if(P1.Distance(D2.FirstPoint())<=D2.FirstTolerance()) {
0701 Pos2 = IntRes2d_Head;
0702 HeadOn2 = Standard_True;
0703 SP2 = D2.FirstPoint();
0704 v = D2.FirstParameter();
0705 }
0706 //----------------------------------------------------------------------
0707 //-- End On 2 : End2 <-> P1
0708 else if(P1.Distance(D2.LastPoint())<=D2.LastTolerance()) {
0709 Pos2 = IntRes2d_End;
0710 EndOn2 = Standard_True;
0711 SP2 = D2.LastPoint();
0712 v = D2.LastParameter();
0713 }
0714
0715 Standard_Real EpsX1 = TheCurveTool::EpsX(C1);
0716 Standard_Real EpsX2 = TheCurveTool::EpsX(C2);
0717
0718 if((Pos1 != IntRes2d_Middle)||(Pos2 != IntRes2d_Middle)) {
0719 if(Pos1 == IntRes2d_Middle) {
0720 if(Abs(u-D1.FirstParameter()) <= EpsX1) {
0721 Pos1 = IntRes2d_Head;
0722 P1 = D1.FirstPoint();
0723 HeadOn1 = Standard_True;
0724 }
0725 else if(Abs(u-D1.LastParameter()) <= EpsX1) {
0726 Pos1 = IntRes2d_End;
0727 P1 = D1.LastPoint();
0728 EndOn1 = Standard_True;
0729 }
0730 }
0731 else if(u!=tu) {
0732 P1 = SP1;
0733 }
0734
0735
0736 if(Pos2 == IntRes2d_Middle) {
0737 if(Abs(v-D2.FirstParameter()) <= EpsX2) {
0738 Pos2 = IntRes2d_Head;
0739 HeadOn2 = Standard_True;
0740 P2 = D2.FirstPoint();
0741 if(Pos1 != IntRes2d_Middle) {
0742 P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y()));
0743 }
0744 else {
0745 P2 = P1;
0746 }
0747 }
0748 else if(Abs(v-D2.LastParameter()) <= EpsX2) {
0749 Pos2 = IntRes2d_End;
0750 EndOn2 = Standard_True;
0751 P2 = D2.LastPoint();
0752 if(Pos1 != IntRes2d_Middle) {
0753 P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y()));
0754 }
0755 else {
0756 P2 = P1;
0757 }
0758 }
0759 }
0760
0761 //--------------------------------------------------------------------
0762 //-- It is tested if a point at the end of segment already has its transitions
0763 //-- If Yes, the new point is not created
0764 //--
0765 //-- PosSegment = 1 if Head Head
0766 //-- 2 if Head End
0767 //-- 4 if End Head
0768 //-- 8 if End End
0769 //--------------------------------------------------------------------
0770 if(Pos1 == IntRes2d_Head) {
0771 if((Pos2 == IntRes2d_Head)&&(PosSegment & 1)) return(Standard_False);
0772 if((Pos2 == IntRes2d_End )&&(PosSegment & 2)) return(Standard_False);
0773 }
0774 else if(Pos1 == IntRes2d_End) {
0775 if((Pos2 == IntRes2d_Head)&&(PosSegment & 4)) return(Standard_False);
0776 if((Pos2 == IntRes2d_End )&&(PosSegment & 8)) return(Standard_False);
0777 }
0778
0779
0780 if(IntImpParGen::DetermineTransition( Pos1,T1,Trans1,Pos2,T2,Trans2,TolConf)
0781 == Standard_False) {
0782 TheCurveTool::D2(C1,svu,P1,T1,N1);
0783 TheCurveTool::D2(C2,svv,P2,T2,N2);
0784 IntImpParGen::DetermineTransition(Pos1,T1,N1,Trans1,
0785 Pos2,T2,N2,Trans2,TolConf);
0786 }
0787 IntPt.SetValues(P1,u,v,Trans1,Trans2,Standard_False);
0788 return(Standard_True);
0789 }
0790 else
0791 return(Standard_False);
0792 }
0793
0794 //=======================================================================
0795 //function : Perform
0796 //purpose : Base method to perform polyline / polyline intersection for
0797 // pair of curves.
0798 //=======================================================================
0799 void IntCurve_IntPolyPolyGen::Perform(const TheCurve& C1,
0800 const IntRes2d_Domain& D1,
0801 const TheCurve& C2,
0802 const IntRes2d_Domain& D2,
0803 const Standard_Real TolConf,
0804 const Standard_Real Tol,
0805 const Standard_Integer NbIter,
0806 const Standard_Real DeltaU,
0807 const Standard_Real DeltaV)
0808 {
0809 Standard_Integer nbsamplesOnC1,nbsamplesOnC2;
0810 done = Standard_False;
0811
0812 if(NbIter>NBITER_MAX_POLYGON) return;
0813
0814 // Number of samples running.
0815 nbsamplesOnC1 = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
0816 nbsamplesOnC2 = TheCurveTool::NbSamples(C2,D2.FirstParameter(),D2.LastParameter());
0817
0818 if (NbIter == 0)
0819 {
0820 // Minimal number of points.
0821 nbsamplesOnC1 = Max(nbsamplesOnC1, myMinPntNb);
0822 nbsamplesOnC2 = Max(nbsamplesOnC2, myMinPntNb);
0823 }
0824 else
0825 {
0826 // Increase number of samples in second and next iterations.
0827 nbsamplesOnC1=(5 * (nbsamplesOnC1 * NbIter)) / 4;
0828 nbsamplesOnC2=(5 * (nbsamplesOnC2 * NbIter)) / 4;
0829 }
0830
0831 NCollection_Handle<IntCurve_ThePolygon2d>
0832 aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol),
0833 aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
0834
0835 if( (aPoly1->DeflectionOverEstimation() > TolConf) &&
0836 (aPoly2->DeflectionOverEstimation() > TolConf))
0837 {
0838 const Standard_Real aDeflectionSum =
0839 Max(aPoly1->DeflectionOverEstimation(), TolConf) +
0840 Max(aPoly2->DeflectionOverEstimation(), TolConf);
0841
0842 if (nbsamplesOnC2 > nbsamplesOnC1)
0843 {
0844 aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
0845 aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
0846 aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
0847 }
0848 else
0849 {
0850 aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
0851 aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
0852 aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
0853 }
0854 }
0855
0856 //----------------------------------------------------------------------
0857 //-- if the deflection less then the Tolerance of Confusion
0858 //-- Then the deflection of the polygon is set in TolConf
0859 //-- (Detection of Tangency Zones)
0860 //----------------------------------------------------------------------
0861
0862 if(aPoly1->DeflectionOverEstimation() < TolConf) {
0863 aPoly1->SetDeflectionOverEstimation(TolConf);
0864 }
0865 if(aPoly2->DeflectionOverEstimation() < TolConf) {
0866 aPoly2->SetDeflectionOverEstimation(TolConf);
0867 }
0868 // for case when a few polygon points were replaced by line
0869 // if exact solution was not found
0870 // then search of precise solution will be repeated
0871 // for polygon contains all initial points
0872 // secondary search will be performed only for case when initial points
0873 // were dropped
0874 Standard_Boolean isFullRepresentation = ( aPoly1->NbSegments() == nbsamplesOnC1 &&
0875 aPoly2->NbSegments() == nbsamplesOnC2 );
0876
0877 if( !findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
0878 DeltaU, DeltaV, *aPoly1, *aPoly2, isFullRepresentation ) && !isFullRepresentation )
0879 {
0880 if(aPoly1->NbSegments() < nbsamplesOnC1)
0881 {
0882 aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
0883 }
0884 if(aPoly2->NbSegments() < nbsamplesOnC2)
0885 {
0886 aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
0887 }
0888
0889 findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
0890 DeltaU, DeltaV, *aPoly1, *aPoly2,
0891 Standard_True);
0892
0893 }
0894
0895 done = Standard_True;
0896 }
0897
0898 //======================================================================
0899 // Purpose : findIntersect
0900 //======================================================================
0901
0902 Standard_Boolean IntCurve_IntPolyPolyGen::findIntersect(
0903 const TheCurve& C1,
0904 const IntRes2d_Domain& D1,
0905 const TheCurve& C2,
0906 const IntRes2d_Domain& D2,
0907 const Standard_Real TolConf,
0908 const Standard_Real Tol,
0909 const Standard_Integer NbIter,
0910 const Standard_Real DeltaU,
0911 const Standard_Real DeltaV,
0912 const IntCurve_ThePolygon2d& thePoly1,
0913 const IntCurve_ThePolygon2d& thePoly2,
0914 Standard_Boolean isFullPolygon )
0915 {
0916
0917 gp_Vec2d Tan1,Tan2,Norm1,Norm2;
0918 gp_Pnt2d P1,P2;
0919 Intf_InterferencePolygon2d InterPP(thePoly1,thePoly2);
0920 IntCurve_ExactIntersectionPoint EIP(C1,C2,TolConf);
0921 Standard_Real U = 0., V = 0.;
0922 Standard_Boolean AnErrorOccurred = Standard_False;
0923 done = Standard_True; // To prevent exception in nbp=NbPoints();
0924 //----------------------------------------------------------------------
0925 //-- Processing of SectionPoint
0926 //----------------------------------------------------------------------
0927 Standard_Integer Nbsp = InterPP.NbSectionPoints();
0928 for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
0929 const Intf_SectionPoint& SPnt = InterPP.PntValue(sp);
0930 Standard_Integer SegIndex1,SegIndex2;
0931 Standard_Real ParamOn1,ParamOn2;
0932 Intf_PIType Type;
0933
0934 SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
0935 SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
0936 EIP.Perform(thePoly1,thePoly2,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
0937 AnErrorOccurred = EIP.AnErrorOccurred();
0938
0939 if( !EIP.NbRoots() && !isFullPolygon)
0940 return Standard_False;
0941
0942 if(AnErrorOccurred)
0943 {
0944 continue;
0945 }
0946
0947 //--------------------------------------------------------------------
0948 //-- It is checked if the found point is really a root
0949 //--------------------------------------------------------------------
0950
0951 EIP.Roots(U,V);
0952 TheCurveTool::D1(C1,U,P1,Tan1);
0953 TheCurveTool::D1(C2,V,P2,Tan2);
0954 Standard_Real Dist = P1.Distance(P2);
0955 if(EIP.NbRoots() == 0 && Dist > TolConf)
0956 {
0957 IntRes2d_Transition aTrans;
0958 IntRes2d_IntersectionPoint aPInt(P1, U, V, aTrans, aTrans, Standard_False);
0959 Standard_Real aT1f, aT1l, aT2f, aT2l;
0960 aT1f= thePoly1.ApproxParamOnCurve(SegIndex1, 0.0);
0961 aT1l= thePoly1.ApproxParamOnCurve(SegIndex1, 1.0);
0962 aT2f= thePoly2.ApproxParamOnCurve(SegIndex2, 0.0);
0963 aT2l= thePoly2.ApproxParamOnCurve(SegIndex2, 1.0);
0964 //
0965 Standard_Integer aMaxCount = 16, aCount = 0;
0966 GetIntersection(C1, aT1f, aT1l, C2, aT2f, aT2l, TolConf, aMaxCount,
0967 aPInt, Dist, aCount);
0968 U = aPInt.ParamOnFirst();
0969 V = aPInt.ParamOnSecond();
0970 TheCurveTool::D1(C1,U,P1,Tan1);
0971 TheCurveTool::D1(C2,V,P2,Tan2);
0972 Dist = P1.Distance(P2);
0973 }
0974 //-----------------------------------------------------------------
0975 //-- It is checked if the point (u,v) does not exist already
0976 //--
0977 Standard_Integer nbp=NbPoints();
0978 Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1);
0979 Standard_Real EpsX2 = 10.0*TheCurveTool::EpsX(C2);
0980 for(Standard_Integer p=1; p<=nbp; p++) {
0981 const IntRes2d_IntersectionPoint& P=Point(p);
0982 if(Abs(U-P.ParamOnFirst()) <= EpsX1) {
0983 if(Abs(V-P.ParamOnSecond()) <= EpsX2) {
0984 Dist = TolConf+1.0; p+=nbp;
0985 }
0986 }
0987 }
0988
0989 if(Dist <= TolConf) { //-- Or the point is already present
0990 IntRes2d_Position Pos1 = IntRes2d_Middle;
0991 IntRes2d_Position Pos2 = IntRes2d_Middle;
0992 IntRes2d_Transition Trans1,Trans2;
0993 //-----------------------------------------------------------------
0994 //-- Calculate the Positions of Points on the curve
0995 //--
0996 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())
0997 Pos1 = IntRes2d_Head;
0998 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance())
0999 Pos1 = IntRes2d_End;
1000
1001 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())
1002 Pos2 = IntRes2d_Head;
1003 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance())
1004 Pos2 = IntRes2d_End;
1005 //-----------------------------------------------------------------
1006 //-- Calculate the Transitions (see IntImpParGen.cxx)
1007 //--
1008 if(IntImpParGen::DetermineTransition (Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf) == Standard_False) {
1009 TheCurveTool::D2(C1,U,P1,Tan1,Norm1);
1010 TheCurveTool::D2(C2,V,P2,Tan2,Norm2);
1011 IntImpParGen::DetermineTransition (Pos1, Tan1, Norm1, Trans1, Pos2, Tan2, Norm2, Trans2, TolConf);
1012 }
1013 IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
1014 Insert(IP);
1015 }
1016 }
1017
1018 //----------------------------------------------------------------------
1019 //-- Processing of TangentZone
1020 //----------------------------------------------------------------------
1021 Standard_Integer Nbtz = InterPP.NbTangentZones();
1022 for(Standard_Integer tz=1; tz <= Nbtz; tz++) {
1023 Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
1024 //====================================================================
1025 //== Find the first and the last point in the tangency zone.
1026 //====================================================================
1027 Standard_Real ParamSupOnCurve2,ParamInfOnCurve2;
1028 Standard_Real ParamSupOnCurve1,ParamInfOnCurve1;
1029 // Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
1030 Standard_Integer SegIndex1onP1,SegIndex1onP2;
1031 Intf_PIType Type;
1032 Standard_Real ParamOnLine;
1033 Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup;
1034 ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast();
1035 ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast();
1036 for(Standard_Integer qq=1;qq<=NbPnts;qq++) {
1037 const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
1038 //====================================================================
1039 //== The zones of tangency are discretized
1040 //== Test of stop : Check if
1041 //== (Deflection < Tolerance)
1042 //== Or (Sample < EpsX) (normally the first condition is
1043 //== more strict)
1044 //====================================================================
1045 // Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
1046 Standard_Real _PolyUInf,_PolyVInf;
1047
1048 SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine);
1049 if(SegIndex1onP1 > thePoly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
1050 if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; }
1051 _PolyUInf = thePoly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
1052
1053 SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine);
1054 if(SegIndex1onP2 > thePoly2.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
1055 if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; }
1056 _PolyVInf = thePoly2.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
1057
1058 //----------------------------------------------------------------------
1059
1060 if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf;
1061 if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf;
1062
1063 if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf;
1064 if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf;
1065 }
1066
1067 PolyUInf= ParamInfOnCurve1;
1068 PolyUSup= ParamSupOnCurve1;
1069 PolyVInf= ParamInfOnCurve2;
1070 PolyVSup= ParamSupOnCurve2;
1071
1072 TheCurveTool::D0(C1,PolyUInf,P1);
1073 TheCurveTool::D0(C2,PolyVInf,P2);
1074 Standard_Real distmemesens = P1.SquareDistance(P2);
1075 TheCurveTool::D0(C2,PolyVSup,P2);
1076 Standard_Real distdiffsens = P1.SquareDistance(P2);
1077 if(distmemesens > distdiffsens) {
1078 Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty;
1079 }
1080
1081 if( ( (thePoly1.DeflectionOverEstimation() > TolConf)
1082 ||(thePoly2.DeflectionOverEstimation() > TolConf))
1083 &&(NbIter<NBITER_MAX_POLYGON)) {
1084
1085 IntRes2d_Domain RecursD1( TheCurveTool::Value(C1,ParamInfOnCurve1)
1086 ,ParamInfOnCurve1,TolConf
1087 ,TheCurveTool::Value(C1,ParamSupOnCurve1)
1088 ,ParamSupOnCurve1,TolConf);
1089 IntRes2d_Domain RecursD2( TheCurveTool::Value(C2,ParamInfOnCurve2)
1090 ,ParamInfOnCurve2,TolConf
1091 ,TheCurveTool::Value(C2,ParamSupOnCurve2)
1092 ,ParamSupOnCurve2,TolConf);
1093 //-- thePoly1(2) are not deleted,
1094 //-- finally they are destroyed.
1095 //-- !! No untimely return !!
1096 Perform(C1,RecursD1,C2,RecursD2,Tol,TolConf,NbIter+1,DeltaU,DeltaV);
1097 }
1098 else {
1099 //-----------------------------------------------------------------
1100 //-- Calculate Positions of Points on the curve and
1101 //-- Transitions on each limit of the segment
1102
1103 IntRes2d_Position Pos1 = IntRes2d_Middle;
1104 IntRes2d_Position Pos2 = IntRes2d_Middle;
1105 IntRes2d_Transition Trans1,Trans2;
1106
1107 TheCurveTool::D1(C1,PolyUInf,P1,Tan1);
1108 TheCurveTool::D1(C2,PolyVInf,P2,Tan2);
1109
1110 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
1111 Pos1 = IntRes2d_Head;
1112 }
1113 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
1114 Pos1 = IntRes2d_End;
1115 }
1116 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
1117 Pos2 = IntRes2d_Head;
1118 }
1119 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
1120 Pos2 = IntRes2d_End;
1121 }
1122
1123 if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
1124 PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1125 }
1126 else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
1127 PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1128 }
1129 else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
1130 PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1131 }
1132 else {
1133 PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1134 }
1135
1136
1137
1138 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
1139 == Standard_False)
1140 {
1141 TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1);
1142 TheCurveTool::D2(C2,PolyVInf,P2,Tan2,Norm2);
1143 IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
1144 Pos2,Tan2,Norm2,Trans2,TolConf);
1145 }
1146 IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf
1147 ,Trans1,Trans2,Standard_False);
1148 //----------------------------------------------------------------------
1149
1150 if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1))
1151 || (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C2)))
1152 {
1153 Insert(PtSeg1);
1154 }
1155 else
1156 {
1157 TheCurveTool::D1(C1,PolyUSup,P1,Tan1);
1158 TheCurveTool::D1(C2,PolyVSup,P2,Tan2);
1159 Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle;
1160
1161 if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
1162 Pos1 = IntRes2d_Head;
1163 }
1164 else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
1165 Pos1 = IntRes2d_End;
1166 }
1167 if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
1168 Pos2 = IntRes2d_Head;
1169 }
1170 else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
1171 Pos2 = IntRes2d_End;
1172 }
1173
1174
1175 if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
1176 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1177 }
1178 else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
1179 PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1180 }
1181 else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
1182 PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1183 }
1184 else {
1185 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1186 }
1187
1188 if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
1189 ==Standard_False) {
1190 TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1);
1191 TheCurveTool::D2(C2,PolyVSup,P2,Tan2,Norm2);
1192 IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
1193 Pos2,Tan2,Norm2,Trans2,TolConf);
1194 }
1195 IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup
1196 ,Trans1,Trans2,Standard_False);
1197
1198 Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True;
1199 if(ParamInfOnCurve1 > ParamSupOnCurve1) {
1200 IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False);
1201 Append(Seg);
1202 }
1203 else {
1204 IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False);
1205 Append(Seg);
1206 }
1207 }
1208 }
1209 }
1210 return Standard_True;
1211 }
1212
1213 //======================================================================
1214 // GetIntersection
1215 //======================================================================
1216
1217 void GetIntersection(const TheCurve& theC1, const Standard_Real theT1f, const Standard_Real theT1l,
1218 const TheCurve& theC2, const Standard_Real theT2f, const Standard_Real theT2l,
1219 const Standard_Real theTolConf,
1220 const Standard_Integer theMaxCount,
1221 IntRes2d_IntersectionPoint& thePInt, Standard_Real& theDist,
1222 Standard_Integer& theCount)
1223 {
1224 theCount++;
1225 //
1226 Standard_Real aTol2 = theTolConf*theTolConf;
1227 Standard_Real aPTol1 = Max(100.*Epsilon(Max(Abs(theT1f), Abs(theT1l))), Precision::PConfusion());
1228 Standard_Real aPTol2 = Max(100.*Epsilon(Max(Abs(theT2f), Abs(theT2l))), Precision::PConfusion());
1229 gp_Pnt2d aP1f, aP1l, aP2f, aP2l;
1230 Bnd_Box2d aB1, aB2;
1231 //
1232 TheCurveTool::D0(theC1, theT1f, aP1f);
1233 TheCurveTool::D0(theC1, theT1l, aP1l);
1234 aB1.Add(aP1f);
1235 aB1.Add(aP1l);
1236 aB1.Enlarge(theTolConf);
1237 //
1238 TheCurveTool::D0(theC2, theT2f, aP2f);
1239 TheCurveTool::D0(theC2, theT2l, aP2l);
1240 aB2.Add(aP2f);
1241 aB2.Add(aP2l);
1242 aB2.Enlarge(theTolConf);
1243 //
1244 if(aB1.IsOut(aB2))
1245 {
1246 theCount--;
1247 return;
1248 }
1249 //
1250 Standard_Boolean isSmall1 = (theT1l - theT1f) <= aPTol1 || aP1f.SquareDistance(aP1l) / 4. <= aTol2;
1251 Standard_Boolean isSmall2 = (theT2l - theT2f) <= aPTol2 || aP2f.SquareDistance(aP2l) / 4. <= aTol2;
1252
1253 if((isSmall1 && isSmall2) || (theCount > theMaxCount))
1254 {
1255 //Seems to be intersection
1256 //Simple treatment of segment intersection
1257 gp_XY aPnts1[3] = {aP1f.XY(), (aP1f.XY() + aP1l.XY()) / 2., aP1l.XY()};
1258 gp_XY aPnts2[3] = {aP2f.XY(), (aP2f.XY() + aP2l.XY()) / 2., aP2l.XY()};
1259 Standard_Integer i, j, imin = -1, jmin = -1;
1260 Standard_Real dmin = RealLast(), d;
1261 for(i = 0; i < 3; i++)
1262 {
1263 for(j = 0; j < 3; j++)
1264 {
1265 d = (aPnts1[i] - aPnts2[j]).SquareModulus();
1266 if(d < dmin)
1267 {
1268 dmin=d;
1269 imin = i;
1270 jmin = j;
1271 }
1272 }
1273 }
1274 //
1275 dmin = Sqrt(dmin);
1276 if(theDist > dmin)
1277 {
1278 theDist = dmin;
1279 //
1280 Standard_Real t1;
1281 if(imin == 0)
1282 {
1283 t1 = theT1f;
1284 }
1285 else if(imin == 1)
1286 {
1287 t1 = (theT1f + theT1l) / 2.;
1288 }
1289 else
1290 {
1291 t1 = theT1l;
1292 }
1293 //
1294 Standard_Real t2;
1295 if(jmin == 0)
1296 {
1297 t2 = theT2f;
1298 }
1299 else if(jmin == 1)
1300 {
1301 t2 = (theT2f + theT2l) / 2.;
1302 }
1303 else
1304 {
1305 t2 = theT2l;
1306 }
1307 //
1308 gp_Pnt2d aPint((aPnts1[imin] + aPnts2[jmin])/2.);
1309 //
1310 IntRes2d_Transition aTrans1, aTrans2;
1311 thePInt.SetValues(aPint, t1, t2, aTrans1, aTrans2, Standard_False);
1312 }
1313 theCount--;
1314 return;
1315 }
1316
1317 if(isSmall1)
1318 {
1319 Standard_Real aT2m = (theT2l + theT2f) / 2.;
1320 GetIntersection(theC1, theT1f, theT1l, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1321 GetIntersection(theC1, theT1f, theT1l, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1322 }
1323 else if(isSmall2)
1324 {
1325 Standard_Real aT1m = (theT1l + theT1f) / 2.;
1326 GetIntersection(theC1, theT1f, aT1m, theC2, theT2f, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1327 GetIntersection(theC1, aT1m, theT1l, theC2, theT2f, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1328 }
1329 else
1330 {
1331 Standard_Real aT1m = (theT1l + theT1f) / 2.;
1332 Standard_Real aT2m = (theT2l + theT2f) / 2.;
1333 GetIntersection(theC1, theT1f, aT1m, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1334 GetIntersection(theC1, theT1f, aT1m, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1335 GetIntersection(theC1, aT1m, theT1l, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1336 GetIntersection(theC1, aT1m, theT1l, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1337 }
1338
1339 }
1340
1341 //=======================================================================
1342 //function : GetMinNbPoints
1343 //purpose :
1344 //=======================================================================
1345 Standard_Integer IntCurve_IntPolyPolyGen::GetMinNbSamples() const
1346 {
1347 return myMinPntNb;
1348 }
1349
1350 //=======================================================================
1351 //function : SetMinNbPoints
1352 //purpose :
1353 //=======================================================================
1354 void IntCurve_IntPolyPolyGen::SetMinNbSamples(const Standard_Integer theMinNbSamples)
1355 {
1356 myMinPntNb = theMinNbSamples;
1357 }