1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

0029866: Intersector returns two overlapped curves as a result

Since now a new WLine is not created if its start point lies in another earlier computed WLine. It allows avoiding creation of duplicate WLines in the intersection result.

<!break>

1. Methods IsOutSurf1Box(...), IsOutSurf2Box(...), IsOutBox(...) for classes IntSurf_LineOn2S and IntPatch_RLine have been created.
This commit is contained in:
nbv
2018-07-03 18:14:30 +03:00
committed by bugmaster
parent 8ff2e494f5
commit 92a55b01af
15 changed files with 448 additions and 137 deletions

View File

@@ -99,20 +99,29 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
}
// modified by NIZHNY-MKK Fri Oct 27 12:32:38 2000.END
TheIWFunction aFuncForDuplicate = Func;
for (I = 1; I <= nbPath; I++) {
//start point of the progression
// if (wd1[I].etat > 11) {
// modified by NIZHNY-MKK Fri Oct 27 12:33:37 2000.BEGIN
if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) {
// modified by NIZHNY-MKK Fri Oct 27 12:33:43 2000.END
PathPnt = Pnts1.Value(I);
PathPnt = Pnts1.Value(I);
UVap(1) = wd1[I].ustart;
UVap(2) = wd1[I].vstart;
MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
{
wd1[I].etat = -Abs(wd1[I].etat); //mark point as processed
continue;
}
CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
CurrentLine->SetTangencyAtBegining(Standard_False);
Tgtend = Standard_False;
CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
UVap(1) = wd1[I].ustart;
UVap(2) = wd1[I].vstart;
MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
previousd3d = Func.Direction3d();
previousd2d = Func.Direction2d();
CurrentLine->AddPoint(previousPoint);
@@ -139,7 +148,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
// modified by NIZHNY-MKK Fri Oct 27 12:34:37 2000.END
// Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
wd1[I].etat = - abs(wd1[I].etat);
wd1[I].etat = -Abs(wd1[I].etat);
movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0;
// Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End
// first step of advancement

View File

@@ -118,12 +118,21 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
}
}
TheIWFunction aFuncForDuplicate = Func;
for (I = 1;I<=nbLoop;I++) {
if (wd2[I].etat > 12)
{ // start point of closed line
LoopPnt = Pnts2.Value(I);
previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed,
wd2[I].ustart,wd2[I].vstart);
previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt), reversed,
wd2[I].ustart, wd2[I].vstart);
if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate))
{
wd2[I].etat = -wd2[I].etat; //mark point as processed
continue;
}
previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);

View File

@@ -47,26 +47,25 @@ void IntWalk_IWalking::MakeWalkingPoint
// but F is updated according to U and V
// Case == other : the exception Standard_Failure is raised.
if (Case == 1)
Psol.SetValue(sp.Point(),reversed, U, V);
else if (Case == 2) {
Psol.SetValue(sp.Point(),reversed, U, V);
if ((Case == 1) || (Case == 2))
{
Psol.SetValue(sp.Point(), reversed, U, V);
}
else if (Case == 11 || Case == 12 ) {
else if (Case == 11 || Case == 12)
{
Standard_Real aUV[2], aFF[1], aDD[1][2];
math_Vector UV(aUV,1, 2);
math_Vector FF(aFF,1, 1);
math_Matrix DD(aDD,1, 1, 1, 2);
math_Vector UV(aUV, 1, 2);
math_Vector FF(aFF, 1, 1);
math_Matrix DD(aDD, 1, 1, 1, 2);
UV(1) = U;
UV(2) = V;
sp.Values(UV, FF, DD);
MakeWalkingPoint(Case - 10, U, V, sp, Psol);
MakeWalkingPoint(Case - 10, U, V, sp, Psol);
}
else {
else
{
throw Standard_ConstructionError();
}
}
@@ -167,3 +166,103 @@ Standard_Boolean IntWalk_IWalking::IsPointOnLine(const gp_Pnt2d& theP2d,
}
return Standard_False;
}
//==================================================================================
//function : IsPointOnLine
//purpose : Projects thePOn2S on the nearest segment of the already computed line.
// The retrieved projection point (aPa) is refined using theSolver.
// After the refinement, we will obtain a point aPb.
// If thePOn2S is quite far from aPb then thePOn2S is not
// in the line.
// Every already computed line is checked.
//==================================================================================
Standard_Boolean IntWalk_IWalking::IsPointOnLine(const IntSurf_PntOn2S& thePOn2S,
const math_Vector& theInfBounds,
const math_Vector& theSupBounds,
math_FunctionSetRoot& theSolver,
TheIWFunction& theFunc)
{
const gp_Pnt &aP3d = thePOn2S.Value();
for (Standard_Integer aLIdx = 1; aLIdx <= lines.Length(); aLIdx++)
{
const Handle(IntSurf_LineOn2S) &aL = lines(aLIdx)->Line();
if (aL->IsOutBox(aP3d))
continue;
//Look for the nearest segment
Standard_Real aUMin = 0.0, aVMin = 0.0;
Standard_Real aMinSqDist = RealLast();
for (Standard_Integer aPtIdx = 1; aPtIdx < aL->NbPoints(); aPtIdx++)
{
const gp_Pnt &aP1 = aL->Value(aPtIdx).Value();
const gp_Pnt &aP2 = aL->Value(aPtIdx + 1).Value();
const gp_XYZ aP1P(aP3d.XYZ() - aP1.XYZ());
const gp_XYZ aP1P2(aP2.XYZ() - aP1.XYZ());
const Standard_Real aSq12 = aP1P2.SquareModulus();
if (aSq12 < gp::Resolution())
continue;
const Standard_Real aDP = aP1P.Dot(aP1P2);
Standard_Real aSqD = RealLast();
if (aDP < 0.0)
{
//aSqD = aP1P.SquareModulus();
continue;
}
else if (aDP > aSq12)
{
//aSqD = (aP3d.XYZ() - aP2.XYZ()).SquareModulus();
continue;
}
else
{
aSqD = aP1P.CrossSquareMagnitude(aP1P2) / aSq12;
}
if (aSqD < aMinSqDist)
{
aMinSqDist = aSqD;
const Standard_Real aL1 = aDP / aSq12;
const Standard_Real aL2 = 1.0 - aL1;
Standard_Real aU1, aV1, aU2, aV2;
aL->Value(aPtIdx).ParametersOnSurface(reversed, aU1, aV1);
aL->Value(aPtIdx + 1).ParametersOnSurface(reversed, aU2, aV2);
aUMin = aL1*aU2 + aL2*aU1;
aVMin = aL1*aV2 + aL2*aV1;
}
}
if (aMinSqDist == RealLast())
continue;
math_Vector aVecPrms(1, 2);
aVecPrms(1) = aUMin;
aVecPrms(2) = aVMin;
theSolver.Perform(theFunc, aVecPrms, theInfBounds, theSupBounds);
if (!theSolver.IsDone())
continue;
theSolver.Root(aVecPrms);
const gp_Pnt aPa(theFunc.PSurface()->Value(aUMin, aVMin)),
aPb(theFunc.PSurface()->Value(aVecPrms(1), aVecPrms(2)));
const Standard_Real aSqD1 = aPb.SquareDistance(aP3d);
const Standard_Real aSqD2 = aPa.SquareDistance(aPb);
if (aSqD1 < 4.0*aSqD2)
{
return Standard_True;
}
}
return Standard_False;
}