1. VRange of intersection curve has been limited. As result, too oblong intersection curve(s) will be never returned.
2. Now, purger algorithm is not called for lines obtained by Geom-Geom intersection method.
3. New statuses are entered in IntPatch_ImpImpIntersection class. It makes intersection algorithm more informative and flexible for using.
4. Method IntPatch_ImpImpIntersection::GetStatus() has been created.
Tuning of test case bugs modalg_6/bug26894
DEFINE_STANDARD_ALLOC
-
+ enum IntStatus
+ {
+ //! OK. Good intersection result.
+ IntStatus_OK,
+
+ //! Intersection curve is too long (e.g. as in the bug #26894).
+ //! We cannot provide precise computation of value and
+ //! derivatives of this curve having used floating-point model
+ //! determined by IEEE 754 standard. As result, OCCT algorithms
+ //! cannot work with that curve correctly.
+ IntStatus_InfiniteSectionCurve,
+
+ //! Algorithm cannot finish correctly.
+ IntStatus_Fail
+ };
+
Standard_EXPORT IntPatch_ImpImpIntersection();
- //! Flag theIsReqToKeepRLine has been enterred only for
+ //! Flag theIsReqToKeepRLine has been entered only for
//! compatibility with TopOpeBRep package. It shall be deleted
//! after deleting TopOpeBRep.
//! When intersection result returns IntPatch_RLine and another
//! will always keep both lines even if they are coincided.
Standard_EXPORT IntPatch_ImpImpIntersection(const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_TopolTool)& D1, const Handle(Adaptor3d_HSurface)& S2, const Handle(Adaptor3d_TopolTool)& D2, const Standard_Real TolArc, const Standard_Real TolTang, const Standard_Boolean theIsReqToKeepRLine = Standard_False);
- //! Flag theIsReqToKeepRLine has been enterred only for
+ //! Flag theIsReqToKeepRLine has been entered only for
//! compatibility with TopOpeBRep package. It shall be deleted
//! after deleting TopOpeBRep.
//! When intersection result returns IntPatch_RLine and another
const Standard_Boolean theIsReqToKeepRLine =
Standard_False);
- //! Returns True if the calculus was succesfull.
- Standard_Boolean IsDone() const;
+ //! Returns True if the calculus was successful.
+ Standard_Boolean IsDone() const;
+
+ //! Returns status
+ IntStatus GetStatus() const;
//! Returns true if the is no intersection.
Standard_Boolean IsEmpty() const;
- Standard_Boolean done;
+ IntStatus myDone;
Standard_Boolean empt;
Standard_Boolean tgte;
Standard_Boolean oppo;
inline Standard_Boolean IntPatch_ImpImpIntersection::IsDone () const
{
- return done;
+ return (GetStatus() != IntStatus_Fail);
+}
+
+inline IntPatch_ImpImpIntersection::IntStatus
+ IntPatch_ImpImpIntersection::GetStatus() const
+{
+ return myDone;
}
inline Standard_Boolean IntPatch_ImpImpIntersection::IsEmpty () const
{
- if (!done) {StdFail_NotDone::Raise();}
+ if (!IsDone ()) { StdFail_NotDone::Raise(); }
return empt;
}
inline Standard_Boolean IntPatch_ImpImpIntersection::TangentFaces () const
{
- if (!done) {StdFail_NotDone::Raise();}
+ if (!IsDone ()) { StdFail_NotDone::Raise(); }
return tgte;
}
inline Standard_Boolean IntPatch_ImpImpIntersection::OppositeFaces () const
{
- if (!done) {StdFail_NotDone::Raise();}
+ if (!IsDone ()) { StdFail_NotDone::Raise(); }
if (!tgte) {Standard_DomainError::Raise();}
return oppo;
}
inline Standard_Integer IntPatch_ImpImpIntersection::NbPnts () const
{
- if (!done) {StdFail_NotDone::Raise();}
+ if (!IsDone ()) { StdFail_NotDone::Raise(); }
return spnt.Length();
}
inline const IntPatch_Point& IntPatch_ImpImpIntersection::Point (const Standard_Integer Index) const
{
- if (!done) {StdFail_NotDone::Raise();}
+ if (!IsDone ()) { StdFail_NotDone::Raise(); }
return spnt(Index);
}
inline Standard_Integer IntPatch_ImpImpIntersection::NbLines () const
{
- if (!done) {StdFail_NotDone::Raise();}
+ if (!IsDone ()) { StdFail_NotDone::Raise(); }
return slin.Length();
}
inline const Handle(IntPatch_Line)& IntPatch_ImpImpIntersection::Line (const Standard_Integer Index) const
{
- if (!done) {StdFail_NotDone::Raise();}
+ if (!IsDone ()) { StdFail_NotDone::Raise(); }
return slin(Index);
}
const Standard_Real);
-static Standard_Boolean IntCyCy(const IntSurf_Quadric& theQuad1,
- const IntSurf_Quadric& theQuad2,
- const Standard_Real theTol3D,
- const Standard_Real theTol2D,
- const Bnd_Box2d& theUVSurf1,
- const Bnd_Box2d& theUVSurf2,
- const Standard_Boolean isTheReverse,
- Standard_Boolean& isTheEmpty,
- Standard_Boolean& isTheSameSurface,
- Standard_Boolean& isTheMultiplePoint,
- IntPatch_SequenceOfLine& theSlin,
- IntPatch_SequenceOfPoint& theSPnt);
-
+static
+ IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
+ const IntSurf_Quadric& theQuad2,
+ const Standard_Real theTol3D,
+ const Standard_Real theTol2D,
+ const Bnd_Box2d& theUVSurf1,
+ const Bnd_Box2d& theUVSurf2,
+ const Standard_Boolean isTheReverse,
+ Standard_Boolean& isTheEmpty,
+ Standard_Boolean& isTheSameSurface,
+ Standard_Boolean& isTheMultiplePoint,
+ IntPatch_SequenceOfLine& theSlin,
+ IntPatch_SequenceOfPoint& theSPnt);
static Standard_Boolean IntCySp(const IntSurf_Quadric&,
const IntSurf_Quadric&,
//purpose :
//=======================================================================
IntPatch_ImpImpIntersection::IntPatch_ImpImpIntersection ():
- done(Standard_False)
+myDone(IntStatus_Fail)
{
}
//=======================================================================
const Standard_Real TolTang,
const Standard_Boolean theIsReqToKeepRLine)
{
- done = Standard_False;
+ myDone = IntStatus_Fail;
spnt.Clear();
slin.Clear();
//
case 22:
{ // Cylinder/Cylinder
- Standard_Boolean isDONE = Standard_False;
Bnd_Box2d aBox1, aBox2;
const Standard_Real aU1f = S1->FirstUParameter();
if(isReversed)
{
- isDONE = IntCyCy(quad2, quad1, TolTang, a2DTol, aBox2, aBox1,
+ myDone = IntCyCy(quad2, quad1, TolTang, a2DTol, aBox2, aBox1,
Standard_True, empt, SameSurf, multpoint, slin, spnt);
}
else
{
- isDONE = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
+ myDone = IntCyCy(quad1, quad2, TolTang, a2DTol, aBox1, aBox2,
Standard_False, empt, SameSurf, multpoint, slin, spnt);
}
- if (!isDONE)
+ if (myDone == IntPatch_ImpImpIntersection::IntStatus_Fail)
{
return;
}
}
//
if (bEmpty) {
- done = Standard_True;
+ if (myDone == IntStatus_Fail)
+ myDone = IntStatus_OK;
+
return;
}
//
}
//
oppo = quad1.Normale(Ptreference).Dot(quad2.Normale(Ptreference)) < 0.0;
- done = Standard_True;
+ myDone = IntStatus_OK;
return;
}// if (SameSurf || (all1 && all2)) {
}
}
}
- done = Standard_True;
+ myDone = IntStatus_OK;
}
//=======================================================================
//function : IntCyCy
//purpose :
//=======================================================================
-Standard_Boolean IntCyCy( const IntSurf_Quadric& theQuad1,
- const IntSurf_Quadric& theQuad2,
- const Standard_Real theTol3D,
- const Standard_Real theTol2D,
- const Bnd_Box2d& theUVSurf1,
- const Bnd_Box2d& theUVSurf2,
- const Standard_Boolean isTheReverse,
- Standard_Boolean& isTheEmpty,
- Standard_Boolean& isTheSameSurface,
- Standard_Boolean& isTheMultiplePoint,
- IntPatch_SequenceOfLine& theSlin,
- IntPatch_SequenceOfPoint& theSPnt)
+IntPatch_ImpImpIntersection::IntStatus IntCyCy(const IntSurf_Quadric& theQuad1,
+ const IntSurf_Quadric& theQuad2,
+ const Standard_Real theTol3D,
+ const Standard_Real theTol2D,
+ const Bnd_Box2d& theUVSurf1,
+ const Bnd_Box2d& theUVSurf2,
+ const Standard_Boolean isTheReverse,
+ Standard_Boolean& isTheEmpty,
+ Standard_Boolean& isTheSameSurface,
+ Standard_Boolean& isTheMultiplePoint,
+ IntPatch_SequenceOfLine& theSlin,
+ IntPatch_SequenceOfPoint& theSPnt)
{
isTheEmpty = Standard_True;
isTheSameSurface = Standard_False;
if (!anInter.IsDone())
{
- return Standard_False;
+ return IntPatch_ImpImpIntersection::IntStatus_Fail;
}
if(anInter.TypeInter() != IntAna_NoGeometricSolution)
{
- return CyCyAnalyticalIntersect( theQuad1, theQuad2, anInter,
- theTol3D, isTheReverse, isTheEmpty,
- isTheSameSurface, isTheMultiplePoint,
- theSlin, theSPnt);
+ if (CyCyAnalyticalIntersect(theQuad1, theQuad2, anInter,
+ theTol3D, isTheReverse, isTheEmpty,
+ isTheSameSurface, isTheMultiplePoint,
+ theSlin, theSPnt))
+ {
+ return IntPatch_ImpImpIntersection::IntStatus_OK;
+ }
}
Standard_Real aUSurf1f = 0.0, //const
Bnd_Range aRangeS1, aRangeS2;
aBoundWork.BoundaryEstimation(aCyl1, aCyl2, aRangeS1, aRangeS2);
if (aRangeS1.IsVoid() || aRangeS2.IsVoid())
- return Standard_True;
+ return IntPatch_ImpImpIntersection::IntStatus_OK;
+
+ {
+ //Quotation of the message from issue #26894 (author MSV):
+ //"We should return fail status from intersector if the result should be an
+ //infinite curve of non-analytical type... I propose to define the limit for the
+ //extent as the radius divided by 1e+2 and multiplied by 1e+7.
+ //Thus, taking into account the number of valuable digits (15), we provide reliable
+ //computations with an error not exceeding R/100."
+ const Standard_Real aF = 1.0e+5;
+ const Standard_Real aMaxV1Range = aF*aCyl1.Radius(), aMaxV2Range = aF*aCyl2.Radius();
+ if ((aRangeS1.Delta() > aMaxV1Range) || (aRangeS2.Delta() > aMaxV2Range))
+ return IntPatch_ImpImpIntersection::IntStatus_InfiniteSectionCurve;
+ }
//Boundaries
const Standard_Integer aNbOfBoundaries = 2;
Standard_Real aU1l[aNbOfBoundaries] = {Precision::Infinite(), Precision::Infinite()};
if(!aBoundWork.BoundariesComputing(aU1f, aU1l))
- return Standard_True;
+ return IntPatch_ImpImpIntersection::IntStatus_OK;
for(Standard_Integer i = 0; i < aNbOfBoundaries; i++)
{
}
}
- return Standard_True;
+ return IntPatch_ImpImpIntersection::IntStatus_OK;
}
//=======================================================================
if(aWL.IsNull())
continue;
+ if (!aWL->IsPurgingAllowed())
+ continue;
+
Handle(IntPatch_WLine) aRW =
IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
{
IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,
myTolArc,myTolTang, theIsReqToKeepRLine);
- const Standard_Boolean anIS = interii.IsDone();
- if (anIS)
+ if (interii.IsDone())
{
- done = anIS;
+ done = (interii.GetStatus() == IntPatch_ImpImpIntersection::IntStatus_OK);
empt = interii.IsEmpty();
if (!empt)
{
if(aWL.IsNull())
continue;
+ if (!aWL->IsPurgingAllowed())
+ continue;
+
Handle(IntPatch_WLine) aRW =
IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2, Standard_True);
--- /dev/null
+puts "================"
+puts "OCC26894"
+puts "================"
+puts ""
+#######################################################################
+# Intersection algorithm between two infinite cylinders is hanging
+#######################################################################
+
+# Attention!!!
+# The test on performance meter.
+# On the MASTER it takes:
+# Elapsed time: 0 Hours 0 Minutes 6.3723911111 Seconds
+# CPU user time: 6.15625 seconds
+# CPU system time: 0.0625 seconds
+
+# The intersection curve is almost infinite.
+# Therefore, we must have failed to return
+# any section curve (see comments to the issue #26894).
+set GoodNbCurv 0
+
+restore [locate_data_file bug26884-f1.brep] f1
+restore [locate_data_file bug26884-f2.brep] f2
+
+mksurface ss1 f1
+mksurface ss2 f2
+
+if { ![ catch {intersect result ss1 ss2 } ] } {
+ puts "Error: intersection algorithm must return fail status. But it is not."
+}
+
+set che [whatis result]
+set ind [string first "3d curve" $che]
+if {${ind} >= 0} {
+ #Only variable "result" exists
+ renamevar result result_1
+}
+
+set ic 1
+set AllowRepeate 1
+while { $AllowRepeate != 0 } {
+ set che [whatis result_$ic]
+ set ind [string first "3d curve" $che]
+ if {${ind} < 0} {
+ set AllowRepeate 0
+ } else {
+ display result_$ic
+
+ bounds result_$ic U1 U2
+
+ dump U1 U2
+
+ if {[dval U2-U1] < 1.0e-9} {
+ puts "Error: Wrong curve's range!"
+ }
+
+ xdistcs result_$ic ss1 U1 U2 10 1.0e-7
+ xdistcs result_$ic ss2 U1 U2 10 1.0e-7
+
+ incr ic
+ }
+}
+
+if {[expr {$ic - 1}] == $GoodNbCurv} {
+ puts "OK: Number of curves is good!"
+} else {
+ puts "Error: $GoodNbCurv is expected but [expr {$ic - 1}] is found!"
+}