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

0027302: Invalid curves number in intersection result

1. In frame of the fix for #27282 issue, we have obtained several prolonged curves, which have common point(s). Fix for this issue joins these curves if it is possible.

2. ElCLib::InPeriod(...) method has been improved. Now it has become more faster (in general cases) and more reliable (in frame of  FLT_OVERFLOW and DIVISION_BY_ZERO cases processing).

Creation of test case for issue #27302
Test case tests\bugs\modalg_6\bug27282_2 has been adjusted in accordance with its new behavior.
This commit is contained in:
nbv 2016-03-29 16:38:53 +03:00 committed by bugmaster
parent 8b9a309b48
commit b8f67cc236
11 changed files with 645 additions and 278 deletions

View File

@ -48,20 +48,25 @@ static Standard_Real PIPI = M_PI + M_PI;
//=======================================================================
//function : InPeriod
//purpose :
//purpose : Value theULast is never returned.
//=======================================================================
Standard_Real ElCLib::InPeriod(const Standard_Real U,
const Standard_Real UFirst,
const Standard_Real ULast)
Standard_Real ElCLib::InPeriod(const Standard_Real theU,
const Standard_Real theUFirst,
const Standard_Real theULast)
{
Standard_Real u = U, period = ULast - UFirst;
Standard_Real Eps = Epsilon(period);
if( Precision::IsInfinite(theU) ||
Precision::IsInfinite(theUFirst) ||
Precision::IsInfinite(theULast))
{//In order to avoid FLT_Overflow exception
return theU;
}
while (Eps < (UFirst-u)) u += period;
while (Eps > (ULast -u)) u -= period;
if ( u < UFirst) u = UFirst;
return u;
const Standard_Real aPeriod = theULast - theUFirst;
if(aPeriod < Epsilon(theULast))
return theU;
return Max(theUFirst, theU + aPeriod*Ceiling((theUFirst-theU)/aPeriod));
}
//=======================================================================

View File

@ -1442,12 +1442,34 @@ void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& the
if(isQuadSet)
{
Bnd_Box2d aBx1, aBx2;
const Standard_Real aU1F = theS1->FirstUParameter(),
aU1L = theS1->LastUParameter(),
aV1F = theS1->FirstVParameter(),
aV1L = theS1->LastVParameter(),
aU2F = theS2->FirstUParameter(),
aU2L = theS2->LastUParameter(),
aV2F = theS2->FirstVParameter(),
aV2L = theS2->LastVParameter();
aBx1.Add(gp_Pnt2d(aU1F, aV1F));
aBx1.Add(gp_Pnt2d(aU1L, aV1F));
aBx1.Add(gp_Pnt2d(aU1L, aV1L));
aBx1.Add(gp_Pnt2d(aU1F, aV1L));
aBx2.Add(gp_Pnt2d(aU2F, aV2F));
aBx2.Add(gp_Pnt2d(aU2L, aV2F));
aBx2.Add(gp_Pnt2d(aU2L, aV2L));
aBx2.Add(gp_Pnt2d(aU2F, aV2L));
aBx1.Enlarge(Precision::PConfusion());
aBx2.Enlarge(Precision::PConfusion());
IntPatch_WLineTool::
ExtendTwoWlinesToEachOther(slin, Quad1, Quad2, TolTang,
theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
theS2->IsVPeriodic()? theS2->VPeriod() : 0.0);
theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
aBx1, aBx2);
}
for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)

View File

@ -45,8 +45,12 @@ class IntPatch_PointLine : public IntPatch_Line
public:
//! Adds a vertex in the list.
Standard_EXPORT virtual void AddVertex (const IntPatch_Point& Pnt) = 0;
//! Adds a vertex in the list. If theIsPrepend == TRUE the new
//! vertex will be added before the first element of vertices sequence.
//! Otherwise, to the end of the sequence
Standard_EXPORT virtual
void AddVertex (const IntPatch_Point& Pnt,
const Standard_Boolean theIsPrepend = Standard_False) = 0;
//! Returns the number of intersection points.
Standard_EXPORT virtual Standard_Integer NbPnts() const = 0;

View File

@ -58,8 +58,11 @@ public:
//! when the transitions are Undecided.
Standard_EXPORT IntPatch_RLine(const Standard_Boolean Tang);
//! To add a vertex in the list.
virtual void AddVertex (const IntPatch_Point& Pnt) Standard_OVERRIDE;
//! Adds a vertex in the list. If theIsPrepend == TRUE the new
//! vertex will be added before the first element of vertices sequence.
//! Otherwise, to the end of the sequence
virtual void AddVertex (const IntPatch_Point& Pnt,
const Standard_Boolean theIsPrepend = Standard_False) Standard_OVERRIDE;
//! Replaces the element of range Index in the list
//! of points.

View File

@ -32,9 +32,13 @@ inline const Handle(Adaptor2d_HCurve2d)& IntPatch_RLine::ArcOnS2() const
//-- Il faut mettre cet include ici , car l include fait un define Handle(Adaptor2d_HCurve2d) ...
//-- et en fin de fichier un undef Handle(Adaptor2d_HCurve2d) ...
inline void IntPatch_RLine::AddVertex (const IntPatch_Point& Pnt)
inline void IntPatch_RLine::AddVertex (const IntPatch_Point& thePnt,
const Standard_Boolean theIsPrepend)
{
svtx.Append(Pnt);
if(theIsPrepend)
svtx.Prepend(thePnt);
else
svtx.Append(thePnt);
}
inline void IntPatch_RLine::Replace (const Standard_Integer Index,

View File

@ -62,8 +62,11 @@ public:
//! transitions are Undecided.
Standard_EXPORT IntPatch_WLine(const Handle(IntSurf_LineOn2S)& Line, const Standard_Boolean Tang);
//! Adds a vertex in the list.
virtual void AddVertex (const IntPatch_Point& Pnt) Standard_OVERRIDE;
//! Adds a vertex in the list. If theIsPrepend == TRUE the new
//! vertex will be added before the first element of vertices sequence.
//! Otherwise, to the end of the sequence
virtual void AddVertex (const IntPatch_Point& Pnt,
const Standard_Boolean theIsPrepend = Standard_False) Standard_OVERRIDE;
//! Set the Point of index <Index> in the LineOn2S
Standard_EXPORT void SetPoint (const Standard_Integer Index, const IntPatch_Point& Pnt);

View File

@ -19,9 +19,13 @@
#include <IntPatch_Point.hxx>
inline void IntPatch_WLine::AddVertex (const IntPatch_Point& Pnt)
inline void IntPatch_WLine::AddVertex (const IntPatch_Point& thePnt,
const Standard_Boolean theIsPrepend)
{
svtx.Append(Pnt);
if(theIsPrepend)
svtx.Prepend(thePnt);
else
svtx.Append(thePnt);
}
inline void IntPatch_WLine::Replace (const Standard_Integer Index,

View File

@ -15,6 +15,19 @@
#include <Adaptor3d_HSurface.hxx>
#include <Adaptor3d_TopolTool.hxx>
#include <ElCLib.hxx>
//Bit-mask is used for information about
//the operation made in
//IntPatch_WLineTool::ExtendTwoWlinesToEachOther() method.
enum
{
IntPatchWT_EnAll = 0x00,
IntPatchWT_DisLastLast = 0x01,
IntPatchWT_DisLastFirst = 0x02,
IntPatchWT_DisFirstLast = 0x04,
IntPatchWT_DisFirstFirst = 0x08
};
//=======================================================================
//function : MinMax
@ -458,23 +471,24 @@ static Handle(IntPatch_WLine)
}
//=======================================================================
//function : IsSeam
//purpose : Returns:
// 0 - if interval [theU1, theU2] does not intersect the "seam-edge"
// or if "seam-edge" do not exist;
// 1 - if interval (theU1, theU2) intersect the "seam-edge".
// 2 - if theU1 or/and theU2 lie ON the "seam-edge"
//function : IsOnPeriod
//purpose : Checks, if [theU1, theU2] intersects the period-value
// (k*thePeriod, where k is an integer number (k = 0, +/-1, +/-2, ...).
//
// Returns:
// 0 - if interval [theU1, theU2] does not intersect the "period-value"
// or if thePeriod == 0.0;
// 1 - if interval (theU1, theU2) intersect the "period-value".
// 2 - if theU1 or/and theU2 lie ON the "period-value"
//
//ATTENTION!!!
// If (theU1 == theU2) then this function will return only both 0 or 2.
//
// Static subfunction in IsSeamOrBound.
//=======================================================================
static Standard_Integer IsSeam( const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Real thePeriod)
static Standard_Integer IsOnPeriod(const Standard_Real theU1,
const Standard_Real theU2,
const Standard_Real thePeriod)
{
if(IsEqual(thePeriod, 0.0))
if(thePeriod < RealSmall())
return 0;
//If interval [theU1, theU2] intersect seam-edge then there exists an integer
@ -590,16 +604,16 @@ static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
return Standard_True;
}
if(IsSeam(aU11, aU21, theU1Period))
if(IsOnPeriod(aU11, aU21, theU1Period))
return Standard_True;
if(IsSeam(aV11, aV21, theV1Period))
if(IsOnPeriod(aV11, aV21, theV1Period))
return Standard_True;
if(IsSeam(aU12, aU22, theU2Period))
if(IsOnPeriod(aU12, aU22, theU2Period))
return Standard_True;
if(IsSeam(aV12, aV22, theV2Period))
if(IsOnPeriod(aV12, aV22, theV2Period))
return Standard_True;
/*
@ -634,16 +648,16 @@ static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2))
return Standard_True;
if(IsSeam(aU1, aU1, theU1Period))
if(IsOnPeriod(aU1, aU1, theU1Period))
return Standard_True;
if(IsSeam(aU2, aU2, theU2Period))
if(IsOnPeriod(aU2, aU2, theU2Period))
return Standard_True;
if(IsSeam(aV1, aV1, theV1Period))
if(IsOnPeriod(aV1, aV1, theV1Period))
return Standard_True;
if(IsSeam(aV2, aV2, theV2Period))
if(IsOnPeriod(aV2, aV2, theV2Period))
return Standard_True;
return Standard_False;
@ -712,22 +726,42 @@ static Standard_Boolean IsIntersectionPoint(const gp_Pnt& thePmid,
//purpose : Adds thePOn2S to the begin of theWline
//=======================================================================
static void ExtendFirst(const Handle(IntPatch_WLine)& theWline,
const IntSurf_PntOn2S &thePOn2S)
const IntSurf_PntOn2S& theAddedPt)
{
theWline->Curve()->InsertBefore(1, thePOn2S);
IntPatch_Point &aVert = theWline->ChangeVertex(1);
Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
thePOn2S.Parameters(aU1, aV1, aU2, aV2);
theAddedPt.Parameters(aU1, aV1, aU2, aV2);
aVert.SetParameters(aU1, aV1, aU2, aV2);
aVert.SetValue(thePOn2S.Value());
for(Standard_Integer i = 2; i <= theWline->NbVertex(); i++)
if(theAddedPt.IsSame(theWline->Point(1), Precision::Confusion()))
{
IntPatch_Point &aV = theWline->ChangeVertex(i);
aV.SetParameter(aV.ParameterOnLine()+1);
theWline->Curve()->Value(1, theAddedPt);
for(Standard_Integer i = 1; i <= theWline->NbVertex(); i++)
{
IntPatch_Point &aVert = theWline->ChangeVertex(i);
if(aVert.ParameterOnLine() != 1)
break;
aVert.SetParameters(aU1, aV1, aU2, aV2);
aVert.SetValue(theAddedPt.Value());
}
return;
}
theWline->Curve()->InsertBefore(1, theAddedPt);
for(Standard_Integer i = 1; i <= theWline->NbVertex(); i++)
{
IntPatch_Point &aVert = theWline->ChangeVertex(i);
if(aVert.ParameterOnLine() == 1)
{
aVert.SetParameters(aU1, aV1, aU2, aV2);
aVert.SetValue(theAddedPt.Value());
}
else
{
aVert.SetParameter(aVert.ParameterOnLine()+1);
}
}
}
@ -736,18 +770,421 @@ static void ExtendFirst(const Handle(IntPatch_WLine)& theWline,
//purpose : Adds thePOn2S to the end of theWline
//=======================================================================
static void ExtendLast(const Handle(IntPatch_WLine)& theWline,
const IntSurf_PntOn2S &thePOn2S)
const IntSurf_PntOn2S& theAddedPt)
{
theWline->Curve()->Add(thePOn2S);
IntPatch_Point &aVert = theWline->ChangeVertex(theWline->NbVertex());
Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
theAddedPt.Parameters(aU1, aV1, aU2, aV2);
const Standard_Integer aNbPnts = theWline->NbPnts();
if(theAddedPt.IsSame(theWline->Point(aNbPnts), Precision::Confusion()))
{
theWline->Curve()->Value(aNbPnts, theAddedPt);
}
else
{
theWline->Curve()->Add(theAddedPt);
}
for(Standard_Integer i = theWline->NbVertex(); i >= 1; i--)
{
IntPatch_Point &aVert = theWline->ChangeVertex(i);
if(aVert.ParameterOnLine() != aNbPnts)
break;
aVert.SetParameters(aU1, aV1, aU2, aV2);
aVert.SetValue(theAddedPt.Value());
aVert.SetParameter(theWline->NbPnts());
}
}
//=========================================================================
// function: IsOutOfDomain
// purpose : Checks, if 2D-representation of thePOn2S is in surfaces domain,
// defined by bounding-boxes theBoxS1 and theBoxS2
//=========================================================================
static Standard_Boolean IsOutOfDomain(const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2,
const IntSurf_PntOn2S &thePOn2S,
const Standard_Real theU1Period,
const Standard_Real theU2Period,
const Standard_Real theV1Period,
const Standard_Real theV2Period)
{
Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
Standard_Real aU1min = 0.0, aU1max = 0.0, aV1min = 0.0, aV1max = 0.0;
Standard_Real aU2min = 0.0, aU2max = 0.0, aV2min = 0.0, aV2max = 0.0;
thePOn2S.Parameters(aU1, aV1, aU2, aV2);
aVert.SetParameters(aU1, aV1, aU2, aV2);
aVert.SetValue(thePOn2S.Value());
aVert.SetParameter(theWline->NbPnts());
theBoxS1.Get(aU1min, aV1min, aU1max, aV1max);
theBoxS2.Get(aU2min, aV2min, aU2max, aV2max);
aU1 = ElCLib::InPeriod(aU1, aU1min, aU1min + theU1Period);
aV1 = ElCLib::InPeriod(aV1, aV1min, aV1min + theV1Period);
aU2 = ElCLib::InPeriod(aU2, aU2min, aU2min + theU2Period);
aV2 = ElCLib::InPeriod(aV2, aV2min, aV2min + theV2Period);
return (theBoxS1.IsOut(gp_Pnt2d(aU1, aV1)) ||
theBoxS2.IsOut(gp_Pnt2d(aU2, aV2)));
}
//=======================================================================
//function : CheckArguments
//purpose : Check if extending is possible
// (see IntPatch_WLineTool::ExtendTwoWlinesToEachOther)
//=======================================================================
static Standard_Boolean CheckArguments(const IntSurf_Quadric& theS1,
const IntSurf_Quadric& theS2,
const IntSurf_PntOn2S& thePtWL1,
const IntSurf_PntOn2S& thePtWL2,
IntSurf_PntOn2S& theNewPoint,
const gp_Vec& theVec1,
const gp_Vec& theVec2,
const gp_Vec& theVec3,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2,
const Standard_Real theToler3D,
const Standard_Real theU1Period,
const Standard_Real theU2Period,
const Standard_Real theV1Period,
const Standard_Real theV2Period)
{
const Standard_Real aMaxAngle = M_PI/6; //30 degree
const Standard_Real aSqToler = theToler3D*theToler3D;
if(theVec3.SquareMagnitude() <= aSqToler)
{
return Standard_False;
}
if((theVec1.Angle(theVec2) > aMaxAngle) ||
(theVec1.Angle(theVec3) > aMaxAngle) ||
(theVec2.Angle(theVec3) > aMaxAngle))
{
return Standard_False;
}
const gp_Pnt aPmid(0.5*(thePtWL1.Value().XYZ()+thePtWL2.Value().XYZ()));
Standard_Real aU1=0.0, aV1=0.0, aU2=0.0, aV2=0.0;
theBoxS1.Get(aU1, aV1, aU2, aV2);
const Standard_Real aU1f = aU1, aV1f = aV1;
theBoxS2.Get(aU1, aV1, aU2, aV2);
const Standard_Real aU2f = aU1, aV2f = aV1;
if(!IsIntersectionPoint(aPmid, theS1, theS2, thePtWL1, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aU1, aV1, aU2, aV2))
{
return Standard_False;
}
theNewPoint.SetValue(aPmid, aU1, aV1, aU2, aV2);
if(IsOutOfDomain(theBoxS1, theBoxS2, theNewPoint,
theU1Period, theU2Period,
theV1Period, theV2Period))
{
return Standard_False;
}
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
thePtWL1.Parameters(aU11, aV11, aU21, aV21);
thePtWL2.Parameters(aU12, aV12, aU22, aV22);
if(IsOnPeriod(aU11 - aU1f, aU12 - aU1f, theU1Period) ||
IsOnPeriod(aV11 - aV1f, aV12 - aV1f, theV1Period) ||
IsOnPeriod(aU21 - aU2f, aU22 - aU2f, theU2Period) ||
IsOnPeriod(aV21 - aV2f, aV22 - aV2f, theV2Period))
{
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : ExtendTwoWLFirstFirst
//purpose : Performs extending theWLine1 and theWLine2 through their
// respecting start point.
//=======================================================================
static void ExtendTwoWLFirstFirst(const IntSurf_Quadric& theS1,
const IntSurf_Quadric& theS2,
const Handle(IntPatch_WLine)& theWLine1,
const Handle(IntPatch_WLine)& theWLine2,
const IntSurf_PntOn2S& thePtWL1,
const IntSurf_PntOn2S& thePtWL2,
const gp_Vec& theVec1,
const gp_Vec& theVec2,
const gp_Vec& theVec3,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2,
const Standard_Real theToler3D,
const Standard_Real theU1Period,
const Standard_Real theU2Period,
const Standard_Real theV1Period,
const Standard_Real theV2Period,
unsigned int &theCheckResult,
Standard_Boolean &theHasBeenJoined)
{
IntSurf_PntOn2S aPOn2S;
if(!CheckArguments(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
theVec1, theVec2, theVec3,
theBoxS1, theBoxS2, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period))
{
return;
}
theCheckResult |= (IntPatchWT_DisFirstLast | IntPatchWT_DisLastFirst);
ExtendFirst(theWLine1, aPOn2S);
ExtendFirst(theWLine2, aPOn2S);
if(theHasBeenJoined)
return;
Standard_Real aPrm = theWLine1->Vertex(1).ParameterOnLine();
while(theWLine1->Vertex(1).ParameterOnLine() == aPrm)
theWLine1->RemoveVertex(1);
aPrm = theWLine2->Vertex(1).ParameterOnLine();
while(theWLine2->Vertex(1).ParameterOnLine() == aPrm)
theWLine2->RemoveVertex(1);
const Standard_Integer aNbPts = theWLine2->NbPnts();
for(Standard_Integer aNPt = 2; aNPt <= aNbPts; aNPt++)
{
const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt);
theWLine1->Curve()->InsertBefore(1, aPt);
}
for(Standard_Integer aNVtx = 1; aNVtx <= theWLine1->NbVertex(); aNVtx++)
{
IntPatch_Point &aVert = theWLine1->ChangeVertex(aNVtx);
const Standard_Real aCurParam = aVert.ParameterOnLine();
aVert.SetParameter(aNbPts+aCurParam-1);
}
for(Standard_Integer aNVtx = 1; aNVtx <= theWLine2->NbVertex(); aNVtx++)
{
IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx);
const Standard_Real aCurParam = aVert.ParameterOnLine();
aVert.SetParameter(aNbPts-aCurParam+1);
theWLine1->AddVertex(aVert, Standard_True);
}
theHasBeenJoined = Standard_True;
}
//=======================================================================
//function : ExtendTwoWLFirstLast
//purpose : Performs extending theWLine1 through its start point and theWLine2
// through its end point.
//=======================================================================
static void ExtendTwoWLFirstLast(const IntSurf_Quadric& theS1,
const IntSurf_Quadric& theS2,
const Handle(IntPatch_WLine)& theWLine1,
const Handle(IntPatch_WLine)& theWLine2,
const IntSurf_PntOn2S& thePtWL1,
const IntSurf_PntOn2S& thePtWL2,
const gp_Vec& theVec1,
const gp_Vec& theVec2,
const gp_Vec& theVec3,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2,
const Standard_Real theToler3D,
const Standard_Real theU1Period,
const Standard_Real theU2Period,
const Standard_Real theV1Period,
const Standard_Real theV2Period,
unsigned int &theCheckResult,
Standard_Boolean &theHasBeenJoined)
{
IntSurf_PntOn2S aPOn2S;
if(!CheckArguments(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
theVec1, theVec2, theVec3,
theBoxS1, theBoxS2, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period))
{
return;
}
theCheckResult |= IntPatchWT_DisLastLast;
ExtendFirst(theWLine1, aPOn2S);
ExtendLast (theWLine2, aPOn2S);
if(theHasBeenJoined)
return;
Standard_Real aPrm = theWLine1->Vertex(1).ParameterOnLine();
while(theWLine1->Vertex(1).ParameterOnLine() == aPrm)
theWLine1->RemoveVertex(1);
aPrm = theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine();
while(theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine() == aPrm)
theWLine2->RemoveVertex(theWLine2->NbVertex());
const Standard_Integer aNbPts = theWLine2->NbPnts();
for(Standard_Integer aNPt = aNbPts - 1; aNPt >= 1; aNPt--)
{
const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt);
theWLine1->Curve()->InsertBefore(1, aPt);
}
for(Standard_Integer aNVtx = 1; aNVtx <= theWLine1->NbVertex(); aNVtx++)
{
IntPatch_Point &aVert = theWLine1->ChangeVertex(aNVtx);
const Standard_Real aCurParam = aVert.ParameterOnLine();
aVert.SetParameter(aNbPts+aCurParam-1);
}
for(Standard_Integer aNVtx = theWLine2->NbVertex(); aNVtx >= 1; aNVtx--)
{
const IntPatch_Point &aVert = theWLine2->Vertex(aNVtx);
theWLine1->AddVertex(aVert, Standard_True);
}
theHasBeenJoined = Standard_True;
}
//=======================================================================
//function : ExtendTwoWLLastFirst
//purpose : Performs extending theWLine1 through its end point and theWLine2
// through its start point.
//=======================================================================
static void ExtendTwoWLLastFirst(const IntSurf_Quadric& theS1,
const IntSurf_Quadric& theS2,
const Handle(IntPatch_WLine)& theWLine1,
const Handle(IntPatch_WLine)& theWLine2,
const IntSurf_PntOn2S& thePtWL1,
const IntSurf_PntOn2S& thePtWL2,
const gp_Vec& theVec1,
const gp_Vec& theVec2,
const gp_Vec& theVec3,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2,
const Standard_Real theToler3D,
const Standard_Real theU1Period,
const Standard_Real theU2Period,
const Standard_Real theV1Period,
const Standard_Real theV2Period,
unsigned int &theCheckResult,
Standard_Boolean &theHasBeenJoined)
{
IntSurf_PntOn2S aPOn2S;
if(!CheckArguments(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
theVec1, theVec2, theVec3,
theBoxS1, theBoxS2, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period))
{
return;
}
theCheckResult |= IntPatchWT_DisLastLast;
ExtendLast (theWLine1, aPOn2S);
ExtendFirst(theWLine2, aPOn2S);
if(theHasBeenJoined)
{
return;
}
Standard_Real aPrm = theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine();
while(theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine() == aPrm)
theWLine1->RemoveVertex(theWLine1->NbVertex());
aPrm = theWLine2->Vertex(1).ParameterOnLine();
while(theWLine2->Vertex(1).ParameterOnLine() == aPrm)
theWLine2->RemoveVertex(1);
const Standard_Integer aNbPts = theWLine1->NbPnts();
for(Standard_Integer aNPt = 2; aNPt <= theWLine2->NbPnts(); aNPt++)
{
const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt);
theWLine1->Curve()->Add(aPt);
}
for(Standard_Integer aNVtx = 1; aNVtx <= theWLine2->NbVertex(); aNVtx++)
{
IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx);
const Standard_Real aCurParam = aVert.ParameterOnLine();
aVert.SetParameter(aNbPts+aCurParam-1);
theWLine1->AddVertex(aVert, Standard_False);
}
theHasBeenJoined = Standard_True;
}
//=======================================================================
//function : ExtendTwoWLLastLast
//purpose :
//=======================================================================
static void ExtendTwoWLLastLast(const IntSurf_Quadric& theS1,
const IntSurf_Quadric& theS2,
const Handle(IntPatch_WLine)& theWLine1,
const Handle(IntPatch_WLine)& theWLine2,
const IntSurf_PntOn2S& thePtWL1,
const IntSurf_PntOn2S& thePtWL2,
const gp_Vec& theVec1,
const gp_Vec& theVec2,
const gp_Vec& theVec3,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2,
const Standard_Real theToler3D,
const Standard_Real theU1Period,
const Standard_Real theU2Period,
const Standard_Real theV1Period,
const Standard_Real theV2Period,
unsigned int &/*theCheckResult*/,
Standard_Boolean &theHasBeenJoined)
{
IntSurf_PntOn2S aPOn2S;
if(!CheckArguments(theS1, theS2, thePtWL1, thePtWL2, aPOn2S,
theVec1, theVec2, theVec3,
theBoxS1, theBoxS2, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period))
{
return;
}
//theCheckResult |= IntPatchWT_DisLastLast;
ExtendLast(theWLine1, aPOn2S);
ExtendLast(theWLine2, aPOn2S);
if(theHasBeenJoined)
return;
Standard_Real aPrm = theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine();
while(theWLine1->Vertex(theWLine1->NbVertex()).ParameterOnLine() == aPrm)
theWLine1->RemoveVertex(theWLine1->NbVertex());
aPrm = theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine();
while(theWLine2->Vertex(theWLine2->NbVertex()).ParameterOnLine() == aPrm)
theWLine2->RemoveVertex(theWLine2->NbVertex());
const Standard_Integer aNbPts = theWLine1->NbPnts() + theWLine2->NbPnts();
for(Standard_Integer aNPt = theWLine2->NbPnts()-1; aNPt >= 1; aNPt--)
{
const IntSurf_PntOn2S& aPt = theWLine2->Point(aNPt);
theWLine1->Curve()->Add(aPt);
}
for(Standard_Integer aNVtx = theWLine2->NbVertex(); aNVtx >= 1; aNVtx--)
{
IntPatch_Point &aVert = theWLine2->ChangeVertex(aNVtx);
const Standard_Real aCurParam = aVert.ParameterOnLine();
aVert.SetParameter(aNbPts - aCurParam);
theWLine1->AddVertex(aVert, Standard_False);
}
theHasBeenJoined = Standard_True;
}
//=========================================================================
@ -1054,7 +1491,8 @@ void IntPatch_WLineTool::JoinWLines(IntPatch_SequenceOfLine& theSlin,
//=======================================================================
//function : ExtendTwoWlinesToEachOther
//purpose :
//purpose : Performs extending theWLine1 and theWLine2 through their
// respecting end point.
//=======================================================================
void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& theSlin,
const IntSurf_Quadric& theS1,
@ -1063,15 +1501,13 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
const Standard_Real theU1Period,
const Standard_Real theU2Period,
const Standard_Real theV1Period,
const Standard_Real theV2Period)
const Standard_Real theV2Period,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2)
{
if(theSlin.Length() < 2)
return;
const Standard_Real aMaxAngle = M_PI/6; //30 degree
const Standard_Real aSqToler = theToler3D*theToler3D;
Standard_Real aU1=0.0, aV1=0.0, aU2=0.0, aV2=0.0;
gp_Pnt aPmid;
gp_Vec aVec1, aVec2, aVec3;
for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
@ -1086,6 +1522,12 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
if(aWLine1->Vertex(1).ParameterOnLine() != 1)
continue;
if(aWLine1->Vertex(aWLine1->NbVertex()).ParameterOnLine() != aWLine1->NbPnts())
continue;
for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1;
aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
{
@ -1095,21 +1537,20 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
if(aWLine2.IsNull())
continue;
if(aWLine2->Vertex(1).ParameterOnLine() != 1)
continue;
if(aWLine2->Vertex(aWLine2->NbVertex()).ParameterOnLine() != aWLine2->NbPnts())
continue;
//Enable/Disable of some ckeck. Bit-mask is used for it.
//E.g. if 1st point of aWLine1 matches with
//1st point of aWLine2 then we do not need in check
//1st point of aWLine1 and last point of aWLine2 etc.
enum
{
IntPatchWT_EnAll = 0x00,
IntPatchWT_DisLastLast = 0x01,
IntPatchWT_DisLastFirst = 0x02,
IntPatchWT_DisFirstLast = 0x04,
IntPatchWT_DisFirstFirst = 0x08
};
unsigned int aCheckResult = IntPatchWT_EnAll;
Standard_Boolean hasBeenJoined = Standard_False;
const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
@ -1130,55 +1571,11 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
aVec2.SetXYZ(aPntFWL2.Value().XYZ() - aPntFp1WL2.Value().XYZ());
aVec3.SetXYZ(aPntFWL1.Value().XYZ() - aPntFWL2.Value().XYZ());
if(aVec3.SquareMagnitude() > aSqToler)
{
if( (aVec1.Angle(aVec2) < aMaxAngle) &&
(aVec1.Angle(aVec3) < aMaxAngle) &&
(aVec2.Angle(aVec3) < aMaxAngle))
{
aPmid.SetXYZ(0.5*(aPntFWL1.Value().XYZ()+aPntFWL2.Value().XYZ()));
if(IsIntersectionPoint(aPmid, theS1, theS2, aPntFWL1, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aU1, aV1, aU2, aV2))
{
IntSurf_PntOn2S aPOn2S;
aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2);
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
aPntFWL1.Parameters(aU11, aV11, aU21, aV21);
aPntFWL2.Parameters(aU12, aV12, aU22, aV22);
if(!IsSeam(aU11, aU12, theU1Period) &&
!IsSeam(aV11, aV12, theV1Period) &&
!IsSeam(aU21, aU22, theU2Period) &&
!IsSeam(aV21, aV22, theV2Period))
{
aCheckResult |= (IntPatchWT_DisFirstLast |
IntPatchWT_DisLastFirst);
if(!aPOn2S.IsSame(aPntFWL1, Precision::Confusion()))
{
ExtendFirst(aWLine1, aPOn2S);
}
else
{
aWLine1->Curve()->Value(1, aPOn2S);
}
if(!aPOn2S.IsSame(aPntFWL2, Precision::Confusion()))
{
ExtendFirst(aWLine2, aPOn2S);
}
else
{
aWLine2->Curve()->Value(1, aPOn2S);
}
}
}
}
}//if(aVec3.SquareMagnitude() > aSqToler) cond.
}//if(!(aCheckResult & 0x08)) cond.
ExtendTwoWLFirstFirst(theS1, theS2, aWLine1, aWLine2, aPntFWL1, aPntFWL2,
aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aCheckResult, hasBeenJoined);
}
if(!(aCheckResult & IntPatchWT_DisFirstLast))
{// First/Last
@ -1186,54 +1583,11 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
aVec2.SetXYZ(aPntLWL2.Value().XYZ() - aPntLm1WL2.Value().XYZ());
aVec3.SetXYZ(aPntFWL1.Value().XYZ() - aPntLWL2.Value().XYZ());
if(aVec3.SquareMagnitude() > aSqToler)
{
if((aVec1.Angle(aVec2) < aMaxAngle) &&
(aVec1.Angle(aVec3) < aMaxAngle) &&
(aVec2.Angle(aVec3) < aMaxAngle))
{
aPmid.SetXYZ(0.5*(aPntFWL1.Value().XYZ()+aPntLWL2.Value().XYZ()));
if(IsIntersectionPoint(aPmid, theS1, theS2, aPntFWL1, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aU1, aV1, aU2, aV2))
{
IntSurf_PntOn2S aPOn2S;
aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2);
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
aPntFWL1.Parameters(aU11, aV11, aU21, aV21);
aPntLWL2.Parameters(aU12, aV12, aU22, aV22);
if(!IsSeam(aU11, aU12, theU1Period) &&
!IsSeam(aV11, aV12, theV1Period) &&
!IsSeam(aU21, aU22, theU2Period) &&
!IsSeam(aV21, aV22, theV2Period))
{
aCheckResult |= IntPatchWT_DisLastLast;
if(!aPOn2S.IsSame(aPntFWL1, Precision::Confusion()))
{
ExtendFirst(aWLine1, aPOn2S);
}
else
{
aWLine1->Curve()->Value(1, aPOn2S);
}
if(!aPOn2S.IsSame(aPntLWL2, Precision::Confusion()))
{
ExtendLast(aWLine2, aPOn2S);
}
else
{
aWLine2->Curve()->Value(aWLine2->NbPnts(), aPOn2S);
}
}
}
}
}//if(aVec3.SquareMagnitude() > aSqToler) cond.
}//if(!(aCheckResult & 0x04)) cond.
ExtendTwoWLFirstLast(theS1, theS2, aWLine1, aWLine2, aPntFWL1, aPntLWL2,
aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aCheckResult, hasBeenJoined);
}
if(!(aCheckResult & IntPatchWT_DisLastFirst))
{// Last/First
@ -1241,54 +1595,11 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
aVec2.SetXYZ(aPntFp1WL2.Value().XYZ() - aPntFWL2.Value().XYZ());
aVec3.SetXYZ(aPntFWL2.Value().XYZ() - aPntLWL1.Value().XYZ());
if(aVec3.SquareMagnitude() > aSqToler)
{
if((aVec1.Angle(aVec2) < aMaxAngle) &&
(aVec1.Angle(aVec3) < aMaxAngle) &&
(aVec2.Angle(aVec3) < aMaxAngle))
{
aPmid.SetXYZ(0.5*(aPntLWL1.Value().XYZ()+aPntFWL2.Value().XYZ()));
if(IsIntersectionPoint(aPmid, theS1, theS2, aPntLWL1, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aU1, aV1, aU2, aV2))
{
IntSurf_PntOn2S aPOn2S;
aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2);
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
aPntLWL1.Parameters(aU11, aV11, aU21, aV21);
aPntFWL2.Parameters(aU12, aV12, aU22, aV22);
if(!IsSeam(aU11, aU12, theU1Period) &&
!IsSeam(aV11, aV12, theV1Period) &&
!IsSeam(aU21, aU22, theU2Period) &&
!IsSeam(aV21, aV22, theV2Period))
{
aCheckResult |= IntPatchWT_DisLastLast;
if(!aPOn2S.IsSame(aPntLWL1, Precision::Confusion()))
{
ExtendLast(aWLine1, aPOn2S);
}
else
{
aWLine1->Curve()->Value(aWLine1->NbPnts(), aPOn2S);
}
if(!aPOn2S.IsSame(aPntFWL2, Precision::Confusion()))
{
ExtendFirst(aWLine2, aPOn2S);
}
else
{
aWLine2->Curve()->Value(1, aPOn2S);
}
}
}
}
}//if(aVec3.SquareMagnitude() > aSqToler) cond.
}//if(!(aCheckResult & 0x02)) cond.
ExtendTwoWLLastFirst(theS1, theS2, aWLine1, aWLine2, aPntLWL1, aPntFWL2,
aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aCheckResult, hasBeenJoined);
}
if(!(aCheckResult & IntPatchWT_DisLastLast))
{// Last/Last
@ -1296,52 +1607,17 @@ void IntPatch_WLineTool::ExtendTwoWlinesToEachOther(IntPatch_SequenceOfLine& the
aVec2.SetXYZ(aPntLm1WL2.Value().XYZ() - aPntLWL2.Value().XYZ());
aVec3.SetXYZ(aPntLWL2.Value().XYZ() - aPntLWL1.Value().XYZ());
if(aVec3.SquareMagnitude() > aSqToler)
{
if((aVec1.Angle(aVec2) < aMaxAngle) &&
(aVec1.Angle(aVec3) < aMaxAngle) &&
(aVec2.Angle(aVec3) < aMaxAngle))
{
aPmid.SetXYZ(0.5*(aPntLWL1.Value().XYZ()+aPntLWL2.Value().XYZ()));
if(IsIntersectionPoint(aPmid, theS1, theS2, aPntLWL1, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aU1, aV1, aU2, aV2))
{
IntSurf_PntOn2S aPOn2S;
aPOn2S.SetValue(aPmid, aU1, aV1, aU2, aV2);
ExtendTwoWLLastLast(theS1, theS2, aWLine1, aWLine2, aPntLWL1, aPntLWL2,
aVec1, aVec2, aVec3, theBoxS1, theBoxS2, theToler3D,
theU1Period, theU2Period, theV1Period, theV2Period,
aCheckResult, hasBeenJoined);
}
Standard_Real aU11 = 0.0, aV11 = 0.0, aU21 = 0.0, aV21 = 0.0,
aU12 = 0.0, aV12 = 0.0, aU22 = 0.0, aV22 = 0.0;
aPntLWL1.Parameters(aU11, aV11, aU21, aV21);
aPntLWL2.Parameters(aU12, aV12, aU22, aV22);
if(!IsSeam(aU11, aU12, theU1Period) &&
!IsSeam(aV11, aV12, theV1Period) &&
!IsSeam(aU21, aU22, theU2Period) &&
!IsSeam(aV21, aV22, theV2Period))
{
if(!aPOn2S.IsSame(aPntLWL1, Precision::Confusion()))
{
ExtendLast(aWLine1, aPOn2S);
}
else
{
aWLine1->Curve()->Value(aWLine1->NbPnts(), aPOn2S);
}
if(!aPOn2S.IsSame(aPntLWL2, Precision::Confusion()))
{
ExtendLast(aWLine2, aPOn2S);
}
else
{
aWLine2->Curve()->Value(aWLine2->NbPnts(), aPOn2S);
}
}
}
}
}//if(aVec3.SquareMagnitude() > aSqToler) cond.
}//if(!(aCheckResult & 0x01)) cond.
if(hasBeenJoined)
{
theSlin.Remove(aNumOfLine2);
aNumOfLine2--;
}
}
}
}

View File

@ -78,11 +78,9 @@ public:
const Standard_Real theVlSurf2);
//! Concatenates two some Walking lines from theSlin if it is possible.
//! This method does not create single line from several. It allows every
//! extended line to be started/finished in strictly determined point
//! (in the place of joint of two lines). As result, some gaps between two lines
//! will vanish.
//! Extends every line from theSlin (if it is possible) to be started/finished
//! in strictly determined point (in the place of joint of two lines).
//! As result, some gaps between two lines will vanish.
//! The Walking lines are supposed (algorithm will do nothing for not-Walking line)
//! to be computed as a result of intersection of two quadrics.
//! The quadrics definition is accepted in input parameters.
@ -93,7 +91,9 @@ public:
const Standard_Real theU1Period,
const Standard_Real theU2Period,
const Standard_Real theV1Period,
const Standard_Real theV2Period);
const Standard_Real theV2Period,
const Bnd_Box2d& theBoxS1,
const Bnd_Box2d& theBoxS2);
};
#endif

View File

@ -1,5 +1,3 @@
puts "TODO OCC27302 ALL: Error: Curve Number is bad!"
puts "============"
puts "OCC27282"
puts "============"
@ -8,7 +6,7 @@ puts ""
## [Regression to 6.9.1] smesh/bugs_00/A6: Cut produces an empty shape
###############################
set MaxTol 4.8106951786435371e-006
set MaxTol 4.8106952270863644e-006
set GoodNbCurv 1
restore [locate_data_file bug27282_cmpd.brep] a
@ -27,7 +25,7 @@ checkreal ToleranceReached ${Toler} ${MaxTol} 0.0 0.1
checkview -screenshot -2d -path ${imagedir}/${test_image}.png
if {${NbCurv} != ${GoodNbCurv}} {
puts "Error: Curve Number is bad!"
puts "Error: Number of curves is bad!"
for {set i 1} {$i < ${NbCurv}} {incr i} {
for {set j [expr $i+1]} {$j <= $NbCurv} {incr j} {
@ -43,5 +41,5 @@ if {${NbCurv} != ${GoodNbCurv}} {
}
}
} else {
checklength c_1 -l 833.56846559428755
checklength c_1 -l 833.56846557106064
}

View File

@ -0,0 +1,48 @@
puts "============"
puts "OCC27302"
puts "============"
puts ""
###############################
## Invalid curves number in intersection result
###############################
set MaxTol 9.9579577516847715e-005
set GoodNbCurv 1
restore [locate_data_file CTO900_pro12913a.rle] a
restore [locate_data_file CTO900_pro12913b.rle] b
explode a f
explode b f
smallview
don a_34 b_9
fit
set log [bopcurves a_34 b_9 -2d]
regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
checkreal ToleranceReached ${Toler} ${MaxTol} 0.0 0.1
checkview -screenshot -2d -path ${imagedir}/${test_image}.png
if {${NbCurv} != ${GoodNbCurv}} {
puts "Error: Number of curves is bad!"
for {set i 1} {$i < ${NbCurv}} {incr i} {
for {set j [expr $i+1]} {$j <= $NbCurv} {incr j} {
mkedge e1 c_$i
mkedge e2 c_$j
dset dd_val 100.0*${Toler}
distmini dd e1 e2
if { [dval dd_val] > ${Toler} } {
puts "Error: Intersection result is not closed"
}
}
}
} else {
checklength c_1 -l 86.536841230136204
}