]> OCCT Git - occt.git/commitdiff
0032721: Modeling Algorithms - BOP wrong results on a cone and an extrusion
authorjgv <jgv@opencascade.com>
Wed, 30 Mar 2022 01:28:02 +0000 (04:28 +0300)
committersmoskvin <smoskvin@opencascade.com>
Tue, 19 Apr 2022 16:23:10 +0000 (19:23 +0300)
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.

15 files changed:
src/IntPatch/IntPatch_ALineToWLine.cxx
src/IntPatch/IntPatch_ALineToWLine.hxx
src/IntPatch/IntPatch_WLine.cxx
src/IntSurf/IntSurf_LineOn2S.hxx
src/IntSurf/IntSurf_LineOn2S.lxx
tests/bugs/modalg_7/bug29807_b3a
tests/bugs/modalg_7/bug29807_b5a
tests/bugs/modalg_8/bug32721 [new file with mode: 0644]
tests/lowalgos/intss/bug29807_i1002
tests/lowalgos/intss/bug29807_i1003
tests/lowalgos/intss/bug29807_i1004
tests/lowalgos/intss/bug29807_i1005
tests/lowalgos/intss/bug29807_i3002
tests/lowalgos/intss/bug29807_i3004
tests/lowalgos/intss/bug29807_i3005

index 8d9480f3b0abd7b081ef3f5330004181ac170fc2..001d901a59dfb171a92b86c1015eef3aca8bd808 100644 (file)
@@ -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;
     }
   }
@@ -457,6 +523,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;
     
     Standard_Real aStepMin = 0.1 * aStep, aStepMax = 10.0 * aStep;
 
@@ -489,6 +557,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;
         }
@@ -617,6 +688,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;
       }
@@ -656,6 +748,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)
@@ -760,6 +861,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      ---
     //-----------------------------------------------------------------
index ce150e9c2441a649235f580068b5ded11470ef83..10161fdcfc7b6b23789413e3f8f91c74fbca5fe3 100644 (file)
@@ -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;
@@ -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:
 
 
index e2d1b72edf73f5ad1b62fcfff59270c0e44d621b..44713bc9350254b56db5c7c9d7dbcbf5c8df7e48 100644 (file)
@@ -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 <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;
index d9575557e642e490eee2dca66d0277454e6a92f3..b44dc77838de006ee744f8aee47e3387dfa60826 100644 (file)
@@ -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();
   
index 76e96da10f6e8aaf69db85b422cf2d82b680df28..a13c15918656ae12157e3b7d1eb9208bbb306703 100644 (file)
@@ -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();
index fc86cbe0ab84ef6ecf3bbbf305b140131b488caf..276e92e105f4a299fe6c9eddfc8db290e9958e0d 100644 (file)
@@ -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
 
index 9fd83f056017511ab0e8ae72861ed2a25435a113..3921b20638e7ec99b6f09425a5b041914d91d63f 100644 (file)
@@ -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 (file)
index 0000000..42d2499
--- /dev/null
@@ -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
index 544cbab320c8900d0347fd58b01ad16d6f0e40c8..1a4df76d3d4a572bcc6f3b62ed942808264208c7 100644 (file)
@@ -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"
index 10e841e39a9f8577e0edc7fb7e67d63ee9057cd0..d14684addbd5c90023132699545f6197b4c106a0 100644 (file)
@@ -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"
index 2704a41f7fccf21627348ef9ba6a75410b142d2b..08c0682884c60c21c634f40b3602c3458594bb0e 100644 (file)
@@ -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"
index dea1d945d056e6052a969ffea900ee46c0533ab3..73cc268543b6882b85502f69772b36a7019a5aea 100644 (file)
@@ -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"
index 627752d2131b7c440dbd4f1dd67f6356e25f09c5..2495218d984446fd39150c82fe04a16c9cb98f81 100644 (file)
@@ -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"
index 67c2287e479d7d7589500333c0a0c29e0bfe09a6..5ab01f619fef2de2aa84a46453c2adf9b6bbbf8d 100644 (file)
@@ -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"
index c774db50956433bcf986368fb00704f39ec5f131..5298494d18e9b3e329fc0bce615f72b0e8dd7e59 100644 (file)
@@ -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"