// Created on: 1992-10-13
// Created by: Laurent BUCHARD
// Copyright (c) 1992-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// 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.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// 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 DEB
+#ifndef OCCT_DEBUG
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#endif
#include <math_FunctionSetRoot.hxx>
#include <math_NewtonFunctionSetRoot.hxx>
#include <NCollection_Handle.hxx>
+#include <Bnd_Box2d.hxx>
+#include <Precision.hxx>
//======================================================================
-// Modified by skv - Tue Mar 1 14:22:09 2005 OCC8169 Begin
-// #define NBITER_MAX_POLYGON 3
#define NBITER_MAX_POLYGON 10
-// Modified by skv - Tue Mar 1 14:22:09 2005 OCC8169 End
#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
//======================================================================
-IntCurve_IntPolyPolyGen::IntCurve_IntPolyPolyGen(void) {
+IntCurve_IntPolyPolyGen::IntCurve_IntPolyPolyGen()
+{
+ const Standard_Integer aMinPntNb = 20; // Minimum number of samples.
+ myMinPntNb = aMinPntNb;
done = Standard_False;
}
//======================================================================
,const Standard_Real TheTolConf
,const Standard_Real TheTol)
{
-
- Standard_Boolean AnErrorOccurred = Standard_False;
-
this->ResetFields();
DomainOnCurve1=D1;
DomainOnCurve2=D2;
Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
Perform(C1,D1,C2,D2,TlConf,Tl,0,DU,DV);
//----------------------------------------------------------------------
- //-- Traitement des points en bouts
+ //-- Processing of end points
//----------------------------------------------------------------------
Standard_Boolean HeadOn1 = Standard_False;
Standard_Boolean HeadOn2 = Standard_False;
//--------------------------------------------------------------------
- //-- On ne rejette les points Head Head ... End End
- //-- si ils figurent deja dans un bout de segment
- //-- ( On ne peut pas tester les egalites sur les parametres)
- //-- ( ces points n etant pas trouves a EpsX pres )
- //-- PosSegment = 1 si Head Head
- //-- 2 si Head End
- //-- 4 si End Head
- //-- 8 si End End
+ //-- 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;
}
}
-
-
Standard_Real U0 = D1.FirstParameter();
Standard_Real U1 = D1.LastParameter();
Standard_Real V0 = D2.FirstParameter();
Standard_Real V1 = D2.LastParameter();
- Standard_Real v,u;
- Standard_Real EpsX1 = TheCurveTool::EpsX(C1);
- Standard_Real EpsX2 = TheCurveTool::EpsX(C2);
IntRes2d_IntersectionPoint IntPt;
if(D1.FirstTolerance() || D2.FirstTolerance()) {
if(HeadOrEndPoint(D1,C1,U1,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
this->Insert(IntPt);
}
- if(AnErrorOccurred) {
- //----------------------------------------------------------------------------------
- //-- On a donne un point approche a la recherche du point exact, et cette recherche
- //-- a echoue.
- //-- Soit le point n'existe pas, soit c'est un point en bout dont un des parameteres
- //-- est en dehors du domaine de la courbe.
- //--
- //-- Dans le cas contraire, on suppose que les points en bouts ont ete trouves par
- //-- les interferences des polygones
- //--
- if(!HeadOn1) {
- u = U0;
- v = TheProjPCur::FindParameter( C2,D1.FirstPoint(),V0,V1,EpsX2);
- if(HeadOrEndPoint(D1,C1,u,D2,C2,v,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
- this->Insert(IntPt);
- }
-
- if(!EndOn1) {
- u = U1;
- v = TheProjPCur::FindParameter( C2,D1.LastPoint(),V0,V1,EpsX2);
- if(HeadOrEndPoint(D1,C1,u,D2,C2,v,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
- this->Insert(IntPt);
- }
-
- if(!HeadOn2) {
- u = TheProjPCur::FindParameter( C1,D2.FirstPoint(),U0,U1,EpsX1);
- v = V0;
- if(HeadOrEndPoint(D1,C1,u,D2,C2,v,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment))
- this->Insert(IntPt);
- }
-
- if(!EndOn2) {
- u = TheProjPCur::FindParameter( C1,D2.LastPoint(),U0,U1,EpsX1);
- v = V1;
- if(HeadOrEndPoint(D1,C1,u,D2,C2,v,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
//======================================================================
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);
- //----------------------------------------------------------------------
- //-- Traitement des points en bouts
- //----------------------------------------------------------------------
- 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();
-
//--------------------------------------------------------------------
- //-- On ne rejette les points Head Head ... End End
- //-- si ils figurent deja dans un bout de segment
- //-- ( On ne peut pas tester les egalites sur les parametres)
- //-- ( ces points n etant pas trouves a EpsX pres )
- //-- PosSegment = 1 si Head Head
- //-- 2 si Head End
- //-- 4 si End Head
- //-- 8 si End End
+ //-- 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;
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;
}
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;
}
//======================================================================
-
-
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 /*DeltaU*/
,const Standard_Real) {
gp_Vec2d Tan1,Tan2,Norm1,Norm2;
gp_Pnt2d P1,P2;
Standard_Integer nbsamples;
done = Standard_False;
- Standard_Boolean AnErrorOccurred = Standard_False;
-
nbsamples = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
if(NbIter>3 || (NbIter>2 && nbsamples>100)) return;
- nbsamples*=2; //--- On prend systematiquement 2 fois plus de points que
- //-- sur une courbe normale.
- //-- Les courbes auto-intersectantes donne souvent des
- //-- polygones assez loin de la courbe a parametre ct.
+ 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;
+ nbsamples=(3*(nbsamples*NbIter))/2;
}
IntCurve_ThePolygon2d Poly1(C1,nbsamples,D1,Tol);
if(!Poly1.AutoIntersectionIsPossible()) {
}
//-- Poly1.Dump();
//----------------------------------------------------------------------
- //-- Si la deflection est inferieure a la Tolerance de Confusion
- //-- Alors la deflection du polygone est fixee a TolConf
- //-- (Detection des Zones de Tangence)
+ //-- 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);
Standard_Real U,V;
//----------------------------------------------------------------------
- //-- Traitement des SectionPoint
+ //-- Processing of SectionPoint
//----------------------------------------------------------------------
Standard_Integer Nbsp = InterPP.NbSectionPoints();
if(Nbsp>=1) {
//-- ---------------------------------------------------------------------
- //-- tri tri tri tri tri tri tri tri tri tri tri tri tri tri
+ //-- filtering, filtering, filtering ...
//--
Standard_Integer* TriIndex = new Standard_Integer [Nbsp+1];
Standard_Integer* PtrSegIndex1 = new Standard_Integer [Nbsp+1];
Triok=Standard_True;
for(Standard_Integer tr=1;tr<Nbsp;tr++) {
- SegIndex1=PtrSegIndex1[TriIndex[tr]];
- SegIndex_1=PtrSegIndex1[TriIndex[tr+1]];
-
- SegIndex2=PtrSegIndex2[TriIndex[tr]];
- SegIndex_2=PtrSegIndex2[TriIndex[tr+1]];
-
- if(SegIndex1 > 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;
- }
- }
+ SegIndex1=PtrSegIndex1[TriIndex[tr]];
+ SegIndex_1=PtrSegIndex1[TriIndex[tr+1]];
+
+ SegIndex2=PtrSegIndex2[TriIndex[tr]];
+ SegIndex_2=PtrSegIndex2[TriIndex[tr+1]];
+
+ if(SegIndex1 > 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; i<Nbsp;i++) {
if( (PtrSegIndex1[TriIndex[i]] == PtrSegIndex1[TriIndex[i+1]])
- && (PtrSegIndex2[TriIndex[i]] == PtrSegIndex2[TriIndex[i+1]])) {
- TriIndex[i]=-i;
-
+ && (PtrSegIndex2[TriIndex[i]] == PtrSegIndex2[TriIndex[i+1]])) {
+ TriIndex[i]=-i;
}
}
for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
if(TriIndex[sp]>0) {
- const Intf_SectionPoint& SPnt = InterPP.PntValue(TriIndex[sp]);
-
- SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
- SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
-
- if(Abs(SegIndex1-SegIndex2)>1) {
+ 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);
- AnErrorOccurred = EIP.AnErrorOccurred();
- if(EIP.NbRoots()==0) {
- //-- On supprime tous les segments voisins
- for(Standard_Integer k=sp+1;k<=Nbsp;k++) {
- Standard_Integer kk=TriIndex[k];
- // modified by OFV OCC2502 Tue Apr 29 15:07:45 2003 .Begin
- // --- 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;
- }
- }
- // modified by OFV OCC2502 Tue Apr 29 15:11:34 2003 .End
- }
- }
- else if(EIP.NbRoots()>=1) {
- //--------------------------------------------------------------------
- //-- On verifie que le point trouve est bien une racine
- //--------------------------------------------------------------------
- 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 non valide
- //-- Les maths ont du converger vers une
- //-- solution triviale ( point U = V )
- //-----------------------------------------
- Dist = TolConf+1.0;
- }
-
- //-----------------------------------------------------------------
- //-- On verifie que le point (u,v) n existe pas deja
- //--
- 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) { //-- Ou le point est deja present
- IntRes2d_Position Pos1 = IntRes2d_Middle;
- IntRes2d_Position Pos2 = IntRes2d_Middle;
- IntRes2d_Transition Trans1,Trans2;
- //-----------------------------------------------------------------
- //-- Calcul des Positions des Points sur la courbe
- //--
- 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);
+ 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);
+ }
+ }
}
- IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
- Insert(IP);
- }
- }
- }
}
}
delete [] TriIndex;
u = D1.LastParameter();
}
-
//----------------------------------------------------------------------
//-- Head On 2 : Head2 <-> P1
else if(P1.Distance(D2.FirstPoint())<=D2.FirstTolerance()) {
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;
+ 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;
+ Pos1 = IntRes2d_End;
+ P1 = D1.LastPoint();
+ EndOn1 = Standard_True;
}
}
else if(u!=tu) {
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;
- }
+ 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;
- }
+ 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;
+ }
}
}
-
//--------------------------------------------------------------------
- //-- On Teste si un point de bout de segment a deja ces trnasitions
- //-- Si Oui, on ne cree pas de nouveau point
+ //-- 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 si Head Head
- //-- 2 si Head End
- //-- 4 si End Head
- //-- 8 si End End
+ //-- 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);
return(Standard_False);
}
-
-
-
-
-
-
-//======================================================================
-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) {
-
+//=======================================================================
+//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;
- nbsamplesOnC1 = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
+ // Number of samples tunning.
+ nbsamplesOnC1 = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
+ nbsamplesOnC2 = TheCurveTool::NbSamples(C2,D2.FirstParameter(),D2.LastParameter());
- //// modified by jgv, 5.12.02 for OCC935 ////
- if (NbIter == 0) // first time
- {
- if (nbsamplesOnC1 < 20)
- nbsamplesOnC1 = 20;
- }
- else // NbIter > 0
- {
- nbsamplesOnC1=(5*(nbsamplesOnC1*NbIter))/4;
- }
- /////////////////////////////////////////////
+ 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;
+ }
- nbsamplesOnC2 = TheCurveTool::NbSamples(C2,D2.FirstParameter(),D2.LastParameter());
-
- //// modified by jgv, 5.12.02 for OCC935 ////
- if (NbIter == 0) // first time
+ NCollection_Handle<IntCurve_ThePolygon2d>
+ 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)
{
- if (nbsamplesOnC2 < 20)
- nbsamplesOnC2 = 20;
+ aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
+ aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
+ aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
}
- else // NbIter > 0
+ else
{
- nbsamplesOnC2=(5*(nbsamplesOnC2*NbIter))/4;
- }
- /////////////////////////////////////////////
-
-
- NCollection_Handle<IntCurve_ThePolygon2d> aPoly1 ,aPoly2;
- if(nbsamplesOnC2 > nbsamplesOnC1) {
- aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
- if(aPoly1->DeflectionOverEstimation() < TolConf) {
- aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
- }
- else {
- aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol,aPoly1->Bounding());
- aPoly1->SetDeflectionOverEstimation( aPoly2->DeflectionOverEstimation()
- + aPoly1->DeflectionOverEstimation());
- aPoly1->ComputeWithBox(C1,aPoly2->Bounding());
- }
- }
- else {
- aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
- if(aPoly2->DeflectionOverEstimation() < TolConf) {
- aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
- }
- else {
- aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol,aPoly2->Bounding());
- aPoly2->SetDeflectionOverEstimation( aPoly2->DeflectionOverEstimation()
- + aPoly1->DeflectionOverEstimation());
- aPoly2->ComputeWithBox(C2,aPoly1->Bounding());
+ aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
+ aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
+ aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
}
}
+
//----------------------------------------------------------------------
- //-- Si la deflection est inferieure a la Tolerance de Confusion
- //-- Alors la deflection du polygone est fixee a TolConf
- //-- (Detection des Zones de Tangence)
+ //-- 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) {
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 repeat
- //for polygon conatins all initial points
- //secondary search will be performed only for case when initial points
- //were dropped
+ // 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);
-
+ 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 :
+// 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 )
+ 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,V;
-
+ Standard_Real U = 0., V = 0.;
+ Standard_Boolean AnErrorOccurred = Standard_False;
+ done = Standard_True; // To prevent exception in nbp=NbPoints();
//----------------------------------------------------------------------
- //-- Traitement des SectionPoint
+ //-- Processing of SectionPoint
//----------------------------------------------------------------------
Standard_Integer Nbsp = InterPP.NbSectionPoints();
-
for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
- const Intf_SectionPoint& SPnt = InterPP.PntValue(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();
+ AnErrorOccurred = EIP.AnErrorOccurred();
+
if( !EIP.NbRoots() && !isFullPolygon)
return Standard_False;
-
-
- //--------------------------------------------------------------------
- //-- On verifie que le point trouve est bien une racine
- //--------------------------------------------------------------------
- EIP.Roots(U,V);
- TheCurveTool::D1(C1,U,P1,Tan1);
- TheCurveTool::D1(C2,V,P2,Tan2);
- Standard_Real Dist = P1.Distance(P2);
- //-----------------------------------------------------------------
- //-- On verifie que le point (u,v) n existe pas deja
- //--
- done = Standard_True;
- 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) { //-- Ou le point est deja present
- IntRes2d_Position Pos1 = IntRes2d_Middle;
- IntRes2d_Position Pos2 = IntRes2d_Middle;
- IntRes2d_Transition Trans1,Trans2;
- //-----------------------------------------------------------------
- //-- Calcul des Positions des Points sur la courbe
- //--
- 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;
- //-----------------------------------------------------------------
- //-- Calcul des Transitions (Voir 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);
- }
+
+ 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);
+ }
}
//----------------------------------------------------------------------
- //-- Traitement des TangentZone
+ //-- Processing of TangentZone
//----------------------------------------------------------------------
Standard_Integer Nbtz = InterPP.NbTangentZones();
for(Standard_Integer tz=1; tz <= Nbtz; tz++) {
Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
//====================================================================
- //== Recherche du premier et du dernier point dans la zone de tg.
+ //== Find the first and the last point in the tangency zone.
//====================================================================
Standard_Real ParamSupOnCurve2,ParamInfOnCurve2;
Standard_Real ParamSupOnCurve1,ParamInfOnCurve1;
for(Standard_Integer qq=1;qq<=NbPnts;qq++) {
const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
//====================================================================
- //== On discretise sur les zones de tangence
- //== Test d arret :
- //== Compteur
- //== Deflection < Tolerance
- //== OU Echantillon < EpsX (normalement la premiere condition est
- //== plus severe)
+ //== 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;
if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf;
if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf;
-
}
PolyUInf= ParamInfOnCurve1;
Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty;
}
-
-
if( ( (thePoly1.DeflectionOverEstimation() > TolConf)
||(thePoly2.DeflectionOverEstimation() > TolConf))
- &&(NbIter<NBITER_MAX_POLYGON)) {
+ &&(NbIter<NBITER_MAX_POLYGON)) {
IntRes2d_Domain RecursD1( TheCurveTool::Value(C1,ParamInfOnCurve1)
,ParamInfOnCurve1,TolConf
,ParamInfOnCurve2,TolConf
,TheCurveTool::Value(C2,ParamSupOnCurve2)
,ParamSupOnCurve2,TolConf);
- //-- On ne delete pas thePoly1(2) ,
- //-- ils sont detruits enfin de fct.
- //-- !! Pas de return intempestif !!
+ //-- thePoly1(2) are not deleted,
+ //-- finally they are destroyed.
+ //-- !! No untimely return !!
Perform(C1,RecursD1,C2,RecursD2,Tol,TolConf,NbIter+1,DeltaU,DeltaV);
}
else {
//-----------------------------------------------------------------
- //-- Calcul des Positions des Points sur la courbe et des
- //-- Transitions sur chaque borne du segment
+ //-- 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;
TheCurveTool::D1(C2,PolyVInf,P2,Tan2);
if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance()) {
- Pos1 = IntRes2d_Head;
+ Pos1 = IntRes2d_Head;
}
else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) {
- Pos1 = IntRes2d_End;
+ Pos1 = IntRes2d_End;
}
if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance()) {
- Pos2 = IntRes2d_Head;
+ Pos2 = IntRes2d_Head;
}
else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) {
- Pos2 = IntRes2d_End;
+ Pos2 = IntRes2d_End;
}
if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) {
- PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
+ PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
}
else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) {
- PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
+ PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
}
else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) {
- PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
+ 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));
+ 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);
+ == 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);
+ || (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;
+ 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);
-
+ 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);
- }
+ 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;
+}