Skip to content

Commit bb368e2

Browse files
jgvsmoskvin
authored andcommitted
0032721: Modeling Algorithms - BOP wrong results on a cone and an extrusion
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.
1 parent 04ecb23 commit bb368e2

15 files changed

Lines changed: 230 additions & 30 deletions

src/IntPatch/IntPatch_ALineToWLine.cxx

Lines changed: 121 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
//function : AddPointIntoLine
3030
//purpose :
3131
//=======================================================================
32-
static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S) theLine,
32+
static inline void AddPointIntoLine(Handle(IntSurf_LineOn2S)& theLine,
3333
const Standard_Real* const theArrPeriods,
3434
IntSurf_PntOn2S &thePoint,
3535
IntPatch_Point* theVertex = 0)
@@ -252,6 +252,69 @@ void IntPatch_ALineToWLine::SetTolOpenDomain(const Standard_Real aTol)
252252
return myTolOpenDomain;
253253
}
254254

255+
//=======================================================================
256+
//function : CorrectEndPoint
257+
//purpose :
258+
//=======================================================================
259+
void IntPatch_ALineToWLine::CorrectEndPoint(Handle(IntSurf_LineOn2S)& theLine,
260+
const Standard_Integer theIndex) const
261+
{
262+
const Standard_Real aTol = 1.e-5;
263+
const Standard_Real aSqTol = 1.e-10;
264+
265+
//Perform linear extrapolation from two previous points
266+
Standard_Integer anIndFirst, anIndSecond;
267+
if (theIndex == 1)
268+
{
269+
anIndFirst = 3;
270+
anIndSecond = 2;
271+
}
272+
else
273+
{
274+
anIndFirst = theIndex - 2;
275+
anIndSecond = theIndex - 1;
276+
}
277+
IntSurf_PntOn2S aPntOn2S = theLine->Value(theIndex);
278+
279+
for (Standard_Integer ii = 1; ii <= 2; ii++)
280+
{
281+
Standard_Boolean anIsOnFirst = (ii == 1);
282+
283+
const IntSurf_Quadric& aQuad = (ii == 1)? myQuad1 : myQuad2;
284+
if (aQuad.TypeQuadric() == GeomAbs_Cone)
285+
{
286+
const gp_Cone aCone = aQuad.Cone();
287+
const gp_Pnt anApex = aCone.Apex();
288+
if (anApex.SquareDistance (aPntOn2S.Value()) > aSqTol)
289+
continue;
290+
}
291+
else if (aQuad.TypeQuadric() == GeomAbs_Sphere)
292+
{
293+
Standard_Real aU, aV;
294+
aPntOn2S.ParametersOnSurface(anIsOnFirst, aU, aV);
295+
if (Abs(aV - M_PI/2) > aTol &&
296+
Abs(aV + M_PI/2) > aTol)
297+
continue;
298+
}
299+
else
300+
continue;
301+
302+
gp_Pnt2d PrevPrevP2d = theLine->Value(anIndFirst).ValueOnSurface(anIsOnFirst);
303+
gp_Pnt2d PrevP2d = theLine->Value (anIndSecond).ValueOnSurface(anIsOnFirst);
304+
gp_Dir2d aDir = gp_Vec2d(PrevPrevP2d, PrevP2d);
305+
Standard_Real aX0 = PrevPrevP2d.X(), aY0 = PrevPrevP2d.Y();
306+
Standard_Real aXend, aYend;
307+
aPntOn2S.ParametersOnSurface(anIsOnFirst, aXend, aYend);
308+
309+
if (Abs(aDir.Y()) < gp::Resolution())
310+
continue;
311+
312+
Standard_Real aNewXend = aDir.X()/aDir.Y() * (aYend - aY0) + aX0;
313+
314+
theLine->SetUV (theIndex, anIsOnFirst, aNewXend, aYend);
315+
}
316+
}
317+
255318
//=======================================================================
256319
//function : GetSectionRadius
257320
//purpose :
@@ -331,24 +394,27 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
331394
#if 0
332395
//To draw ALine as a wire DRAW-object use the following code.
333396
{
334-
static int zzz = 0;
335-
zzz++;
397+
static int ind = 0;
398+
ind++;
336399

337-
bool flShow = /*(zzz == 1)*/false;
400+
bool flShow = true;
338401

339402
if (flShow)
340403
{
341404
std::cout << " +++ DUMP ALine (begin) +++++" << std::endl;
342-
Standard_Integer aI = 0;
343-
const Standard_Real aStep = (theLPar - theFPar) / 9999.0;
344-
for (Standard_Real aPrm = theFPar; aPrm < theLPar; aPrm += aStep)
405+
const Standard_Integer NbSamples = 20;
406+
const Standard_Real aStep = (theLPar - theFPar) / NbSamples;
407+
char* name = new char[100];
408+
409+
for (Standard_Integer ii = 0; ii <= NbSamples; ii++)
345410
{
411+
Standard_Real aPrm = theFPar + ii * aStep;
346412
const gp_Pnt aPP(theALine->Value(aPrm));
347-
std::cout << "vertex v" << ++aI << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
348-
}
413+
std::cout << "vertex v" << ii << " " << aPP.X() << " " << aPP.Y() << " " << aPP.Z() << std::endl;
349414

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

436502
Standard_Integer aNewVertID = 0;
437503
aLinOn2S = new IntSurf_LineOn2S;
504+
Standard_Boolean anIsFirstDegenerated = Standard_False,
505+
anIsLastDegenerated = Standard_False;
438506

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

@@ -467,6 +535,9 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
467535
{
468536
// We cannot compute 2D-parameters of
469537
// aPOn2S correctly.
538+
539+
if (anIsLastDegenerated) //the current last point is wrong
540+
aLinOn2S->RemovePoint (aLinOn2S->NbPoints());
470541

471542
isPointValid = Standard_False;
472543
}
@@ -591,6 +662,27 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
591662
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
592663
aPrevLPoint = aPOn2S;
593664
}
665+
else
666+
{
667+
//add point, set correxponding status: to be corrected later
668+
Standard_Boolean ToAdd = Standard_False;
669+
if (aLinOn2S->NbPoints() == 0)
670+
{
671+
anIsFirstDegenerated = Standard_True;
672+
ToAdd = Standard_True;
673+
}
674+
else if (aLinOn2S->NbPoints() > 1)
675+
{
676+
anIsLastDegenerated = Standard_True;
677+
ToAdd = Standard_True;
678+
}
679+
680+
if (ToAdd)
681+
{
682+
AddPointIntoLine(aLinOn2S, anArrPeriods, aPOn2S);
683+
aPrevLPoint = aPOn2S;
684+
}
685+
}
594686

595687
continue;
596688
}
@@ -630,6 +722,15 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
630722

631723
aPrePointExist = IsPoleOrSeam(myS1, myS2, aPrefIso, aLinOn2S, aVtx,
632724
anArrPeriods, aTol, aSingularSurfaceID);
725+
if (aPrePointExist == IntPatch_SPntPole ||
726+
aPrePointExist == IntPatch_SPntPoleSeamU)
727+
{
728+
//set correxponding status: to be corrected later
729+
if (aLinOn2S->NbPoints() == 1)
730+
anIsFirstDegenerated = Standard_True;
731+
else
732+
anIsLastDegenerated = Standard_True;
733+
}
633734

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

806+
//Correct first and last points if needed
807+
if (aLinOn2S->NbPoints() >= 3)
808+
{
809+
if (anIsFirstDegenerated)
810+
CorrectEndPoint (aLinOn2S, 1);
811+
if (anIsLastDegenerated)
812+
CorrectEndPoint (aLinOn2S, aLinOn2S->NbPoints());
813+
}
814+
705815
//-----------------------------------------------------------------
706816
//-- W L i n e c r e a t i o n ---
707817
//-----------------------------------------------------------------

src/IntPatch/IntPatch_ALineToWLine.hxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <Adaptor3d_Surface.hxx>
2121
#include <IntPatch_SequenceOfLine.hxx>
2222
#include <IntSurf_Quadric.hxx>
23+
#include <IntSurf_LineOn2S.hxx>
2324

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

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

95103

src/IntPatch/IntPatch_WLine.cxx

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,7 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
471471

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

517516
IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
518517
RecadreMemePeriode(POn2S,curv->Value(1),U1Period(),V1Period(),U2Period(),V2Period());
519-
curv->Value(1,POn2S);
518+
if (myCreationWay == IntPatch_WLImpImp)
519+
{
520+
//Adjust first point of curve to corresponding vertex the following way:
521+
//set 3D point as the point of the vertex and 2D points as the points of the point on curve.
522+
curv->SetPoint (1, POn2S.Value());
523+
Standard_Real mu1,mv1,mu2,mv2;
524+
curv->Value(1).Parameters(mu1,mv1,mu2,mv2);
525+
svtx.ChangeValue(i).SetParameter(1);
526+
svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2);
527+
}
528+
else
529+
{
530+
curv->Value(1,POn2S);
531+
}
520532

521533
//--curv->Value(1,svtx.Value(i).PntOn2S());
522534
svtx.ChangeValue(i).SetParameter(1.0);
@@ -551,6 +563,9 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
551563
//---------------------------------------------------------
552564
Standard_Boolean Substitution = Standard_False;
553565
//-- for(k=indicevertexonline+1; !Substitution && k>=indicevertexonline-1;k--) { avant le 9 oct 97
566+
Standard_Real mu1,mv1,mu2,mv2;
567+
curv->Value(indicevertexonline).Parameters(mu1,mv1,mu2,mv2);
568+
554569
for(k=indicevertexonline+1; k>=indicevertexonline-1;k--) {
555570
if(k>0 && k<=nbponline) {
556571
if(CompareVertexAndPoint(P,curv->Value(k).Value(),vTol)) {
@@ -560,9 +575,21 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol)
560575
//-------------------------------------------------------
561576
IntSurf_PntOn2S POn2S = svtx.Value(i).PntOn2S();
562577
RecadreMemePeriode(POn2S,curv->Value(k),U1Period(),V1Period(),U2Period(),V2Period());
563-
curv->Value(k,POn2S);
564-
Standard_Real mu1,mv1,mu2,mv2;
565-
POn2S.Parameters(mu1,mv1,mu2,mv2);
578+
579+
if (myCreationWay == IntPatch_WLImpImp)
580+
{
581+
//Adjust a point of curve to corresponding vertex the following way:
582+
//set 3D point as the point of the vertex and 2D points as the points
583+
//of the point on curve with index <indicevertexonline>
584+
curv->SetPoint (k, POn2S.Value());
585+
curv->SetUV (k, Standard_True, mu1, mv1);
586+
curv->SetUV (k, Standard_False, mu2, mv2);
587+
}
588+
else
589+
{
590+
curv->Value(k,POn2S);
591+
POn2S.Parameters(mu1,mv1,mu2,mv2);
592+
}
566593
svtx.ChangeValue(i).SetParameter(k);
567594
svtx.ChangeValue(i).SetParameters(mu1,mv1,mu2,mv2);
568595
Substitution = Standard_True;

src/IntSurf/IntSurf_LineOn2S.hxx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,14 @@ public:
6262
//! Replaces the point of range Index in the line.
6363
void Value (const Standard_Integer Index, const IntSurf_PntOn2S& P);
6464

65+
//! Sets the 3D point of the Index-th PntOn2S
66+
Standard_EXPORT void SetPoint(const Standard_Integer Index, const gp_Pnt& thePnt);
67+
6568
//! Sets the parametric coordinates on one of the surfaces
6669
//! of the point of range Index in the line.
67-
Standard_EXPORT void SetUV(const Standard_Integer Index, const Standard_Boolean OnFirst, const Standard_Real U, const Standard_Real V);
70+
Standard_EXPORT void SetUV(const Standard_Integer Index,
71+
const Standard_Boolean OnFirst,
72+
const Standard_Real U, const Standard_Real V);
6873

6974
void Clear();
7075

src/IntSurf/IntSurf_LineOn2S.lxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ inline void IntSurf_LineOn2S::Value(const Standard_Integer Index,
3838
mySeq(Index) = P;
3939
}
4040

41+
inline void IntSurf_LineOn2S::SetPoint(const Standard_Integer Index,
42+
const gp_Pnt& thePnt)
43+
{
44+
mySeq(Index).SetValue (thePnt);
45+
}
46+
4147
inline void IntSurf_LineOn2S::Clear ()
4248
{
4349
mySeq.Clear();

tests/bugs/modalg_7/bug29807_b3a

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ puts "0029807: Impossible to cut cone from prism"
33
puts "========"
44
puts ""
55

6-
puts "TODO OCC29922 ALL: Error: Degenerated edge is not found"
7-
86
restore [locate_data_file bug29807-obj.brep] b1
97
restore [locate_data_file bug29807-tool.brep] b2
108

tests/bugs/modalg_7/bug29807_b5a

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ puts "0029807: Impossible to cut cone from prism"
33
puts "========"
44
puts ""
55

6-
puts "TODO OCC29860 ALL: Error : is WRONG because number of WIRE entities in shape \"result\" is 10"
7-
puts "TODO OCC29860 ALL: Error : is WRONG because number of FACE entities in shape \"result\" is 10"
8-
96
restore [locate_data_file bug29807-obj.brep] b1
107
restore [locate_data_file bug29807-tool.brep] b2
118

tests/bugs/modalg_8/bug32721

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
puts "======================================================"
2+
puts "OCC32721: BOP wrong results on a cone and an extrusion"
3+
puts "======================================================"
4+
puts ""
5+
6+
restore [locate_data_file bug32721.brep] prism
7+
pcone cone 6 0 10
8+
9+
bop cone prism
10+
bopfuse r1
11+
bopcommon r2
12+
bopcut r3
13+
boptuc r4
14+
15+
checkshape r1
16+
checknbshapes r1 -t -vertex 8 -edge 17 -wire 8 -face 8 -shell 1 -solid 1
17+
checkshape r2
18+
checknbshapes r2 -t -vertex 3 -edge 7 -wire 4 -face 4 -shell 1 -solid 1
19+
checkshape r3
20+
checknbshapes r3 -t -vertex 4 -edge 10 -wire 4 -face 4 -shell 1 -solid 1
21+
checkshape r4
22+
checknbshapes r4 -t -vertex 7 -edge 14 -wire 8 -face 8 -shell 2 -solid 2
23+
24+
set tolres [checkmaxtol r1]
25+
26+
if { ${tolres} > 0.0002} {
27+
puts "Error: bad tolerance of result"
28+
}
29+
30+
checkprops r1 -s 388.634 -v 406.357
31+
checkprops r2 -s 57.8605 -v 22.8116
32+
checkprops r3 -s 358.735 -v 354.179
33+
checkprops r4 -s 87.7592 -v 29.3659
34+
35+
checkview -display r1 -2d -path ${imagedir}/${test_image}.png

tests/lowalgos/intss/bug29807_i1002

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ fit
1717

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

20-
checkreal Tolerance $Toler 0.00039718358540697849 0.0 0.01
20+
if { ${Toler} > 0.0004} {
21+
puts "Error: bad tolerance of result"
22+
}
2123

2224
if {$NbCurv != 2} {
2325
puts "Error: Please check NbCurves for intersector"

tests/lowalgos/intss/bug29807_i1003

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ fit
1717

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

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

2224
if {$NbCurv != 2} {
2325
puts "Error: Please check NbCurves for intersector"

0 commit comments

Comments
 (0)