1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0024005: Intersecting a slightly off angle plane with a cylinder takes 7+ seconds

Checking of possibility of bad result.
Adding test case for issue CR24005
Correction of test case for issue CR24005
This commit is contained in:
nbv 2013-09-19 16:46:17 +04:00 committed by bugmaster
parent bb58e462ad
commit 788cbaf4c4
11 changed files with 1406 additions and 1060 deletions

View File

@ -3068,7 +3068,17 @@ Standard_Boolean ChFi3d_ComputeCurves(Handle(Adaptor3d_HSurface)& S1,
cyl = S1->Cylinder();
}
IntAna_QuadQuadGeo ImpKK(pl,cyl,Precision::Angular(),tol3d);
if (ImpKK.IsDone()) {
Standard_Boolean isIntDone = ImpKK.IsDone();
if(ImpKK.TypeInter() == IntAna_Ellipse)
{
const gp_Elips anEl = ImpKK.Ellipse(1);
const Standard_Real aMajorR = anEl.MajorRadius();
const Standard_Real aMinorR = anEl.MinorRadius();
isIntDone = (aMajorR < 100000.0 * aMinorR);
}
if (isIntDone) {
Standard_Boolean c1line = 0;
switch (ImpKK.TypeInter()) {
case IntAna_Line:

View File

@ -1627,10 +1627,21 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
#endif
return NewS;
}
if (Abs(Angle) > Precision::Angular()) {
if (Abs(Angle) > Precision::Angular())
{
IntAna_QuadQuadGeo i2s;
i2s.Perform(NeutralPlane,Cy,Precision::Angular(),Precision::Confusion());
if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
Standard_Boolean isIntDone = i2s.IsDone();
if(i2s.TypeInter() == IntAna_Ellipse)
{
const gp_Elips anEl = i2s.Ellipse(1);
const Standard_Real aMajorR = anEl.MajorRadius();
const Standard_Real aMinorR = anEl.MinorRadius();
isIntDone = (aMajorR < 100000.0 * aMinorR);
}
if (!isIntDone || i2s.TypeInter() != IntAna_Circle) {
#ifdef DEB
cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
#endif

View File

@ -534,13 +534,7 @@ gp_Ax2 DirToAx2(const gp_Pnt& P,const gp_Dir& D)
param1bis = radius;
}
}
if(typeres == IntAna_Ellipse) {
if( param1>100000.0*param1bis
|| param1bis>100000.0*param1) {
done = Standard_False;
return;
}
}
done = Standard_True;
}
//=======================================================================

View File

@ -550,102 +550,166 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
SortAgain = Standard_False;
SortIsOK = Standard_True;
for(i=2; i<=nbvtx && SortIsOK; i++) {
for(i=2; i<=nbvtx && SortIsOK; i++)
{
IntPatch_Point& VTX = svtx.ChangeValue(i);
for(j=1; j<=nbvtx && SortIsOK; j++) {
if(i!=j) {
for(j=1; j<=nbvtx && SortIsOK; j++)
{
if(i!=j)
{
IntPatch_Point& VTXM1 = svtx.ChangeValue(j);
Standard_Boolean kill = Standard_False;
Standard_Boolean killm1 = Standard_False;
if(Abs(VTXM1.ParameterOnLine()-VTX.ParameterOnLine())<PrecisionPConfusion) {
if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()) { //-- OnS1 OnS1
if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) { //-- OnS1 == OnS1
if(VTXM1.IsOnDomS2()) { //-- OnS1 == OnS1 OnS2
if(VTX.IsOnDomS2()==Standard_False) { //-- OnS1 == OnS1 OnS2 PasOnS2
if(Abs(VTXM1.ParameterOnLine()-VTX.ParameterOnLine())<PrecisionPConfusion)
{
if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()) //-- OnS1 OnS1
{
if(VTXM1.ArcOnS1() == VTX.ArcOnS1())//-- OnS1 == OnS1
{
if(VTXM1.IsOnDomS2()) //-- OnS1 == OnS1 OnS2
{
if(VTX.IsOnDomS2()==Standard_False)//-- OnS1 == OnS1 OnS2 PasOnS2
{
kill=Standard_True;
}
else {
if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) { //-- OnS1 == OnS1 OnS2 == OnS2
if(VTXM1.IsVertexOnS2()) {
else
{
if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) //-- OnS1 == OnS1 OnS2 == OnS2
{
if(VTXM1.IsVertexOnS2())
{
kill=Standard_True;
}
else {
else
{
killm1=Standard_True;
}
}
}
}
else { //-- OnS1 == OnS1 PasOnS2
if(VTX.IsOnDomS2()) { //-- OnS1 == OnS1 PasOnS2 OnS2
else //-- OnS1 == OnS1 PasOnS2
{
if(VTX.IsOnDomS2()) //-- OnS1 == OnS1 PasOnS2 OnS2
{
killm1=Standard_True;
}
}
}
}
else { //-- Pas OnS1 et OnS1
if(VTXM1.IsOnDomS2()==Standard_False && VTX.IsOnDomS2()==Standard_False) {
if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()==Standard_False) {
else //-- Pas OnS1 et OnS1
{
if(VTXM1.IsOnDomS2()==Standard_False && VTX.IsOnDomS2()==Standard_False)
{
if(VTXM1.IsOnDomS1() && VTX.IsOnDomS1()==Standard_False)
{
kill=Standard_True;
}
else if(VTX.IsOnDomS1() && VTXM1.IsOnDomS1()==Standard_False) {
else if(VTX.IsOnDomS1() && VTXM1.IsOnDomS1()==Standard_False)
{
killm1=Standard_True;
}
}
}
if(!(kill || killm1)) {
if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()) { //-- OnS2 OnS2
if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) { //-- OnS2 == OnS2
if(VTXM1.IsOnDomS1()) { //-- OnS2 == OnS2 OnS1
if(VTX.IsOnDomS1()==Standard_False) { //-- OnS2 == OnS2 OnS1 PasOnS1
if(!(kill || killm1))
{
if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()) //-- OnS2 OnS2
{
if(VTXM1.ArcOnS2() == VTX.ArcOnS2()) //-- OnS2 == OnS2
{
if(VTXM1.IsOnDomS1()) //-- OnS2 == OnS2 OnS1
{
if(VTX.IsOnDomS1()==Standard_False) //-- OnS2 == OnS2 OnS1 PasOnS1
{
kill=Standard_True;
}
else {
if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) { //-- OnS2 == OnS2 OnS1 == OnS1
if(VTXM1.IsVertexOnS1()) {
else
{
if(VTXM1.ArcOnS1() == VTX.ArcOnS1()) //-- OnS2 == OnS2 OnS1 == OnS1
{
if(VTXM1.IsVertexOnS1())
{
kill=Standard_True; //-- OnS2 == OnS2 OnS1 == OnS1 Vtx PasVtx
}
else {
else
{
killm1=Standard_True; //-- OnS2 == OnS2 OnS1 == OnS1 PasVtx Vtx
}
}
}
}
else { //-- OnS2 == OnS2 PasOnS1
if(VTX.IsOnDomS1()) { //-- OnS2 == OnS2 PasOnS1 OnS1
else
{ //-- OnS2 == OnS2 PasOnS1
if(VTX.IsOnDomS1()) //-- OnS2 == OnS2 PasOnS1 OnS1
{
killm1=Standard_True;
}
}
}
}
else { //-- Pas OnS2 et OnS2
if(VTXM1.IsOnDomS1()==Standard_False && VTX.IsOnDomS1()==Standard_False) {
if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()==Standard_False) {
else //-- Pas OnS2 et OnS2
{
if(VTXM1.IsOnDomS1()==Standard_False && VTX.IsOnDomS1()==Standard_False)
{
if(VTXM1.IsOnDomS2() && VTX.IsOnDomS2()==Standard_False)
{
kill=Standard_True;
}
else if(VTX.IsOnDomS2() && VTXM1.IsOnDomS2()==Standard_False) {
else if(VTX.IsOnDomS2() && VTXM1.IsOnDomS2()==Standard_False)
{
killm1=Standard_True;
}
}
}
}
//-- On a j < i
if(kill) {
if(kill)
{
SortIsOK = Standard_False;
if(lapt) { if(indl>i) indl--; else if(indl==i) indl=j; }
if(fipt) { if(indf>i) indf--; else if(indf==i) indf=j; }
if(lapt)
{
if(indl>i)
indl--;
else if(indl==i)
indl=j;
}
if(fipt)
{
if(indf>i)
indf--;
else if(indf==i)
indf=j;
}
svtx.Remove(i);
nbvtx--;
}
else if(killm1) {
else if(killm1)
{
SortIsOK = Standard_False;
if(lapt) { if(indl>j) indl--; else if(indl==j) indl=i-1;}
if(fipt) { if(indf>j) indf--; else if(indf==j) indf=i-1;}
if(lapt)
{
if(indl>j)
indl--;
else if(indl==j)
indl=i-1;
}
if(fipt)
{
if(indf>j)
indf--;
else if(indf==j)
indf=i-1;
}
svtx.Remove(j);
nbvtx--;
}
// else
else if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) { // eap
}// else
else if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) // eap
{
//-- deux points de meme parametre qui ne peuvent etre confondus
//-- On change les parametres d un des points si les points UV sont
//-- differents. Ceci distingue le cas des aretes de couture.
@ -653,6 +717,7 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
//-- 2 points with the same parameters
//-- Change parametres of one point if points UV are
//-- different. This is the case of seam edge
Standard_Real ponline = VTX.ParameterOnLine();
// eap, =>>
Standard_Real newParam = ponline;
@ -669,21 +734,32 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
newParam = PiPi;
else
newParam -= PiPi;
// if( (Abs(ponline)<=PrecisionPConfusion)
// ||(Abs(ponline-M_PI-M_PI) <=PrecisionPConfusion))
// eap, <<=
Standard_Real u1a,v1a,u2a,v2a,u1b,v1b,u2b,v2b;
VTXM1.Parameters(u1a,v1a,u2a,v2a);
VTX.Parameters(u1b,v1b,u2b,v2b);
Standard_Integer flag = 0;
if( (Abs(u1a-u1b)<=PrecisionPConfusion) ) flag|=1;
if( (Abs(v1a-v1b)<=PrecisionPConfusion) ) flag|=2;
if( (Abs(u2a-u2b)<=PrecisionPConfusion) ) flag|=4;
if( (Abs(v2a-v2b)<=PrecisionPConfusion) ) flag|=8;
if( (Abs(u1a-u1b)<=PrecisionPConfusion) )
flag|=1;
if( (Abs(v1a-v1b)<=PrecisionPConfusion) )
flag|=2;
if( (Abs(u2a-u2b)<=PrecisionPConfusion) )
flag|=4;
if( (Abs(v2a-v2b)<=PrecisionPConfusion) )
flag|=8;
Standard_Boolean TestOn1 = Standard_False;
Standard_Boolean TestOn2 = Standard_False;
switch(flag) {
switch(flag)
{
case 3: //-- meme point U1 V1
case 7: //-- meme point U1 V1 meme U2
case 12: //-- meme U2 V2
@ -691,17 +767,28 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
case 10: //-- meme point V1 meme V2 Test si U1a=U1b Mod 2PI et Test si U2a=U2b Mod 2PI
break;
case 11: //-- meme point U1 V1 meme V2 Test si U2a=U2b Mod 2PI
{ TestOn2 = Standard_True; break; }
{
TestOn2 = Standard_True;
break;
}
case 14: //-- meme point V1 meme U2 V2 Test si U1a=U1b Mod 2PI
{ TestOn1 = Standard_True; break; }
default: break;
{
TestOn1 = Standard_True;
break;
}
default:
break;
};
// eap
//if(ArcType()==IntPatch_Circle || ArcType()==IntPatch_Ellipse) {}
if(TestOn1) {
if(TestOn1)
{
//// modified by jgv, 2.11.01 for BUC61033 ////
Standard_Real U1A = (u1a < u1b)? u1a : u1b;
Standard_Real U1B = (u1a < u1b)? u1b : u1a;
if (u1min == RealLast())
{
u1min = U1A;
@ -719,15 +806,32 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
// if (Abs(ponline) <= PrecisionPConfusion) {
// const Standard_Real PiPi = M_PI+M_PI;
if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine
/*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/) {
/*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/)
{
SortAgain = Standard_True;
SortIsOK = Standard_False;
if (newParam > ponline)
if(u1a < u1b) { VTX.SetParameter(newParam); }
else { VTXM1.SetParameter(newParam); }
{
if(u1a < u1b)
{
VTX.SetParameter(newParam);
}
else
if(u1a > u1b) { VTX.SetParameter(newParam); }
else { VTXM1.SetParameter(newParam); }
{
VTXM1.SetParameter(newParam);
}
}
else
{
if(u1a > u1b)
{
VTX.SetParameter(newParam);
}
else
{
VTXM1.SetParameter(newParam);
}
}
}
// }
// else {
@ -740,7 +844,9 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
// }
// eap, <<=
}
if(TestOn2) {
if(TestOn2)
{
//// modified by jgv, 2.11.01 for BUC61033 ////
Standard_Real U2A = (u2a < u2b)? u2a : u2b;
Standard_Real U2B = (u2a < u2b)? u2b : u2a;
@ -753,23 +859,42 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
{
if (Abs(U2A-u2min) > PrecisionPConfusion)
ToBreak = Standard_True;
if (Abs(U2B-u2max) > PrecisionPConfusion)
ToBreak = Standard_True;
}
///////////////////////////////////////////////
// eap, =>>
// if (Abs(ponline) <= PrecisionPConfusion) {
// const Standard_Real PiPi = M_PI+M_PI;
if(newParam >= ParamMinOnLine && newParam <= ParamMaxOnLine
/*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/) {
/*PiPi >= ParamMinOnLine && PiPi<=ParamMaxOnLine*/)
{
SortAgain = Standard_True;
SortIsOK = Standard_False;
if (newParam > ponline)
if(u2a < u2b) { VTX.SetParameter(newParam); }
else { VTXM1.SetParameter(newParam); }
{
if(u2a < u2b)
{
VTX.SetParameter(newParam);
}
else
if(u2a > u2b) { VTX.SetParameter(newParam); }
else { VTXM1.SetParameter(newParam); }
{
VTXM1.SetParameter(newParam);
}
}
else
{
if(u2a > u2b)
{
VTX.SetParameter(newParam);
}
else
{
VTXM1.SetParameter(newParam);
}
}
}
// }
// else {
@ -809,6 +934,7 @@ void IntPatch_GLine::ComputeVertexParameters(const Standard_Real /*Tol*/)
}
}
while(!SortIsOK);
indl=nbvtx;
indf=1;
}

View File

@ -76,7 +76,7 @@ void IntPatch_ImpImpIntersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
IntSurf_Quadric quad1;
IntSurf_Quadric quad2;
IntPatch_ArcFunction AFunc;
Standard_Real Tolang = 1.e-8;
const Standard_Real Tolang = 1.e-8;
GeomAbs_SurfaceType typs1 = S1->GetType();
GeomAbs_SurfaceType typs2 = S2->GetType();
//

View File

@ -34,7 +34,7 @@ uses
TopolTool from Adaptor3d,
SequenceOfLine from IntPatch,
Line from IntPatch,
--amv
SurfaceType from GeomAbs,
ListOfPntOn2S from IntSurf
raises NotDone from StdFail,
@ -53,14 +53,12 @@ is
TolArc,TolTang: Real from Standard)
returns Intersection from IntPatch
raises ConstructionError from Standard;
Create (S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
TolArc,TolTang: Real from Standard)
returns Intersection from IntPatch
raises ConstructionError from Standard;
@ -89,15 +87,16 @@ is
-- algorithms to compute the distance between to
-- points in their respective parametrtic spaces.
--
is static;
Perform (me: in out;
S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
TolArc,TolTang: Real from Standard)
TolArc,TolTang: Real from Standard;
isGeomInt : Boolean from Standard = Standard_True)
raises ConstructionError from Standard
is static;
--amv
@ -106,10 +105,13 @@ is
S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
TolArc,TolTang: Real from Standard;
LOfPnts: in out ListOfPntOn2S from IntSurf;
RestrictLine: Boolean from Standard = Standard_True)
RestrictLine: Boolean from Standard = Standard_True;
isGeomInt : Boolean from Standard = Standard_True)
---Purpose: If isGeomInt == Standard_False, then method
-- Param-Param intersection will be used.
raises ConstructionError from Standard
is static;
Perform ( me: in out;
@ -119,7 +121,6 @@ is
TolArc,TolTang: Real from Standard)
raises ConstructionError from Standard
is static;
Perform (me: in out;
@ -127,9 +128,35 @@ is
TolArc,TolTang: Real from Standard)
raises ConstructionError from Standard
is static;
ParamParamPerfom( me: in out;
S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
TolArc,TolTang: Real from Standard;
LOfPnts: in out ListOfPntOn2S from IntSurf;
RestrictLine: Boolean from Standard;
typs1, typs2: SurfaceType from GeomAbs)
is private;
GeomGeomPerfom( me: in out;
S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
TolArc,TolTang: Real from Standard;
LOfPnts: in out ListOfPntOn2S from IntSurf;
RestrictLine: Boolean from Standard;
typs1, typs2: SurfaceType from GeomAbs)
is private;
GeomParamPerfom(me: in out;
S1: HSurface from Adaptor3d; D1: TopolTool from Adaptor3d;
S2: HSurface from Adaptor3d; D2: TopolTool from Adaptor3d;
isNotAnalitical: Boolean from Standard;
typs1, typs2: SurfaceType from GeomAbs)
is private;
IsDone(me)
@ -142,57 +169,43 @@ is
IsEmpty(me)
---Purpose: Returns true if the is no intersection.
returns Boolean from Standard
---C++: inline
returns Boolean from Standard
raises NotDone from StdFail
is static;
TangentFaces(me)
---Purpose: Returns True if the two patches are considered as
-- entierly tangent, i-e every restriction arc of one
-- patch is inside the geometric base of the other patch.
returns Boolean from Standard
---C++: inline
returns Boolean from Standard
raises NotDone from StdFail
is static;
OppositeFaces(me)
---Purpose: Returns True when the TangentFaces returns True and the
-- normal vectors evaluated at a point on the first and the
-- second surface are opposite.
-- The exception DomainError is raised if TangentFaces
-- returns False.
returns Boolean from Standard
---C++: inline
returns Boolean from Standard
raises NotDone from StdFail,
DomainError from Standard
is static;
NbPnts(me)
---Purpose: Returns the number of "single" points.
returns Integer from Standard
---C++: inline
returns Integer from Standard
raises NotDone from StdFail
is static;
@ -200,11 +213,10 @@ is
---Purpose: Returns the point of range Index.
-- An exception is raised if Index<=0 or Index>NbPnt.
returns Point from IntPatch
---C++: return const&
---C++: inline
returns Point from IntPatch
raises NotDone from StdFail,
OutOfRange from Standard
@ -212,34 +224,29 @@ is
NbLines(me)
---Purpose: Returns the number of intersection lines.
returns Integer from Standard
---C++: inline
returns Integer from Standard
raises NotDone from StdFail
is static;
Line(me; Index: Integer from Standard)
---Purpose: Returns the line of range Index.
-- An exception is raised if Index<=0 or Index>NbLine.
returns Line from IntPatch
---C++: return const&
---C++: inline
returns Line from IntPatch
raises NotDone from StdFail,
OutOfRange from Standard
is static;
SequenceOfLine(me)
returns SequenceOfLine from IntPatch
---C++: return const&
returns SequenceOfLine from IntPatch
raises NotDone from StdFail
is static;

File diff suppressed because it is too large Load Diff

View File

@ -284,10 +284,7 @@ static
static
void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
const Handle(GeomAdaptor_HSurface)& aHS2,
Standard_Real& aTolArc,
Standard_Real& aTolTang,
Standard_Real& aUVMaxStep,
Standard_Real& aDeflection);
Standard_Real& aTolTang);
static
Standard_Boolean SortTypes(const GeomAbs_SurfaceType aType1,
@ -413,7 +410,7 @@ const IntTools_SequenceOfCurves& IntTools_FaceFace::Lines() const
{
StdFail_NotDone_Raise_if
(!myIsDone,
"IntTools_FaceFace::Lines() => !myIntersector.IsDone()");
"IntTools_FaceFace::Lines() => myIntersector NOT DONE");
return mySeqOfCurve;
}
//=======================================================================
@ -446,6 +443,84 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
{
myListOfPnts = aListOfPnts;
}
static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
const TopoDS_Face& theF2)
{
const Standard_Real Tolang = 1.e-8;
const Standard_Real aTolF1=BRep_Tool::Tolerance(theF1);
const Standard_Real aTolF2=BRep_Tool::Tolerance(theF2);
const Standard_Real aTolSum = aTolF1 + aTolF2;
Standard_Real aHigh = 0.0;
const BRepAdaptor_Surface aBAS1(theF1), aBAS2(theF2);
const GeomAbs_SurfaceType aType1=aBAS1.GetType();
const GeomAbs_SurfaceType aType2=aBAS2.GetType();
gp_Pln aS1;
gp_Cylinder aS2;
if(aType1 == GeomAbs_Plane)
{
aS1=aBAS1.Plane();
}
else if(aType2 == GeomAbs_Plane)
{
aS1=aBAS2.Plane();
}
else
{
return Standard_True;
}
if(aType1 == GeomAbs_Cylinder)
{
aS2=aBAS1.Cylinder();
const Standard_Real VMin = aBAS1.FirstVParameter();
const Standard_Real VMax = aBAS1.LastVParameter();
if( Precision::IsNegativeInfinite(VMin) ||
Precision::IsPositiveInfinite(VMax))
return Standard_True;
else
aHigh = VMax - VMin;
}
else if(aType2 == GeomAbs_Cylinder)
{
aS2=aBAS2.Cylinder();
const Standard_Real VMin = aBAS2.FirstVParameter();
const Standard_Real VMax = aBAS2.LastVParameter();
if( Precision::IsNegativeInfinite(VMin) ||
Precision::IsPositiveInfinite(VMax))
return Standard_True;
else
aHigh = VMax - VMin;
}
else
{
return Standard_True;
}
IntAna_QuadQuadGeo inter;
inter.Perform(aS1,aS2,Tolang,aTolSum, aHigh);
if(inter.TypeInter() == IntAna_Ellipse)
{
const gp_Elips anEl = inter.Ellipse(1);
const Standard_Real aMajorR = anEl.MajorRadius();
const Standard_Real aMinorR = anEl.MinorRadius();
return (aMajorR < 100000.0 * aMinorR);
}
else
{
return inter.IsDone();
}
}
//=======================================================================
//function : Perform
//purpose : intersect surfaces of the faces
@ -453,120 +528,124 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
const TopoDS_Face& aF2)
{
Standard_Boolean hasCone, RestrictLine, bTwoPlanes, bReverse;
Standard_Integer aNbLin, aNbPnts, i, NbLinPP;
Standard_Real TolArc, TolTang, Deflection, UVMaxStep;
Standard_Real umin, umax, vmin, vmax;
Standard_Real aTolF1, aTolF2;
GeomAbs_SurfaceType aType1, aType2;
Handle(Geom_Surface) S1, S2;
Handle(IntTools_TopolTool) dom1, dom2;
BRepAdaptor_Surface aBAS1, aBAS2;
//
Standard_Boolean RestrictLine = Standard_False, hasCone = Standard_False;
if (myContext.IsNull()) {
myContext=new BOPInt_Context;
}
//
mySeqOfCurve.Clear();
myTolReached2d=0.;
myTolReached3d=0.;
myIsDone = Standard_False;
myNbrestr=0;//?
hasCone = Standard_False;
bTwoPlanes = Standard_False;
//
myFace1=aF1;
myFace2=aF2;
//
aBAS1.Initialize(myFace1, Standard_False);
aBAS2.Initialize(myFace2, Standard_False);
aType1=aBAS1.GetType();
aType2=aBAS2.GetType();
//
bReverse=SortTypes(aType1, aType2);
if (bReverse) {
const BRepAdaptor_Surface aBAS1(myFace1, Standard_False);
const BRepAdaptor_Surface aBAS2(myFace2, Standard_False);
GeomAbs_SurfaceType aType1=aBAS1.GetType();
GeomAbs_SurfaceType aType2=aBAS2.GetType();
const Standard_Boolean bReverse=SortTypes(aType1, aType2);
if (bReverse)
{
myFace1=aF2;
myFace2=aF1;
aType1=aBAS2.GetType();
aType2=aBAS1.GetType();
//
if (myListOfPnts.Extent()) {
if (myListOfPnts.Extent())
{
Standard_Real aU1,aV1,aU2,aV2;
IntSurf_ListIteratorOfListOfPntOn2S aItP2S;
//
aItP2S.Initialize(myListOfPnts);
for (; aItP2S.More(); aItP2S.Next()){
for (; aItP2S.More(); aItP2S.Next())
{
IntSurf_PntOn2S& aP2S=aItP2S.Value();
aP2S.Parameters(aU1,aV1,aU2,aV2);
aP2S.SetValue(aU2,aV2,aU1,aV1);
}
}
}
//
S1=BRep_Tool::Surface(myFace1);
S2=BRep_Tool::Surface(myFace2);
//
aTolF1=BRep_Tool::Tolerance(myFace1);
aTolF2=BRep_Tool::Tolerance(myFace2);
//
TolArc= aTolF1 + aTolF2;
TolTang = TolArc;
//
NbLinPP = 0;
if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
bTwoPlanes = Standard_True;
const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1);
const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2);
const Standard_Real aTolF1=BRep_Tool::Tolerance(myFace1);
const Standard_Real aTolF2=BRep_Tool::Tolerance(myFace2);
Standard_Real TolArc = aTolF1 + aTolF2;
Standard_Real TolTang = TolArc;
const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
aType1 == GeomAbs_Cone ||
aType1 == GeomAbs_Torus);
const Standard_Boolean isFace2Quad = (aType2 == GeomAbs_Cylinder ||
aType2 == GeomAbs_Cone ||
aType2 == GeomAbs_Torus);
if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane)
{
Standard_Real umin, umax, vmin, vmax;
BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
//
BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
Standard_Real TolAng = 1.e-8;
PerformPlanes(myHS1, myHS2, TolAng, TolTang, myApprox1, myApprox2,
mySeqOfCurve, myTangentFaces);
myIsDone = Standard_True;
if(!myTangentFaces) {
//
NbLinPP = mySeqOfCurve.Length();
if(NbLinPP) {
if(!myTangentFaces)
{
const Standard_Integer NbLinPP = mySeqOfCurve.Length();
if(NbLinPP)
{
Standard_Real aTolFMax;
//
myTolReached3d = 1.e-7;
//
aTolFMax=Max(aTolF1, aTolF2);
//
if (aTolFMax>myTolReached3d) {
if (aTolFMax>myTolReached3d)
{
myTolReached3d=aTolFMax;
}
myTolReached2d = myTolReached3d;
//
if (bReverse) {
if (bReverse)
{
Handle(Geom2d_Curve) aC2D1, aC2D2;
//
aNbLin=mySeqOfCurve.Length();
for (i=1; i<=aNbLin; ++i) {
const Standard_Integer aNbLin = mySeqOfCurve.Length();
for (Standard_Integer i = 1; i <= aNbLin; ++i)
{
IntTools_Curve& aIC=mySeqOfCurve(i);
aC2D1=aIC.FirstCurve2d();
aC2D2=aIC.SecondCurve2d();
//
aIC.SetFirstCurve2d(aC2D2);
aIC.SetSecondCurve2d(aC2D1);
}
}
}
}
return;
}//if(aType1==GeomAbs_Plane && aType2==GeomAbs_Plane){
//
if (aType1==GeomAbs_Plane &&
(aType2==GeomAbs_Cylinder ||
aType2==GeomAbs_Cone ||
aType2==GeomAbs_Torus)) {
if ((aType1==GeomAbs_Plane) && isFace2Quad)
{
Standard_Real dU, dV;
// F1
Standard_Real umin, umax, vmin, vmax;
BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
dU=0.1*(umax-umin);
dV=0.1*(vmax-vmin);
umin=umin-dU;
@ -584,13 +663,12 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
hasCone = Standard_True;
}
}
//
else if ((aType1==GeomAbs_Cylinder||
aType1==GeomAbs_Cone ||
aType1==GeomAbs_Torus) &&
aType2==GeomAbs_Plane) {
else if ((aType2==GeomAbs_Plane) && isFace1Quad)
{
Standard_Real dU, dV;
//F1
Standard_Real umin, umax, vmin, vmax;
BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
@ -609,80 +687,84 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
hasCone = Standard_True;
}
}
//
else {
else
{
Standard_Real umin, umax, vmin, vmax;
BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
//
CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
//
myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
//
BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
//
CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
//
myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
}
//
dom1 = new IntTools_TopolTool(myHS1);
dom2 = new IntTools_TopolTool(myHS2);
//
const Handle(IntTools_TopolTool) dom1 = new IntTools_TopolTool(myHS1);
const Handle(IntTools_TopolTool) dom2 = new IntTools_TopolTool(myHS2);
myLConstruct.Load(dom1, dom2, myHS1, myHS2);
//
Deflection = (hasCone) ? 0.085 : 0.1;
UVMaxStep = 0.001;
//
Tolerances(myHS1, myHS2, TolArc, TolTang, UVMaxStep, Deflection);
//
Tolerances(myHS1, myHS2, TolTang);
{
const Standard_Real UVMaxStep = 0.001;
const Standard_Real Deflection = (hasCone) ? 0.085 : 0.1;
myIntersector.SetTolerances(TolArc, TolTang, UVMaxStep, Deflection);
//
RestrictLine = Standard_False;
//
}
if((myHS1->IsUClosed() && !myHS1->IsUPeriodic()) ||
(myHS1->IsVClosed() && !myHS1->IsVPeriodic()) ||
(myHS2->IsUClosed() && !myHS2->IsUPeriodic()) ||
(myHS2->IsVClosed() && !myHS2->IsVPeriodic())) {
(myHS2->IsVClosed() && !myHS2->IsVPeriodic()))
{
RestrictLine = Standard_True;
}
//
if(((aType1 != GeomAbs_BSplineSurface) &&
if((aType1 != GeomAbs_BSplineSurface) &&
(aType1 != GeomAbs_BezierSurface) &&
(aType1 != GeomAbs_OtherSurface)) &&
((aType2 != GeomAbs_BSplineSurface) &&
(aType1 != GeomAbs_OtherSurface) &&
(aType2 != GeomAbs_BSplineSurface) &&
(aType2 != GeomAbs_BezierSurface) &&
(aType2 != GeomAbs_OtherSurface))) {
(aType2 != GeomAbs_OtherSurface))
{
RestrictLine = Standard_True;
//
if ((aType1 == GeomAbs_Torus) ||
(aType2 == GeomAbs_Torus) ) {
(aType2 == GeomAbs_Torus))
{
myListOfPnts.Clear();
}
}
//
if(!RestrictLine) {
if(!RestrictLine)
{
TopExp_Explorer aExp;
//
for(i = 0; (!RestrictLine) && (i < 2); i++) {
for(Standard_Integer i = 0; (!RestrictLine) && (i < 2); i++)
{
const TopoDS_Face& aF=(!i) ? myFace1 : myFace2;
aExp.Init(aF, TopAbs_EDGE);
for(; aExp.More(); aExp.Next()) {
for(; aExp.More(); aExp.Next())
{
const TopoDS_Edge& aE=TopoDS::Edge(aExp.Current());
//
if(BRep_Tool::Degenerated(aE)) {
if(BRep_Tool::Degenerated(aE))
{
RestrictLine = Standard_True;
break;
}
}
}
}
//
myIntersector.Perform(myHS1, dom1, myHS2, dom2,
TolArc, TolTang,
myListOfPnts, RestrictLine);
//
const Standard_Boolean isGeomInt = isTreatAnalityc(aF1, aF2);
myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang,
myListOfPnts, RestrictLine, isGeomInt);
myIsDone = myIntersector.IsDone();
if (myIsDone) {
if (myIsDone)
{
myTangentFaces=myIntersector.TangentFaces();
if (myTangentFaces) {
return;
@ -692,8 +774,8 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
myListOfPnts.Clear(); // to use LineConstructor
}
//
aNbLin = myIntersector.NbLines();
for (i=1; i<=aNbLin; ++i) {
const Standard_Integer aNbLin = myIntersector.NbLines();
for (Standard_Integer i=1; i <= aNbLin; ++i) {
MakeCurve(i, dom1, dom2);
}
//
@ -702,43 +784,47 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
if (bReverse) {
Handle(Geom2d_Curve) aC2D1, aC2D2;
//
aNbLin=mySeqOfCurve.Length();
for (i=1; i<=aNbLin; ++i) {
const Standard_Integer aNbLin=mySeqOfCurve.Length();
for (Standard_Integer i=1; i<=aNbLin; ++i)
{
IntTools_Curve& aIC=mySeqOfCurve(i);
aC2D1=aIC.FirstCurve2d();
aC2D2=aIC.SecondCurve2d();
//
aIC.SetFirstCurve2d(aC2D2);
aIC.SetSecondCurve2d(aC2D1);
}
}
//
// Points
Standard_Real U1,V1,U2,V2;
IntTools_PntOnFace aPntOnF1, aPntOnF2;
IntTools_PntOn2Faces aPntOn2Faces;
//
aNbPnts=myIntersector.NbPnts();
for (i=1; i<=aNbPnts; ++i) {
const Standard_Integer aNbPnts = myIntersector.NbPnts();
for (Standard_Integer i=1; i <= aNbPnts; ++i)
{
const IntSurf_PntOn2S& aISPnt=myIntersector.Point(i).PntOn2S();
const gp_Pnt& aPnt=aISPnt.Value();
aISPnt.Parameters(U1,V1,U2,V2);
aPntOnF1.Init(myFace1, aPnt, U1, V1);
aPntOnF2.Init(myFace2, aPnt, U2, V2);
//
if (!bReverse) {
if (!bReverse)
{
aPntOn2Faces.SetP1(aPntOnF1);
aPntOn2Faces.SetP2(aPntOnF2);
}
else {
else
{
aPntOn2Faces.SetP2(aPntOnF1);
aPntOn2Faces.SetP1(aPntOnF2);
}
myPnts.Append(aPntOn2Faces);
}
//
}
}
//=======================================================================
//function :ComputeTolReached3d
//purpose :
@ -4657,10 +4743,7 @@ void ApproxParameters(const Handle(GeomAdaptor_HSurface)& aHS1,
//=======================================================================
void Tolerances(const Handle(GeomAdaptor_HSurface)& aHS1,
const Handle(GeomAdaptor_HSurface)& aHS2,
Standard_Real& ,//aTolArc,
Standard_Real& aTolTang,
Standard_Real& ,//aUVMaxStep,
Standard_Real& )//aDeflection)
Standard_Real& aTolTang)
{
GeomAbs_SurfaceType aTS1, aTS2;
//

View File

@ -1144,6 +1144,96 @@ static Standard_Integer OCC11758 (Draw_Interpretor& di, Standard_Integer n, cons
return 0;
}
#include <Geom_CylindricalSurface.hxx>
#include <IntTools_FaceFace.hxx>
#include <IntTools_Curve.hxx>
#include <IntTools_PntOn2Faces.hxx>
static Standard_Integer OCC24005 (Draw_Interpretor& theDI, Standard_Integer theNArg, const char** theArgv)
{
if(theNArg < 2)
{
theDI << "Wrong a number of arguments!\n";
return 1;
}
Handle_Geom_Plane plane(new Geom_Plane(
gp_Ax3( gp_Pnt(-72.948737453424499, 754.30437716359393, 259.52151854671678),
gp_Dir(6.2471473085930200e-007, -0.99999999999980493, 0.00000000000000000),
gp_Dir(0.99999999999980493, 6.2471473085930200e-007, 0.00000000000000000))));
Handle(Geom_CylindricalSurface) cylinder(
new Geom_CylindricalSurface(
gp_Ax3(gp_Pnt(-6.4812490053250649, 753.39408794522092, 279.16400974257465),
gp_Dir(1.0000000000000000, 0.0, 0.00000000000000000),
gp_Dir(0.0, 1.0000000000000000, 0.00000000000000000)),
19.712534607908712));
DrawTrSurf::Set("pln", plane);
theDI << "pln\n";
DrawTrSurf::Set("cyl", cylinder);
theDI << "cyl\n";
BRep_Builder builder;
TopoDS_Face face1, face2;
builder.MakeFace(face1, plane, Precision::Confusion());
builder.MakeFace(face2, cylinder, Precision::Confusion());
IntTools_FaceFace anInters;
anInters.SetParameters(false, true, true, Precision::Confusion());
anInters.Perform(face1, face2);
if (!anInters.IsDone())
{
theDI<<"No intersections found!"<<"\n";
return 1;
}
//Handle(Geom_Curve) aResult;
//gp_Pnt aPoint;
const IntTools_SequenceOfCurves& aCvsX=anInters.Lines();
const IntTools_SequenceOfPntOn2Faces& aPntsX=anInters.Points();
char buf[1024];
Standard_Integer aNbCurves, aNbPoints;
aNbCurves=aCvsX.Length();
aNbPoints=aPntsX.Length();
if (aNbCurves >= 2)
{
for (Standard_Integer i=1; i<=aNbCurves; ++i)
{
Sprintf(buf, "%s_%d",theArgv[1],i);
theDI << buf << " ";
const IntTools_Curve& aIC = aCvsX(i);
const Handle(Geom_Curve)& aC3D= aIC.Curve();
DrawTrSurf::Set(buf,aC3D);
}
}
else if (aNbCurves == 1)
{
const IntTools_Curve& aIC = aCvsX(1);
const Handle(Geom_Curve)& aC3D= aIC.Curve();
Sprintf(buf, "%s",theArgv[1]);
theDI << buf << " ";
DrawTrSurf::Set(buf,aC3D);
}
for (Standard_Integer i = 1; i<=aNbPoints; ++i)
{
const IntTools_PntOn2Faces& aPi=aPntsX(i);
const gp_Pnt& aP=aPi.P1().Pnt();
Sprintf(buf,"%s_p_%d",theArgv[1],i);
theDI << buf << " ";
DrawTrSurf::Set(buf, aP);
}
return 0;
}
void QABugs::Commands_19(Draw_Interpretor& theCommands) {
const char *group = "QABugs";
@ -1163,6 +1253,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
theCommands.Add("OCC23945", "OCC23945 surfname U V X Y Z [DUX DUY DUZ DVX DVY DVZ [D2UX D2UY D2UZ D2VX D2VY D2VZ D2UVX D2UVY D2UVZ]]", __FILE__, OCC23945,group);
theCommands.Add ("OCC24019", "OCC24019 aShape", __FILE__, OCC24019, group);
theCommands.Add ("OCC11758", "OCC11758", __FILE__, OCC11758, group);
theCommands.Add ("OCC24005", "OCC24005 result", __FILE__, OCC24005, group);
return;
}

35
tests/bugs/modalg_5/bug24005 Executable file
View File

@ -0,0 +1,35 @@
puts "============"
puts "OCC24005"
puts "============"
puts ""
###############################
## Intersecting a slightly off angle plane with a cylinder takes 7+ seconds
###############################
pload QAcommands
dchrono h reset
dchrono h start
OCC24005 result
dchrono h stop
set q [dchrono h show]
regexp {CPU user time: ([-0-9.+eE]+) seconds} $q full z
puts "$z"
set max_time 0.1
if { $z > ${max_time} } {
puts "Elapsed time is more than ${max_time} seconds - Faulty"
} else {
puts "Elapsed time is less than ${max_time} seconds - OK"
}
if { [regexp {Ellipse} [dump result]] == 1 } {
puts "result is OK"
} else {
puts "result is Faulty"
}
set 2dviewer 1