1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0032066: Modeling Algorithms - Incorrect result of Boolean CUT operation

Use IWalking algorithm of OCCT 7.5.0
This commit is contained in:
azv
2021-02-19 22:24:50 +03:00
parent 9b0cd1bc40
commit 0281abc7ca
17 changed files with 467 additions and 96 deletions

View File

@@ -32,11 +32,19 @@ Contap_SurfFunction::Contap_SurfFunction ():
myMean(1.),
myType(Contap_ContourStd),
myDir(0.,0.,1.),
myAng(0.0),
myCosAng(0.), // PI/2 - Angle de depouille
tol(1.e-6),
valf(0.0),
Usol(0.0),
Vsol(0.0),
Fpu(0.0),
Fpv(0.0),
tangent(Standard_False),
computed(Standard_False),
derived(Standard_False)
{}
{
}
void Contap_SurfFunction::Set(const Handle(Adaptor3d_HSurface)& S)
{

View File

@@ -106,7 +106,11 @@ public:
const Handle(Adaptor3d_HSurface)& Surface() const;
//! Method is entered for compatibility with IntPatch_TheSurfFunction.
const Handle(Adaptor3d_HSurface)& PSurface() const
{
return Surface();
}
protected:

View File

@@ -49,6 +49,7 @@ class Adaptor3d_HSurfaceTool;
class Contap_SurfFunction;
class Contap_TheIWLineOfTheIWalking;
class IntSurf_PntOn2S;
class math_FunctionSetRoot;
class Contap_TheIWalking
{
@@ -150,7 +151,12 @@ protected:
//! Clears up internal containers
Standard_EXPORT void Clear();
//! Returns TRUE if thePOn2S is in one of existing lines.
Standard_EXPORT Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S& thePOn2S,
const math_Vector& theInfBounds,
const math_Vector& theSupBounds,
math_FunctionSetRoot& theSolver,
Contap_SurfFunction& theFunc);
private:

View File

@@ -49,6 +49,7 @@ class Adaptor3d_HSurfaceTool;
class IntPatch_TheSurfFunction;
class IntPatch_TheIWLineOfTheIWalking;
class IntSurf_PntOn2S;
class math_FunctionSetRoot;
class IntPatch_TheIWalking
{
@@ -150,6 +151,12 @@ protected:
//! Clears up internal containers
Standard_EXPORT void Clear();
//! Returns TRUE if thePOn2S is in one of existing lines.
Standard_EXPORT Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S& thePOn2S,
const math_Vector& theInfBounds,
const math_Vector& theSupBounds,
math_FunctionSetRoot& theSolver,
IntPatch_TheSurfFunction& theFunc);

View File

@@ -20,9 +20,13 @@
IMPLEMENT_STANDARD_RTTIEXT(IntSurf_LineOn2S,Standard_Transient)
IntSurf_LineOn2S::IntSurf_LineOn2S (const IntSurf_Allocator& theAllocator) :
mySeq (theAllocator)
{}
IntSurf_LineOn2S::
IntSurf_LineOn2S(const IntSurf_Allocator& theAllocator) : mySeq(theAllocator)
{
myBuv1.SetWhole();
myBuv2.SetWhole();
myBxyz.SetWhole();
}
Handle(IntSurf_LineOn2S) IntSurf_LineOn2S::Split (const Standard_Integer Index)
@@ -46,8 +50,167 @@ void IntSurf_LineOn2S::InsertBefore(const Standard_Integer index, const IntSurf_
else {
mySeq.InsertBefore(index,P);
}
if (!myBxyz.IsWhole())
{
myBxyz.Add(P.Value());
}
if (!myBuv1.IsWhole())
{
myBuv1.Add(P.ValueOnSurface(Standard_True));
}
if (!myBuv2.IsWhole())
{
myBuv2.Add(P.ValueOnSurface(Standard_False));
}
}
void IntSurf_LineOn2S::RemovePoint(const Standard_Integer index) {
mySeq.Remove(index);
myBuv1.SetWhole();
myBuv2.SetWhole();
myBxyz.SetWhole();
}
Standard_Boolean IntSurf_LineOn2S::IsOutBox(const gp_Pnt& Pxyz)
{
if (myBxyz.IsWhole())
{
Standard_Integer n = NbPoints();
myBxyz.SetVoid();
for (Standard_Integer i = 1; i <= n; i++)
{
gp_Pnt P = mySeq(i).Value();
myBxyz.Add(P);
}
Standard_Real x0, y0, z0, x1, y1, z1;
myBxyz.Get(x0, y0, z0, x1, y1, z1);
x1 -= x0; y1 -= y0; z1 -= z0;
if (x1>y1)
{
if (x1>z1)
{
myBxyz.Enlarge(x1*0.01);
}
else
{
myBxyz.Enlarge(z1*0.01);
}
}
else
{
if (y1>z1)
{
myBxyz.Enlarge(y1*0.01);
}
else
{
myBxyz.Enlarge(z1*0.01);
}
}
}
Standard_Boolean out = myBxyz.IsOut(Pxyz);
return(out);
}
Standard_Boolean IntSurf_LineOn2S::IsOutSurf1Box(const gp_Pnt2d& P1uv)
{
if (myBuv1.IsWhole())
{
Standard_Integer n = NbPoints();
Standard_Real pu1, pu2, pv1, pv2;
myBuv1.SetVoid();
for (Standard_Integer i = 1; i <= n; i++)
{
mySeq(i).Parameters(pu1, pv1, pu2, pv2);
myBuv1.Add(gp_Pnt2d(pu1, pv1));
}
myBuv1.Get(pu1, pv1, pu2, pv2);
pu2 -= pu1;
pv2 -= pv1;
if (pu2>pv2)
{
myBuv1.Enlarge(pu2*0.01);
}
else
{
myBuv1.Enlarge(pv2*0.01);
}
}
Standard_Boolean out = myBuv1.IsOut(P1uv);
return(out);
}
Standard_Boolean IntSurf_LineOn2S::IsOutSurf2Box(const gp_Pnt2d& P2uv)
{
if (myBuv2.IsWhole())
{
Standard_Integer n = NbPoints();
Standard_Real pu1, pu2, pv1, pv2;
myBuv2.SetVoid();
for (Standard_Integer i = 1; i <= n; i++)
{
mySeq(i).Parameters(pu1, pv1, pu2, pv2);
myBuv2.Add(gp_Pnt2d(pu2, pv2));
}
myBuv2.Get(pu1, pv1, pu2, pv2);
pu2 -= pu1;
pv2 -= pv1;
if (pu2>pv2)
{
myBuv2.Enlarge(pu2*0.01);
}
else
{
myBuv2.Enlarge(pv2*0.01);
}
}
Standard_Boolean out = myBuv2.IsOut(P2uv);
return(out);
}
//=======================================================================
//function : Add
//purpose :
//=======================================================================
void IntSurf_LineOn2S::Add(const IntSurf_PntOn2S& P)
{
mySeq.Append(P);
if (!myBxyz.IsWhole())
{
myBxyz.Add(P.Value());
}
if (!myBuv1.IsWhole())
{
myBuv1.Add(P.ValueOnSurface(Standard_True));
}
if (!myBuv2.IsWhole())
{
myBuv2.Add(P.ValueOnSurface(Standard_False));
}
}
//=======================================================================
//function : SetUV
//purpose :
//=======================================================================
void IntSurf_LineOn2S::SetUV(const Standard_Integer Index,
const Standard_Boolean OnFirst,
const Standard_Real U,
const Standard_Real V)
{
mySeq(Index).SetValue(OnFirst, U, V);
if (OnFirst && !myBuv1.IsWhole())
{
myBuv1.Add(gp_Pnt2d(U, V));
}
else if (!OnFirst && !myBuv2.IsWhole())
{
myBuv2.Add(gp_Pnt2d(U, V));
}
}

View File

@@ -20,6 +20,8 @@
#include <Standard.hxx>
#include <Standard_Type.hxx>
#include <Bnd_Box.hxx>
#include <Bnd_Box2d.hxx>
#include <IntSurf_SequenceOfPntOn2S.hxx>
#include <Standard_Transient.hxx>
#include <IntSurf_Allocator.hxx>
@@ -43,7 +45,7 @@ public:
Standard_EXPORT IntSurf_LineOn2S(const IntSurf_Allocator& theAllocator = 0);
//! Adds a point in the line.
void Add (const IntSurf_PntOn2S& P);
Standard_EXPORT void Add(const IntSurf_PntOn2S& P);
//! Returns the number of points in the line.
Standard_Integer NbPoints() const;
@@ -63,7 +65,7 @@ public:
//! Sets the parametric coordinates on one of the surfaces
//! of the point of range Index in the line.
void SetUV (const Standard_Integer Index, const Standard_Boolean OnFirst, const Standard_Real U, const Standard_Real V);
Standard_EXPORT void SetUV(const Standard_Integer Index, const Standard_Boolean OnFirst, const Standard_Real U, const Standard_Real V);
void Clear();
@@ -71,8 +73,16 @@ public:
Standard_EXPORT void RemovePoint (const Standard_Integer I);
//! Returns TRUE if theP is out of the box built from
//! the points on 1st surface
Standard_EXPORT Standard_Boolean IsOutSurf1Box(const gp_Pnt2d& theP);
//! Returns TRUE if theP is out of the box built from
//! the points on 2nd surface
Standard_EXPORT Standard_Boolean IsOutSurf2Box(const gp_Pnt2d& theP);
//! Returns TRUE if theP is out of the box built from 3D-points.
Standard_EXPORT Standard_Boolean IsOutBox(const gp_Pnt& theP);
DEFINE_STANDARD_RTTIEXT(IntSurf_LineOn2S,Standard_Transient)
@@ -85,7 +95,9 @@ private:
IntSurf_SequenceOfPntOn2S mySeq;
Bnd_Box2d myBuv1;
Bnd_Box2d myBuv2;
Bnd_Box myBxyz;
};

View File

@@ -14,15 +14,6 @@
#include <IntSurf_PntOn2S.hxx>
inline void IntSurf_LineOn2S::Add(const IntSurf_PntOn2S& P) {
mySeq.Append(P);
}
inline Standard_Integer IntSurf_LineOn2S::NbPoints() const {
return mySeq.Length();
@@ -47,16 +38,11 @@ inline void IntSurf_LineOn2S::Value(const Standard_Integer Index,
mySeq(Index) = P;
}
inline void IntSurf_LineOn2S::SetUV(const Standard_Integer Index,
const Standard_Boolean OnFirst,
const Standard_Real U,
const Standard_Real V)
{
mySeq(Index).SetValue(OnFirst,U,V);
}
inline void IntSurf_LineOn2S::Clear ()
{
mySeq.Clear();
myBuv1.SetWhole();
myBuv2.SetWhole();
myBxyz.SetWhole();
}

View File

@@ -19,7 +19,7 @@
inline void IntWalk_IWLine::Cut(const Standard_Integer Index)
{
//-- cout<<" split : "<<Index<<endl;
//-- std::cout<<" split : "<<Index<<std::endl;
Handle(IntSurf_LineOn2S) lost = line->Split(Index);
}
@@ -146,7 +146,7 @@ inline void IntWalk_IWLine::SetTangentVector (const gp_Vec& V,
indextg = Index;
vcttg = V;
//-- cout<<"\n IntWalk_IWLine::SetTangentVector : "<<V.X()<<" "<<V.Y()<<" "<<V.Z()<<" Ind:"<<Index<<" NbPts:"<<NbPoints()<<endl;
//-- std::cout<<"\n IntWalk_IWLine::SetTangentVector : "<<V.X()<<" "<<V.Y()<<" "<<V.Z()<<" Ind:"<<Index<<" NbPts:"<<NbPoints()<<std::endl;
}
@@ -165,7 +165,7 @@ inline void IntWalk_IWLine::SetTangencyAtEnd
inline const gp_Vec& IntWalk_IWLine::TangentVector
(Standard_Integer& Index) const {
//-- if(istgtend == Standard_False && istgtbeg == Standard_False) {
//-- cout<<" IntWalk_IWLine.lxx : Pb "<<endl;
//-- std::cout<<" IntWalk_IWLine.lxx : Pb "<<std::endl;
//-- }
Index = indextg;
return vcttg;

View File

@@ -59,7 +59,7 @@ static Standard_Boolean IsTangentExtCheck(TheIWFunction& theFunc,
if(!theFunc.Value(aX, aVal))
continue;
if(aVal(1) > aTol)
if(Abs(theFunc.Root()) > aTol)
return Standard_False;
}
@@ -77,9 +77,14 @@ IntWalk_IWalking::IntWalk_IWalking (const Standard_Real Epsilon,
pas(Increment),
tolerance(1,2),
epsilon(Epsilon*Epsilon),
reversed(Standard_False),
wd1 (IntWalk_VectorOfWalkingData::allocator_type (new NCollection_IncAllocator)),
wd2 (wd1.get_allocator()),
nbMultiplicities (wd1.get_allocator()),
Um(0.0),
UM(0.0),
Vm(0.0),
VM(0.0),
ToFillHoles(theToFillHoles)
{
}

View File

@@ -141,7 +141,7 @@ Standard_Boolean IntWalk_IWalking::Cadrage
}
BornSup(1) = BornInf(1); // limit the parameter
UVap(1) = BornInf(1);
UVap(2) += Step*Duvy*StepSign;;
UVap(2) += Step*Duvy*StepSign;
return Standard_True;
}
else if (supu) { // jag 940616
@@ -392,8 +392,13 @@ Standard_Boolean IntWalk_IWalking::TestArretPassage
//Normalizing factor. If it is less than 1.0 then the range will be expanded.
//This is no good for computation. Therefore, it is limited.
const Standard_Real deltau = mySRangeU.IsVoid() ? UM - Um : Max(mySRangeU.Delta(), 1.0);
const Standard_Real deltav = mySRangeV.IsVoid() ? VM - Vm : Max(mySRangeV.Delta(), 1.0);
//Do not limit these factor in case of highly anisotropic parametrization
//(parametric space is considerably larger in one direction than another).
Standard_Boolean isHighlyAnisotropic = Max(tolu, tolv) > 1000. * Min(tolu, tolv);
Standard_Real deltau = mySRangeU.IsVoid() ? UM - Um
: (isHighlyAnisotropic ? mySRangeU.Delta() : Max(mySRangeU.Delta(), 1.0));
Standard_Real deltav = mySRangeV.IsVoid() ? VM - Vm
: (isHighlyAnisotropic ? mySRangeV.Delta() : Max(mySRangeV.Delta(), 1.0));
Up/=deltau; UV1/=deltau;
Vp/=deltav; UV2/=deltav;
@@ -833,7 +838,7 @@ void IntWalk_IWalking::TestArretCadre
}
#ifdef OCCT_DEBUG
else {
cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<endl;
std::cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<std::endl;
}
#endif
}

View File

@@ -74,7 +74,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
Handle(IntWalk_TheIWLine) CurrentLine; // line under construction
Standard_Boolean Tgtend;
IntWalk_StatusDeflection aStatus, StatusPrecedent;
IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent = IntWalk_OK;
Standard_Integer NbDivision;
// number of divisions of step for each section
@@ -99,6 +99,8 @@ 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) {
@@ -106,13 +108,20 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
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);
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);
@@ -439,7 +448,9 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
Standard_False,Standard_False);
CurrentLine->AddPoint(CurrentLine->Value(1));
}
else if (N >0) { //point of stop given at input
else if ((N >0) && (Pnts1.Length() >= N))
{
//point of stop given at input
PathPnt = Pnts1.Value(N);
CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
AddPointInCurrentLine(N,PathPnt,CurrentLine);

View File

@@ -74,18 +74,19 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
gp_Vec Corde(previousPoint.Value(), sp.Point());
const Standard_Real Norme = Corde.SquareMagnitude(),
aTol = epsilon*Precision::PConfusion();
const Standard_Real Norme = Corde.SquareMagnitude();
//if ((++NbPointsConfondusConsecutifs < 10) && (Norme <= epsilon)) { // the square is already taken in the constructor
if ((Norme <= epsilon) && ((Duv <= aTol) || (StatusPrecedent != IntWalk_OK)))
if ((Norme <= 4.0*Precision::SquareConfusion()) &&
((Duv <= Precision::SquarePConfusion()) || (StatusPrecedent != IntWalk_OK)))
{ // the square is already taken in the constructor
aStatus = IntWalk_PointConfondu;
if (StatusPrecedent == IntWalk_PasTropGrand) {
if (StatusPrecedent == IntWalk_PasTropGrand)
{
return IntWalk_ArretSurPointPrecedent;
}
}
else {
else
{
Standard_Real Cosi = Corde * previousd3d;
Standard_Real Cosi2 = 0.0;

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);
}
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;
}

View File

@@ -202,10 +202,15 @@ IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
done(Standard_True),
close(Standard_False),
tgfirst(Standard_False),
tglast(Standard_False),
myTangentIdx(0),
fleche(Deflection),
pasMax(0.0),
tolconf(Epsilon),
myTolTang(TolTangency),
sensCheminement(1),
previoustg(Standard_False),
myIntersectionOn2S(Caro1,Caro2,TolTangency),
STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
STATIC_PRECEDENT_INFLEXION(0)
@@ -758,10 +763,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
Standard_Integer LevelOfIterWithoutAppend = -1;
//
const Standard_Real aTol[4] = { Epsilon(u1max - u1min),
Epsilon(v1max - v1min),
Epsilon(u2max - u2min),
Epsilon(v2max - v2min)};
const Standard_Real aTol[4] = { Epsilon(UM1 - Um1),
Epsilon(VM1 - Vm1),
Epsilon(UM2 - Um2),
Epsilon(VM2 - Vm2)};
Standard_Integer aPrevNbPoints = line->NbPoints();
Arrive = Standard_False;
while(!Arrive) //010
{
@@ -853,8 +861,8 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
Standard_Real aNewPnt[4], anAbsParamDist[4];
myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]);
const Standard_Real aParMin[4] = {u1min, v1min, u2min, v2min};
const Standard_Real aParMax[4] = {u1max, v1max, u2max, v2max};
const Standard_Real aParMin[4] = {Um1, Vm1, Um2, Vm2};
const Standard_Real aParMax[4] = {UM1, VM1, UM2, VM2};
for(Standard_Integer i = 0; i < 4; i++)
{
@@ -864,12 +872,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
aNewPnt[i] = aParMax[i];
}
if (aNewPnt[0] < u1min || aNewPnt[0] > u1max ||
aNewPnt[1] < v1min || aNewPnt[1] > v1max ||
aNewPnt[2] < u2min || aNewPnt[2] > u2max ||
aNewPnt[3] < v2min || aNewPnt[3] > v2max)
if (aNewPnt[0] < Um1 || aNewPnt[0] > UM1 ||
aNewPnt[1] < Vm1 || aNewPnt[1] > VM1 ||
aNewPnt[2] < Um2 || aNewPnt[2] > UM2 ||
aNewPnt[3] < Vm2 || aNewPnt[3] > VM2)
{
break; // Out of borders, handle this later.
// Out of borders, process it later.
break;
}
myIntersectionOn2S.ChangePoint().SetValue(aNewPnt[0],
@@ -959,7 +968,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
LevelOfEmptyInmyIntersectionOn2S=0;
if(LevelOfIterWithoutAppend < 10)
{
aStatus = TestDeflection(ChoixIso);
aStatus = TestDeflection(ChoixIso, aStatus);
}
else
{
@@ -1098,7 +1107,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
if(aDelta > Epsilon(pasInit[i]))
{
pasInit[i] -= aDelta;
LevelOfIterWithoutAppend=0;
if ((aPrevStatus != IntWalk_StepTooSmall) &&
(line->NbPoints() != aPrevNbPoints))
{
LevelOfIterWithoutAppend = 0;
}
aPrevNbPoints = line->NbPoints();
}
}
}
@@ -1173,8 +1188,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
// StepTooSmall --> Increase step --> PasTropGrand...)
// nullify LevelOfIterWithoutAppend only if the condition
// is satisfied:
if (aPrevStatus != IntWalk_PasTropGrand)
if ((aPrevStatus != IntWalk_PasTropGrand) &&
(line->NbPoints() != aPrevNbPoints))
{
LevelOfIterWithoutAppend = 0;
}
aPrevNbPoints = line->NbPoints();
break;
}
@@ -1195,7 +1215,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
{
Arrive=Standard_True;
#ifdef OCCT_DEBUG
cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<endl;
std::cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<std::endl;
#endif
}
@@ -1690,7 +1710,7 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop
if((nbIterWithoutAppend > 20) || (nbEqualPoints > 20)) {
#ifdef OCCT_DEBUG
cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl;
std::cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << std::endl;
#endif
bStop = Standard_True;
break;
@@ -1740,7 +1760,7 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop
return bOutOfTangentZone;
}
aStatus = TestDeflection(ChoixIso);
aStatus = TestDeflection(ChoixIso, aStatus);
if(aStatus == IntWalk_OK) {
@@ -2981,7 +3001,8 @@ namespace {
static const Standard_Real d = 7.0;
}
IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIsoparametric choixIso)
IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIsoparametric choixIso,
const IntWalk_StatusDeflection theStatus)
// test if vector is observed by calculating an increase of vector
// or the previous point and its tangent, the new calculated point and its
@@ -3376,7 +3397,8 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIso
const Standard_Real anInvSqAbsArcDeflMin = 4.0*anInvSqAbsArcDeflMax;
const Standard_Real aSinB2Min = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMin);
if((aSinB2Min < 0.0) || (aCosBetweenTangent >= 2.0 * aSinB2Min * aSinB2Min - 1.0))
if (theStatus != IntWalk_PasTropGrand &&
((aSinB2Min < 0.0) || (aCosBetweenTangent >= 2.0 * aSinB2Min * aSinB2Min - 1.0)))
{//Real deflection is less than tolconf/2.0
aStatus = IntWalk_StepTooSmall;
}

View File

@@ -66,7 +66,12 @@ public:
//! border of one of the domains. If an open line
//! stops at the middle of a domain, one stops at the tangent point.
//! Epsilon is SquareTolerance of points confusion.
Standard_EXPORT IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_HSurface)& Caro2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment);
Standard_EXPORT IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
const Handle(Adaptor3d_HSurface)& Caro2,
const Standard_Real TolTangency,
const Standard_Real Epsilon,
const Standard_Real Deflection,
const Standard_Real Increment);
//! Returns the intersection line containing the exact
//! point Poin. This line is a polygonal line.
@@ -81,7 +86,16 @@ public:
//! border of one of the domains. If an open line
//! stops at the middle of a domain, one stops at the tangent point.
//! Epsilon is SquareTolerance of points confusion.
Standard_EXPORT IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_HSurface)& Caro2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2);
Standard_EXPORT IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1,
const Handle(Adaptor3d_HSurface)& Caro2,
const Standard_Real TolTangency,
const Standard_Real Epsilon,
const Standard_Real Deflection,
const Standard_Real Increment,
const Standard_Real U1,
const Standard_Real V1,
const Standard_Real U2,
const Standard_Real V2);
//! calculate the line of intersection
Standard_EXPORT void Perform (const TColStd_Array1OfReal& ParDep);
@@ -91,10 +105,19 @@ public:
//! v. (if this data is not presented as in the
//! previous method, the initial steps are calculated
//! starting from min and max uv of faces).
Standard_EXPORT void Perform (const TColStd_Array1OfReal& ParDep, const Standard_Real u1min, const Standard_Real v1min, const Standard_Real u2min, const Standard_Real v2min, const Standard_Real u1max, const Standard_Real v1max, const Standard_Real u2max, const Standard_Real v2max);
Standard_EXPORT void Perform (const TColStd_Array1OfReal& ParDep,
const Standard_Real u1min,
const Standard_Real v1min,
const Standard_Real u2min,
const Standard_Real v2min,
const Standard_Real u1max,
const Standard_Real v1max,
const Standard_Real u2max,
const Standard_Real v2max);
//! calculate the first point of a line of intersection
Standard_EXPORT Standard_Boolean PerformFirstPoint (const TColStd_Array1OfReal& ParDep, IntSurf_PntOn2S& FirstPoint);
Standard_EXPORT Standard_Boolean PerformFirstPoint (const TColStd_Array1OfReal& ParDep,
IntSurf_PntOn2S& FirstPoint);
//! Returns true if the calculus was successful.
Standard_Boolean IsDone() const;
@@ -126,11 +149,16 @@ public:
const gp_Dir& TangentAtLine (Standard_Integer& Index) const;
Standard_EXPORT IntWalk_StatusDeflection TestDeflection (const IntImp_ConstIsoparametric ChoixIso) ;
Standard_EXPORT IntWalk_StatusDeflection TestDeflection (const IntImp_ConstIsoparametric ChoixIso,
const IntWalk_StatusDeflection theStatus);
Standard_EXPORT Standard_Boolean TestArret (const Standard_Boolean DejaReparti, TColStd_Array1OfReal& Param, IntImp_ConstIsoparametric& ChoixIso);
Standard_EXPORT Standard_Boolean TestArret (const Standard_Boolean DejaReparti,
TColStd_Array1OfReal& Param,
IntImp_ConstIsoparametric& ChoixIso);
Standard_EXPORT void RepartirOuDiviser (Standard_Boolean& DejaReparti, IntImp_ConstIsoparametric& ChoixIso, Standard_Boolean& Arrive);
Standard_EXPORT void RepartirOuDiviser (Standard_Boolean& DejaReparti,
IntImp_ConstIsoparametric& ChoixIso,
Standard_Boolean& Arrive);
//! Inserts thePOn2S in the end of line
void AddAPoint (const IntSurf_PntOn2S& thePOn2S);
@@ -157,9 +185,12 @@ public:
line->RemovePoint(anIdx);
}
Standard_EXPORT Standard_Boolean PutToBoundary (const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2);
Standard_EXPORT Standard_Boolean PutToBoundary (const Handle(Adaptor3d_HSurface)& theASurf1,
const Handle(Adaptor3d_HSurface)& theASurf2);
Standard_EXPORT Standard_Boolean SeekAdditionalPoints (const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2, const Standard_Integer theMinNbPoints);
Standard_EXPORT Standard_Boolean SeekAdditionalPoints (const Handle(Adaptor3d_HSurface)& theASurf1,
const Handle(Adaptor3d_HSurface)& theASurf2,
const Standard_Integer theMinNbPoints);
Standard_Real MaxStep(Standard_Integer theIndex)
{

View File

@@ -65,15 +65,17 @@ inline const gp_Dir& IntWalk_PWalking::TangentAtLine(Standard_Integer& theIndex)
inline void IntWalk_PWalking::AddAPoint(const IntSurf_PntOn2S& POn2S) {
#if REGLAGE
Standard_Integer n=theLine->NbPoints();
Standard_Integer n=line->NbPoints()+1;
if (n == 1)
{
std::cout << "Dump of WL" << std::endl;
}
if(n) {
gp_Vec V(POn2S.Value(),theLine->Value(n).Value());
Standard_Real u1,v1,u2,v2;
Standard_Real U1,V1,U2,V2;
POn2S.Parameters(u1,v1,u2,v2);
theLine->Value(n).Parameters(U1,V1,U2,V2);
printf("\n%3d: (%10.5g)(%+12.5g %+12.5g %+12.5g) (%+12.5g %+12.5g) (%+12.5g %+12.5g)",n,
V.Magnitude(),V.X(),V.Y(),V.Z(),U1-u1,V1-v1,U2-u2,V2-v2);
printf("point p%d %+10.20f %+10.20f %+10.20f\n",
n, POn2S.Value().X(), POn2S.Value().Y(), POn2S.Value().Z());
fflush(stdout);
}
#endif