Salome HOME
0023588: [CEA 2272] : GEOM test failed after transition to OCC 7.3
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IMeasureOperations.cxx
index ff068838bd5d74eac566d94419c90255dc2eb83b..a06332644285efcee503ab9dcc6dbfac9d83bc89 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -20,8 +20,6 @@
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#include <Basics_OCCTVersion.hxx>
-
 #include <GEOMImpl_IMeasureOperations.hxx>
 #include <GEOMImpl_IMeasure.hxx>
 #include <GEOMImpl_MeasureDriver.hxx>
 // OCCT Includes
 #include <Bnd_Box.hxx>
 #include <BOPAlgo_CheckerSI.hxx>
-#include <BOPCol_ListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
 #include <BOPDS_DS.hxx>
-#include <BOPDS_MapOfPassKey.hxx>
+#include <BOPDS_MapOfPair.hxx>
+#include <BOPDS_Pair.hxx>
 #include <BRepBndLib.hxx>
 #include <BRepBuilderAPI_Copy.hxx>
 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
 #include <BRepClass_FaceClassifier.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepExtrema_ShapeProximity.hxx>
-#if OCC_VERSION_LARGE > 0x06090000
 #include <BRepExtrema_SelfIntersection.hxx>
 #include <BRepExtrema_MapOfIntegerPackedMapOfInteger.hxx>
-#endif
 #include <BRepGProp.hxx>
 #include <BRepTools.hxx>
 #include <BRep_Tool.hxx>
@@ -63,6 +60,7 @@
 #include <GeomAPI_ProjectPointOnSurf.hxx>
 #include <GeomLProp_CLProps.hxx>
 #include <GeomLProp_SLProps.hxx>
+#include <Geom_Plane.hxx>
 #include <GProp_GProps.hxx>
 #include <GProp_PrincipalProps.hxx>
 #include <ShapeAnalysis.hxx>
@@ -85,8 +83,8 @@
  *  Constructor
  */
 //=============================================================================
-GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine, int theDocID)
-: GEOM_IOperations(theEngine, theDocID)
+GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine)
+: GEOM_IOperations(theEngine)
 {
   MESSAGE("GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations");
 }
@@ -140,14 +138,48 @@ GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
   GEOMAlgo_ShapeInfoFiller aSF;
   aSF.SetShape(aShape);
   aSF.Perform();
+
   Standard_Integer iErr = aSF.ErrorStatus();
+
   if (iErr) {
     SetErrorCode("Error in GEOMAlgo_ShapeInfoFiller");
     return SK_NO_SHAPE;
   }
   const GEOMAlgo_ShapeInfo& anInfo = aSF.Info();
 
-  // Interprete results
+  // specific processing for some "advanced" objects
+  switch ( geom_type ) {
+  case GEOM_MARKER:
+    // local coordinate system
+    // (+) geompy.kind.LCS  xc yc zc xx xy xz yx yy yz zx zy zz
+
+    TopoDS_Face aFace = TopoDS::Face( aShape );
+    Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast( BRep_Tool::Surface( aFace ) );
+    gp_Pnt aC = aPlane->Pln().Location();
+    gp_Ax3 anAx3 = aPlane->Pln().Position();
+
+    theDoubles->Append(aC.X());
+    theDoubles->Append(aC.Y());
+    theDoubles->Append(aC.Z());
+    
+    gp_Dir aD = anAx3.XDirection();
+    theDoubles->Append(aD.X());
+    theDoubles->Append(aD.Y());
+    theDoubles->Append(aD.Z());
+    aD = anAx3.YDirection();
+    theDoubles->Append(aD.X());
+    theDoubles->Append(aD.Y());
+    theDoubles->Append(aD.Z());
+    aD = anAx3.Direction();
+    theDoubles->Append(aD.X());
+    theDoubles->Append(aD.Y());
+    theDoubles->Append(aD.Z());
+
+    SetErrorCode(OK);
+    return SK_LCS;
+  }
+
+  // Interpret results
   TopAbs_ShapeEnum aType = anInfo.Type();
   switch (aType)
   {
@@ -528,35 +560,22 @@ GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
           theDoubles->Append(aD.X());
           theDoubles->Append(aD.Y());
           theDoubles->Append(aD.Z());
+
+          if (anInfo.KindOfBounds() != GEOMAlgo_KB_INFINITE)
+          {
+            // (+) geompy.kind.PLANAR  xo yo zo  dx dy dz  nb_edges nb_vertices
+            aKind = SK_PLANAR;
+            
+            theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+            theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
+          }
         }
         break;
       default:
-        if (anInfo.KindOfShape() == GEOMAlgo_KS_PLANE) {
-          // (+) geompy.kind.PLANAR  xo yo zo  dx dy dz  nb_edges nb_vertices
-
-          aKind = SK_PLANAR;
-
-          gp_Pnt aC = anInfo.Location();
-          theDoubles->Append(aC.X());
-          theDoubles->Append(aC.Y());
-          theDoubles->Append(aC.Z());
-
-          gp_Ax3 anAx3 = anInfo.Position();
-          gp_Dir aD = anAx3.Direction();
-          theDoubles->Append(aD.X());
-          theDoubles->Append(aD.Y());
-          theDoubles->Append(aD.Z());
-
-          theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
-          theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
-        }
-        else {
-          // ??? geompy.kind.FACE  nb_edges nb_vertices _surface_type_id_
-          // (+) geompy.kind.FACE  nb_edges nb_vertices
-
-          theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
-          theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
-        }
+        // ??? geompy.kind.FACE  nb_edges nb_vertices _surface_type_id_
+        // (+) geompy.kind.FACE  nb_edges nb_vertices
+        theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
+        theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
       }
     }
     break;
@@ -717,6 +736,7 @@ GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
       theDoubles->Append(aP.Z());
     }
     break;
+  default:;
   }
 
   SetErrorCode(OK);
@@ -765,9 +785,8 @@ void GEOMImpl_IMeasureOperations::GetPosition
     aDirZ.Coord(Zx, Zy, Zz);
     aDirX.Coord(Xx, Xy, Xz);
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return;
   }
 
@@ -787,7 +806,7 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
   if (theShape.IsNull()) return NULL;
 
   //Add a new CentreOfMass object
-  Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GetDocID(), GEOM_CDG);
+  Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GEOM_CDG);
 
   //Add a new CentreOfMass function
   Handle(GEOM_Function) aFunction =
@@ -812,9 +831,8 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -842,7 +860,7 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetVertexByIndex
   if (aRefShape.IsNull()) return NULL;
 
   //Add a new Vertex object
-  Handle(GEOM_Object) aVertex = GetEngine()->AddObject(GetDocID(), GEOM_POINT);
+  Handle(GEOM_Object) aVertex = GetEngine()->AddObject(GEOM_POINT);
 
   //Add a function
   Handle(GEOM_Function) aFunction =
@@ -864,9 +882,8 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetVertexByIndex
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -891,7 +908,7 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
   if (theFace.IsNull()) return NULL;
 
   //Add a new Normale object
-  Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GetDocID(), GEOM_VECTOR);
+  Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GEOM_VECTOR);
 
   //Add a new Normale function
   Handle(GEOM_Function) aFunction =
@@ -921,9 +938,8 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -945,6 +961,7 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
  */
 //=============================================================================
 void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theShape,
+                                                      const Standard_Real theTolerance,
                                                       Standard_Real& theLength,
                                                       Standard_Real& theSurfArea,
                                                       Standard_Real& theVolume)
@@ -964,26 +981,26 @@ void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theSha
 
   //Compute the parameters
   GProp_GProps LProps, SProps;
+  Standard_Real anEps = theTolerance >= 0 ? theTolerance : 1.e-6;
   try {
     OCC_CATCH_SIGNALS;
-    BRepGProp::LinearProperties(aShape, LProps);
+    BRepGProp::LinearProperties(aShape, LProps, Standard_True);
     theLength = LProps.Mass();
 
-    BRepGProp::SurfaceProperties(aShape, SProps);
+    BRepGProp::SurfaceProperties(aShape, SProps, anEps, Standard_True);
     theSurfArea = SProps.Mass();
 
     theVolume = 0.0;
     if (aShape.ShapeType() < TopAbs_SHELL) {
       for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
         GProp_GProps VProps;
-        BRepGProp::VolumeProperties(Exp.Current(), VProps);
+        BRepGProp::VolumeProperties(Exp.Current(), VProps, anEps, Standard_True);
         theVolume += VProps.Mass();
       }
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return;
   }
 
@@ -1023,12 +1040,12 @@ void GEOMImpl_IMeasureOperations::GetInertia
     if (aShape.ShapeType() == TopAbs_VERTEX ||
         aShape.ShapeType() == TopAbs_EDGE ||
         aShape.ShapeType() == TopAbs_WIRE) {
-      BRepGProp::LinearProperties(aShape, System);
+      BRepGProp::LinearProperties(aShape, System, Standard_True);
     } else if (aShape.ShapeType() == TopAbs_FACE ||
                aShape.ShapeType() == TopAbs_SHELL) {
-      BRepGProp::SurfaceProperties(aShape, System);
+      BRepGProp::SurfaceProperties(aShape, System, Standard_True);
     } else {
-      BRepGProp::VolumeProperties(aShape, System);
+      BRepGProp::VolumeProperties(aShape, System, Standard_True);
     }
     gp_Mat I = System.MatrixOfInertia();
 
@@ -1047,9 +1064,8 @@ void GEOMImpl_IMeasureOperations::GetInertia
     GProp_PrincipalProps Pr = System.PrincipalProperties();
     Pr.Moments(Ix,Iy,Iz);
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return;
   }
 
@@ -1108,9 +1124,8 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
 
     B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return;
   }
 
@@ -1131,7 +1146,7 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
   if (theShape.IsNull()) return NULL;
 
   //Add a new BoundingBox object
-  Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
+  Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GEOM_BOX);
 
   //Add a new BoundingBox function
   const int aType = (precise ? BND_BOX_MEASURE_PRECISE : BND_BOX_MEASURE);
@@ -1157,9 +1172,8 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -1234,9 +1248,8 @@ void GEOMImpl_IMeasureOperations::GetTolerance
         VertMin = T;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return;
   }
 
@@ -1277,9 +1290,8 @@ bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object)     theShape,
       FillErrors(ana, aShape, theErrors);
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return false;
   }
 
@@ -1539,7 +1551,7 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
   TopTools_IndexedMapOfShape anIndices;
   TopExp::MapShapes(aScopy, anIndices);
 
-  BOPCol_ListOfShape aLCS;
+  TopTools_ListOfShape aLCS;
   aLCS.Append(aScopy);
   //
   BOPAlgo_CheckerSI aCSI; // checker of self-interferences
@@ -1548,22 +1560,22 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
 
   // 1. Launch the checker
   aCSI.Perform();
-  Standard_Integer iErr = aCSI.ErrorStatus();
+  Standard_Boolean iErr = aCSI.HasErrors();
 
   //
   Standard_Integer aNbS, n1, n2;
-  BOPDS_MapIteratorMapOfPassKey aItMPK;
+  BOPDS_MapIteratorOfMapOfPair aItMPK;
   //
   // 2. Take the shapes from DS
   const BOPDS_DS& aDS = aCSI.DS();
   aNbS=aDS.NbShapes();
   //
   // 3. Get the pairs of interfered shapes
-  const BOPDS_MapOfPassKey& aMPK=aDS.Interferences();
+  const BOPDS_MapOfPair& aMPK=aDS.Interferences();
   aItMPK.Initialize(aMPK);
   for (; aItMPK.More(); aItMPK.Next()) {
-    const BOPDS_PassKey& aPK=aItMPK.Value();
-    aPK.Ids(n1, n2);
+    const BOPDS_Pair& aPK=aItMPK.Value();
+    aPK.Indices(n1, n2);
     //
     if (n1 > aNbS || n2 > aNbS){
       return false; // Error
@@ -1589,7 +1601,7 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
 //=============================================================================
 bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast
                          (Handle(GEOM_Object) theShape,
-                         float theDeflection, double theTolerance,
+                          float theDeflection, double theTolerance,
                           Handle(TColStd_HSequenceOfInteger)& theIntersections)
 {
   SetErrorCode(KO);
@@ -1618,7 +1630,6 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast
   TopTools_IndexedMapOfShape anIndices;
   TopExp::MapShapes(aScopy, anIndices);
 
-#if OCC_VERSION_LARGE > 0x06090000
   // Checker of fast interferences
   BRepExtrema_SelfIntersection aTool(aScopy, (theTolerance <= 0.) ? 0.0 : theTolerance);
 
@@ -1646,11 +1657,44 @@ bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast
 
   if (aTool.IsDone())
     SetErrorCode(OK);
-#endif
 
   return theIntersections->IsEmpty();
 }
 
+//=============================================================================
+/*!
+ *  CheckBOPArguments
+ */
+//=============================================================================
+bool GEOMImpl_IMeasureOperations::CheckBOPArguments
+                                      (const Handle(GEOM_Object) &theShape)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull()) {
+    return false;
+  }
+
+  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+
+  if (aRefShape.IsNull()) {
+    return false;
+  }
+
+  TopoDS_Shape aShape = aRefShape->GetValue();
+
+  if (aShape.IsNull()) {
+    return false;
+  }
+
+  //Compute the parameters
+  bool isValid = GEOMUtils::CheckBOPArguments(aShape);
+
+  SetErrorCode(OK);
+
+  return isValid;
+}
+
 //=============================================================================
 /*!
  *  FastIntersect
@@ -1704,7 +1748,7 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1,
   TopExp::MapShapes(aScopy1, anIndices1);
   TopExp::MapShapes(aScopy2, anIndices2);
 
-  BOPCol_ListOfShape aLCS1, aLCS2;
+  TopTools_ListOfShape aLCS1, aLCS2;
   aLCS1.Append(aScopy1); aLCS2.Append(aScopy2);
   //
   BRepExtrema_ShapeProximity aBSP; // checker of fast interferences
@@ -1715,21 +1759,13 @@ bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1,
   aBSP.Perform();
  
   // 2. Get sets of IDs of overlapped faces
-#if OCC_VERSION_LARGE > 0x06090000
   for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
-#else
-  for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
-#endif
   {
     const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key());
     theIntersections1->Append(anIndices1.FindIndex(aS1));
   }
   
-#if OCC_VERSION_LARGE > 0x06090000
   for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
-#else
-  for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
-#endif
   {
     const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key());
     theIntersections2->Append(anIndices2.FindIndex(aS2));
@@ -1846,7 +1882,7 @@ TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object)
           aListOfShape.Append(s);
           nbTypes[s.ShapeType()]++;
           if ((sp.ShapeType() == TopAbs_COMPOUND) || (sp.ShapeType() == TopAbs_COMPSOLID)) {
-           nbFlatType[s.ShapeType()]++;
+            nbFlatType[s.ShapeType()]++;
           }
         }
       }
@@ -1865,22 +1901,21 @@ TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object)
     if ((aShape.ShapeType() == TopAbs_COMPOUND) || (aShape.ShapeType() == TopAbs_COMPSOLID)){
       Astr = Astr + " --------------------- \n Flat content : \n";
       if (nbFlatType[TopAbs_VERTEX] > 0)
-       Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbFlatType[TopAbs_VERTEX]) + "\n";
+        Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbFlatType[TopAbs_VERTEX]) + "\n";
       if (nbFlatType[TopAbs_EDGE] > 0)
-       Astr = Astr + " EDGE : " + TCollection_AsciiString(nbFlatType[TopAbs_EDGE]) + "\n";
+        Astr = Astr + " EDGE : " + TCollection_AsciiString(nbFlatType[TopAbs_EDGE]) + "\n";
       if (nbFlatType[TopAbs_WIRE] > 0)
-       Astr = Astr + " WIRE : " + TCollection_AsciiString(nbFlatType[TopAbs_WIRE]) + "\n";
+        Astr = Astr + " WIRE : " + TCollection_AsciiString(nbFlatType[TopAbs_WIRE]) + "\n";
       if (nbFlatType[TopAbs_FACE] > 0)
-       Astr = Astr + " FACE : " + TCollection_AsciiString(nbFlatType[TopAbs_FACE]) + "\n";
+        Astr = Astr + " FACE : " + TCollection_AsciiString(nbFlatType[TopAbs_FACE]) + "\n";
       if (nbFlatType[TopAbs_SHELL] > 0)
-       Astr = Astr + " SHELL : " + TCollection_AsciiString(nbFlatType[TopAbs_SHELL]) + "\n";
+        Astr = Astr + " SHELL : " + TCollection_AsciiString(nbFlatType[TopAbs_SHELL]) + "\n";
       if (nbFlatType[TopAbs_SOLID] > 0)
-       Astr = Astr + " SOLID : " + TCollection_AsciiString(nbFlatType[TopAbs_SOLID]) + "\n";
+        Astr = Astr + " SOLID : " + TCollection_AsciiString(nbFlatType[TopAbs_SOLID]) + "\n";
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return Astr;
   }
 
@@ -1956,7 +1991,7 @@ GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object)        theShape
                    project.NbPoints() > 0 &&
                    project.LowerDistance() <= tolerance )
               {
-                Quantity_Parameter u, v;
+                Standard_Real u, v;
                 project.LowerDistanceParameters(u, v);
                 gp_Pnt2d uv( u, v );
                 BRepClass_FaceClassifier FC ( face, uv, tolerance );
@@ -2051,9 +2086,8 @@ GEOMImpl_IMeasureOperations::GetMinDistance (Handle(GEOM_Object) theShape1,
       return MinDist;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return MinDist;
   }
 
@@ -2092,21 +2126,9 @@ Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object)
 
     // skl 30.06.2008
     // additional workaround for bugs 19899, 19908 and 19910 from Mantis
-    gp_Pnt P1, P2;
-    double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1, P2);
-    if (dist > -1.0) {
-      nbSolutions = 1;
-
-      theDoubles->Append(P1.X());
-      theDoubles->Append(P1.Y());
-      theDoubles->Append(P1.Z());
-      theDoubles->Append(P2.X());
-      theDoubles->Append(P2.Y());
-      theDoubles->Append(P2.Z());
-
-      SetErrorCode(OK);
-      return nbSolutions;
-    }
+    gp_Pnt P1s, P2s;
+    double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1s, P2s);
+    bool singularBetter = dist >= 0;
 
     BRepExtrema_DistShapeShape dst (aShape1, aShape2);
     if (dst.IsDone()) {
@@ -2117,19 +2139,35 @@ Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object)
       for (int i = 1; i <= nbSolutions; i++) {
         P1 = dst.PointOnShape1(i);
         P2 = dst.PointOnShape2(i);
-
+       
         theDoubles->Append(P1.X());
         theDoubles->Append(P1.Y());
         theDoubles->Append(P1.Z());
         theDoubles->Append(P2.X());
         theDoubles->Append(P2.Y());
         theDoubles->Append(P2.Z());
+       
+       Standard_Real Dist = P1.Distance(P2);
+       singularBetter = singularBetter && dist < Dist;
       }
     }
+
+    if (singularBetter) {
+      if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
+      else theDoubles->Clear();
+
+      nbSolutions = 1;
+    
+      theDoubles->Append(P1s.X());
+      theDoubles->Append(P1s.Y());
+      theDoubles->Append(P1s.Z());
+      theDoubles->Append(P2s.X());
+      theDoubles->Append(P2s.Y());
+      theDoubles->Append(P2s.Z());
+    }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return nbSolutions;
   }
 
@@ -2170,10 +2208,9 @@ void GEOMImpl_IMeasureOperations::PointCoordinates (Handle(GEOM_Object) theShape
 
     SetErrorCode(OK);
   }
-  catch (Standard_Failure)
+  catch (Standard_Failure& aFail)
   {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode( aFail->GetMessageString() );
+    SetErrorCode( aFail.GetMessageString() );
   }
 }
 
@@ -2243,10 +2280,9 @@ Standard_Real GEOMImpl_IMeasureOperations::GetAngle (Handle(GEOM_Object) theLine
 
     SetErrorCode(OK);
   }
-  catch (Standard_Failure)
+  catch (Standard_Failure& aFail)
   {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+    SetErrorCode(aFail.GetMessageString());
   }
 
   return anAngle;
@@ -2308,10 +2344,9 @@ Standard_Real GEOMImpl_IMeasureOperations::GetAngleBtwVectors (Handle(GEOM_Objec
 
     SetErrorCode(OK);
   }
-  catch (Standard_Failure)
+  catch (Standard_Failure& aFail)
   {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+    SetErrorCode(aFail.GetMessageString());
   }
 
   return anAngle;
@@ -2354,9 +2389,8 @@ Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByParam
     aRes = fabs(Prop.Curvature());
     SetErrorCode(OK);
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return aRes;
   }
 
@@ -2409,9 +2443,8 @@ Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByPoint
       SetErrorCode(OK);
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return aRes;
   }
 
@@ -2461,9 +2494,8 @@ Standard_Real GEOMImpl_IMeasureOperations::getSurfaceCurvatures
       SetErrorCode(OK);
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return aRes;
   }