// Created on: 1992-10-13 // Created by: Laurent BUCHARD // Copyright (c) 1992-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. // Modified by skv - Tue Mar 1 14:22:09 2005 OCC8169 #ifndef OCCT_DEBUG #define No_Standard_RangeError #define No_Standard_OutOfRange #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //====================================================================== #define NBITER_MAX_POLYGON 10 #define TOL_CONF_MINI 0.0000000001 #define TOL_MINI 0.0000000001 //---------------------------------------------------------------------- void GetIntersection(const TheCurve& theC1, const Standard_Real theT1f, const Standard_Real theT1l, const TheCurve& theC2, const Standard_Real theT2f, const Standard_Real theT2l, const Standard_Real theTolConf, const Standard_Integer theMaxCount, IntRes2d_IntersectionPoint& thePInt, Standard_Real& theDist, Standard_Integer& theCount); Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1 ,const TheCurve& C1 ,const Standard_Real u ,const IntRes2d_Domain& D2 ,const TheCurve& C2 ,const Standard_Real v ,const Standard_Real TolConf ,IntRes2d_IntersectionPoint& IntPt ,Standard_Boolean& HeadOn1 ,Standard_Boolean& HeadOn2 ,Standard_Boolean& EndOn1 ,Standard_Boolean& EndOn2 ,Standard_Integer PosSegment); //====================================================================== IntCurve_IntPolyPolyGen::IntCurve_IntPolyPolyGen() { const Standard_Integer aMinPntNb = 20; // Minimum number of samples. myMinPntNb = aMinPntNb; done = Standard_False; } //====================================================================== void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1 ,const IntRes2d_Domain& D1 ,const TheCurve& C2 ,const IntRes2d_Domain& D2 ,const Standard_Real TheTolConf ,const Standard_Real TheTol) { this->ResetFields(); DomainOnCurve1=D1; DomainOnCurve2=D2; Standard_Real DU = D1.LastParameter()-D1.FirstParameter(); Standard_Real DV = D2.LastParameter()-D2.FirstParameter(); Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol; Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf; Perform(C1,D1,C2,D2,TlConf,Tl,0,DU,DV); //---------------------------------------------------------------------- //-- Processing of end points //---------------------------------------------------------------------- Standard_Boolean HeadOn1 = Standard_False; Standard_Boolean HeadOn2 = Standard_False; Standard_Boolean EndOn1 = Standard_False; Standard_Boolean EndOn2 = Standard_False; Standard_Integer i; Standard_Integer n=this->NbPoints(); //-------------------------------------------------------------------- //-- The points Head Head ... End End are not rejected if //-- they are already present at the end of segment //-- ( It is not possible to test the equities on the parameters) //-- ( these points are not found at EpsX precision ) //-- PosSegment = 1 if Head Head //-- 2 if Head End //-- 4 if End Head //-- 8 if End End //-------------------------------------------------------------------- Standard_Integer PosSegment = 0; for(i=1;i<=n;i++) { IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve(); if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True; else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True; IntRes2d_Position Pos2 = this->Point(i).TransitionOfSecond().PositionOnCurve(); if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True; else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True; if(Pos1 == IntRes2d_Head) { if(Pos2 == IntRes2d_Head) PosSegment|=1; else if(Pos2 == IntRes2d_End) PosSegment|=2; } else if(Pos1 == IntRes2d_End) { if(Pos2 == IntRes2d_Head) PosSegment|=4; else if(Pos2 == IntRes2d_End) PosSegment|=8; } } n=this->NbSegments(); for(i=1;i<=n;i++) { IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve(); if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True; else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True; IntRes2d_Position Pos2 = this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve(); if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True; else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True; if(Pos1 == IntRes2d_Head) { if(Pos2 == IntRes2d_Head) PosSegment|=1; else if(Pos2 == IntRes2d_End) PosSegment|=2; } else if(Pos1 == IntRes2d_End) { if(Pos2 == IntRes2d_Head) PosSegment|=4; else if(Pos2 == IntRes2d_End) PosSegment|=8; } Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve(); if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True; else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True; Pos2 = this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve(); if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True; else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True; if(Pos1 == IntRes2d_Head) { if(Pos2 == IntRes2d_Head) PosSegment|=1; else if(Pos2 == IntRes2d_End) PosSegment|=2; } else if(Pos1 == IntRes2d_End) { if(Pos2 == IntRes2d_Head) PosSegment|=4; else if(Pos2 == IntRes2d_End) PosSegment|=8; } } Standard_Real U0 = D1.FirstParameter(); Standard_Real U1 = D1.LastParameter(); Standard_Real V0 = D2.FirstParameter(); Standard_Real V1 = D2.LastParameter(); IntRes2d_IntersectionPoint IntPt; if(D1.FirstTolerance() || D2.FirstTolerance()) { if(HeadOrEndPoint(D1,C1,U0,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) this->Insert(IntPt); } if(D1.FirstTolerance() || D2.LastTolerance()) { if(HeadOrEndPoint(D1,C1,U0,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) this->Insert(IntPt); } if(D1.LastTolerance() || D2.FirstTolerance()) { if(HeadOrEndPoint(D1,C1,U1,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) this->Insert(IntPt); } if(D1.LastTolerance() || D2.LastTolerance()) { if(HeadOrEndPoint(D1,C1,U1,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) this->Insert(IntPt); } } //====================================================================== //== A u t o I n t e r s e c t i o n //====================================================================== void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1 ,const IntRes2d_Domain& D1 ,const Standard_Real TheTolConf ,const Standard_Real TheTol) { this->ResetFields(); DomainOnCurve1=D1; DomainOnCurve2=D1; Standard_Real DU = D1.LastParameter()-D1.FirstParameter(); Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol; Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf; Perform(C1,D1,TlConf,Tl,0,DU,DU); Standard_Integer i; Standard_Integer n=this->NbPoints(); //-------------------------------------------------------------------- //-- The points Head Head ... End End are not rejected if //-- they are already present at the end of segment //-- ( It is not possible to test the equities on the parameters) //-- ( these points are not found at EpsX precision ) //-- PosSegment = 1 if Head Head //-- 2 if Head End //-- 4 if End Head //-- 8 if End End //-------------------------------------------------------------------- Standard_Integer PosSegment = 0; for(i=1;i<=n;i++) { IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve(); IntRes2d_Position Pos2 = this->Point(i).TransitionOfSecond().PositionOnCurve(); if(Pos1 == IntRes2d_Head) { if(Pos2 == IntRes2d_Head) PosSegment|=1; else if(Pos2 == IntRes2d_End) PosSegment|=2; } else if(Pos1 == IntRes2d_End) { if(Pos2 == IntRes2d_Head) PosSegment|=4; else if(Pos2 == IntRes2d_End) PosSegment|=8; } } n=this->NbSegments(); for(i=1;i<=n;i++) { IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve(); IntRes2d_Position Pos2 = this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve(); if(Pos1 == IntRes2d_Head) { if(Pos2 == IntRes2d_Head) PosSegment|=1; else if(Pos2 == IntRes2d_End) PosSegment|=2; } else if(Pos1 == IntRes2d_End) { if(Pos2 == IntRes2d_Head) PosSegment|=4; else if(Pos2 == IntRes2d_End) PosSegment|=8; } Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve(); Pos2 = this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve(); if(Pos1 == IntRes2d_Head) { if(Pos2 == IntRes2d_Head) PosSegment|=1; else if(Pos2 == IntRes2d_End) PosSegment|=2; } else if(Pos1 == IntRes2d_End) { if(Pos2 == IntRes2d_Head) PosSegment|=4; else if(Pos2 == IntRes2d_End) PosSegment|=8; } } } //====================================================================== void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1 ,const IntRes2d_Domain& D1 ,const Standard_Real TolConf ,const Standard_Real Tol ,const Standard_Integer NbIter ,const Standard_Real /*DeltaU*/ ,const Standard_Real) { gp_Vec2d Tan1,Tan2,Norm1,Norm2; gp_Pnt2d P1,P2; Standard_Integer nbsamples; done = Standard_False; nbsamples = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter()); if(NbIter>3 || (NbIter>2 && nbsamples>100)) return; nbsamples*=2; //--- We take systematically two times more points //-- than on a normal curve. //-- Auto-intersecting curves often produce //-- polygons rather far from the curve with parameter ct. if(NbIter>0) { nbsamples=(3*(nbsamples*NbIter))/2; } IntCurve_ThePolygon2d Poly1(C1,nbsamples,D1,Tol); if(!Poly1.AutoIntersectionIsPossible()) { done = Standard_True; return; } //-- Poly1.Dump(); //---------------------------------------------------------------------- //-- If the deflection is less than the Tolerance of Confusion //-- then the deflection of the polygon is set in TolConf //-- (Detection of Tangency Zones) //---------------------------------------------------------------------- if(Poly1.DeflectionOverEstimation() < TolConf) { Poly1.SetDeflectionOverEstimation(TolConf); } Intf_InterferencePolygon2d InterPP(Poly1); IntCurve_ExactIntersectionPoint EIP(C1,C1,TolConf); Standard_Real U,V; //---------------------------------------------------------------------- //-- Processing of SectionPoint //---------------------------------------------------------------------- Standard_Integer Nbsp = InterPP.NbSectionPoints(); if(Nbsp>=1) { //-- --------------------------------------------------------------------- //-- filtering, filtering, filtering ... //-- Standard_Integer* TriIndex = new Standard_Integer [Nbsp+1]; Standard_Integer* PtrSegIndex1 = new Standard_Integer [Nbsp+1]; Standard_Integer* PtrSegIndex2 = new Standard_Integer [Nbsp+1]; Standard_Boolean Triok; Standard_Integer SegIndex1,SegIndex2,SegIndex_1,SegIndex_2; // Standard_Real ParamOn1,ParamOn2,ParamOn_1,ParamOn_2; Standard_Real ParamOn1,ParamOn2; Intf_PIType Type; Standard_Integer i ; for( i=1;i<=Nbsp;i++) { TriIndex[i]=i; const Intf_SectionPoint& SPnt1 = InterPP.PntValue(i); SPnt1.InfoFirst(Type,PtrSegIndex1[i],ParamOn1); SPnt1.InfoSecond(Type,PtrSegIndex2[i],ParamOn2); } do { Triok=Standard_True; for(Standard_Integer tr=1;tr SegIndex_1) { Standard_Integer q=TriIndex[tr]; TriIndex[tr]=TriIndex[tr+1]; TriIndex[tr+1]=q; Triok=Standard_False; } else if(SegIndex1 == SegIndex_1) { if(SegIndex2 > SegIndex_2) { Standard_Integer q=TriIndex[tr]; TriIndex[tr]=TriIndex[tr+1]; TriIndex[tr+1]=q; Triok=Standard_False; } } } } while(Triok==Standard_False); //-- supression des doublons Si Si ! for(i=1; i0) { const Intf_SectionPoint& SPnt = InterPP.PntValue(TriIndex[sp]); SPnt.InfoFirst(Type,SegIndex1,ParamOn1); SPnt.InfoSecond(Type,SegIndex2,ParamOn2); if(Abs(SegIndex1-SegIndex2)>1) { EIP.Perform(Poly1,Poly1,SegIndex1,SegIndex2,ParamOn1,ParamOn2); if(EIP.NbRoots()==0) { //-- All neighbor segments are removed for(Standard_Integer k=sp+1;k<=Nbsp;k++) { Standard_Integer kk=TriIndex[k]; // --- avoid negative indicies as well as in outer done if( kk > 0 ) { if( Abs(SegIndex1-PtrSegIndex1[kk])< Nelarg && Abs(SegIndex2-PtrSegIndex2[kk])< Nelarg) { TriIndex[k]=-k; } } } } else if(EIP.NbRoots()>=1) { //-------------------------------------------------------------------- //-- It is checked if the found point is a root //-------------------------------------------------------------------- EIP.Roots(U,V); TheCurveTool::D1(C1,U,P1,Tan1); TheCurveTool::D1(C1,V,P2,Tan2); Standard_Real Dist = P1.Distance(P2); Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1); if(Abs(U-V)<=EpsX1) { //----------------------------------------- //-- Solution not valid //-- The maths should have converged in a //-- trivial solution ( point U = V ) //----------------------------------------- Dist = TolConf+1.0; } //----------------------------------------------------------------- //-- It is checked if the point (u,v) already exists //-- done = Standard_True; Standard_Integer nbp=NbPoints(); for(Standard_Integer p=1; p<=nbp; p++) { const IntRes2d_IntersectionPoint& P=Point(p); if(Abs(U-P.ParamOnFirst()) <= EpsX1) { if(Abs(V-P.ParamOnSecond()) <= EpsX1) { Dist = TolConf+1.0; p+=nbp; } } } if(Dist <= TolConf) { //-- Or the point is already present IntRes2d_Position Pos1 = IntRes2d_Middle; IntRes2d_Position Pos2 = IntRes2d_Middle; IntRes2d_Transition Trans1,Trans2; //----------------------------------------------------------------- //-- Calculate Positions of Points on the curve //-- if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) Pos1 = IntRes2d_Head; else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) Pos1 = IntRes2d_End; if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) Pos2 = IntRes2d_Head; else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) Pos2 = IntRes2d_End; //----------------------------------------------------------------- if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1 ,Pos2,Tan2,Trans2 ,TolConf) == Standard_False) { TheCurveTool::D2(C1,U,P1,Tan1,Norm1); TheCurveTool::D2(C1,V,P2,Tan2,Norm2); IntImpParGen::DetermineTransition( Pos1,Tan1,Norm1,Trans1 ,Pos2,Tan2,Norm2,Trans2 ,TolConf); } IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False); Insert(IP); } } } } } delete [] TriIndex; delete [] PtrSegIndex1; delete [] PtrSegIndex2; } //---------------------------------------------------------------------- //-- Processing of TangentZone //---------------------------------------------------------------------- Standard_Integer Nbtz = InterPP.NbTangentZones(); for(Standard_Integer tz=1; tz <= Nbtz; tz++) { Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints(); //==================================================================== //== Find the first and the last point in the tangency zone. //==================================================================== Standard_Real ParamSupOnCurve2,ParamInfOnCurve2; Standard_Real ParamSupOnCurve1,ParamInfOnCurve1; // Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2; Standard_Integer SegIndex1onP1,SegIndex1onP2; Intf_PIType Type; Standard_Real ParamOnLine; Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup; ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast(); ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast(); for(Standard_Integer qq=1;qq<=NbPnts;qq++) { const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq); //==================================================================== //== The zones of tangency are discretized //== Test of stop : Check if //== (Deflection < Tolerance) //== Or (Sample < EpsX) (normally the first condition is //== more strict) //==================================================================== // Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup; Standard_Real _PolyUInf,_PolyVInf; SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine); if(SegIndex1onP1 > Poly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; } if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; } _PolyUInf = Poly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine); SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine); if(SegIndex1onP2 > Poly1.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; } if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; } _PolyVInf = Poly1.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine); //---------------------------------------------------------------------- if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf; if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf; if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf; if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf; } PolyUInf= ParamInfOnCurve1; PolyUSup= ParamSupOnCurve1; PolyVInf= ParamInfOnCurve2; PolyVSup= ParamSupOnCurve2; TheCurveTool::D0(C1,PolyUInf,P1); TheCurveTool::D0(C1,PolyVInf,P2); Standard_Real distmemesens = P1.SquareDistance(P2); TheCurveTool::D0(C1,PolyVSup,P2); Standard_Real distdiffsens = P1.SquareDistance(P2); if(distmemesens > distdiffsens) { Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty; } //----------------------------------------------------------------- //-- Calculate Positions of Points on the curve and //-- Transitions on each limit of the segment IntRes2d_Position Pos1 = IntRes2d_Middle; IntRes2d_Position Pos2 = IntRes2d_Middle; IntRes2d_Transition Trans1,Trans2; TheCurveTool::D1(C1,PolyUInf,P1,Tan1); TheCurveTool::D1(C1,PolyVInf,P2,Tan2); if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) { Pos1 = IntRes2d_Head; } else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { Pos1 = IntRes2d_End; } if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) { Pos2 = IntRes2d_Head; } else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { Pos2 = IntRes2d_End; } if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } else { PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) == Standard_False) { TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1); TheCurveTool::D2(C1,PolyVInf,P2,Tan2,Norm2); IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1, Pos2,Tan2,Norm2,Trans2,TolConf); } IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf ,Trans1,Trans2,Standard_False); //---------------------------------------------------------------------- if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1)) || (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C1))) { //bad segment } else { TheCurveTool::D1(C1,PolyUSup,P1,Tan1); TheCurveTool::D1(C1,PolyVSup,P2,Tan2); Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle; if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) { Pos1 = IntRes2d_Head; } else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { Pos1 = IntRes2d_End; } if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) { Pos2 = IntRes2d_Head; } else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { Pos2 = IntRes2d_End; } if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } else { PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) ==Standard_False) { TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1); TheCurveTool::D2(C1,PolyVSup,P2,Tan2,Norm2); IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1, Pos2,Tan2,Norm2,Trans2,TolConf); } IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup ,Trans1,Trans2,Standard_False); Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True; if(ParamInfOnCurve1 > ParamSupOnCurve1) { IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False); Append(Seg); } else { IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False); Append(Seg); } } } //end of processing of TangentZone done = Standard_True; } Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1 ,const TheCurve& C1 ,const Standard_Real tu ,const IntRes2d_Domain& D2 ,const TheCurve& C2 ,const Standard_Real tv ,const Standard_Real TolConf ,IntRes2d_IntersectionPoint& IntPt ,Standard_Boolean& HeadOn1 ,Standard_Boolean& HeadOn2 ,Standard_Boolean& EndOn1 ,Standard_Boolean& EndOn2 ,Standard_Integer PosSegment) { gp_Pnt2d P1,P2,SP1,SP2; gp_Vec2d T1,T2,N1,N2; Standard_Real u=tu; Standard_Real v=tv; Standard_Real svu = u; Standard_Real svv = v; TheCurveTool::D1(C1,u,P1,T1); TheCurveTool::D1(C2,v,P2,T2); IntRes2d_Position Pos1 = IntRes2d_Middle; IntRes2d_Position Pos2 = IntRes2d_Middle; IntRes2d_Transition Trans1,Trans2; //---------------------------------------------------------------------- //-- Head On 1 : Head1 <-> P2 if(P2.Distance(D1.FirstPoint())<=D1.FirstTolerance()) { Pos1 = IntRes2d_Head; HeadOn1 = Standard_True; SP1 = D1.FirstPoint(); u = D1.FirstParameter(); } //---------------------------------------------------------------------- //-- End On 1 : End1 <-> P2 else if(P2.Distance(D1.LastPoint())<=D1.LastTolerance()) { Pos1 = IntRes2d_End; EndOn1 = Standard_True; SP1 = D1.LastPoint(); u = D1.LastParameter(); } //---------------------------------------------------------------------- //-- Head On 2 : Head2 <-> P1 else if(P1.Distance(D2.FirstPoint())<=D2.FirstTolerance()) { Pos2 = IntRes2d_Head; HeadOn2 = Standard_True; SP2 = D2.FirstPoint(); v = D2.FirstParameter(); } //---------------------------------------------------------------------- //-- End On 2 : End2 <-> P1 else if(P1.Distance(D2.LastPoint())<=D2.LastTolerance()) { Pos2 = IntRes2d_End; EndOn2 = Standard_True; SP2 = D2.LastPoint(); v = D2.LastParameter(); } Standard_Real EpsX1 = TheCurveTool::EpsX(C1); Standard_Real EpsX2 = TheCurveTool::EpsX(C2); if((Pos1 != IntRes2d_Middle)||(Pos2 != IntRes2d_Middle)) { if(Pos1 == IntRes2d_Middle) { if(Abs(u-D1.FirstParameter()) <= EpsX1) { Pos1 = IntRes2d_Head; P1 = D1.FirstPoint(); HeadOn1 = Standard_True; } else if(Abs(u-D1.LastParameter()) <= EpsX1) { Pos1 = IntRes2d_End; P1 = D1.LastPoint(); EndOn1 = Standard_True; } } else if(u!=tu) { P1 = SP1; } if(Pos2 == IntRes2d_Middle) { if(Abs(v-D2.FirstParameter()) <= EpsX2) { Pos2 = IntRes2d_Head; HeadOn2 = Standard_True; P2 = D2.FirstPoint(); if(Pos1 != IntRes2d_Middle) { P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y())); } else { P2 = P1; } } else if(Abs(v-D2.LastParameter()) <= EpsX2) { Pos2 = IntRes2d_End; EndOn2 = Standard_True; P2 = D2.LastPoint(); if(Pos1 != IntRes2d_Middle) { P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y())); } else { P2 = P1; } } } //-------------------------------------------------------------------- //-- It is tested if a point at the end of segment already has its transitions //-- If Yes, the new point is not created //-- //-- PosSegment = 1 if Head Head //-- 2 if Head End //-- 4 if End Head //-- 8 if End End //-------------------------------------------------------------------- if(Pos1 == IntRes2d_Head) { if((Pos2 == IntRes2d_Head)&&(PosSegment & 1)) return(Standard_False); if((Pos2 == IntRes2d_End )&&(PosSegment & 2)) return(Standard_False); } else if(Pos1 == IntRes2d_End) { if((Pos2 == IntRes2d_Head)&&(PosSegment & 4)) return(Standard_False); if((Pos2 == IntRes2d_End )&&(PosSegment & 8)) return(Standard_False); } if(IntImpParGen::DetermineTransition( Pos1,T1,Trans1,Pos2,T2,Trans2,TolConf) == Standard_False) { TheCurveTool::D2(C1,svu,P1,T1,N1); TheCurveTool::D2(C2,svv,P2,T2,N2); IntImpParGen::DetermineTransition(Pos1,T1,N1,Trans1, Pos2,T2,N2,Trans2,TolConf); } IntPt.SetValues(P1,u,v,Trans1,Trans2,Standard_False); return(Standard_True); } else return(Standard_False); } //======================================================================= //function : Perform //purpose : Base method to perform polyline / polyline intersection for // pair of curves. //======================================================================= void IntCurve_IntPolyPolyGen::Perform(const TheCurve& C1, const IntRes2d_Domain& D1, const TheCurve& C2, const IntRes2d_Domain& D2, const Standard_Real TolConf, const Standard_Real Tol, const Standard_Integer NbIter, const Standard_Real DeltaU, const Standard_Real DeltaV) { Standard_Integer nbsamplesOnC1,nbsamplesOnC2; done = Standard_False; if(NbIter>NBITER_MAX_POLYGON) return; // Number of samples tunning. nbsamplesOnC1 = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter()); nbsamplesOnC2 = TheCurveTool::NbSamples(C2,D2.FirstParameter(),D2.LastParameter()); if (NbIter == 0) { // Minimal number of points. nbsamplesOnC1 = Max(nbsamplesOnC1, myMinPntNb); nbsamplesOnC2 = Max(nbsamplesOnC2, myMinPntNb); } else { // Increase number of samples in second and next iterations. nbsamplesOnC1=(5 * (nbsamplesOnC1 * NbIter)) / 4; nbsamplesOnC2=(5 * (nbsamplesOnC2 * NbIter)) / 4; } NCollection_Handle aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol), aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol); if( (aPoly1->DeflectionOverEstimation() > TolConf) && (aPoly2->DeflectionOverEstimation() > TolConf)) { const Standard_Real aDeflectionSum = Max(aPoly1->DeflectionOverEstimation(), TolConf) + Max(aPoly2->DeflectionOverEstimation(), TolConf); if (nbsamplesOnC2 > nbsamplesOnC1) { aPoly2->ComputeWithBox(C2, aPoly1->Bounding()); aPoly1->SetDeflectionOverEstimation(aDeflectionSum); aPoly1->ComputeWithBox(C1, aPoly2->Bounding()); } else { aPoly1->ComputeWithBox(C1, aPoly2->Bounding()); aPoly2->SetDeflectionOverEstimation(aDeflectionSum); aPoly2->ComputeWithBox(C2, aPoly1->Bounding()); } } //---------------------------------------------------------------------- //-- if the deflection less then the Tolerance of Confusion //-- Then the deflection of the polygon is set in TolConf //-- (Detection of Tangency Zones) //---------------------------------------------------------------------- if(aPoly1->DeflectionOverEstimation() < TolConf) { aPoly1->SetDeflectionOverEstimation(TolConf); } if(aPoly2->DeflectionOverEstimation() < TolConf) { aPoly2->SetDeflectionOverEstimation(TolConf); } // for case when a few polygon points were replaced by line // if exact solution was not found // then search of precise solution will be repeated // for polygon contains all initial points // secondary search will be performed only for case when initial points // were dropped Standard_Boolean isFullRepresentation = ( aPoly1->NbSegments() == nbsamplesOnC1 && aPoly2->NbSegments() == nbsamplesOnC2 ); if( !findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter, DeltaU, DeltaV, *aPoly1, *aPoly2, isFullRepresentation ) && !isFullRepresentation ) { if(aPoly1->NbSegments() < nbsamplesOnC1) { aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol); } if(aPoly2->NbSegments() < nbsamplesOnC2) { aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol); } findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter, DeltaU, DeltaV, *aPoly1, *aPoly2, Standard_True); } done = Standard_True; } //====================================================================== // Purpose : findIntersect //====================================================================== Standard_Boolean IntCurve_IntPolyPolyGen::findIntersect( const TheCurve& C1, const IntRes2d_Domain& D1, const TheCurve& C2, const IntRes2d_Domain& D2, const Standard_Real TolConf, const Standard_Real Tol, const Standard_Integer NbIter, const Standard_Real DeltaU, const Standard_Real DeltaV, const IntCurve_ThePolygon2d& thePoly1, const IntCurve_ThePolygon2d& thePoly2, Standard_Boolean isFullPolygon ) { gp_Vec2d Tan1,Tan2,Norm1,Norm2; gp_Pnt2d P1,P2; Intf_InterferencePolygon2d InterPP(thePoly1,thePoly2); IntCurve_ExactIntersectionPoint EIP(C1,C2,TolConf); Standard_Real U = 0., V = 0.; Standard_Boolean AnErrorOccurred = Standard_False; done = Standard_True; // To prevent exception in nbp=NbPoints(); //---------------------------------------------------------------------- //-- Processing of SectionPoint //---------------------------------------------------------------------- Standard_Integer Nbsp = InterPP.NbSectionPoints(); for(Standard_Integer sp=1; sp <= Nbsp; sp++) { const Intf_SectionPoint& SPnt = InterPP.PntValue(sp); Standard_Integer SegIndex1,SegIndex2; Standard_Real ParamOn1,ParamOn2; Intf_PIType Type; SPnt.InfoFirst(Type,SegIndex1,ParamOn1); SPnt.InfoSecond(Type,SegIndex2,ParamOn2); EIP.Perform(thePoly1,thePoly2,SegIndex1,SegIndex2,ParamOn1,ParamOn2); AnErrorOccurred = EIP.AnErrorOccurred(); if( !EIP.NbRoots() && !isFullPolygon) return Standard_False; if(AnErrorOccurred) { continue; } //-------------------------------------------------------------------- //-- It is checked if the found point is really a root //-------------------------------------------------------------------- EIP.Roots(U,V); TheCurveTool::D1(C1,U,P1,Tan1); TheCurveTool::D1(C2,V,P2,Tan2); Standard_Real Dist = P1.Distance(P2); if(EIP.NbRoots() == 0 && Dist > TolConf) { IntRes2d_Transition aTrans; IntRes2d_IntersectionPoint aPInt(P1, U, V, aTrans, aTrans, Standard_False); Standard_Real aT1f, aT1l, aT2f, aT2l; aT1f= thePoly1.ApproxParamOnCurve(SegIndex1, 0.0); aT1l= thePoly1.ApproxParamOnCurve(SegIndex1, 1.0); aT2f= thePoly2.ApproxParamOnCurve(SegIndex2, 0.0); aT2l= thePoly2.ApproxParamOnCurve(SegIndex2, 1.0); // Standard_Integer aMaxCount = 16, aCount = 0; GetIntersection(C1, aT1f, aT1l, C2, aT2f, aT2l, TolConf, aMaxCount, aPInt, Dist, aCount); U = aPInt.ParamOnFirst(); V = aPInt.ParamOnSecond(); TheCurveTool::D1(C1,U,P1,Tan1); TheCurveTool::D1(C2,V,P2,Tan2); Dist = P1.Distance(P2); } //----------------------------------------------------------------- //-- It is checked if the point (u,v) does not exist already //-- Standard_Integer nbp=NbPoints(); Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1); Standard_Real EpsX2 = 10.0*TheCurveTool::EpsX(C2); for(Standard_Integer p=1; p<=nbp; p++) { const IntRes2d_IntersectionPoint& P=Point(p); if(Abs(U-P.ParamOnFirst()) <= EpsX1) { if(Abs(V-P.ParamOnSecond()) <= EpsX2) { Dist = TolConf+1.0; p+=nbp; } } } if(Dist <= TolConf) { //-- Or the point is already present IntRes2d_Position Pos1 = IntRes2d_Middle; IntRes2d_Position Pos2 = IntRes2d_Middle; IntRes2d_Transition Trans1,Trans2; //----------------------------------------------------------------- //-- Calculate the Positions of Points on the curve //-- if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) Pos1 = IntRes2d_Head; else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) Pos1 = IntRes2d_End; if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) Pos2 = IntRes2d_Head; else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) Pos2 = IntRes2d_End; //----------------------------------------------------------------- //-- Calculate the Transitions (see IntImpParGen.cxx) //-- if(IntImpParGen::DetermineTransition (Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf) == Standard_False) { TheCurveTool::D2(C1,U,P1,Tan1,Norm1); TheCurveTool::D2(C2,V,P2,Tan2,Norm2); IntImpParGen::DetermineTransition (Pos1, Tan1, Norm1, Trans1, Pos2, Tan2, Norm2, Trans2, TolConf); } IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False); Insert(IP); } } //---------------------------------------------------------------------- //-- Processing of TangentZone //---------------------------------------------------------------------- Standard_Integer Nbtz = InterPP.NbTangentZones(); for(Standard_Integer tz=1; tz <= Nbtz; tz++) { Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints(); //==================================================================== //== Find the first and the last point in the tangency zone. //==================================================================== Standard_Real ParamSupOnCurve2,ParamInfOnCurve2; Standard_Real ParamSupOnCurve1,ParamInfOnCurve1; // Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2; Standard_Integer SegIndex1onP1,SegIndex1onP2; Intf_PIType Type; Standard_Real ParamOnLine; Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup; ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast(); ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast(); for(Standard_Integer qq=1;qq<=NbPnts;qq++) { const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq); //==================================================================== //== The zones of tangency are discretized //== Test of stop : Check if //== (Deflection < Tolerance) //== Or (Sample < EpsX) (normally the first condition is //== more strict) //==================================================================== // Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup; Standard_Real _PolyUInf,_PolyVInf; SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine); if(SegIndex1onP1 > thePoly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; } if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; } _PolyUInf = thePoly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine); SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine); if(SegIndex1onP2 > thePoly2.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; } if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; } _PolyVInf = thePoly2.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine); //---------------------------------------------------------------------- if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf; if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf; if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf; if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf; } PolyUInf= ParamInfOnCurve1; PolyUSup= ParamSupOnCurve1; PolyVInf= ParamInfOnCurve2; PolyVSup= ParamSupOnCurve2; TheCurveTool::D0(C1,PolyUInf,P1); TheCurveTool::D0(C2,PolyVInf,P2); Standard_Real distmemesens = P1.SquareDistance(P2); TheCurveTool::D0(C2,PolyVSup,P2); Standard_Real distdiffsens = P1.SquareDistance(P2); if(distmemesens > distdiffsens) { Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty; } if( ( (thePoly1.DeflectionOverEstimation() > TolConf) ||(thePoly2.DeflectionOverEstimation() > TolConf)) &&(NbIter Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2)); } else { PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) == Standard_False) { TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1); TheCurveTool::D2(C2,PolyVInf,P2,Tan2,Norm2); IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1, Pos2,Tan2,Norm2,Trans2,TolConf); } IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf ,Trans1,Trans2,Standard_False); //---------------------------------------------------------------------- if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1)) || (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C2))) { Insert(PtSeg1); } else { TheCurveTool::D1(C1,PolyUSup,P1,Tan1); TheCurveTool::D1(C2,PolyVSup,P2,Tan2); Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle; if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) { Pos1 = IntRes2d_Head; } else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { Pos1 = IntRes2d_End; } if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) { Pos2 = IntRes2d_Head; } else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { Pos2 = IntRes2d_End; } if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2)); } else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2)); } else { PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1)); } if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) ==Standard_False) { TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1); TheCurveTool::D2(C2,PolyVSup,P2,Tan2,Norm2); IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1, Pos2,Tan2,Norm2,Trans2,TolConf); } IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup ,Trans1,Trans2,Standard_False); Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True; if(ParamInfOnCurve1 > ParamSupOnCurve1) { IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False); Append(Seg); } else { IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False); Append(Seg); } } } } return Standard_True; } //====================================================================== // GetIntersection //====================================================================== void GetIntersection(const TheCurve& theC1, const Standard_Real theT1f, const Standard_Real theT1l, const TheCurve& theC2, const Standard_Real theT2f, const Standard_Real theT2l, const Standard_Real theTolConf, const Standard_Integer theMaxCount, IntRes2d_IntersectionPoint& thePInt, Standard_Real& theDist, Standard_Integer& theCount) { theCount++; // Standard_Real aTol2 = theTolConf*theTolConf; Standard_Real aPTol1 = Max(100.*Epsilon(Max(Abs(theT1f), Abs(theT1l))), Precision::PConfusion()); Standard_Real aPTol2 = Max(100.*Epsilon(Max(Abs(theT2f), Abs(theT2l))), Precision::PConfusion()); gp_Pnt2d aP1f, aP1l, aP2f, aP2l; Bnd_Box2d aB1, aB2; // TheCurveTool::D0(theC1, theT1f, aP1f); TheCurveTool::D0(theC1, theT1l, aP1l); aB1.Add(aP1f); aB1.Add(aP1l); aB1.Enlarge(theTolConf); // TheCurveTool::D0(theC2, theT2f, aP2f); TheCurveTool::D0(theC2, theT2l, aP2l); aB2.Add(aP2f); aB2.Add(aP2l); aB2.Enlarge(theTolConf); // if(aB1.IsOut(aB2)) { theCount--; return; } // Standard_Boolean isSmall1 = (theT1l - theT1f) <= aPTol1 || aP1f.SquareDistance(aP1l) / 4. <= aTol2; Standard_Boolean isSmall2 = (theT2l - theT2f) <= aPTol2 || aP2f.SquareDistance(aP2l) / 4. <= aTol2; if((isSmall1 && isSmall2) || (theCount > theMaxCount)) { //Seems to be intersection //Simple treatment of segment intersection gp_XY aPnts1[3] = {aP1f.XY(), (aP1f.XY() + aP1l.XY()) / 2., aP1l.XY()}; gp_XY aPnts2[3] = {aP2f.XY(), (aP2f.XY() + aP2l.XY()) / 2., aP2l.XY()}; Standard_Integer i, j, imin = -1, jmin = -1; Standard_Real dmin = RealLast(), d; for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { d = (aPnts1[i] - aPnts2[j]).SquareModulus(); if(d < dmin) { dmin=d; imin = i; jmin = j; } } } // dmin = Sqrt(dmin); if(theDist > dmin) { theDist = dmin; // Standard_Real t1; if(imin == 0) { t1 = theT1f; } else if(imin == 1) { t1 = (theT1f + theT1l) / 2.; } else { t1 = theT1l; } // Standard_Real t2; if(jmin == 0) { t2 = theT2f; } else if(jmin == 1) { t2 = (theT2f + theT2l) / 2.; } else { t2 = theT2l; } // gp_Pnt2d aPint((aPnts1[imin] + aPnts2[jmin])/2.); // IntRes2d_Transition aTrans1, aTrans2; thePInt.SetValues(aPint, t1, t2, aTrans1, aTrans2, Standard_False); } theCount--; return; } if(isSmall1) { Standard_Real aT2m = (theT2l + theT2f) / 2.; GetIntersection(theC1, theT1f, theT1l, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount); GetIntersection(theC1, theT1f, theT1l, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount); } else if(isSmall2) { Standard_Real aT1m = (theT1l + theT1f) / 2.; GetIntersection(theC1, theT1f, aT1m, theC2, theT2f, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount); GetIntersection(theC1, aT1m, theT1l, theC2, theT2f, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount); } else { Standard_Real aT1m = (theT1l + theT1f) / 2.; Standard_Real aT2m = (theT2l + theT2f) / 2.; GetIntersection(theC1, theT1f, aT1m, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount); GetIntersection(theC1, theT1f, aT1m, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount); GetIntersection(theC1, aT1m, theT1l, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount); GetIntersection(theC1, aT1m, theT1l, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount); } } //======================================================================= //function : GetMinNbPoints //purpose : //======================================================================= Standard_Integer IntCurve_IntPolyPolyGen::GetMinNbSamples() const { return myMinPntNb; } //======================================================================= //function : SetMinNbPoints //purpose : //======================================================================= void IntCurve_IntPolyPolyGen::SetMinNbSamples(const Standard_Integer theMinNbSamples) { myMinPntNb = theMinNbSamples; }