Skip to content

Commit

Permalink
0032721: Modeling Algorithms - BOP wrong results on a cone and an ext…
Browse files Browse the repository at this point in the history
…rusion

1. Modify method IntPatch_ALineToWLine::MakeWLine: add correction of end points of each line on 2 surfaces if an end point is a pole on a surface.
2. Modify method IntPatch_WLine::ComputeVertexParameters: adjust a point on curve to corresponding vertex the following way: set 3D point as the point of the vertex and 2D points as the points of the point on curve.
  • Loading branch information
jgv authored and smoskvin committed Apr 26, 2022
1 parent 04ecb23 commit bb368e2
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 30 deletions.
132 changes: 121 additions & 11 deletions src/IntPatch/IntPatch_ALineToWLine.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//function : AddPointIntoLine
//purpose :
//=======================================================================
static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S) theLine,
static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S)& theLine,
const Standard_Real* const theArrPeriods,
IntSurf_PntOn2S &thePoint,
IntPatch_Point* theVertex = 0)
Expand Down Expand Up @@ -252,6 +252,69 @@ void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
return myTolOpenDomain;
}

//=======================================================================
//function : CorrectEndPoint
//purpose :
//=======================================================================
void IntPatch_ALineToWLine::CorrectEndPoint(Handle(IntSurf_LineOn2S)& theLine,
const Standard_Integer theIndex) const
{
const Standard_Real aTol = 1.e-5;
const Standard_Real aSqTol = 1.e-10;

//Perform linear extrapolation from two previous points
Standard_Integer anIndFirst, anIndSecond;
if (theIndex == 1)
{
anIndFirst = 3;
anIndSecond = 2;
}
else
{
anIndFirst = theIndex - 2;
anIndSecond = theIndex - 1;
}
IntSurf_PntOn2S aPntOn2S = theLine->Value(theIndex);

for (Standard_Integer ii = 1; ii <= 2; ii++)
{
Standard_Boolean anIsOnFirst = (ii == 1);

const IntSurf_Quadric& aQuad = (ii == 1)? myQuad1 : myQuad2;
if (aQuad.TypeQuadric() == GeomAbs_Cone)
{
const gp_Cone aCone = aQuad.Cone();
const gp_Pnt anApex = aCone.Apex();
if (anApex.SquareDistance (aPntOn2S.Value()) > aSqTol)
continue;
}
else if (aQuad.TypeQuadric() == GeomAbs_Sphere)
{
Standard_Real aU, aV;
aPntOn2S.ParametersOnSurface(anIsOnFirst, aU, aV);
if (Abs(aV - M_PI/2) > aTol &&
Abs(aV + M_PI/2) > aTol)
continue;
}
else
continue;

gp_Pnt2d PrevPrevP2d = theLine->Value(anIndFirst).ValueOnSurface(anIsOnFirst);
gp_Pnt2d PrevP2d = theLine->Value (anIndSecond).ValueOnSurface(anIsOnFirst);
gp_Dir2d aDir = gp_Vec2d(PrevPrevP2d, PrevP2d);
Standard_Real aX0 = PrevPrevP2d.X(), aY0 = PrevPrevP2d.Y();
Standard_Real aXend, aYend;
aPntOn2S.ParametersOnSurface(anIsOnFirst, aXend, aYend);

if (Abs(aDir.Y()) < gp::Resolution())
continue;

Standard_Real aNewXend = aDir.X()/aDir.Y() * (aYend - aY0) + aX0;

theLine->SetUV (theIndex, anIsOnFirst, aNewXend, aYend);
}
}

//=======================================================================
//function : GetSectionRadius
//purpose :
Expand Down Expand Up @@ -331,24 +394,27 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
#if 0
//To draw ALine as a wire DRAW-object use the following code.
{
static int zzz = 0;
zzz++;
static int ind = 0;
ind++;

bool flShow = /*(zzz == 1)*/false;
bool flShow = true;

if (flShow)
{
std::cout << " +++ DUMP ALine (begin) +++++" << std::endl;
Standard_Integer aI = 0;
const Standard_Real aStep = (theLPar - theFPar) / 9999.0;
for (Standard_Real aPrm = theFPar; aPrm < theLPar; aPrm += aStep)
const Standard_Integer NbSamples = 20;
const Standard_Real aStep = (theLPar - theFPar) / NbSamples;
char* name = new char[100];

for (Standard_Integer ii = 0; ii <= NbSamples; ii++)
{
Standard_Real aPrm = theFPar + ii * aStep;
const gp_Pnt aPP(theALine->Value(aPrm));
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
}
std::cout << "vertex v" << ii << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;

gp_Pnt aPP(theALine->Value(theLPar));
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
sprintf(name, "p%d_%d", ii, ind);
Draw::Set(name, aPP);
}
std::cout << " --- DUMP ALine (end) -----" << std::endl;
}
}
Expand Down Expand Up @@ -435,6 +501,8 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,

Standard_Integer aNewVertID = 0;
aLinOn2S = new IntSurf_LineOn2S;
Standard_Boolean anIsFirstDegenerated = Standard_False,
anIsLastDegenerated = Standard_False;

const Standard_Real aStepMin = 0.1*aStep, aStepMax = 10.0*aStep;

Expand Down Expand Up @@ -467,6 +535,9 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
{
// We cannot compute 2D-parameters of
// aPOn2S correctly.

if (anIsLastDegenerated) //the current last point is wrong
aLinOn2S->RemovePoint (aLinOn2S->NbPoints());

isPointValid = Standard_False;
}
Expand Down Expand Up @@ -591,6 +662,27 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
aPrevLPoint = aPOn2S;
}
else
{
//add point, set correxponding status: to be corrected later
Standard_Boolean ToAdd = Standard_False;
if (aLinOn2S->NbPoints() == 0)
{
anIsFirstDegenerated = Standard_True;
ToAdd = Standard_True;
}
else if (aLinOn2S->NbPoints() > 1)
{
anIsLastDegenerated = Standard_True;
ToAdd = Standard_True;
}

if (ToAdd)
{
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
aPrevLPoint = aPOn2S;
}
}

continue;
}
Expand Down Expand Up @@ -630,6 +722,15 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,

aPrePointExist = IsPoleOrSeam(myS1, myS2, aPrefIso, aLinOn2S, aVtx,
anArrPeriods, aTol, aSingularSurfaceID);
if (aPrePointExist == IntPatch_SPntPole ||
aPrePointExist == IntPatch_SPntPoleSeamU)
{
//set correxponding status: to be corrected later
if (aLinOn2S->NbPoints() == 1)
anIsFirstDegenerated = Standard_True;
else
anIsLastDegenerated = Standard_True;
}

const Standard_Real aCurVertParam = aVtx.ParameterOnLine();
if(aPrePointExist != IntPatch_SPntNone)
Expand Down Expand Up @@ -702,6 +803,15 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
continue;
}

//Correct first and last points if needed
if (aLinOn2S->NbPoints() >= 3)
{
if (anIsFirstDegenerated)
CorrectEndPoint (aLinOn2S, 1);
if (anIsLastDegenerated)
CorrectEndPoint (aLinOn2S, aLinOn2S->NbPoints());
}

//-----------------------------------------------------------------
//-- W L i n e c r e a t i o n ---
//-----------------------------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions src/IntPatch/IntPatch_ALineToWLine.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <Adaptor3d_Surface.hxx>
#include <IntPatch_SequenceOfLine.hxx>
#include <IntSurf_Quadric.hxx>
#include <IntSurf_LineOn2S.hxx>

class IntPatch_ALine;
class IntSurf_PntOn2S;
Expand Down Expand Up @@ -90,6 +91,13 @@ protected:
//! This check is made for cone and sphere only.
Standard_EXPORT Standard_Real GetSectionRadius(const gp_Pnt& thePnt3d) const;

//! Corrects the U-parameter of an end point (first or last) of the line
//! if this end point is a pole.
//! The line must contain at least 3 points.
//! This is made for cone and sphere only.
Standard_EXPORT void CorrectEndPoint(Handle(IntSurf_LineOn2S)& theLine,
const Standard_Integer theIndex) const;

private:


Expand Down
39 changes: 33 additions & 6 deletions src/IntPatch/IntPatch_WLine.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,7 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)

//----------------------------------------------------
//-- On detecte les points confondus dans la LineOn2S
Standard_Real dmini = Precision::Confusion();
dmini*=dmini;
Standard_Real dmini = Precision::SquareConfusion();
for(i=2; (i<=nbponline) && (nbponline > 2); i++) {
const IntSurf_PntOn2S& aPnt1=curv->Value(i-1);
const IntSurf_PntOn2S& aPnt2=curv->Value(i);
Expand Down Expand Up @@ -516,7 +515,20 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)

IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period());
curv->Value(1,POn2S);
if (myCreationWay == IntPatch_WLImpImp)
{
//Adjust first point of curve to corresponding vertex the following way:
//set 3D point as the point of the vertex and 2D points as the points of the point on curve.
curv->SetPoint (1, POn2S.Value());
Standard_Real mu1,mv1,mu2,mv2;
curv->Value(1).Parameters(mu1,mv1,mu2,mv2);
svtx.ChangeValue(i).SetParameter(1);
svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2);
}
else
{
curv->Value(1,POn2S);
}

//--curv->Value(1,svtx.Value(i).PntOn2S());
svtx.ChangeValue(i).SetParameter(1.0);
Expand Down Expand Up @@ -551,6 +563,9 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
//---------------------------------------------------------
Standard_Boolean Substitution = Standard_False;
//-- for(k=indicevertexonline+1; !Substitution && k>=indicevertexonline-1;k--) { avant le 9 oct 97
Standard_Real mu1,mv1,mu2,mv2;
curv->Value(indicevertexonline).Parameters(mu1,mv1,mu2,mv2);

for(k=indicevertexonline+1; k>=indicevertexonline-1;k--) {
if(k>0 && k<=nbponline) {
if(CompareVertexAndPoint(P,curv->Value(k).Value(),vTol)) {
Expand All @@ -560,9 +575,21 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
//-------------------------------------------------------
IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
RecadreMemePeriode(POn2S,curv->Value(k),U1Period(),V1Period(),U2Period(),V2Period());
curv->Value(k,POn2S);
Standard_Real mu1,mv1,mu2,mv2;
POn2S.Parameters(mu1,mv1,mu2,mv2);

if (myCreationWay == IntPatch_WLImpImp)
{
//Adjust a point of curve to corresponding vertex the following way:
//set 3D point as the point of the vertex and 2D points as the points
//of the point on curve with index <indicevertexonline>
curv->SetPoint (k, POn2S.Value());
curv->SetUV (k, Standard_True, mu1, mv1);
curv->SetUV (k, Standard_False, mu2, mv2);
}
else
{
curv->Value(k,POn2S);
POn2S.Parameters(mu1,mv1,mu2,mv2);
}
svtx.ChangeValue(i).SetParameter(k);
svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2);
Substitution = Standard_True;
Expand Down
7 changes: 6 additions & 1 deletion src/IntSurf/IntSurf_LineOn2S.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,14 @@ public:
//! Replaces the point of range Index in the line.
void Value (const Standard_Integer Index, const IntSurf_PntOn2S& P);

//! Sets the 3D point of the Index-th PntOn2S
Standard_EXPORT void SetPoint(const Standard_Integer Index, const gp_Pnt& thePnt);

//! Sets the parametric coordinates on one of the surfaces
//! of the point of range Index in the line.
Standard_EXPORT 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();

Expand Down
6 changes: 6 additions & 0 deletions src/IntSurf/IntSurf_LineOn2S.lxx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ inline void IntSurf_LineOn2S::Value(const Standard_Integer Index,
mySeq(Index) = P;
}

inline void IntSurf_LineOn2S::SetPoint(const Standard_Integer Index,
const gp_Pnt& thePnt)
{
mySeq(Index).SetValue (thePnt);
}

inline void IntSurf_LineOn2S::Clear ()
{
mySeq.Clear();
Expand Down
2 changes: 0 additions & 2 deletions tests/bugs/modalg_7/bug29807_b3a
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ puts "0029807: Impossible to cut cone from prism"
puts "========"
puts ""

puts "TODO OCC29922 ALL: Error: Degenerated edge is not found"

restore [locate_data_file bug29807-obj.brep] b1
restore [locate_data_file bug29807-tool.brep] b2

Expand Down
3 changes: 0 additions & 3 deletions tests/bugs/modalg_7/bug29807_b5a
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ puts "0029807: Impossible to cut cone from prism"
puts "========"
puts ""

puts "TODO OCC29860 ALL: Error : is WRONG because number of WIRE entities in shape \"result\" is 10"
puts "TODO OCC29860 ALL: Error : is WRONG because number of FACE entities in shape \"result\" is 10"

restore [locate_data_file bug29807-obj.brep] b1
restore [locate_data_file bug29807-tool.brep] b2

Expand Down
35 changes: 35 additions & 0 deletions tests/bugs/modalg_8/bug32721
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
puts "======================================================"
puts "OCC32721: BOP wrong results on a cone and an extrusion"
puts "======================================================"
puts ""

restore [locate_data_file bug32721.brep] prism
pcone cone 6 0 10

bop cone prism
bopfuse r1
bopcommon r2
bopcut r3
boptuc r4

checkshape r1
checknbshapes r1 -t -vertex 8 -edge 17 -wire 8 -face 8 -shell 1 -solid 1
checkshape r2
checknbshapes r2 -t -vertex 3 -edge 7 -wire 4 -face 4 -shell 1 -solid 1
checkshape r3
checknbshapes r3 -t -vertex 4 -edge 10 -wire 4 -face 4 -shell 1 -solid 1
checkshape r4
checknbshapes r4 -t -vertex 7 -edge 14 -wire 8 -face 8 -shell 2 -solid 2

set tolres [checkmaxtol r1]

if { ${tolres} > 0.0002} {
puts "Error: bad tolerance of result"
}

checkprops r1 -s 388.634 -v 406.357
checkprops r2 -s 57.8605 -v 22.8116
checkprops r3 -s 358.735 -v 354.179
checkprops r4 -s 87.7592 -v 29.3659

checkview -display r1 -2d -path ${imagedir}/${test_image}.png
4 changes: 3 additions & 1 deletion tests/lowalgos/intss/bug29807_i1002
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ fit

regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 b2_2 -2d] full Toler NbCurv

checkreal Tolerance $Toler 0.00039718358540697849 0.0 0.01
if { ${Toler} > 0.0004} {
puts "Error: bad tolerance of result"
}

if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
Expand Down
4 changes: 3 additions & 1 deletion tests/lowalgos/intss/bug29807_i1003
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ fit

regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 b2_2 -2d] full Toler NbCurv

checkreal Tolerance $Toler 5.0314111870170835e-005 0.0 0.01
if { ${Toler} > 5.1e-5} {
puts "Error: bad tolerance of result"
}

if {$NbCurv != 2} {
puts "Error: Please check NbCurves for intersector"
Expand Down
Loading

0 comments on commit bb368e2

Please sign in to comment.