]> OCCT Git - occt-copy.git/commitdiff
0032502: Modeling Algorithms - BOP wrong result on sphere and cylinder CR32502
authorjgv <jgv@opencascade.com>
Fri, 27 Aug 2021 09:53:29 +0000 (12:53 +0300)
committerjgv <jgv@opencascade.com>
Tue, 31 Aug 2021 14:36:14 +0000 (17:36 +0300)
Modifications in the method IntPatch_ALineToWLine::MakeWLine:
1. Correct modifying tolerances of vertices;
2. Correct setting parameters to vertices on IntPatch_WLine curve.

src/IntPatch/IntPatch_ALineToWLine.cxx
tests/bugs/modalg_7/bug32502 [new file with mode: 0644]

index 7055727a44cbf1fbeb3022eddc27dcbaa32094ed..089a0557ea775550dad35b32e4ff5ca2789a77e8 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <Adaptor3d_Surface.hxx>
 #include <ElSLib.hxx>
+#include <ElCLib.hxx>
 #include <IntPatch_ALine.hxx>
 #include <IntPatch_Point.hxx>
 #include <IntPatch_SpecialPoints.hxx>
@@ -379,18 +380,49 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
   {
     IntPatch_Point &aCurVert = theALine->ChangeVertex(i);
     const IntSurf_PntOn2S &aCurrPt = aCurVert.PntOn2S();
+    const gp_Pnt& aCurPnt = aCurVert.Value();
     const Standard_Real aCurToler = aCurVert.Tolerance();
     for (Standard_Integer j = i + 1; j <= aNbVert; j++)
     {
       IntPatch_Point &aVert = theALine->ChangeVertex(j);
       const IntSurf_PntOn2S &aNewPt = aVert.PntOn2S();
+      const gp_Pnt& aPnt = aVert.Value();
       const Standard_Real aToler = aVert.Tolerance();
 
       const Standard_Real aSumTol = aCurToler + aToler;
+      gp_Vec aVec (aCurPnt, aPnt);
       if (aCurrPt.IsSame(aNewPt, aSumTol))
       {
-        aCurVert.SetTolerance(aSumTol);
-        aVert.SetTolerance(aSumTol);
+        Standard_Real aDist = aVec.Magnitude();
+        Standard_Real aBiggerTol  = Max (aCurToler, aToler);
+        Standard_Real aSmallerTol = Min (aCurToler, aToler);
+        if (aDist + aSmallerTol <= aBiggerTol) //one tolsphere is inside another or they coincide
+        {
+          if (aCurToler < aToler)
+          {
+            aCurVert.SetValue (aPnt);
+            aCurVert.SetTolerance (aToler);
+          }
+          else
+          {
+            aVert.SetValue (aCurPnt);
+            aVert.SetTolerance (aCurToler);
+          }
+        }
+        else //two tolspheres have a common part or a point of contact
+        {
+          gp_Dir aDir (aVec);
+          gp_Lin aLin (aCurPnt, aDir);
+          gp_Pnt aLeftPnt  = ElCLib::Value(-aCurToler, aLin);
+          gp_Pnt aRightPnt = ElCLib::Value(aDist + aToler, aLin);
+          gp_Pnt aMidPnt((aLeftPnt.XYZ() + aRightPnt.XYZ())/2);
+          Standard_Real aNewTol = (aCurToler + aDist + aToler)/2;
+
+          aCurVert.SetValue (aMidPnt);
+          aVert.SetValue (aMidPnt);
+          aCurVert.SetTolerance (aNewTol);
+          aVert.SetTolerance (aNewTol);
+        }
       }
     }
   }
@@ -676,7 +708,11 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
             IntPatch_Point aLVtx = theALine->Vertex(i);
             aLVtx.SetValue(aVertP2S);
             aLVtx.SetTolerance(aVertToler);
-            aLVtx.SetParameter(aNewVertexParam);
+            Standard_Real aParam = aLVtx.ParameterOnLine();
+            if (Abs(aParam - theLPar) <= Precision::PConfusion()) //in the case of closed curve,
+              aLVtx.SetParameter(-1); //we don't know yet the number of points in the curve
+            else
+              aLVtx.SetParameter(aNewVertexParam);
             aSeqVertex(++aNewVertID) = aLVtx;
             hasVertexBeenChecked(i) = Standard_True;
             isFound = Standard_True;
@@ -748,7 +784,9 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
 
     for(Standard_Integer i = aSeqVertex.Lower(); i <= aNewVertID; i++)
     {
-      const IntPatch_Point& aVtx = aSeqVertex(i);
+      IntPatch_Point aVtx = aSeqVertex(i);
+      if (aVtx.ParameterOnLine() == -1) //in the case of closed curve,
+        aVtx.SetParameter (aWLine->NbPnts()); //we set the last parameter
       aWLine->AddVertex(aVtx);
     }
 
@@ -756,7 +794,7 @@ void IntPatch_ALineToWLine::MakeWLine(const Handle(IntPatch_ALine)& theALine,
 
     //the method ComputeVertexParameters can reduce the number of points in <aWLine>
     aWLine->ComputeVertexParameters(myTol3D);
-
+    
     if (aWLine->NbPnts() > 1)
     {
       aWLine->EnablePurging(Standard_False);
diff --git a/tests/bugs/modalg_7/bug32502 b/tests/bugs/modalg_7/bug32502
new file mode 100644 (file)
index 0000000..2f4cef1
--- /dev/null
@@ -0,0 +1,24 @@
+puts "================================================="
+puts "OCC32502: BOP wrong result on sphere and cylinder"
+puts "================================================="
+puts ""
+
+psphere sph 10
+plane pln 0 0 7 0 1 0 0 0 1
+pcylinder cyl pln 3 40
+ttranslate cyl 0 -20 0
+
+bop sph cyl
+bopfuse result
+
+checkshape result
+
+checknbshapes result -t -vertex 4 -edge 11 -wire 5 -face 5 -shell 1 -solid 1
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 3.e-5} {
+   puts "Error: bad tolerance of result"
+}
+
+checkprops result -s 1750.1 -v 4947.2