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:
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user