0030590: Wrong result of Boolean Cut algorithm WEEK-21
authorjgv <jgv@opencascade.com>
Thu, 25 Apr 2019 16:46:14 +0000 (19:46 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 24 May 2019 09:11:52 +0000 (12:11 +0300)
    Modification in static method BoundedArc of IntStart_SearchOnBoundaries:
    add exact intersection of canonical curve-surface (when Func is IntPatch_ArcFunction).

13 files changed:
src/Adaptor3d/Adaptor3d_CurveOnSurface.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/IntAna/IntAna_Curve.cxx
src/IntStart/IntStart_SearchOnBoundaries.gxx
tests/bugs/modalg_6/bug10234
tests/bugs/modalg_7/bug30590_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug30590_2 [new file with mode: 0644]
tests/bugs/modalg_7/bug30590_3 [new file with mode: 0644]
tests/evolved/voluved/HMC001
tests/lowalgos/intss/bug29807_i5001
tests/lowalgos/intss/bug29972_5
tests/lowalgos/intss/bug29972_6

index ebf7fa5..43f8530 100644 (file)
@@ -954,6 +954,10 @@ Standard_Boolean Adaptor3d_CurveOnSurface::IsClosed() const
 
 Standard_Boolean Adaptor3d_CurveOnSurface::IsPeriodic() const
 {
+  if (myType == GeomAbs_Circle ||
+      myType == GeomAbs_Ellipse)
+    return Standard_True;
+  
   return myCurve->IsPeriodic();
 }
 
@@ -964,6 +968,10 @@ Standard_Boolean Adaptor3d_CurveOnSurface::IsPeriodic() const
 
 Standard_Real Adaptor3d_CurveOnSurface::Period() const
 {
+  if (myType == GeomAbs_Circle ||
+      myType == GeomAbs_Ellipse)
+    return (2.*M_PI);
+  
   return myCurve->Period();
 }
 
index f93d867..b31a11a 100644 (file)
@@ -256,7 +256,8 @@ protected:
   
   Standard_EXPORT void FillShrunkData (Handle(BOPDS_PaveBlock)& thePB);
   
-  Standard_EXPORT void FillShrunkData (const TopAbs_ShapeEnum theType1, const TopAbs_ShapeEnum theType2);
+  Standard_EXPORT void FillShrunkData (const TopAbs_ShapeEnum theType1,
+                                       const TopAbs_ShapeEnum theType2);
 
   //! Analyzes the results of computation of the valid range for the
   //! pave block and in case of error adds the warning status, otherwise
@@ -269,11 +270,16 @@ protected:
                                           const Handle(NCollection_BaseAllocator)& theAllocator,
                                           const Standard_Boolean theIsEEIntersection = Standard_True);
   
-  Standard_EXPORT Standard_Boolean CheckFacePaves (const TopoDS_Vertex& theVnew, const TColStd_MapOfInteger& theMIF);
+  Standard_EXPORT Standard_Boolean CheckFacePaves (const TopoDS_Vertex& theVnew,
+                                                   const TColStd_MapOfInteger& theMIF);
   
-  Standard_EXPORT static Standard_Boolean CheckFacePaves (const Standard_Integer theN, const TColStd_MapOfInteger& theMIFOn, const TColStd_MapOfInteger& theMIFIn);
+  Standard_EXPORT static Standard_Boolean CheckFacePaves (const Standard_Integer theN,
+                                                          const TColStd_MapOfInteger& theMIFOn,
+                                                          const TColStd_MapOfInteger& theMIFIn);
   
-  Standard_EXPORT Standard_Boolean IsExistingVertex (const gp_Pnt& theP, const Standard_Real theTol, const TColStd_MapOfInteger& theMVOn) const;
+  Standard_EXPORT Standard_Boolean IsExistingVertex (const gp_Pnt& theP,
+                                                     const Standard_Real theTol,
+                                                     const TColStd_MapOfInteger& theMVOn) const;
   
 
   //! Checks and puts paves from <theMVOnIn> on the curve <theNC>.
@@ -298,7 +304,10 @@ protected:
   //! 1 - checks only EE;
   //! 2 - checks only EF;
   //! other - checks both types of intersections.
-  Standard_EXPORT Standard_Boolean ExtendedTolerance (const Standard_Integer nV, const TColStd_MapOfInteger& aMI, Standard_Real& aTolVExt, const Standard_Integer aType = 0);
+  Standard_EXPORT Standard_Boolean ExtendedTolerance (const Standard_Integer nV,
+                                                      const TColStd_MapOfInteger& aMI,
+                                                      Standard_Real& aTolVExt,
+                                                      const Standard_Integer aType = 0);
   
   Standard_EXPORT void PutBoundPaveOnCurve(const TopoDS_Face& theF1,
                                            const TopoDS_Face& theF2,
@@ -331,38 +340,52 @@ protected:
                                     const TopTools_IndexedMapOfShape& theVertsOnRejectedPB,
                                     const Handle(NCollection_BaseAllocator)& theAllocator);
   
-  Standard_EXPORT void FindPaveBlocks (const Standard_Integer theV, const Standard_Integer theF, BOPDS_ListOfPaveBlock& theLPB);
+  Standard_EXPORT void FindPaveBlocks (const Standard_Integer theV,
+                                       const Standard_Integer theF,
+                                       BOPDS_ListOfPaveBlock& theLPB);
   
-  Standard_EXPORT void FillPaves (const Standard_Integer theV, const Standard_Integer theE, const Standard_Integer theF, const BOPDS_ListOfPaveBlock& theLPB, const Handle(BOPDS_PaveBlock)& thePB);
+  Standard_EXPORT void FillPaves (const Standard_Integer theV,
+                                  const Standard_Integer theE,
+                                  const Standard_Integer theF,
+                                  const BOPDS_ListOfPaveBlock& theLPB,
+                                  const Handle(BOPDS_PaveBlock)& thePB);
   
   Standard_EXPORT void MakeSplitEdge (const Standard_Integer theV, const Standard_Integer theF);
   
-  Standard_EXPORT void GetEFPnts (const Standard_Integer nF1, const Standard_Integer nF2, IntSurf_ListOfPntOn2S& aListOfPnts);
+  Standard_EXPORT void GetEFPnts (const Standard_Integer nF1,
+                                  const Standard_Integer nF2,
+                                  IntSurf_ListOfPntOn2S& aListOfPnts);
   
 
   //! Checks and puts paves created in EF intersections on the curve <theNC>.
-  Standard_EXPORT void PutEFPavesOnCurve (BOPDS_Curve& theNC, 
-                                const TColStd_MapOfInteger& theMI, 
-                                const TColStd_MapOfInteger& theMVEF, 
-                                TColStd_DataMapOfIntegerReal& theMVTol,
-                                TColStd_DataMapOfIntegerListOfInteger& aDMVLV);
+  Standard_EXPORT void PutEFPavesOnCurve (const BOPDS_VectorOfCurve& theVC, 
+                                          const Standard_Integer theIndex,
+                                          const TColStd_MapOfInteger& theMI, 
+                                          const TColStd_MapOfInteger& theMVEF, 
+                                          TColStd_DataMapOfIntegerReal& theMVTol,
+                                          TColStd_DataMapOfIntegerListOfInteger& aDMVLV);
   
 
   //! Puts stick paves on the curve <theNC>
   Standard_EXPORT void PutStickPavesOnCurve (const TopoDS_Face& aF1, 
-                                const TopoDS_Face& aF2, 
-                                const TColStd_MapOfInteger& theMI, 
-                                BOPDS_Curve& theNC, 
-                                const TColStd_MapOfInteger& theMVStick, 
-                                TColStd_DataMapOfIntegerReal& theMVTol,
-                                TColStd_DataMapOfIntegerListOfInteger& aDMVLV);
+                                             const TopoDS_Face& aF2, 
+                                             const TColStd_MapOfInteger& theMI, 
+                                             const BOPDS_VectorOfCurve& theVC,
+                                             const Standard_Integer theIndex,
+                                             const TColStd_MapOfInteger& theMVStick, 
+                                             TColStd_DataMapOfIntegerReal& theMVTol,
+                                             TColStd_DataMapOfIntegerListOfInteger& aDMVLV);
   
 
   //! Collects indices of vertices created in all intersections between
   //! two faces (<nF1> and <nF2>) to the map <theMVStick>.
   //! Also, it collects indices of EF vertices to the <theMVEF> map
   //! and indices of all subshapes of these two faces to the <theMI> map.
-  Standard_EXPORT void GetStickVertices (const Standard_Integer nF1, const Standard_Integer nF2, TColStd_MapOfInteger& theMVStick, TColStd_MapOfInteger& theMVEF, TColStd_MapOfInteger& theMI);
+  Standard_EXPORT void GetStickVertices (const Standard_Integer nF1,
+                                         const Standard_Integer nF2,
+                                         TColStd_MapOfInteger& theMVStick,
+                                         TColStd_MapOfInteger& theMVEF,
+                                         TColStd_MapOfInteger& theMI);
   
 
   //! Collects index nF and indices of all subshapes of the shape with index <nF>
@@ -373,7 +396,7 @@ protected:
   //! Removes indices of vertices that are already on the
   //! curve <theNC> from the map <theMV>.
   //! It is used in PutEFPavesOnCurve and PutStickPavesOnCurve methods.
-  Standard_EXPORT void RemoveUsedVertices (const BOPDS_Curve& theNC, TColStd_MapOfInteger& theMV);
+  Standard_EXPORT void RemoveUsedVertices (const BOPDS_VectorOfCurve& theVC, TColStd_MapOfInteger& theMV);
   
 
   //! Puts the pave nV on the curve theNC.
@@ -412,7 +435,8 @@ protected:
                                                 const BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap);
 
   //! Treatment of vertices that were created in EE intersections.
-  Standard_EXPORT void TreatNewVertices(const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB, TopTools_IndexedDataMapOfShapeListOfShape& theImages);
+  Standard_EXPORT void TreatNewVertices(const BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
+                                        TopTools_IndexedDataMapOfShapeListOfShape& theImages);
   
 
   //! Put paves on the curve <aBC> in case when <aBC>
@@ -421,7 +445,12 @@ protected:
   
 
   //! Keeps data for post treatment
-  Standard_EXPORT void PreparePostTreatFF (const Standard_Integer aInt, const Standard_Integer aCur, const Handle(BOPDS_PaveBlock)& aPB, BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB, TopTools_DataMapOfShapeInteger& aMVI, BOPDS_ListOfPaveBlock& aLPB);
+  Standard_EXPORT void PreparePostTreatFF (const Standard_Integer aInt,
+                                           const Standard_Integer aCur,
+                                           const Handle(BOPDS_PaveBlock)& aPB,
+                                           BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
+                                           TopTools_DataMapOfShapeInteger& aMVI,
+                                           BOPDS_ListOfPaveBlock& aLPB);
 
   //! Updates the information about faces
   Standard_EXPORT void UpdateFaceInfo(BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
@@ -447,7 +476,11 @@ protected:
 
   //! Creates new edge from the edge nE with vertices nV1 and nV2
   //! and returns the index of that new edge in the DS.
-  Standard_EXPORT Standard_Integer SplitEdge (const Standard_Integer nE, const Standard_Integer nV1, const Standard_Real aT1, const Standard_Integer nV2, const Standard_Real aT2);
+  Standard_EXPORT Standard_Integer SplitEdge (const Standard_Integer nE,
+                                              const Standard_Integer nV1,
+                                              const Standard_Real    aT1,
+                                              const Standard_Integer nV2,
+                                              const Standard_Real    aT2);
   
 
   //! Updates pave blocks which have the paves with indices contained
@@ -526,7 +559,8 @@ protected:
   Standard_EXPORT void CheckSelfInterference();
 
   //! Adds the warning about failed intersection of pair of sub-shapes
-  Standard_EXPORT void AddIntersectionFailedWarning(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2);
+  Standard_EXPORT void AddIntersectionFailedWarning(const TopoDS_Shape& theS1,
+                                                    const TopoDS_Shape& theS2);
 
   //! Repeat intersection of sub-shapes with increased vertices.
   Standard_EXPORT void RepeatIntersection();
index 871d738..9588e57 100644 (file)
@@ -487,10 +487,10 @@ void BOPAlgo_PaveFiller::MakeBlocks()
       BOPDS_Curve& aNC=aVC.ChangeValue(j);
       const IntTools_Curve& aIC=aNC.Curve();
       //
-      PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol, aDMVLV);
+      PutStickPavesOnCurve(aF1, aF2, aMI, aVC, j, aMVStick, aMVTol, aDMVLV);
       //904/F7
       if (aNbC == 1) {
-        PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol, aDMVLV);
+        PutEFPavesOnCurve(aVC, j, aMI, aMVEF, aMVTol, aDMVLV);
       }
       //
       if (aIC.HasBounds()) {
@@ -814,12 +814,7 @@ void BOPAlgo_PaveFiller::PostTreatFF
     TColStd_MapOfInteger aMV, aMVEF, aMI;
     GetStickVertices(nF1, nF2, aMV, aMVEF, aMI);
     BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
-    Standard_Integer aNbC = aVC.Length();
-    for (j = 0; j < aNbC; j++)
-    {
-      BOPDS_Curve& aNC = aVC.ChangeValue(j);
-      RemoveUsedVertices(aNC, aMV);
-    }
+    RemoveUsedVertices (aVC, aMV);
 
     TColStd_MapIteratorOfMapOfInteger itmap(aMV);
     for(; itmap.More(); itmap.Next())
@@ -1650,13 +1645,13 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
 //purpose  : 
 //=======================================================================
 static void getBoundPaves(const BOPDS_DS* theDS,
-                          BOPDS_Curve& theNC,
+                          const BOPDS_Curve& theNC,
                           Standard_Integer theNV[2])
 {
   theNV[0] = theNV[1] = -1;
 
   // get extreme paves
-  Handle(BOPDS_PaveBlock)& aPB = theNC.ChangePaveBlock1();
+  const Handle(BOPDS_PaveBlock)& aPB = theNC.PaveBlocks().First();
   const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
   Standard_Integer aNbEP = aLP.Extent();
   if (aNbEP == 0)
@@ -2062,7 +2057,8 @@ void BOPAlgo_PaveFiller::GetEFPnts
 //purpose  : 
 //=======================================================================
   void BOPAlgo_PaveFiller::PutEFPavesOnCurve
-  (BOPDS_Curve& aNC,
+  (const BOPDS_VectorOfCurve& theVC, 
+   const Standard_Integer theIndex,
    const TColStd_MapOfInteger& aMI,
    const TColStd_MapOfInteger& aMVEF,
    TColStd_DataMapOfIntegerReal& aMVTol,
@@ -2072,6 +2068,7 @@ void BOPAlgo_PaveFiller::GetEFPnts
     return;
   }
   //
+  const BOPDS_Curve& aNC = theVC.Value(theIndex);
   const IntTools_Curve& aIC=aNC.Curve();
   GeomAbs_CurveType aTypeC;
   aTypeC=aIC.Type();
@@ -2083,7 +2080,7 @@ void BOPAlgo_PaveFiller::GetEFPnts
   TColStd_MapOfInteger aMV;
   //
   aMV.Assign(aMVEF);
-  RemoveUsedVertices(aNC, aMV);
+  RemoveUsedVertices(theVC, aMV);
   if (!aMV.Extent()) {
     return;
   }
@@ -2117,11 +2114,13 @@ void BOPAlgo_PaveFiller::GetEFPnts
   (const TopoDS_Face& aF1,
    const TopoDS_Face& aF2,
    const TColStd_MapOfInteger& aMI,
-   BOPDS_Curve& aNC,
+   const BOPDS_VectorOfCurve& theVC,
+   const Standard_Integer theIndex,
    const TColStd_MapOfInteger& aMVStick,
    TColStd_DataMapOfIntegerReal& aMVTol,
    TColStd_DataMapOfIntegerListOfInteger& aDMVLV)
 {
+  const BOPDS_Curve& aNC = theVC.Value(theIndex);
   // Get numbers of vertices assigned to the ends of the curve
   Standard_Integer aBndNV[2];
   getBoundPaves(myDS, aNC, aBndNV);
@@ -2132,7 +2131,7 @@ void BOPAlgo_PaveFiller::GetEFPnts
   }
   TColStd_MapOfInteger aMV;
   aMV.Assign(aMVStick);
-  RemoveUsedVertices(aNC, aMV);
+  RemoveUsedVertices(theVC, aMV);
   //
   if (!aMV.Extent()) {
     return;
@@ -2142,7 +2141,6 @@ void BOPAlgo_PaveFiller::GetEFPnts
   Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
   //
   const IntTools_Curve& aIC=aNC.Curve();
-  //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
   Handle(Geom2d_Curve) aC2D[2];
   //
   aC2D[0]=aIC.FirstCurve2d();
@@ -2237,6 +2235,7 @@ void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
         aInt->Indices(nS1, nS2);
         if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
           nVNew = aInt->IndexNew();
+          myDS->HasShapeSD (nVNew, nVNew);
           aMVStick.Add(nVNew);
         }
       }
@@ -2249,6 +2248,7 @@ void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
       aInt.Indices(nS1, nS2);
       if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
         nVNew = aInt.IndexNew();
+        myDS->HasShapeSD (nVNew, nVNew);
         aMVStick.Add(nVNew);
         aMVEF.Add(nVNew);
       }
@@ -2281,24 +2281,28 @@ void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
 // function: RemoveUsedVertices
 // purpose: 
 //=======================================================================
-void BOPAlgo_PaveFiller::RemoveUsedVertices(const BOPDS_Curve& aNC,
+void BOPAlgo_PaveFiller::RemoveUsedVertices(const BOPDS_VectorOfCurve& aVC,
                                             TColStd_MapOfInteger& aMV)
 {
   if (aMV.IsEmpty())
     return;
 
-  const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
-  BOPDS_ListIteratorOfListOfPaveBlock itPB(aLPBC);
-  for (; itPB.More(); itPB.Next())
+  for (Standard_Integer i = 0; i < aVC.Length(); ++i)
   {
-    const Handle(BOPDS_PaveBlock)& aPB = itPB.Value();
-    const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
-    BOPDS_ListIteratorOfListOfPave itLP(aLP);
-    for (; itLP.More(); itLP.Next())
-      aMV.Remove(itLP.Value().Index());
-
-    aMV.Remove(aPB->Pave1().Index());
-    aMV.Remove(aPB->Pave2().Index());
+    const BOPDS_Curve& aNC = aVC.Value(i);
+    const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
+    BOPDS_ListIteratorOfListOfPaveBlock itPB(aLPBC);
+    for (; itPB.More(); itPB.Next())
+    {
+      const Handle(BOPDS_PaveBlock)& aPB = itPB.Value();
+      const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
+      BOPDS_ListIteratorOfListOfPave itLP(aLP);
+      for (; itLP.More(); itLP.Next())
+        aMV.Remove(itLP.Value().Index());
+    
+      aMV.Remove(aPB->Pave1().Index());
+      aMV.Remove(aPB->Pave2().Index());
+    }
   }
 }
 
index e1ee922..a3a8a73 100644 (file)
@@ -428,8 +428,10 @@ void IntAna_Curve::FindParameter(const gp_Pnt& theP,
                                  TColStd_ListOfReal& theParams) const
 {
   const Standard_Real aPIpPI = M_PI + M_PI,
-                      anEpsAng = 1.e-8,
-                      aSqTolPrecision=1.0e-8;
+    anEpsAng = 1.e-8,
+    InternalPrecision = 1.e-8, //precision of internal algorithm of values computation
+    aSqTolPrecision = Precision::SquareConfusion(); //for boundary points to check their coincidence with others
+  
   Standard_Real aTheta = 0.0;
   //
   switch (typequadric)
@@ -494,7 +496,15 @@ void IntAna_Curve::FindParameter(const gp_Pnt& theP,
     InternalUVValue(aParams[i], U, V, A, B, C, 
                     cost, sint, SigneSqrtDis);
     const gp_Pnt aP(InternalValue(U, V));
-    if (aP.SquareDistance(theP) < aSqTolPrecision)
+    
+    Standard_Real aSqTol;
+    if (aParams[i] == aTheta ||
+        (TwoCurves && aParams[i] == DomainSup + DomainSup - aTheta))
+      aSqTol = InternalPrecision;
+    else
+      aSqTol = aSqTolPrecision;
+    
+    if (aP.SquareDistance(theP) < aSqTol)
     {
       theParams.Append(aParams[i]);
     }
index f979b5e..abbcbff 100644 (file)
 // commercial license or contractual agreement.
 
 #include <algorithm>
+#include <memory>
 #include <TopoDS_Edge.hxx>
 #include <Geom_Curve.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <Adaptor3d_HSurface.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+#include <Adaptor3d_HCurveOnSurface.hxx>
 #include <GeomAbs_SurfaceType.hxx>
 #include <BRep_Tool.hxx>
 #include <Geom_Line.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_CylindricalSurface.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_ToroidalSurface.hxx>
 #include <gp_Lin.hxx>
 #include <gp_Vec.hxx>
 #include <gp_Dir.hxx>
 #include <gp_Lin.hxx>
 
 #include <GeomAdaptor_Curve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
 #include <Precision.hxx>
 #include <Extrema_ExtCC.hxx>
+//#include <Extrema_ExtCS.hxx>
 #include <Extrema_POnCurv.hxx>
+#include <IntCurveSurface_HInter.hxx>
 
 #include <math_FunctionSample.hxx>
 #include <math_FunctionAllRoots.hxx>
 #include <math_Vector.hxx>
 #include <NCollection_Array1.hxx>
 
+#ifdef OCCT_DEBUG
+#include <Geom_Circle.hxx>
+#include <Geom_Ellipse.hxx>
+#include <Geom_Hyperbola.hxx>
+#include <Geom_Parabola.hxx>
+#include <Geom_BezierCurve.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <GeomLib.hxx>
+#endif
+
+
+static Standard_Boolean IsDegenerated(const Handle(Adaptor3d_HCurveOnSurface)& theCurve);
+static Standard_Boolean IsDegenerated(const IntSurf_Quadric& theQuadric);
+
 static void FindVertex (const TheArc&,
                         const Handle(TheTopolTool)&,
                         TheFunction&,
@@ -149,6 +174,30 @@ void FindVertex (const TheArc& A,
   }
 }
 
+Standard_Boolean IsDegenerated(const Handle(Adaptor3d_HCurveOnSurface)& theCurve)
+{
+  if (theCurve->GetType() == GeomAbs_Circle)
+  {
+    gp_Circ aCirc = theCurve->Circle();
+    if (aCirc.Radius() <= Precision::Confusion())
+      return Standard_True;
+  }
+  return Standard_False;
+}
+
+Standard_Boolean IsDegenerated(const IntSurf_Quadric& theQuadric)
+{
+  GeomAbs_SurfaceType TypeQuad = theQuadric.TypeQuadric();
+  if (TypeQuad == GeomAbs_Cone)
+  {
+    gp_Cone aCone = theQuadric.Cone();
+    Standard_Real aSemiAngle = Abs(aCone.SemiAngle());
+    if (aSemiAngle < 0.02 || aSemiAngle > 1.55)
+      return Standard_True;
+  }
+  return Standard_False;
+}
+
 class SolInfo
 {
 public:
@@ -162,6 +211,12 @@ public:
     myValue = theSolution.GetPoint(theIndex);
   }
 
+  void Init(const IntCurveSurface_HInter& theSolution, const Standard_Integer theIndex)
+  {
+    myMathIndex = theIndex;
+    myValue = theSolution.Point(theIndex).W();
+  }
+
   Standard_Real Value() const
   {
     return myValue;
@@ -215,13 +270,12 @@ void BoundedArc (const TheArc& A,
   // des arcs ayant un point debut et un point de fin (intervalle ferme de
   // parametrage).
 
-  Standard_Integer i,Nbi,Nbp;
+  Standard_Integer i, Nbi = 0, Nbp = 0;
 
   gp_Pnt ptdeb,ptfin;
   Standard_Real pardeb = 0., parfin = 0.;
   Standard_Integer ideb,ifin,range,ranged,rangef;
 
-
   // Creer l echantillonage (math_FunctionSample ou classe heritant)
   // Appel a math_FunctionAllRoots
 
@@ -238,7 +292,9 @@ void BoundedArc (const TheArc& A,
 
   //  Standard_Integer NbEchant = TheSOBTool::NbSamplesOnArc(A); 
   Standard_Integer NbEchant = Func.NbSamples(); 
-
+  if(NbEchant<100) NbEchant = 100; //-- lbr le 22 Avril 96 
+  //-- Toujours des pbs 
+  
   //-- Modif 24  Aout 93 -----------------------------
   Standard_Real nTolTangency = TolTangency;
   if((Pfin - Pdeb) < (TolTangency*10.0)) { 
@@ -247,6 +303,7 @@ void BoundedArc (const TheArc& A,
   if(EpsX>(nTolTangency+nTolTangency)) { 
     EpsX = nTolTangency * 0.1; 
   }
+
   //--------------------------------------------------
   //-- Plante avec un edge avec 2 Samples  
   //-- dont les extremites son solutions (f=0) 
@@ -255,11 +312,6 @@ void BoundedArc (const TheArc& A,
   //-- if(NbEchant<3) NbEchant = 3; //-- lbr le 19 Avril 95
   //--------------------------------------------------
   Standard_Real para=0,dist,maxdist;
-  /*  if(NbEchant<20) NbEchant = 20; //-- lbr le 22 Avril 96 
-  //-- Toujours des pbs 
-  */
-  if(NbEchant<100) NbEchant = 100; //-- lbr le 22 Avril 96 
-  //-- Toujours des pbs 
   
   //-------------------------------------------------------------- REJECTIONS le 15 oct 98 
   Standard_Boolean Rejection=Standard_True;  
@@ -298,7 +350,21 @@ void BoundedArc (const TheArc& A,
 
   Arcsol=Standard_False;
 
-  if(Rejection==Standard_False) { 
+  if(Rejection==Standard_False)
+  {
+    const IntSurf_Quadric& aQuadric = Func.Quadric();
+    GeomAbs_SurfaceType TypeQuad = aQuadric.TypeQuadric();
+    
+    IntCurveSurface_HInter IntCS;
+    Standard_Boolean IsIntCSdone = Standard_False;
+    TColStd_SequenceOfReal Params;
+    
+#if (defined(_MSC_VER) && (_MSC_VER < 1600))
+    std::auto_ptr<math_FunctionAllRoots>  pSol;
+#else
+    std::unique_ptr<math_FunctionAllRoots> pSol;
+#endif  
+    
     math_FunctionSample Echant(Pdeb,Pfin,NbEchant);
 
     Standard_Boolean aelargir=Standard_True;
@@ -320,11 +386,128 @@ void BoundedArc (const TheArc& A,
       maxdist = TolBoundary;
     }
 
-    math_FunctionAllRoots Sol(Func,Echant,EpsX,maxdist,maxdist); //-- TolBoundary,nTolTangency);
-
-    if (!Sol.IsDone()) {throw Standard_Failure();}
+    if (TypeQuad != GeomAbs_OtherSurface) //intersection of boundary curve and quadric surface
+    {
+      //Exact solution
+      Handle(Adaptor3d_HSurface) aSurf = Func.Surface();
+      Adaptor3d_CurveOnSurface ConS(A, aSurf);
+      GeomAbs_CurveType TypeConS = ConS.GetType();
+#ifdef OCCT_DEBUG
+      Handle(Geom_Curve) CurveConS;
+      switch(TypeConS)
+      {
+      case GeomAbs_Line:
+        {
+          CurveConS = new Geom_Line(ConS.Line());
+          break;
+        }
+      case GeomAbs_Circle:
+        {
+          CurveConS = new Geom_Circle(ConS.Circle());
+          break;
+        }
+      case GeomAbs_Ellipse:
+        {
+          CurveConS = new Geom_Ellipse(ConS.Ellipse());
+          break;
+        }
+      case GeomAbs_Hyperbola:
+        {
+          CurveConS = new Geom_Hyperbola(ConS.Hyperbola());
+          break;
+        }
+      case GeomAbs_Parabola:
+        {
+          CurveConS = new Geom_Parabola(ConS.Parabola());
+          break;
+        }
+      case GeomAbs_BezierCurve:
+        {
+          CurveConS = ConS.Bezier();
+          break;
+        }
+      case GeomAbs_BSplineCurve:
+        {
+          CurveConS = ConS.BSpline();
+          break;
+        }
+      default:
+        {
+          Standard_Real MaxDeviation, AverageDeviation;
+          GeomLib::BuildCurve3d(1.e-5, ConS, ConS.FirstParameter(), ConS.LastParameter(),
+                                CurveConS, MaxDeviation, AverageDeviation);
+          break;
+        }
+      }
+#endif
+      Handle(Adaptor3d_HCurveOnSurface) HConS = new Adaptor3d_HCurveOnSurface(ConS);
+      Handle(Geom_Surface) QuadSurf;
+      switch (TypeQuad)
+      {
+      case GeomAbs_Plane:
+        {
+          QuadSurf = new Geom_Plane(aQuadric.Plane());
+          break;
+        }
+      case GeomAbs_Cylinder:
+        {
+          QuadSurf = new Geom_CylindricalSurface(aQuadric.Cylinder());
+          break;
+        }
+      case GeomAbs_Cone:
+        {
+          QuadSurf = new Geom_ConicalSurface(aQuadric.Cone());
+          break;
+        }
+      case GeomAbs_Sphere:
+        {
+          QuadSurf = new Geom_SphericalSurface(aQuadric.Sphere());
+          break;
+        }
+      case GeomAbs_Torus:
+        {
+          QuadSurf = new Geom_ToroidalSurface(aQuadric.Torus());
+          break;
+        }
+      default:
+        break;
+      }
+      Handle(GeomAdaptor_HSurface) GAHsurf = new GeomAdaptor_HSurface(QuadSurf);
+      
+      if ((TypeConS == GeomAbs_Line ||
+           TypeConS == GeomAbs_Circle ||
+           TypeConS == GeomAbs_Ellipse ||
+           TypeConS == GeomAbs_Parabola ||
+           TypeConS == GeomAbs_Hyperbola) &&
+          TypeQuad != GeomAbs_Torus &&
+          !IsDegenerated(HConS) &&
+          !IsDegenerated(aQuadric))
+      {
+        //exact intersection for only canonic curves and real quadric surfaces
+        IntCS.Perform(HConS, GAHsurf);
+      }
+      
+      IsIntCSdone = IntCS.IsDone();
+      if (IsIntCSdone)
+      {
+        Nbp = IntCS.NbPoints();
+        Nbi = IntCS.NbSegments();
+      }
+      //If we have not got intersection, it may be touch with some tolerance,
+      //need to be checked
+      if (Nbp == 0 && Nbi == 0)
+        IsIntCSdone = Standard_False;
 
-    Nbp=Sol.NbPoints();
+    } //if (TypeQuad != GeomAbs_OtherSurface) - intersection of boundary curve and quadric surface
+    
+    if (!IsIntCSdone)
+    {
+      pSol.reset(new math_FunctionAllRoots(Func,Echant,EpsX,maxdist,maxdist)); //-- TolBoundary,nTolTangency);
+      
+      if (!pSol->IsDone()) {throw Standard_Failure();}
+      
+      Nbp=pSol->NbPoints();
+    }
     //
     //jgv: build solution on the whole boundary
     if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain))
@@ -387,7 +570,7 @@ void BoundedArc (const TheArc& A,
           return;
         }
       }
-    }
+    } //if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain))
     ////////////////////////////////////////////
 
     //-- detection du cas ou la fonction est quasi tangente et que les 
@@ -400,7 +583,10 @@ void BoundedArc (const TheArc& A,
 
       for(i=1;i<=Nbp;i++)
       {
-        aSI(i).Init(Sol, i);
+        if (IsIntCSdone)
+          aSI(i).Init(IntCS, i);
+        else
+          aSI(i).Init(*pSol, i);
       }
 
       std::sort(aSI.begin(), aSI.end());
@@ -413,10 +599,8 @@ void BoundedArc (const TheArc& A,
       // But we have 2,3,.. solutions.     That is wrong ersult.
       // The TreatLC(...) function is dedicated to solve the pb.
       //                           PKV Fri Mar 23 12:17:29 2001
-      Standard_Integer ip;
-      const IntSurf_Quadric& aQuadric=Func.Quadric();
 
-      ip=TreatLC (A, Domain, aQuadric, TolBoundary, pnt);
+      Standard_Integer ip = TreatLC (A, Domain, aQuadric, TolBoundary, pnt);
       if (ip) {
         //////////////////////////////////////////////////////////
         //modified by NIZNHY-PKV Wed Mar 21 18:34:23 2001 t
@@ -483,19 +667,14 @@ void BoundedArc (const TheArc& A,
           dist = Abs(dist);
 
           Standard_Integer anIndx = -1;
-          const Standard_Real aParam = Sol.GetPoint(aSI(i).Index());
+          //const Standard_Real aParam = Sol->GetPoint(aSI(i).Index());
+          const Standard_Real aParam = aSI(i).Value();
           if (dist < maxdist)
           {
-            if (Abs(aParam - Pdeb) <= Precision::PConfusion() || Abs(aParam - Pfin) <= Precision::PConfusion())
+            if (!IsIntCSdone &&
+                (Abs(aParam - Pdeb) <= Precision::PConfusion() || Abs(aParam - Pfin) <= Precision::PConfusion()))
             {
-              Standard_Real aDistTemp = RealLast();
-              if (Func.Value(aParam, aDistTemp))
-              {
-                if (Abs(aDistTemp) < maxdist)
-                {
-                  anIndx = Sol.GetPointState(aSI(i).Index());
-                }
-              }
+              anIndx = pSol->GetPointState(aSI(i).Index());
             }
           }
 
@@ -535,8 +714,8 @@ void BoundedArc (const TheArc& A,
     //   Traiter les extremites comme des points
     //   Ajouter intervalle dans la liste des segments
 
-    Nbi=Sol.NbIntervals();
-
+    if (!IsIntCSdone)
+      Nbi = pSol->NbIntervals();
 
     if (!RecheckOnRegularity && Nbp) { 
       //--cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx :Nbp>0  0 <- Nbi "<<Nbi<<endl;
@@ -549,14 +728,26 @@ void BoundedArc (const TheArc& A,
       IntStart_TheSegment newseg;
       newseg.SetValue(A);
       // Recuperer point debut et fin, et leur parametre.
-      Sol.GetInterval(i,pardeb,parfin);
-      Sol.GetIntervalState(i,ideb,ifin);
-
-
-      //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<"  ParFin:"<<parfin<<endl;
+      if (IsIntCSdone)
+      {
+        IntCurveSurface_IntersectionSegment IntSeg = IntCS.Segment(i);
+        IntCurveSurface_IntersectionPoint End1 = IntSeg.FirstPoint();
+        IntCurveSurface_IntersectionPoint End2 = IntSeg.SecondPoint();
+        pardeb = End1.W();
+        parfin = End2.W();
+        ptdeb  = End1.Pnt();
+        ptfin  = End2.Pnt();
+      }
+      else
+      {
+        pSol->GetInterval(i,pardeb,parfin);
+        pSol->GetIntervalState(i,ideb,ifin);
 
-      ptdeb=Func.Valpoint(ideb);
-      ptfin=Func.Valpoint(ifin);
+        //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<"  ParFin:"<<parfin<<endl;
+        
+        ptdeb=Func.Valpoint(ideb);
+        ptfin=Func.Valpoint(ifin);
+      }
 
       PointProcess(ptdeb,pardeb,A,Domain,pnt,TolBoundary,ranged);
       newseg.SetLimitPoint(pnt.Value(ranged),Standard_True);
index 7c3ca03..407aa6b 100644 (file)
@@ -19,18 +19,24 @@ checkprops result -s 45.9872
 
 set nbshapes_expected "
 Number of shapes in result
- VERTEX    : 6
- EDGE      : 7
+ VERTEX    : 7
+ EDGE      : 8
  WIRE      : 2
  FACE      : 2
  SHELL     : 1
  SOLID     : 0
  COMPSOLID : 0
  COMPOUND  : 0
- SHAPE     : 18
+ SHAPE     : 20
 "
 checknbshapes result -ref ${nbshapes_expected} -t -m "Result obtained by Boolean cut operation"
 
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 5.e-7} {
+   puts "Error: bad tolerance of result"
+}
+
 checkview -display result -2d -path ${imagedir}/${test_image}.png
 
 
diff --git a/tests/bugs/modalg_7/bug30590_1 b/tests/bugs/modalg_7/bug30590_1
new file mode 100644 (file)
index 0000000..f5d060a
--- /dev/null
@@ -0,0 +1,21 @@
+puts "==============================================="
+puts "OCC30590: Wrong result of Boolean Cut algorithm"
+puts "==============================================="
+puts ""
+
+binrestore [locate_data_file bug30590_cut_argument1.bin] a
+binrestore [locate_data_file bug30590_cut_tool1.bin] b
+
+bcut result a b
+
+checkshape result
+
+checknbshapes result -solid 1 -shell 1 -face 15 -wire 15 -edge 39 -vertex 26
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 0.005} {
+   puts "Error: bad tolerance of result"
+}
+
+checkprops result -v 5639.93 -deps 1.e-7
diff --git a/tests/bugs/modalg_7/bug30590_2 b/tests/bugs/modalg_7/bug30590_2
new file mode 100644 (file)
index 0000000..167f2ee
--- /dev/null
@@ -0,0 +1,21 @@
+puts "==============================================="
+puts "OCC30590: Wrong result of Boolean Cut algorithm"
+puts "==============================================="
+puts ""
+
+binrestore [locate_data_file bug30590_cut_argument1.bin] a
+binrestore [locate_data_file bug30590_cut_tool2.bin] b
+
+bcut result a b
+
+checkshape result
+
+checknbshapes result -solid 1 -shell 1 -face 15 -wire 15 -edge 39 -vertex 26
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 0.005} {
+   puts "Error: bad tolerance of result"
+}
+
+checkprops result -v 5639.78 -deps 1.e-7
diff --git a/tests/bugs/modalg_7/bug30590_3 b/tests/bugs/modalg_7/bug30590_3
new file mode 100644 (file)
index 0000000..b7d9a8d
--- /dev/null
@@ -0,0 +1,21 @@
+puts "==============================================="
+puts "OCC30590: Wrong result of Boolean Cut algorithm"
+puts "==============================================="
+puts ""
+
+binrestore [locate_data_file bug30590_cut_argument1.bin] a
+binrestore [locate_data_file bug30590_cut_tool3.bin] b
+
+bcut result a b
+
+checkshape result
+
+checknbshapes result -solid 1 -shell 1 -face 15 -wire 15 -edge 39 -vertex 26
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 0.005} {
+   puts "Error: bad tolerance of result"
+}
+
+checkprops result -v 5638.15 -deps 1.e-7
index dfbaca3..15b87d7 100644 (file)
@@ -16,7 +16,11 @@ if {[regexp "Faulties" [bopargcheck result]]} {
   puts "Error: bopargcheck has found some faulties in res2"
 }
 
-checkmaxtol result -ref 0.00010921129251073595
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 5.e-6} {
+   puts "Error: bad tolerance of result"
+}
 
 smallview
 don result sw tw
index fe0b13e..0a368a8 100644 (file)
@@ -3,10 +3,6 @@ puts "0029807: Impossible to cut cone from prism"
 puts "========"
 puts ""
 
-puts "TODO OCC29883 ALL: Error in res_2: T=0"
-puts "TODO OCC29883 ALL: Error: 0 vertices are expected but 2 are found"
-puts "TODO OCC29883 ALL: Error :  is WRONG because number of VERTEX entities in shape \"result\" is 3"
-
 foreach a [directory res*] {unset $a}
 
 binrestore [locate_data_file bug29807_f1.bin] f1
index b014c19..1fe6ae0 100644 (file)
@@ -3,9 +3,7 @@ puts "OCC29972: Intersection curve has a weird gap in the middle of it"
 puts "========"
 puts ""
 
-puts "TODO OCC27243 ALL: Error: The curve res_1 possibly has a bend"
-
-set GoodNbCurves 2
+set GoodNbCurves 1
 
 foreach a [directory res*] {unset $a}
 
index c4005f6..abfdc2f 100644 (file)
@@ -3,9 +3,7 @@ puts "OCC29972: Intersection curve has a weird gap in the middle of it"
 puts "========"
 puts ""
 
-puts "TODO OCC27243 ALL: Error: The curve res_1 possibly has a bend"
-
-set GoodNbCurves 2
+set GoodNbCurves 1
 
 foreach a [directory res*] {unset $a}