diff --git a/src/IntPatch/IntPatch_ALineToWLine.cxx b/src/IntPatch/IntPatch_ALineToWLine.cxx index 59cbff38ae..3082c303ca 100644 --- a/src/IntPatch/IntPatch_ALineToWLine.cxx +++ b/src/IntPatch/IntPatch_ALineToWLine.cxx @@ -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) @@ -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 : @@ -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; } } @@ -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; @@ -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; } @@ -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; } @@ -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) @@ -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 --- //----------------------------------------------------------------- diff --git a/src/IntPatch/IntPatch_ALineToWLine.hxx b/src/IntPatch/IntPatch_ALineToWLine.hxx index ce150e9c24..10161fdcfc 100644 --- a/src/IntPatch/IntPatch_ALineToWLine.hxx +++ b/src/IntPatch/IntPatch_ALineToWLine.hxx @@ -20,6 +20,7 @@ #include #include #include +#include class IntPatch_ALine; class IntSurf_PntOn2S; @@ -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: diff --git a/src/IntPatch/IntPatch_WLine.cxx b/src/IntPatch/IntPatch_WLine.cxx index e2d1b72edf..44713bc935 100644 --- a/src/IntPatch/IntPatch_WLine.cxx +++ b/src/IntPatch/IntPatch_WLine.cxx @@ -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); @@ -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); @@ -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)) { @@ -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 + 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; diff --git a/src/IntSurf/IntSurf_LineOn2S.hxx b/src/IntSurf/IntSurf_LineOn2S.hxx index d9575557e6..b44dc77838 100644 --- a/src/IntSurf/IntSurf_LineOn2S.hxx +++ b/src/IntSurf/IntSurf_LineOn2S.hxx @@ -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(); diff --git a/src/IntSurf/IntSurf_LineOn2S.lxx b/src/IntSurf/IntSurf_LineOn2S.lxx index 76e96da10f..a13c159186 100644 --- a/src/IntSurf/IntSurf_LineOn2S.lxx +++ b/src/IntSurf/IntSurf_LineOn2S.lxx @@ -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(); diff --git a/tests/bugs/modalg_7/bug29807_b3a b/tests/bugs/modalg_7/bug29807_b3a index fc86cbe0ab..276e92e105 100644 --- a/tests/bugs/modalg_7/bug29807_b3a +++ b/tests/bugs/modalg_7/bug29807_b3a @@ -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 diff --git a/tests/bugs/modalg_7/bug29807_b5a b/tests/bugs/modalg_7/bug29807_b5a index 9fd83f0560..3921b20638 100644 --- a/tests/bugs/modalg_7/bug29807_b5a +++ b/tests/bugs/modalg_7/bug29807_b5a @@ -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 diff --git a/tests/bugs/modalg_8/bug32721 b/tests/bugs/modalg_8/bug32721 new file mode 100644 index 0000000000..42d2499ed2 --- /dev/null +++ b/tests/bugs/modalg_8/bug32721 @@ -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 \ No newline at end of file diff --git a/tests/lowalgos/intss/bug29807_i1002 b/tests/lowalgos/intss/bug29807_i1002 index 544cbab320..1a4df76d3d 100644 --- a/tests/lowalgos/intss/bug29807_i1002 +++ b/tests/lowalgos/intss/bug29807_i1002 @@ -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" diff --git a/tests/lowalgos/intss/bug29807_i1003 b/tests/lowalgos/intss/bug29807_i1003 index 10e841e39a..d14684addb 100644 --- a/tests/lowalgos/intss/bug29807_i1003 +++ b/tests/lowalgos/intss/bug29807_i1003 @@ -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" diff --git a/tests/lowalgos/intss/bug29807_i1004 b/tests/lowalgos/intss/bug29807_i1004 index 2704a41f7f..08c0682884 100644 --- a/tests/lowalgos/intss/bug29807_i1004 +++ b/tests/lowalgos/intss/bug29807_i1004 @@ -18,7 +18,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.00011289757099748416 0.0 0.01 +if { ${Toler} > 0.000113} { + puts "Error: bad tolerance of result" +} if {$NbCurv != 2} { puts "Error: Please check NbCurves for intersector" diff --git a/tests/lowalgos/intss/bug29807_i1005 b/tests/lowalgos/intss/bug29807_i1005 index dea1d945d0..73cc268543 100644 --- a/tests/lowalgos/intss/bug29807_i1005 +++ b/tests/lowalgos/intss/bug29807_i1005 @@ -18,7 +18,9 @@ fit regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 b2_2 -2d] full Toler NbCurv -checkreal Tolerance $Toler 7.7125880147734232e-007 0.0 0.01 +if { ${Toler} > 8e-7} { + puts "Error: bad tolerance of result" +} if {$NbCurv != 2} { puts "Error: Please check NbCurves for intersector" diff --git a/tests/lowalgos/intss/bug29807_i3002 b/tests/lowalgos/intss/bug29807_i3002 index 627752d213..2495218d98 100644 --- a/tests/lowalgos/intss/bug29807_i3002 +++ b/tests/lowalgos/intss/bug29807_i3002 @@ -16,7 +16,9 @@ fit regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 f2 -2d] full Toler NbCurv -checkreal Tolerance $Toler 0.00039718358530349535 0.0 0.01 +if { ${Toler} > 0.0004} { + puts "Error: bad tolerance of result" +} if {$NbCurv != 2} { puts "Error: Please check NbCurves for intersector" diff --git a/tests/lowalgos/intss/bug29807_i3004 b/tests/lowalgos/intss/bug29807_i3004 index 67c2287e47..5ab01f619f 100644 --- a/tests/lowalgos/intss/bug29807_i3004 +++ b/tests/lowalgos/intss/bug29807_i3004 @@ -17,7 +17,9 @@ fit regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 f2 -2d] full Toler NbCurv -checkreal Tolerance $Toler 0.00011289757087827709 0.0 0.01 +if { ${Toler} > 0.000113} { + puts "Error: bad tolerance of result" +} if {$NbCurv != 2} { puts "Error: Please check NbCurves for intersector" diff --git a/tests/lowalgos/intss/bug29807_i3005 b/tests/lowalgos/intss/bug29807_i3005 index c774db5095..5298494d18 100644 --- a/tests/lowalgos/intss/bug29807_i3005 +++ b/tests/lowalgos/intss/bug29807_i3005 @@ -17,7 +17,9 @@ fit regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} [bopcurves b1_5 f2 -2d] full Toler NbCurv -checkreal Tolerance $Toler 7.7124681583892622e-007 0.0 0.01 +if { ${Toler} > 8e-7} { + puts "Error: bad tolerance of result" +} if {$NbCurv != 2} { puts "Error: Please check NbCurves for intersector"