if(PW.IsDone()) {
if(PW.NbPoints()>2)
{
- //Try to extend the intersection line to boundary, if it is possibly
- Standard_Boolean hasBeenAdded = PW.PutToBoundary(Surf1, Surf2);
+ //Try to extend the intersection line to boundary, if it is possible.
+ PW.PutToBoundary(Surf1, Surf2);
RejetLigne = Standard_False;
Point3dDebut = PW.Value(1).Value();
Standard_Real TolTang = TolTangency;
Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
if (RestrictLine){
- IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang,hasBeenAdded);
- IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang,hasBeenAdded);
+ IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
+ IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
}
if(wline->NbVertex() == 0) {
if( iPWNbPoints > 2 )
{
//Try to extend the intersection line to boundary, if it is possibly
- Standard_Boolean hasBeenAdded = PW.PutToBoundary(Surf1, Surf2);
+ PW.PutToBoundary(Surf1, Surf2);
const Standard_Integer aMinNbPoints = 40;
if(iPWNbPoints < aMinNbPoints)
{
- hasBeenAdded =
- PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints) || hasBeenAdded;
+ PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints);
iPWNbPoints = PW.NbPoints();
}
Standard_Real TolTang = TolTangency;
Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2);
- IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang,hasBeenAdded);
- IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang,hasBeenAdded);
-
+ IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang);
+ IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang);
if(wline->NbVertex() == 0)
{
IntPatch_Point vtx;
theIsUparallel = theIsVparallel = Standard_True;
- Standard_Integer aNbPoints = theLine->NbPoints();
+ const Standard_Integer aNbLinePnts = theLine->NbPoints();
+ Standard_Integer aNbPoints = aNbLinePnts;
if(aNbPoints > aNbPointsMAX)
{
aNbPoints = aNbPointsMAX;
Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst();
for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep)
{
- if(aNPoint > aNbPoints)
- {
- aNPoint = aNbPoints;
- }
+ // Fix possible "out of parameter" case.
+ if (aNPoint > aNbLinePnts)
+ aNPoint = aNbLinePnts;
Standard_Real u, v;
if(theCheckSurf1)
theIsUparallel = ((aVmax - aVmin) < theToler);
}
-//=======================================================================
-//function : Checking
-//purpose : Check, if given point is in surface's boundaries.
-// If "yes" then theFactTol = 0.0, else theFactTol is
-// equal maximal deviation.
-//=======================================================================
-static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1,
- const Handle(Adaptor3d_HSurface)& theASurf2,
- Standard_Real& theU1,
- Standard_Real& theV1,
- Standard_Real& theU2,
- Standard_Real& theV2,
- Standard_Real& theFactTol)
-{
- const Standard_Real aTol = Precision::PConfusion();
- const Standard_Real aU1bFirst = theASurf1->FirstUParameter();
- const Standard_Real aU1bLast = theASurf1->LastUParameter();
- const Standard_Real aU2bFirst = theASurf2->FirstUParameter();
- const Standard_Real aU2bLast = theASurf2->LastUParameter();
- const Standard_Real aV1bFirst = theASurf1->FirstVParameter();
- const Standard_Real aV1bLast = theASurf1->LastVParameter();
- const Standard_Real aV2bFirst = theASurf2->FirstVParameter();
- const Standard_Real aV2bLast = theASurf2->LastVParameter();
-
- Standard_Boolean isOnOrIn = Standard_True;
- theFactTol = 0.0;
-
- Standard_Real aDelta = aU1bFirst - theU1;
- if(aDelta > aTol)
- {
- theU1 = aU1bFirst;
- theFactTol = Max(theFactTol, aDelta);
- isOnOrIn = Standard_False;
- }
-
- aDelta = theU1 - aU1bLast;
- if(aDelta > aTol)
- {
- theU1 = aU1bLast;
- theFactTol = Max(theFactTol, aDelta);
- isOnOrIn = Standard_False;
- }
-
- aDelta = aV1bFirst - theV1;
- if(aDelta > aTol)
- {
- theV1 = aV1bFirst;
- theFactTol = Max(theFactTol, aDelta);
- isOnOrIn = Standard_False;
- }
-
- aDelta = theV1 - aV1bLast;
- if(aDelta > aTol)
- {
- theV1 = aV1bLast;
- theFactTol = Max(theFactTol, aDelta);
- isOnOrIn = Standard_False;
- }
-
- aDelta = aU2bFirst - theU2;
- if(aDelta > aTol)
- {
- theU2 = aU2bFirst;
- theFactTol = Max(theFactTol, aDelta);
- isOnOrIn = Standard_False;
- }
-
- aDelta = theU2 - aU2bLast;
- if(aDelta > aTol)
- {
- theU2 = aU2bLast;
- theFactTol = Max(theFactTol, aDelta);
- isOnOrIn = Standard_False;
- }
-
- aDelta = aV2bFirst - theV2;
- if(aDelta > aTol)
- {
- theV2 = aV2bFirst;
- theFactTol = Max(theFactTol, aDelta);
- isOnOrIn = Standard_False;
- }
-
- aDelta = theV2 - aV2bLast;
- if(aDelta > aTol)
- {
- theV2 = aV2bLast;
- theFactTol = Max(theFactTol, aDelta);
- isOnOrIn = Standard_False;
- }
-
- return isOnOrIn;
-}
-
//==================================================================================
// function : IntWalk_PWalking::IntWalk_PWalking
// purpose :
return (aSQDistPrev < aTol);
}
+//=======================================================================
+//function : HandleSingleSingularPoint
+//purpose :
+//=======================================================================
+Standard_Boolean IntWalk_PWalking::HandleSingleSingularPoint(const Handle(Adaptor3d_HSurface)& theASurf1,
+ const Handle(Adaptor3d_HSurface)& theASurf2,
+ const Standard_Real the3DTol,
+ TColStd_Array1OfReal &thePnt)
+{
+ // u1, v1, u2, v2 order is used.
+ Standard_Real aLowBorder[4] = {theASurf1->FirstUParameter(),
+ theASurf1->FirstVParameter(),
+ theASurf2->FirstUParameter(),
+ theASurf2->FirstVParameter()};
+ Standard_Real aUppBorder[4] = {theASurf1->LastUParameter(),
+ theASurf1->LastVParameter(),
+ theASurf2->LastUParameter(),
+ theASurf2->LastVParameter()};
+ IntImp_ConstIsoparametric aLockedDir[4] = {IntImp_UIsoparametricOnCaro1,
+ IntImp_VIsoparametricOnCaro1,
+ IntImp_UIsoparametricOnCaro2,
+ IntImp_VIsoparametricOnCaro2};
+
+ // Create new intersector with new tolerance.
+ IntWalk_TheInt2S anInt(theASurf1, theASurf2, the3DTol);
+ math_FunctionSetRoot aRsnld(anInt.Function());
+
+ for (Standard_Integer i = 1; i <= 4; ++i)
+ {
+ if ( Abs(thePnt(i) - aLowBorder[i - 1]) < Precision::PConfusion() ||
+ Abs(thePnt(i) - aUppBorder[i - 1]) < Precision::PConfusion())
+ {
+
+ anInt.Perform(thePnt,aRsnld, aLockedDir[i - 1]);
+
+ if (!anInt.IsDone())
+ continue;
+
+ if (anInt.IsEmpty())
+ continue;
+
+ anInt.Point().Parameters(thePnt(1), thePnt(2), thePnt(3), thePnt(4));
+ return Standard_True;
+ }
+ }
+
+ return Standard_False;
+}
+
//=======================================================================
//function : SeekPointOnBoundary
//purpose :
const Standard_Real theV2,
const Standard_Boolean isTheFirst)
{
- const Standard_Real aTol = 1.0e-14;
Standard_Boolean isOK = Standard_False;
- Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2;
- Standard_Boolean flFinish = Standard_False;
+ // Tune solution tolerance according with object size.
+ const Standard_Real aRes1 = Max(Precision::PConfusion() / theASurf1->UResolution(1.0),
+ Precision::PConfusion() / theASurf1->VResolution(1.0));
+ const Standard_Real aRes2 = Max(Precision::PConfusion() / theASurf2->UResolution(1.0),
+ Precision::PConfusion() / theASurf2->VResolution(1.0));
+ const Standard_Real a3DTol = Max(aRes1, aRes2);
+ const Standard_Real aTol = Max(Precision::Confusion(), a3DTol);
+
+ // u1, v1, u2, v2 order is used.
+ TColStd_Array1OfReal aPnt(1,4);
+ aPnt(1) = theU1; aPnt(2) = theV1; aPnt(3) = theU2; aPnt(4) = theV2;
+ TColStd_Array1OfReal aSingularPnt(aPnt);
Standard_Integer aNbIter = 20;
- while(!flFinish)
+ Standard_Boolean aStatus = Standard_False;
+ do
{
- flFinish = Standard_False;
- Standard_Boolean aStatus = Standard_False;
-
- do
- {
- aNbIter--;
- aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec);
- if(aStatus)
- {
- break;
- }
-
- aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec);
- if(aStatus)
- {
- break;
- }
-
- aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec);
- if(aStatus)
- {
- break;
- }
- }
- while(!aStatus && (aNbIter > 0));
+ aNbIter--;
+ aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, aPnt(1), aPnt(2), aPnt(3), aPnt(4));
+ if(aStatus)
+ break;
+ aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(aPnt(3), aPnt(4)), aPnt(1), aPnt(2));
if(aStatus)
- {
- const Standard_Real aTolMax = 1.0e-8;
- Standard_Real aTolF = 0.0;
+ break;
- Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec;
+ aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(aPnt(1), aPnt(2)), aPnt(3), aPnt(4));
+ if(aStatus)
+ break;
+ }
+ while(!aStatus && (aNbIter > 0));
- flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF);
+ // Handle singular points.
+ Standard_Boolean aSingularStatus = HandleSingleSingularPoint(theASurf1, theASurf2, aTol, aSingularPnt);
+ if (aSingularStatus)
+ aPnt = aSingularPnt;
- if(aTolF <= aTolMax)
- {
- gp_Pnt aP1 = theASurf1->Value(u1, v1),
- aP2 = theASurf2->Value(u2, v2);
- gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
+ if(aStatus || aSingularStatus)
+ {
+ gp_Pnt aP1 = theASurf1->Value(aPnt(1), aPnt(2)),
+ aP2 = theASurf2->Value(aPnt(3), aPnt(4));
+ gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ()));
- const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1),
- aSQDist2 = aPInt.SquareDistance(aP2);
- if((aSQDist1 < aTol) && (aSQDist2 < aTol))
- {
- IntSurf_PntOn2S anIP;
- anIP.SetValue(aPInt, u1, v1, u2, v2);
+ const Standard_Real aSQDist = aPInt.SquareDistance(aP1);
+ if (aSQDist < aTol * aTol)
+ {
+ IntSurf_PntOn2S anIP;
+ anIP.SetValue(aPInt, aPnt(1), aPnt(2), aPnt(3), aPnt(4));
- if(isTheFirst)
- line->InsertBefore(1,anIP);
- else
- line->Add(anIP);
+ if(isTheFirst)
+ line->InsertBefore(1,anIP);
+ else
+ line->Add(anIP);
- isOK = Standard_True;
- }
- }
+ isOK = Standard_True;
}
- else
- {
- break;
- }
-
- if(aNbIter < 0)
- break;
}
return isOK;
aDelta = u1 - aU1bFirst;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- u1 = aU1bFirst - aDelta;
+ u1 = aU1bFirst;
isNeedAdding = Standard_True;
}
else
aDelta = aU1bLast - u1;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- u1 = aU1bLast + aDelta;
+ u1 = aU1bLast;
isNeedAdding = Standard_True;
}
}
aDelta = u2 - aU2bFirst;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- u2 = aU2bFirst - aDelta;
+ u2 = aU2bFirst;
isNeedAdding = Standard_True;
}
else
aDelta = aU2bLast - u2;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- u2 = aU2bLast + aDelta;
+ u2 = aU2bLast;
isNeedAdding = Standard_True;
}
}
aDelta = v1 - aV1bFirst;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- v1 = aV1bFirst - aDelta;
+ v1 = aV1bFirst;
isNeedAdding = Standard_True;
}
else
aDelta = aV1bLast - v1;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- v1 = aV1bLast + aDelta;
+ v1 = aV1bLast;
isNeedAdding = Standard_True;
}
}
aDelta = v2 - aV2bFirst;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- v2 = aV2bFirst - aDelta;
+ v2 = aV2bFirst;
isNeedAdding = Standard_True;
}
else
aDelta = aV2bLast - v2;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- v2 = aV2bLast + aDelta;
+ v2 = aV2bLast;
isNeedAdding = Standard_True;
}
}
aDelta = u1 - aU1bFirst;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- u1 = aU1bFirst - aDelta;
+ u1 = aU1bFirst;
isNeedAdding = Standard_True;
}
else
aDelta = aU1bLast - u1;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- u1 = aU1bLast + aDelta;
+ u1 = aU1bLast;
isNeedAdding = Standard_True;
}
}
aDelta = u2 - aU2bFirst;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- u2 = aU2bFirst - aDelta;
+ u2 = aU2bFirst;
isNeedAdding = Standard_True;
}
else
aDelta = aU2bLast - u2;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- u2 = aU2bLast + aDelta;
+ u2 = aU2bLast;
isNeedAdding = Standard_True;
}
}
aDelta = v1 - aV1bFirst;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- v1 = aV1bFirst - aDelta;
+ v1 = aV1bFirst;
isNeedAdding = Standard_True;
}
else
aDelta = aV1bLast - v1;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- v1 = aV1bLast + aDelta;
+ v1 = aV1bLast;
isNeedAdding = Standard_True;
}
}
aDelta = v2 - aV2bFirst;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- v2 = aV2bFirst - aDelta;
+ v2 = aV2bFirst;
isNeedAdding = Standard_True;
}
else
aDelta = aV2bLast - v2;
if((aTolMin < aDelta) && (aDelta < aTol))
{
- v2 = aV2bLast + aDelta;
+ v2 = aV2bLast;
isNeedAdding = Standard_True;
}
}