]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
[bos #29473] [EDF] (2022-T1) Advanced geometry features: conformity of non holed... asozinov/29473
authorAlexey SOZINOV <alexey.sozinov@opencascade.com>
Fri, 22 Apr 2022 10:12:04 +0000 (13:12 +0300)
committerAlexey SOZINOV <alexey.sozinov@opencascade.com>
Wed, 15 Jun 2022 11:09:28 +0000 (14:09 +0300)
15 files changed:
doc/salome/gui/GEOM/CMakeLists.txt
idl/GEOM_Gen.idl
src/GEOMImpl/CMakeLists.txt
src/GEOMImpl/GEOMImpl_ConformityDriver.cxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_ConformityDriver.hxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_Gen.cxx
src/GEOMImpl/GEOMImpl_IConformity.cxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_IConformity.hxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
src/GEOMImpl/GEOMImpl_Types.hxx
src/GEOM_I/GEOM_IMeasureOperations_i.cc
src/GEOM_I/GEOM_IMeasureOperations_i.hh
src/GEOM_SWIG/CMakeLists.txt
src/GEOM_SWIG/CheckConformity.py [new file with mode: 0644]

index 7343b1cb6c30bc23fd614b7484d558190ec72301..66c2f32a29af8dd023b9a01326d04ddfb6798c99 100644 (file)
@@ -59,13 +59,14 @@ ENDIF(WIN32)
 
 ADD_CUSTOM_TARGET(usr_docs ${CMAKE_COMMAND} -E make_directory tmp
   COMMAND ${CMAKE_COMMAND} -E make_directory tmp1
-  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomBuilder.py ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/geomBuilder.py
-  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/gsketcher.py   ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/gsketcher.py
-  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomtools.py   ${CMAKE_SOURCE_DIR}/src/GEOM_PY/geomtools.py
-  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/sketcher.py    ${CMAKE_SOURCE_DIR}/src/GEOM_PY/sketcher.py
-  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/structelem.py  ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/__init__.py
-  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/parts.py       ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/parts.py
-  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/orientation.py ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/orientation.py
+  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomBuilder.py      ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/geomBuilder.py
+  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/gsketcher.py        ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/gsketcher.py
+  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/CheckConformity.py   ${CMAKE_SOURCE_DIR}/src/GEOM_SWIG/CheckConformity.py
+  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/geomtools.py        ${CMAKE_SOURCE_DIR}/src/GEOM_PY/geomtools.py
+  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/sketcher.py         ${CMAKE_SOURCE_DIR}/src/GEOM_PY/sketcher.py
+  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/structelem.py       ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/__init__.py
+  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/parts.py            ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/parts.py
+  COMMAND ${PYTHON_EXECUTABLE} ${f} -o tmp/orientation.py      ${CMAKE_SOURCE_DIR}/src/GEOM_PY/structelem/orientation.py
   COMMAND ${plugins_cmd}
   COMMAND ${DOXYGEN_EXECUTABLE} doxyfile_tui 
   COMMAND ${DOXYGEN_EXECUTABLE} doxyfile_py
@@ -77,7 +78,7 @@ ADD_CUSTOM_TARGET(usr_docs ${CMAKE_COMMAND} -E make_directory tmp
 )
 
 INSTALL(CODE "EXECUTE_PROCESS(COMMAND \"${CMAKE_COMMAND}\" --build ${PROJECT_BINARY_DIR} --target usr_docs)")
-INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/GEOM DESTINATION ${SALOME_INSTALL_DOC}/gui)
+INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DESTINATION ${SALOME_INSTALL_DOC}/gui)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/static/SALOME_BOA_PA.pdf DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/static/ExtractAndRebuild.pdf DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM)
 INSTALL(FILES input/geompy_migration.doc input/tui_auto_completion_documentation.doc input/tui_execution_distribution.doc DESTINATION ${SALOME_INSTALL_DOC}/gui/GEOM/input)
index 6af219e0218a8a0ee87ca98638c011293c1e93cf..cf2fe605b622e5ee358e703cf9e5d0c657be3030 100644 (file)
@@ -4716,6 +4716,91 @@ module GEOM
      */
     double MinSurfaceCurvatureByPoint (in GEOM_Object theShape, in GEOM_Object thePoint);
 
+    //! Methods and structure for implement CheckConformity tool
+
+    /*!
+    *  \brief Structure for store shapes from failed checks.
+    *         If failed check on small edges, then second shape is null
+    */
+    struct PairOfShape
+    {
+      GEOM_Object first;
+      GEOM_Object second;
+    };
+
+    /*!
+    *  \brief Structure for store result of check
+    *  store type of check as number and failed shapes
+    */
+    struct CheckResult
+    {
+      long  type;
+      PairOfShape failedShapes;
+    };
+
+    typedef sequence<PairOfShape> SequenceOfPairOfShape;
+    typedef sequence<CheckResult> CheckResults;
+
+    /*!
+    *  \brief Perform analyse of shape and return all failed checks.
+    *
+    *  \param theShape Shape for check.
+    */
+    CheckResults checkConformityShape(in GEOM_Object theShape);
+
+    /*!
+    *  \brief Find all self-intersected 2D curves.
+    *
+    *  \param theResults result of check - list of failed checks and sub-shapes.
+    */
+    SequenceOfPairOfShape selfIntersected2D(in CheckResults theResults);
+
+    /*!
+    *  \brief Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned.
+    *         Avaliable types:
+    *         - vertices touched by tolerance;
+    *         - vertex touching an edge in the inner point;
+    *         - vertex lying on the inner point of a face;
+    *         - edges intersecting by inner points;
+    *         - edge touching/intersecting face in the inner point;
+    *         - faces intersection by inner point
+    * 
+    *  \param theResults result of check - list of failed checks and sub-shapes.
+    *  \param theShapeType1 Type of shape.
+    *  \param theShapeType2 Type of shape.
+    */
+    SequenceOfPairOfShape interferingSubshapes(in CheckResults theResults,
+                                               in long theShapeType1, in long theShapeType2);
+
+    /*!
+    *  \brief Find edges, which are fully covered by tolerances of vertices.
+    *
+    *  \param theResults result of check - list of failed checks and sub-shapes.
+    */
+    ListOfGO smallEdges(in CheckResults theResults);
+
+    /*!
+    *  \brief find remote objects (sub-shape on a shape).
+    *         Avaliable types:
+    *         - vertex far from edge;
+    *         - vertex far from face;
+    *         - edge far from face
+    *
+    *  \param theShape Shape for check.
+    *  \param theShapeType Type of shape.
+    *  \param theSubShapeType Type of sub-shape.
+    *  \param theTolerance tolerance, by default used tolerance of sub-shape.
+    */
+    SequenceOfPairOfShape distantShapes(in GEOM_Object theShape, in long theShapeType,
+                                        in long theSubShapeType, in double theTolerance);
+
+    /*!
+    *  \brief Compute possible tolerance for the shape, minimize tolerance of shape as well
+    *         as tolerance of sub-shapes as much as possible
+    *
+    *  \param theShape Shape for update.
+    */
+    double updateTolerance(in GEOM_Object theShape);
   };
 
  // # GEOM_IGroupOperations:
@@ -4907,7 +4992,7 @@ module GEOM
     boolean Tesselate(in GEOM_Object shape, in double linearDeflection,
                       in boolean isRelative, in double angularDeflection);
   };
-
   // # GEOM_Gen:
   /*!
    *  \brief Interface to access other GEOM interfaces.
index 26d37c40f7c038220227d5482f9e725b8bd0c555..236c90808dbb862ddc1f661093140356b3af36a5 100644 (file)
@@ -119,6 +119,7 @@ SET(GEOMImpl_HEADERS
   GEOMImpl_IPipePath.hxx
   GEOMImpl_IRevolution.hxx
   GEOMImpl_IMeasure.hxx
+  GEOMImpl_IConformity.hxx
   GEOMImpl_IShapes.hxx
   GEOMImpl_IShapeExtend.hxx
   GEOMImpl_IFilling.hxx
@@ -155,6 +156,7 @@ SET(GEOMImpl_HEADERS
   GEOMImpl_BlockDriver.hxx
   GEOMImpl_Block6Explorer.hxx
   GEOMImpl_MeasureDriver.hxx
+  GEOMImpl_ConformityDriver.hxx
   GEOMImpl_PolylineDriver.hxx
   GEOMImpl_PolylineDumper.hxx
   GEOMImpl_CircleDriver.hxx
@@ -202,6 +204,7 @@ SET(GEOMImpl_SOURCES
   GEOMImpl_ITestOperations.cxx
   GEOMImpl_IPolyline2D.cxx
   GEOMImpl_ITransferData.cxx
+  GEOMImpl_IConformity.cxx
   GEOMImpl_Gen.cxx
   GEOMImpl_PointDriver.cxx
   GEOMImpl_VectorDriver.cxx
@@ -230,6 +233,7 @@ SET(GEOMImpl_SOURCES
   GEOMImpl_BlockDriver.cxx
   GEOMImpl_Block6Explorer.cxx
   GEOMImpl_MeasureDriver.cxx
+  GEOMImpl_ConformityDriver.cxx
   GEOMImpl_PolylineDriver.cxx
   GEOMImpl_PolylineDumper.cxx
   GEOMImpl_CircleDriver.cxx
diff --git a/src/GEOMImpl/GEOMImpl_ConformityDriver.cxx b/src/GEOMImpl/GEOMImpl_ConformityDriver.cxx
new file mode 100644 (file)
index 0000000..87fd774
--- /dev/null
@@ -0,0 +1,385 @@
+// Copyright (C) 2013-2022  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "GEOMImpl_ConformityDriver.hxx"
+
+// internal includes
+#include "GEOMImpl_IConformity.hxx"
+
+// KERNEL includes
+#include <utilities.h>
+#include <Basics_Utils.hxx>
+
+// GEOM includes
+#include "GEOM_Function.hxx"
+#include "GEOMImpl_Types.hxx"
+
+#include <BOPAlgo_ArgumentAnalyzer.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_ReShape.hxx>
+#include <BRepLib.hxx>
+#include <BRep_Tool.hxx>
+
+#include <TopExp_Explorer.hxx>
+#include <GEOMUtils.hxx>
+#include <TColStd_HArray2OfInteger.hxx>
+
+namespace
+{
+  //=======================================================================
+  //function : GetPairsOfFaultyShapes
+  //purpose  :
+  //=======================================================================
+  NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> GetPairsOfFaultyShapes(
+                                                          const BOPAlgo_ArgumentAnalyzer& theAnalyzer,
+                                                          const BOPAlgo_CheckStatus       theErrorStatus)
+  {
+    NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aResList;
+
+    const BOPAlgo_ListOfCheckResult& aResult = theAnalyzer.GetCheckResult();
+    BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResult);
+    for (; anIt.More(); anIt.Next())
+    {
+      if (anIt.Value().GetCheckStatus() == theErrorStatus)
+      {
+        auto aFaultyShapes = anIt.Value().GetFaultyShapes1();
+
+        aResList.Append({ aFaultyShapes.First(),
+                        aFaultyShapes.Size() == 1 ? TopoDS_Shape() : aFaultyShapes.Last() });
+      }
+    }
+
+    return aResList;
+  }
+
+  //=======================================================================
+  //function : GetListOfSmallEdges
+  //purpose  :
+  //=======================================================================
+  TopTools_ListOfShape GetListOfSmallEdges(const BOPAlgo_ArgumentAnalyzer& theAnalyzer)
+  {
+    TopTools_ListOfShape aResList;
+
+    const BOPAlgo_ListOfCheckResult& aResult = theAnalyzer.GetCheckResult();
+    BOPAlgo_ListIteratorOfListOfCheckResult anIt(aResult);
+    for (; anIt.More(); anIt.Next())
+    {
+      if (anIt.Value().GetCheckStatus() == BOPAlgo_CheckStatus::BOPAlgo_TooSmallEdge)
+      {
+        auto aFaultyShapes = anIt.Value().GetFaultyShapes1();
+        aResList.Append(aFaultyShapes.First());
+      }
+    }
+
+    return aResList;
+  }
+
+  //=======================================================================
+  //function : ConvertShapesToIndices
+  //purpose  : Convert sub-shapes of shapes to sequence of indices
+  //=======================================================================
+  Handle(TColStd_HArray1OfInteger) ConvertShapesToIndices(const TopoDS_Shape& theShape,
+                                                          const TopTools_ListOfShape& theShapes)
+  {
+    Handle(TColStd_HArray1OfInteger) aSeqOfIDs = new TColStd_HArray1OfInteger(1, theShapes.Size());
+
+    TopTools_IndexedMapOfShape anIndices;
+    TopExp::MapShapes(theShape, anIndices);
+
+    TopTools_ListIteratorOfListOfShape itSub(theShapes);
+    for (int index = 1; itSub.More(); itSub.Next(), ++index)
+    {
+      int id = anIndices.FindIndex(itSub.Value());
+      aSeqOfIDs->SetValue(index, id);
+    }
+
+    return aSeqOfIDs;
+  }
+
+  //=======================================================================
+  //function : ConvertShapesToIndices
+  //purpose  : Convert list of pair shapes to sequence of indices
+  //=======================================================================
+  Handle(TColStd_HArray2OfInteger) ConvertShapesToIndices(
+    const TopoDS_Shape& theShape,
+    const NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>& theShapes)
+  {
+    Handle(TColStd_HArray2OfInteger) aSeqOfIDs = new TColStd_HArray2OfInteger(1, theShapes.Size(), 1, 2);
+
+    TopTools_IndexedMapOfShape anIndices;
+    TopExp::MapShapes(theShape, anIndices);
+
+    NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>::Iterator itSub(theShapes);
+    for (int index = 1; itSub.More(); itSub.Next(), ++index)
+    {
+      int anID1 = anIndices.FindIndex(itSub.Value().first);
+      aSeqOfIDs->SetValue(index, 1, anID1);
+
+      int anID2 = anIndices.FindIndex(itSub.Value().second);
+      aSeqOfIDs->SetValue(index, 2, anID2);
+    }
+
+    return aSeqOfIDs;
+  }
+}
+
+//=======================================================================
+//function : GetID
+//purpose  :
+//=======================================================================
+const Standard_GUID& GEOMImpl_ConformityDriver::GetID()
+{
+  static Standard_GUID aGUID("B77BABDA-C0A1-4E65-9B1E-7EFC4448077E");
+  return aGUID;
+}
+
+//=======================================================================
+//function : GEOMImpl_ConformityDriver
+//purpose  :
+//=======================================================================
+GEOMImpl_ConformityDriver::GEOMImpl_ConformityDriver()
+{
+}
+
+//=======================================================================
+//function : Execute
+//purpose  :
+//=======================================================================
+Standard_Integer GEOMImpl_ConformityDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+  if (Label().IsNull()) return 0;
+  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+  GEOMImpl_IConformity aCI(aFunction);
+
+  Standard_Integer aType = aFunction->GetType();
+
+  Handle(GEOM_Function) aRefShape = aCI.GetShape();
+  if (aRefShape.IsNull()) return 0;
+
+  TopoDS_Shape aShape = aRefShape->GetValue();
+
+  switch (aType)
+  {
+  case CONFORMITY_DISTANT_SHAPES:
+  {
+    Standard_Integer aType1 = aCI.GetShapeType1();
+    Standard_Integer aType2 = aCI.GetShapeType2();
+    NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aRes;
+    if (aType1 == -1 && aType2 == -1)
+    {
+      aRes = distantShapes(aShape);
+    }
+    else if (aType1 == -1)
+    {
+      aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType2);
+    }
+    else if (aType2 == -1)
+    {
+      aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType1);
+    }
+    else
+    {
+      aRes = distantShapes(aShape, (TopAbs_ShapeEnum)aType1, (TopAbs_ShapeEnum)aType2);
+    }
+    if (!aRes.IsEmpty())
+    {
+      Handle(TColStd_HArray2OfInteger) anArray = ConvertShapesToIndices(aShape, aRes);
+      aCI.SetListOfShapesIndices(anArray);
+    }
+  }
+  break;
+  case CONFORMITY_UPDATE_TOL:
+  {
+    Standard_Real aTolerance = updateTolerance(aShape);
+    aFunction->SetReal(CHECKCONFORMITY_RET_TOLERANCE, aTolerance);
+  }
+  break;
+  case CONFORMITY_CHECK_SHAPE:
+  {
+    NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aFailedShape;
+    Handle(TColStd_HArray1OfInteger) aTypesOfCheck;
+    checkShape(aShape, aFailedShape, aTypesOfCheck);
+
+    Handle(TColStd_HArray2OfInteger) anArray = ConvertShapesToIndices(aShape, aFailedShape);
+    aFunction->SetIntegerArray(CHECKCONFORMITY_RET_TYPES_CHECKS, aTypesOfCheck);
+    aCI.SetListOfShapesIndices(anArray);
+  }
+  }
+
+  return 1;
+}
+
+//=======================================================================
+//function : distantShapes
+//purpose  : TODO: Not implemented! Wait for required functionality!
+//=======================================================================
+NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> GEOMImpl_ConformityDriver::distantShapes(
+  const TopoDS_Shape& theShape,
+  const TopAbs_ShapeEnum theShapeType,
+  const TopAbs_ShapeEnum theSubShapeType,
+  Standard_Real          theTolerance) const
+{
+  // TODO: Not implemented! Wait for required functionality!
+  return NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>();
+}
+
+//=======================================================================
+//function : distantShapes
+//purpose  : TODO: Not implemented! Wait for required functionality!
+//=======================================================================
+NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> GEOMImpl_ConformityDriver::distantShapes(
+  const TopoDS_Shape& theShape,
+  const TopAbs_ShapeEnum theShapeType,
+  Standard_Real          theTolerance) const
+{
+  NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aDistShapes;
+  switch (theShapeType)
+  {
+  case TopAbs_VERTEX:
+    aDistShapes.Append(distantShapes(theShape, TopAbs_EDGE, theShapeType, theTolerance));
+    aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, theShapeType, theTolerance));
+    break;
+  case TopAbs_EDGE:
+    aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_VERTEX, theTolerance));
+    aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, theShapeType, theTolerance));
+    break;
+  case TopAbs_FACE:
+    aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_VERTEX, theTolerance));
+    aDistShapes.Append(distantShapes(theShape, theShapeType, TopAbs_EDGE, theTolerance));
+    break;
+  }
+
+  return aDistShapes;
+}
+
+//=======================================================================
+//function : distantShapes
+//purpose  : TODO: Not implemented! Wait for required functionality!
+//=======================================================================
+NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> GEOMImpl_ConformityDriver::distantShapes(
+  const TopoDS_Shape& theShape,
+  Standard_Real       theTolerance) const
+{
+  NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aDistShapes;
+
+  aDistShapes.Append(distantShapes(theShape, TopAbs_EDGE, TopAbs_VERTEX, theTolerance));
+  aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, TopAbs_VERTEX, theTolerance));
+  aDistShapes.Append(distantShapes(theShape, TopAbs_FACE, TopAbs_EDGE, theTolerance));
+
+  return aDistShapes;
+}
+
+void GEOMImpl_ConformityDriver::checkShape(const TopoDS_Shape & theShape,
+                                           NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>& theFailedShape,
+                                           Handle(TColStd_HArray1OfInteger)& theTypesOfCheck) const
+{
+  BOPAlgo_ArgumentAnalyzer anAnalyzer;
+  performAnalyze(theShape, anAnalyzer);
+
+  const BOPAlgo_ListOfCheckResult& aResult = anAnalyzer.GetCheckResult();
+  theTypesOfCheck = new TColStd_HArray1OfInteger(1, aResult.Size());
+
+  BOPAlgo_ListOfCheckResult::Iterator anIter(aResult);
+  for (int index = 1; anIter.More(); anIter.Next(), ++index)
+  {
+    theTypesOfCheck->SetValue(index, anIter.Value().GetCheckStatus());
+    std::pair<TopoDS_Shape, TopoDS_Shape> aPair;
+    aPair.first = anIter.Value().GetFaultyShapes1().First();
+    if (anIter.Value().GetFaultyShapes1().Size() != 1)
+      aPair.second = anIter.Value().GetFaultyShapes1().Last();
+    theFailedShape.Append(aPair);
+  }
+}
+
+//=======================================================================
+//function : updateTolerance
+//purpose  :
+//=======================================================================
+Standard_Real GEOMImpl_ConformityDriver::updateTolerance(const TopoDS_Shape& theShape) const
+{
+  Standard_Real aTolerance = INFINITY;
+
+  TopoDS_Shape aResShape = theShape;
+
+  BRepLib::UpdateTolerances(aResShape, Standard_False);
+
+  for (const auto& aType : { TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE })
+  {
+    for (TopExp_Explorer anExp(aResShape, aType); anExp.More(); anExp.Next())
+    {
+      Standard_Real aCurTolerance = INFINITY;
+      switch (aType)
+      {
+      case TopAbs_VERTEX:
+        aCurTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Value()));
+        break;
+      case TopAbs_EDGE:
+        aCurTolerance = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Value()));
+        break;
+      case TopAbs_FACE:
+        aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
+        break;
+      }
+      aTolerance = Min(aTolerance, aCurTolerance);
+    }
+  }
+
+  TopoDS_Shape aShape = theShape;
+  GEOMUtils::FixShapeTolerance(aShape, aTolerance, Standard_True);
+
+  Standard_Real aResTol = 0.;
+  for (const auto& aType : { TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE })
+  {
+    for (TopExp_Explorer anExp(aShape, aType); anExp.More(); anExp.Next())
+    {
+      Standard_Real aCurTolerance = INFINITY;
+      switch (aType)
+      {
+      case TopAbs_VERTEX:
+        aCurTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Value()));
+        break;
+      case TopAbs_EDGE:
+        aCurTolerance = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Value()));
+        break;
+      case TopAbs_FACE:
+        aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
+        break;
+      }
+      aResTol = Max(aResTol, aCurTolerance);
+    }
+  }
+
+  return aResTol;
+}
+
+//=======================================================================
+//function : performAnalyze
+//purpose  : 
+//=======================================================================
+void GEOMImpl_ConformityDriver::performAnalyze(const TopoDS_Shape& theShape,
+                                               BOPAlgo_ArgumentAnalyzer& theAnalyzer) const
+{
+  theAnalyzer.SetShape1(theShape);
+
+  theAnalyzer.CurveOnSurfaceMode() = Standard_True;
+  theAnalyzer.SelfInterMode() = Standard_True;
+  theAnalyzer.SmallEdgeMode() = Standard_True;
+
+  theAnalyzer.Perform();
+}
diff --git a/src/GEOMImpl/GEOMImpl_ConformityDriver.hxx b/src/GEOMImpl/GEOMImpl_ConformityDriver.hxx
new file mode 100644 (file)
index 0000000..3c01564
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright (C) 2013-2022  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _GEOMImpl_ConformityDriver_HXX_
+#define _GEOMImpl_ConformityDriver_HXX_
+
+#include "GEOM_BaseDriver.hxx"
+
+#include <Standard_Transient.hxx>
+#include <TopoDS_Shape.hxx>
+
+#include <BOPAlgo_ArgumentAnalyzer.hxx>
+
+DEFINE_STANDARD_HANDLE(GEOMImpl_ConformityDriver, GEOM_BaseDriver)
+
+class GEOMImpl_ConformityDriver : public GEOM_BaseDriver
+{
+
+public:
+  Standard_EXPORT GEOMImpl_ConformityDriver();
+  Standard_EXPORT ~GEOMImpl_ConformityDriver() {};
+
+  Standard_EXPORT static const Standard_GUID& GetID();
+  Standard_EXPORT virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+  Standard_EXPORT Standard_Boolean         MustExecute(const Handle(TFunction_Logbook)&) const { return Standard_True; }
+  Standard_EXPORT virtual void             Validate(Handle(TFunction_Logbook)&) const {}
+
+private:
+
+  Standard_EXPORT NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> distantShapes(const TopoDS_Shape& theShape,
+                                                                                        const TopAbs_ShapeEnum theShapeType,
+                                                                                        const TopAbs_ShapeEnum theSubShapeType,
+                                                                                        Standard_Real          theTolerance = -1.) const;
+
+  Standard_EXPORT NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> distantShapes(const TopoDS_Shape& theShape,
+                                                                                        const TopAbs_ShapeEnum theShapeType,
+                                                                                        Standard_Real          theTolerance = -1.) const;
+
+  Standard_EXPORT NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> distantShapes(const TopoDS_Shape& theShape,
+                                                                                        Standard_Real          theTolerance = -1.) const;
+
+  Standard_EXPORT void checkShape(const TopoDS_Shape& theShape,
+                                  NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>& theFailedShape,
+                                  Handle(TColStd_HArray1OfInteger)& theTypesOfCheck) const;
+
+  Standard_EXPORT Standard_Real updateTolerance(const TopoDS_Shape& theShape) const;
+
+  Standard_EXPORT  virtual bool GetCreationInformation(std::string& theOperationName,
+                                                       std::vector<GEOM_Param>& params)
+  {
+    return Standard_False;
+  }
+
+private:
+  void performAnalyze(const TopoDS_Shape& theShape, BOPAlgo_ArgumentAnalyzer& theAnalyzer) const;
+
+};
+
+#endif // _GEOMImpl_ConformityDriver_HXX_
index e61e220a80c9321437c51e85b6bafd556474ccdf..d3e83427b558abcfc261cc38dc8fd933d75d29ea 100644 (file)
@@ -82,6 +82,7 @@
 #include <GEOMImpl_GlueDriver.hxx>
 #include <GEOMImpl_MeasureDriver.hxx>
 #include <GEOMImpl_FieldDriver.hxx>
+#include <GEOMImpl_ConformityDriver.hxx>
 
 //=============================================================================
 /*!
@@ -161,6 +162,7 @@ GEOMImpl_Gen::GEOMImpl_Gen()
 
    // Measurements
    TFunction_DriverTable::Get()->AddDriver(GEOMImpl_MeasureDriver::GetID(), new GEOMImpl_MeasureDriver());
+   TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ConformityDriver::GetID(), new GEOMImpl_ConformityDriver());
 
    // Field
    TFunction_DriverTable::Get()->AddDriver(GEOMImpl_FieldDriver::GetID(), new GEOMImpl_FieldDriver());
diff --git a/src/GEOMImpl/GEOMImpl_IConformity.cxx b/src/GEOMImpl/GEOMImpl_IConformity.cxx
new file mode 100644 (file)
index 0000000..4a80e95
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2013-2022  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "GEOMImpl_IConformity.hxx"
+
+//=============================================================================
+/*!
+ *  SetListOfShapesIndices
+ *  Input 2D array of indexes converted into 1D array
+ */
+ //=============================================================================
+void GEOMImpl_IConformity::SetListOfShapesIndices(const Handle(TColStd_HArray2OfInteger)& theArrayOfIndexes)
+{
+  Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1, theArrayOfIndexes->Size());
+
+  for (Standard_Integer aRow = 1; aRow <= theArrayOfIndexes->NbRows(); ++aRow)
+  {
+    anArray->SetValue(2 * aRow - 1, theArrayOfIndexes->Value(aRow, 1));
+    anArray->SetValue(2 * aRow, theArrayOfIndexes->Value(aRow, 2));
+  }
+
+  _func->SetIntegerArray(CHECKCONFORMITY_RET_LIST_OF_INDEXES, anArray);
+}
+
+//=============================================================================
+/*!
+ *  GetListOfShapesIndices
+ *  Get cached 1D array of indexes and converted into 2D array of indexes
+ */
+ //=============================================================================
+Handle(TColStd_HArray2OfInteger) GEOMImpl_IConformity::GetListOfShapesIndices()
+{
+  Handle(TColStd_HArray1OfInteger) anArray = _func->GetIntegerArray(CHECKCONFORMITY_RET_LIST_OF_INDEXES);
+
+  Standard_Integer aLength = anArray->Size() / 2;
+  Handle(TColStd_HArray2OfInteger) aResArray = new TColStd_HArray2OfInteger(1, aLength, 1, 2);
+
+  for (Standard_Integer anIndex = 1; anIndex <= aLength; ++anIndex)
+  {
+    aResArray->SetValue(anIndex, 1, anArray->Value(2 * anIndex - 1));
+    aResArray->SetValue(anIndex, 2, anArray->Value(2 * anIndex));
+  }
+
+  return aResArray;
+}
\ No newline at end of file
diff --git a/src/GEOMImpl/GEOMImpl_IConformity.hxx b/src/GEOMImpl/GEOMImpl_IConformity.hxx
new file mode 100644 (file)
index 0000000..f9f3435
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (C) 2013-2022  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _GEOMImpl_IConformity_HXX_
+#define _GEOMImpl_IConformity_HXX_
+
+#include "GEOM_Function.hxx"
+#include <TColStd_HArray2OfInteger.hxx>
+#include <TColStd_HArray2OfTransient.hxx>
+
+#define CHECKCONFORMITY_ARG_SHAPE 1
+#define CHECKCONFORMITY_ARG_SHAPETYPE_1 2
+#define CHECKCONFORMITY_ARG_SHAPETYPE_2 3
+#define CHECKCONFORMITY_ARG_TOLERANCE 4
+
+#define CHECKCONFORMITY_RET_TOLERANCE 5
+#define CHECKCONFORMITY_RET_ISVALID 6
+#define CHECKCONFORMITY_RET_SHAPES_IDS 7
+#define CHECKCONFORMITY_RET_TYPES_CHECKS 8
+#define CHECKCONFORMITY_RET_LIST_OF_INDEXES 9
+#define CHECKCONFORMITY_RET_LIST_SHAPES 10
+
+class GEOMImpl_IConformity
+{
+public:
+  GEOMImpl_IConformity(Handle(GEOM_Function) theFunction)
+    : _func(theFunction)
+  {
+  }
+
+  void SetShape(Handle(GEOM_Function) theRef)
+  {
+    _func->SetReference(CHECKCONFORMITY_ARG_SHAPE, theRef);
+  }
+  Handle(GEOM_Function) GetShape()
+  {
+    return _func->GetReference(CHECKCONFORMITY_ARG_SHAPE);
+  }
+
+  void SetShapeType1(int theShapeType) { _func->SetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_1, theShapeType); }
+  Standard_Integer GetShapeType1() { return _func->GetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_1); }
+  void SetShapeType2(int theShapeType) { _func->SetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_2, theShapeType); }
+  Standard_Integer GetShapeType2() { return _func->GetInteger(CHECKCONFORMITY_ARG_SHAPETYPE_2); }
+  void SetTolerance(double theTolerance) { _func->SetReal(CHECKCONFORMITY_ARG_TOLERANCE, theTolerance); }
+  Standard_Real GetTolerance() { return _func->GetReal(CHECKCONFORMITY_ARG_TOLERANCE); }
+
+  void SetListOfShapesIndices(const Handle(TColStd_HArray2OfInteger)& theArrayOfIndexes);
+  Handle(TColStd_HArray2OfInteger) GetListOfShapesIndices();
+
+private:
+  Handle(GEOM_Function) _func;
+};
+
+#endif // _GEOMImpl_IConformity_HXX_
index 69c6e409e1f04bb0aa2f6cc6cc9aee685edb8269..5fd63aef3eb032b296f6fae0aa9728c3615aa766 100644 (file)
@@ -25,6 +25,9 @@
 #include <GEOMImpl_MeasureDriver.hxx>
 #include <GEOMImpl_Types.hxx>
 
+#include <GEOMImpl_IConformity.hxx>
+#include <GEOMImpl_ConformityDriver.hxx>
+
 #include <GEOMUtils.hxx>
 
 #include <GEOMAlgo_AlgoTools.hxx>
@@ -2658,6 +2661,351 @@ Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint
   return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false);
 }
 
+//=============================================================================
+/*!
+ *  selfIntersected2D
+ *  Find all self-intersected 2D curves.
+ *  \param theChecks list of failed checks, contains type of check and failed shapes
+ */
+ //=============================================================================
+std::list<GEOMImpl_IMeasureOperations::FailedShapes> GEOMImpl_IMeasureOperations::selfIntersected2D(
+  std::list<FailedChecks>& theChecks)
+{
+  SetErrorCode(KO);
+  MESSAGE("GEOMImpl_IMeasureOperations::selfIntersected2D");
+
+  std::list<GEOMImpl_IMeasureOperations::FailedShapes> aSelfInters2D;
+  Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
+  Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_SELFINTERSECTED);
+  if (aFunction.IsNull()) return aSelfInters2D;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aSelfInters2D;
+
+  GEOMImpl_IConformity aCI(aFunction);
+  try
+  {
+    OCC_CATCH_SIGNALS;
+    for (std::list<FailedChecks>::iterator anIter(theChecks.begin());
+         anIter != theChecks.end(); ++anIter)
+    {
+      if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_InvalidCurveOnSurface)
+        aSelfInters2D.push_back(anIter->FailedShapes);
+    }
+  }
+  catch (Standard_Failure& aFail)
+  {
+    SetErrorCode(aFail.GetMessageString());
+    return aSelfInters2D;
+  }
+
+  SetErrorCode(OK);
+  return aSelfInters2D;
+}
+
+//=============================================================================
+/*!
+ *  interferingSubshapes
+ *  Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned.
+ *  \param theChecks list of failed checks, contains type of check and failed shapes
+ *  \param theShapeType1 Type of shape.
+ *  \param theShapeType2 Type of shape.
+ */
+ //=============================================================================
+std::list<GEOMImpl_IMeasureOperations::FailedShapes> GEOMImpl_IMeasureOperations::interferingSubshapes(
+  std::list<FailedChecks>& theChecks,
+  const int           theShapeType1,
+  const int           theShapeType2)
+{
+  SetErrorCode(KO);
+  MESSAGE("GEOMImpl_IMeasureOperations::interferingSubshapes");
+
+  std::list < GEOMImpl_IMeasureOperations::FailedShapes> anInterfer;
+  try
+  {
+    OCC_CATCH_SIGNALS;
+    for (std::list<FailedChecks>::iterator anIter(theChecks.begin());
+         anIter != theChecks.end(); ++anIter)
+    {
+      if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_SelfIntersect &&
+          checkTypes(anIter->FailedShapes, theShapeType1, theShapeType2))
+        anInterfer.push_back(anIter->FailedShapes);
+    }
+  }
+  catch (Standard_Failure& aFail)
+  {
+    SetErrorCode(aFail.GetMessageString());
+    return anInterfer;
+  }
+
+  SetErrorCode(OK);
+  return anInterfer;
+}
+
+//=============================================================================
+/*!
+ *  smallEdges
+ *  Find edges, which are fully covered by tolerances of vertices.
+ *  \param theChecks list of failed checks, contains type of check and failed shapes
+ */
+ //=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IMeasureOperations::smallEdges(std::list<FailedChecks>& theChecks)
+{
+  SetErrorCode(KO);
+  MESSAGE("GEOMImpl_IMeasureOperations::smallEdges");
+
+  Handle(TColStd_HSequenceOfTransient) aSmallEdges = new TColStd_HSequenceOfTransient;
+  try
+  {
+    OCC_CATCH_SIGNALS;
+    for (std::list<FailedChecks>::iterator anIter(theChecks.begin());
+         anIter != theChecks.end(); ++anIter)
+    {
+      if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_TooSmallEdge)
+        aSmallEdges->Append(anIter->FailedShapes.first);
+    }
+  }
+  catch (Standard_Failure& aFail)
+  {
+    SetErrorCode(aFail.GetMessageString());
+    return NULL;
+  }
+
+  SetErrorCode(OK);
+  return aSmallEdges;
+}
+
+//=============================================================================
+/*!
+ *  distantShapes
+ *  find remote objects (sub-shape on a shape).
+ *  \param theShape Shape for check.
+ *  \param theShapeType Type of shape.
+ *  \param theSubShapeType Type of sub-shape.
+ *  \param theTolerance tolerance.
+ */
+ //=============================================================================
+std::list<GEOMImpl_IMeasureOperations::FailedShapes> GEOMImpl_IMeasureOperations::distantShapes(
+  Handle(GEOM_Object) theShape,
+  const int           theShapeType,
+  const int           theSubShapeType,
+  double              theTolerance)
+{
+  SetErrorCode(KO);
+  MESSAGE("GEOMImpl_IMeasureOperations::distantShapes");
+
+  std::list<GEOMImpl_IMeasureOperations::FailedShapes> aDistantS;
+
+  Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
+  Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_DISTANT_SHAPES);
+  if (aFunction.IsNull()) return aDistantS;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aDistantS;
+
+  GEOMImpl_IConformity aCI(aFunction);
+
+  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+  if (aRefShape.IsNull()) return aDistantS;
+
+  aCI.SetShape(aRefShape);
+  aCI.SetShapeType1(theShapeType);
+  aCI.SetShapeType2(theSubShapeType);
+  aCI.SetTolerance(theTolerance);
+
+  try
+  {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction))
+    {
+      SetErrorCode("Failed: distantShape");
+      return aDistantS;
+    }
+    TopTools_IndexedMapOfShape anIndices;
+    TopExp::MapShapes(theShape->GetValue(), anIndices);
+    Handle(TColStd_HArray1OfInteger) aRes = aFunction->GetIntegerArray(CHECKCONFORMITY_RET_SHAPES_IDS);
+    if (aRes.IsNull())
+      return aDistantS;
+    for (Standard_Integer anIndex = 1; anIndex <= aRes->Size() / 2; ++anIndex)
+    {
+      std::pair<Handle(GEOM_Object), Handle(GEOM_Object)> aPair;
+      Handle(TColStd_HArray1OfInteger) anArray;
+      anArray = new TColStd_HArray1OfInteger(1, 1);
+      anArray->SetValue(1, aRes->Value(2 * anIndex - 1));
+
+      Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
+      if (!anObj.IsNull())
+        aPair.first = anObj;
+
+      anArray = new TColStd_HArray1OfInteger(1, 1);
+      anArray->SetValue(1, aRes->Value(2 * anIndex));
+
+      anObj = GetEngine()->AddSubShape(theShape, anArray);
+      if (!anObj.IsNull())
+        aPair.second = anObj;
+      aDistantS.push_back(aPair);
+    }
+  }
+  catch (Standard_Failure& aFail)
+  {
+    SetErrorCode(aFail.GetMessageString());
+    return aDistantS;
+  }
+
+  SetErrorCode(OK);
+  return aDistantS;
+}
+
+//=============================================================================
+/*!
+ *  checkConformityShape
+ *  Perform analyse of shape and find imperfections in the shape.
+ *  \param theShape Shape for analyse.
+ */
+ //=============================================================================
+void GEOMImpl_IMeasureOperations::checkConformityShape(Handle(GEOM_Object) theShape, std::list<FailedChecks>& theChecks)
+{
+  SetErrorCode(KO);
+  MESSAGE("GEOMImpl_IMeasureOperations::checkShape");
+
+  Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
+  Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_CHECK_SHAPE);
+  if (aFunction.IsNull()) return;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return;
+
+  GEOMImpl_IConformity aCI(aFunction);
+
+  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+  if (aRefShape.IsNull()) return;
+
+  aCI.SetShape(aRefShape);
+
+  try
+  {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction))
+    {
+      SetErrorCode("Failed: checkShape");
+      return;
+    }
+    Handle(TColStd_HArray1OfInteger) aTypesChecks = aFunction->GetIntegerArray(CHECKCONFORMITY_RET_TYPES_CHECKS);
+    Handle(TColStd_HArray2OfInteger) aRes = aCI.GetListOfShapesIndices();
+    if (aRes.IsNull())
+      return;
+
+    for (Standard_Integer anIndex = 1; anIndex <= aRes->NbRows(); ++anIndex)
+    {
+      std::pair<Handle(GEOM_Object), Handle(GEOM_Object)> aPair;
+      Handle(TColStd_HArray1OfInteger) anArray;
+      anArray = new TColStd_HArray1OfInteger(1, 1);
+      anArray->SetValue(1, aRes->Value(anIndex, 1));
+
+      Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
+      if (!anObj.IsNull())
+        aPair.first = anObj;
+
+      anArray = new TColStd_HArray1OfInteger(1, 1);
+      anArray->SetValue(1, aRes->Value(anIndex, 2));
+
+      anObj = GetEngine()->AddSubShape(theShape, anArray);
+      if (!anObj.IsNull())
+        aPair.second = anObj;
+      theChecks.push_back({ aTypesChecks->Value(anIndex), aPair });
+    }
+  }
+  catch (Standard_Failure& aFail)
+  {
+    SetErrorCode(aFail.GetMessageString());
+    return;
+  }
+
+  SetErrorCode(OK);
+  return;
+}
+
+//=============================================================================
+/*!
+ *  updateTolerance
+ *  Compute possible tolerance for the shape, minimize tolerance of shape as well
+ *  as tolerance of sub-shapes as much as possible
+ *  \param theShape Shape for compute tolerance.
+ */
+ //=============================================================================
+double GEOMImpl_IMeasureOperations::updateTolerance(Handle(GEOM_Object) theShape)
+{
+  SetErrorCode(KO);
+  MESSAGE("GEOMImpl_IMeasureOperations::updateTolerance");
+
+  double aResTol = -1;
+  Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
+  Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_UPDATE_TOL);
+  if (aFunction.IsNull()) return aResTol;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aResTol;
+
+  GEOMImpl_IConformity aCI(aFunction);
+
+  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+  if (aRefShape.IsNull()) return aResTol;
+
+  aCI.SetShape(aRefShape);
+
+  try
+  {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction))
+    {
+      SetErrorCode("Failed: updateTolerance");
+      return aResTol;
+    }
+    aResTol = aFunction->GetReal(CHECKCONFORMITY_RET_TOLERANCE);
+  }
+  catch (Standard_Failure& aFail)
+  {
+    SetErrorCode(aFail.GetMessageString());
+    return aResTol;
+  }
+
+  SetErrorCode(OK);
+  return aResTol;
+}
+
+//=======================================================================
+//function : checkTypes
+//purpose  :
+//=======================================================================
+bool GEOMImpl_IMeasureOperations::checkTypes(const FailedShapes& theShapes,
+                                             const int theShapeType1,
+                                             const int theShapeType2)
+{
+  TopAbs_ShapeEnum aShapeType1, aShapeType2;
+  if (!theShapes.first.IsNull())
+    aShapeType1 = theShapes.first->GetValue().ShapeType();
+  if (!theShapes.second.IsNull())
+    aShapeType2 = theShapes.second->GetValue().ShapeType();
+
+  if (theShapeType1 == -1 && theShapeType2 == -1)
+  {
+    return true;
+  }
+  else if (theShapeType1 == -1)
+  {
+    return aShapeType1 == theShapeType2 || aShapeType2 == theShapeType2;
+  }
+  else if (theShapeType2 == -1)
+  {
+    return aShapeType1 == theShapeType1 || aShapeType2 == theShapeType1;
+  }
+  else
+  {
+    return aShapeType1 == theShapeType1 && aShapeType2 == theShapeType2 ||
+      aShapeType1 == theShapeType2 && aShapeType2 == theShapeType1;
+  }
+}
+
 //=======================================================================
 //function : FillErrorsSub
 //purpose  : Fill the errors list of subshapes on shape.
index 58b27bbda34b97caf83534f625a9a82b8dd34355..71f0926fc3fd5e328d7412618ff8b7549a21bd25 100644 (file)
@@ -215,9 +215,32 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
                                                             Standard_Real& theVParam);
   Standard_EXPORT Standard_Real MinSurfaceCurvatureByPoint (Handle(GEOM_Object) theSurf,
                                                             Handle(GEOM_Object) thePoint);
+  typedef std::pair< Handle(GEOM_Object), Handle(GEOM_Object)> FailedShapes;
+  struct FailedChecks
+  {
+    Standard_Integer TypeOfCheck;
+    FailedShapes FailedShapes;
+  };
+
+  Standard_EXPORT std::list<FailedShapes> selfIntersected2D(std::list<FailedChecks>& theChecks);
+  Standard_EXPORT std::list<FailedShapes> interferingSubshapes(std::list<FailedChecks>& theChecks,
+                                                               const int theShapeType1,
+                                                               const int theShapeType2);
+  Standard_EXPORT Handle(TColStd_HSequenceOfTransient) smallEdges(std::list<FailedChecks>& theChecks);
+  Standard_EXPORT std::list<FailedShapes> distantShapes(Handle(GEOM_Object) theShape,
+                                                        const int theShapeType,
+                                                        const int theSubShapeType,
+                                                        double theTolerance);
+  Standard_EXPORT void checkConformityShape(Handle(GEOM_Object) theShape, std::list<FailedChecks>& theChecks);
+
+  Standard_EXPORT double updateTolerance(Handle(GEOM_Object) theShape);
 
  private:
 
+   bool checkTypes(const FailedShapes& theShapes,
+                   const int theShapeType1,
+                   const int theShapeType2);
+
    void FillErrorsSub
            (const BRepCheck_Analyzer                   &theAna,
             const TopoDS_Shape                         &theShape,
index 1f64191faf60a9c0c499b6b5a2157791da764809..b6a1f485ff880b51d3f97869e34a1eba0ffbc5b4 100644 (file)
 
 #define GEOM_EXTRACTION 58
 
+#define GEOM_CHECKCONFORMITY 59
+
 //GEOM_Function types
 
 #define COPY_WITH_REF    1
 #define TD_GET_IN_PLACE_OLD        2
 #define TD_GET_IN_PLACE_BY_HISTORY 3
 
+// Conformity operations
+#define CONFORMITY_IS_VALID         2
+#define CONFORMITY_SELFINTERSECTED  3
+#define CONFORMITY_INTERFERENCE     4
+#define CONFORMITY_SMALL_EDGES      5
+#define CONFORMITY_DISTANT_SHAPES   6
+#define CONFORMITY_UPDATE_TOL       7
+#define CONFORMITY_CHECK_SHAPE      8
+
 // Plugins specified constants
 #define PLUGIN_NAME "Plugin Name"
 
index c2acb21586ea178967c387f9b43b192a26f0d393..c8e46802ba85b4bd531e57f48cf15d277910878e 100644 (file)
@@ -1188,3 +1188,203 @@ CORBA::Double GEOM_IMeasureOperations_i::MinSurfaceCurvatureByPoint
 
   return GetOperations()->MinSurfaceCurvatureByPoint(aShape,aPoint);
 }
+
+//=============================================================================
+/*!
+ *  selfIntersected2D
+ *  Find all self-intersected 2D curves.
+ *  \param theShape Shape for check.
+ */
+ //=============================================================================
+GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::selfIntersected2D(
+                                          const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts)
+{
+  GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq =
+    new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape;
+
+  // Perform patch face operation
+  std::list<GEOMImpl_IMeasureOperations::FailedChecks> aResults;
+  ConvertToList(theResuts, aResults);
+
+  std::list<GEOMImpl_IMeasureOperations::FailedShapes> aSelfInters = GetOperations()->selfIntersected2D(aResults);
+  if (!GetOperations()->IsDone() || aSelfInters.empty())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aSelfInters.size();
+  aSeq->length(aLength);
+  std::list<GEOMImpl_IMeasureOperations::FailedShapes>::iterator anIter(aSelfInters.begin());
+  for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
+  {
+    aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
+    aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
+  }
+
+  return aSeq._retn();
+}
+
+//=============================================================================
+/*!
+ *  interferingSubshapes
+ *  Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned.
+ *  \param theShape Shape for check.
+ *  \param theShapeType1 Type of shape.
+ *  \param theShapeType2 Type of shape.
+ */
+ //=============================================================================
+GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::interferingSubshapes(
+                                                          const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
+                                                          const CORBA::Long theShapeType1,
+                                                          const CORBA::Long theShapeType2)
+{
+  GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq =
+    new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape;
+
+  // Perform patch face operation
+  std::list<GEOMImpl_IMeasureOperations::FailedChecks> aResults;
+  ConvertToList(theResuts, aResults);
+
+  std::list<GEOMImpl_IMeasureOperations::FailedShapes> aSelfInterf =
+    GetOperations()->interferingSubshapes(aResults, theShapeType1, theShapeType2);
+  if (!GetOperations()->IsDone() || aSelfInterf.empty())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aSelfInterf.size();
+  aSeq->length(aLength);
+  std::list<GEOMImpl_IMeasureOperations::FailedShapes>::iterator anIter(aSelfInterf.begin());
+  for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
+  {
+    aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
+    aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
+  }
+
+  return aSeq._retn();
+}
+
+//=============================================================================
+/*!
+ *  smallEdges
+ *  Find edges, which are fully covered by tolerances of vertices.
+ *  \param theShape Shape for check.
+ */
+ //=============================================================================
+GEOM::ListOfGO* GEOM_IMeasureOperations_i::smallEdges(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts)
+{
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
+
+  std::list<GEOMImpl_IMeasureOperations::FailedChecks> aResults;
+  ConvertToList(theResuts, aResults);
+
+  //Get the reference shape
+  Handle(TColStd_HSequenceOfTransient) aSmallEdges = GetOperations()->smallEdges(aResults);
+  if (!GetOperations()->IsDone() || aSmallEdges.IsNull())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aSmallEdges->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i - 1] = GetObject(Handle(::GEOM_Object)::DownCast(aSmallEdges->Value(i)));
+
+  return aSeq._retn();
+}
+
+//=============================================================================
+/*!
+ *  distantShapes
+ *  find remote objects (sub-shape on a shape).
+ *  \param theShape Shape for check.
+ *  \param theShapeType Type of shape.
+ *  \param theSubShapeType Type of sub-shape.
+ *  \param theTolerance tolerance.
+ */
+ //=============================================================================
+GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i::distantShapes(
+                                                                                  GEOM::GEOM_Object_ptr theShape,
+                                                                                  const CORBA::Long theShapeType,
+                                                                                  const CORBA::Long theSubShapeType,
+                                                                                  const CORBA::Double theTolerance)
+{
+  GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape_var aSeq =
+    new GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape;
+
+  //Get the reference shape
+  Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape);
+  if (aShapeRef.IsNull()) return aSeq._retn();
+
+  // Perform patch face operation
+  std::list<GEOMImpl_IMeasureOperations::FailedShapes> aDistantS =
+    GetOperations()->distantShapes(aShapeRef, theShapeType, theSubShapeType, theTolerance);
+  if (!GetOperations()->IsDone() || aDistantS.empty())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aDistantS.size();
+  aSeq->length(aLength);
+  std::list<GEOMImpl_IMeasureOperations::FailedShapes>::iterator anIter(aDistantS.begin());
+  for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
+  {
+    aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
+    aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
+  }
+
+  return aSeq._retn();
+}
+
+//=============================================================================
+/*!
+ *  checkShape
+ *
+ */
+ //=============================================================================
+GEOM::GEOM_IMeasureOperations::CheckResults* GEOM_IMeasureOperations_i::checkConformityShape(
+                                                                          GEOM::GEOM_Object_ptr theShape)
+{
+  GEOM::GEOM_IMeasureOperations::CheckResults_var aRes = new GEOM::GEOM_IMeasureOperations::CheckResults;
+
+  //Get the reference shape
+  Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape);
+  if (aShapeRef.IsNull()) return false;
+
+  std::list<GEOMImpl_IMeasureOperations::FailedChecks> aChecks;
+  GetOperations()->checkConformityShape(aShapeRef, aChecks);
+
+  Standard_Integer aLength = aChecks.size();
+  aRes->length(aLength);
+  std::list<GEOMImpl_IMeasureOperations::FailedChecks>::const_iterator anIntIt = aChecks.cbegin();
+  for (Standard_Integer i = 0; i < aLength; i++, ++anIntIt)
+  {
+    aRes[i].type = (*anIntIt).TypeOfCheck;
+    aRes[i].failedShapes.first = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.first));
+    aRes[i].failedShapes.second = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.second));
+  }
+
+  return aRes._retn();
+}
+
+//=============================================================================
+/*!
+ *  updateTolerance
+ *  Compute possible tolerance for the shape, minimize tolerance of shape as well
+ *  as tolerance of sub-shapes as much as possible
+ *  \param theShape Shape for check.
+ */
+ //=============================================================================
+CORBA::Double GEOM_IMeasureOperations_i::updateTolerance(GEOM::GEOM_Object_ptr theShape)
+{
+  //Get the reference shape
+  Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape);
+  if (aShapeRef.IsNull()) return false;
+
+  return GetOperations()->updateTolerance(aShapeRef);
+}
+
+void GEOM_IMeasureOperations_i::ConvertToList(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
+                                              std::list<GEOMImpl_IMeasureOperations::FailedChecks>& theListOfResults)
+{
+  for (Standard_Integer i = 0; i < theResuts.length(); ++i)
+  {
+    GEOMImpl_IMeasureOperations::FailedChecks aCheck;
+    aCheck.TypeOfCheck = theResuts[i].type;
+    aCheck.FailedShapes.first = GetObjectImpl(theResuts[i].failedShapes.first);
+    aCheck.FailedShapes.second = GetObjectImpl(theResuts[i].failedShapes.second);
+    theListOfResults.push_back(aCheck);
+  }
+}
index bebaedeec9143ae067fe7edee8a3b6cd094a5ac6..7fa72ec472f984d7e0aa90dcfe1ef6c00a0da35b 100644 (file)
@@ -164,6 +164,30 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
   CORBA::Double MinSurfaceCurvatureByPoint (GEOM::GEOM_Object_ptr theSurf,
                                             GEOM::GEOM_Object_ptr thePoint);
 
+  // Methods for class CheckConformity
+  GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* selfIntersected2D(
+                               const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts);
+
+  GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* interferingSubshapes(
+                                                  const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
+                                                  const CORBA::Long theShapeType1,
+                                                  const CORBA::Long theShapeType2);
+
+  GEOM::ListOfGO* smallEdges(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts);
+
+  GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* distantShapes(GEOM::GEOM_Object_ptr theShape,
+                                                                      const CORBA::Long theShapeType,
+                                                                      const CORBA::Long theSubShapeType,
+                                                                      const CORBA::Double theTolerance);
+
+  GEOM::GEOM_IMeasureOperations::CheckResults* checkConformityShape(GEOM::GEOM_Object_ptr theShape);
+
+  CORBA::Double updateTolerance(GEOM::GEOM_Object_ptr theShape);
+private:
+  void ConvertToList(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
+                     std::list <GEOMImpl_IMeasureOperations::FailedChecks>& theListOfResults);
+
+
   ::GEOMImpl_IMeasureOperations* GetOperations()
   { return (::GEOMImpl_IMeasureOperations*)GetImpl(); }
 };
index 963540446f2c338f7ecb92d1f162e29fbe246cf6..bb21d8b79ad8043479729d5c0aaa05c166eba843 100644 (file)
@@ -71,6 +71,7 @@ SET(_other_SCRIPTS
 SET(_python_SCRIPTS
   geomBuilder.py
   gsketcher.py
+  CheckConformity.py
   )
 
 # Advanced scripts
diff --git a/src/GEOM_SWIG/CheckConformity.py b/src/GEOM_SWIG/CheckConformity.py
new file mode 100644 (file)
index 0000000..d542d0b
--- /dev/null
@@ -0,0 +1,333 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2014-2022  EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Alexey SOZINOV, Open CASCADE S.A.S.
+
+
+## @defgroup check_conformity CheckConformity - Wrapper to find imperfections in the shape
+#  @{ 
+#  @details
+#  This tool provides the user with a simple python API 
+#  to analyze, available shape for Boolean Operations or not.
+#  Also tool provide advanced output to indicate imperfections in the input shape.
+#  @n Example:
+#  @code
+#  import GEOM
+#  from salome.geom import geomBuilder
+#  from salome.geom.CheckConformity import CheckConformity
+#
+#  geompy = geomBuilder.New()
+#
+#  O = geompy.MakeVertex(0, 0, 0)
+#  OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
+#  OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
+#  OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
+#  Vertex_1 = geompy.MakeVertex(-30, -70, 0)
+#  Vertex_2 = geompy.MakeVertex(-30, 50, 0)
+#  Line_1 = geompy.MakeLineTwoPnt(Vertex_2, Vertex_1)
+#  Vertex_3 = geompy.MakeVertex(0, -50, 0)
+#  Vertex_4 = geompy.MakeVertex(-40, -10, 0)
+#  Vertex_5 = geompy.MakeVertex(0, 40, 0)
+#  Arc_1 = geompy.MakeArc(Vertex_5, Vertex_4, Vertex_3)
+#  Vertex_6 = geompy.MakeVertex(10, -50, 4)
+#  Vertex_7 = geompy.MakeVertex(10, -50, 10)
+#  Vertex_8 = geompy.MakeVertex(10, 40, 10)
+#  Arc_1_vertex_3 = geompy.GetSubShape(Arc_1, [3])
+#  Line_2 = geompy.MakeLineTwoPnt(Arc_1_vertex_3, Vertex_6)
+#  Line_3 = geompy.MakeLineTwoPnt(Vertex_6, Vertex_7)
+#  Line_4 = geompy.MakeLineTwoPnt(Vertex_7, Vertex_8)
+#  Vertex_9 = geompy.MakeVertex(15, 40, 10)
+#  Vertex_10 = geompy.MakeVertex(17, 0, 6)
+#  Vertex_11 = geompy.MakeVertex(17, 0, 3)
+#  Line_5 = geompy.MakeLineTwoPnt(Vertex_8, Vertex_9)
+#  Line_6 = geompy.MakeLineTwoPnt(Vertex_9, Vertex_10)
+#  Line_7 = geompy.MakeLineTwoPnt(Vertex_10, Vertex_11)
+#  Arc_1_vertex_2 = geompy.GetSubShape(Arc_1, [2])
+#  Line_8 = geompy.MakeLineTwoPnt(Vertex_11, Arc_1_vertex_2)
+#  Wire_1 = geompy.MakeWire([Arc_1, Line_2, Line_3, Line_4, Line_5, Line_6, Line_7, Line_8], 1e-07)
+#  Wire_2 = geompy.MakeWire([Line_1], 1e-07)
+#  Compound_1 = geompy.MakeCompound([Wire_1, Wire_2])
+#
+#  # Create class CheckConformity for check shape
+#  cc = CheckConformity(Compound_1, geompy)
+#  valid = cc.isValid()
+#  dist = cc.distantShapes()
+#  small = cc.smallEdges()
+#  interfer = cc.interferingSubshapes()
+#  intersect = cc.selfIntersected2D()
+#
+#  geompy.addToStudy( O, 'O' )
+#  geompy.addToStudy( OX, 'OX' )
+#  geompy.addToStudy( OY, 'OY' )
+#  geompy.addToStudy( OZ, 'OZ' )
+#  geompy.addToStudy( Vertex_1, 'Vertex_1' )
+#  geompy.addToStudy( Vertex_2, 'Vertex_2' )
+#  geompy.addToStudy( Line_1, 'Line_1' )
+#  geompy.addToStudy( Vertex_3, 'Vertex_3' )
+#  geompy.addToStudy( Vertex_4, 'Vertex_4' )
+#  geompy.addToStudy( Vertex_5, 'Vertex_5' )
+#  geompy.addToStudy( Arc_1, 'Arc_1' )
+#  geompy.addToStudy( Vertex_6, 'Vertex_6' )
+#  geompy.addToStudy( Vertex_7, 'Vertex_7' )
+#  geompy.addToStudy( Vertex_8, 'Vertex_8' )
+#  geompy.addToStudyInFather( Arc_1, Arc_1_vertex_3, 'Arc_1:vertex_3' )
+#  geompy.addToStudy( Line_2, 'Line_2' )
+#  geompy.addToStudy( Line_3, 'Line_3' )
+#  geompy.addToStudy( Line_4, 'Line_4' )
+#  geompy.addToStudy( Vertex_9, 'Vertex_9' )
+#  geompy.addToStudy( Vertex_10, 'Vertex_10' )
+#  geompy.addToStudy( Vertex_11, 'Vertex_11' )
+#  geompy.addToStudy( Line_5, 'Line_5' )
+#  geompy.addToStudy( Line_6, 'Line_6' )
+#  geompy.addToStudy( Line_7, 'Line_7' )
+#  geompy.addToStudyInFather( Arc_1, Arc_1_vertex_2, 'Arc_1:vertex_2' )
+#  geompy.addToStudy( Line_8, 'Line_8' )
+#  geompy.addToStudy( Wire_1, 'Wire_1' )
+#  geompy.addToStudy( Wire_2, 'Wire_2' )
+#  geompy.addToStudy( Compound_1, 'Compound_1' )
+#  
+#  salome.sg.updateObjBrowser()
+#
+#  @endcode
+#  @n Additional examples can be found as unit tests in the source code.
+#  @}
+
+try:
+    import salome
+    salome.salome_init()
+    from salome import *
+except:
+    pass
+
+import GEOM  
+
+from salome.geom import geomBuilder
+
+geompy = geomBuilder.New()
+
+## An interface to find imperfections in the shape.
+#  Use geompy.CheckConformity(shape) method to obtain an instance of this class
+#
+#  @ref tui_check_conformity_page "Example"
+#  @ingroup check_conformity
+class CheckConformity:
+    """
+    Check Conformity interface
+
+    Example of usage:
+        cc = CheckConformity(Lot4_twistedFace_brep_1, geompy)
+        valid = cc.isValid()
+        dist = cc.distantShapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"]) !!NOT implemented!
+        small = cc.smallEdges()
+        interfer = cc.interferingSubshapes()
+        interferEV = cc.interferingSubshapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"])
+        interferVV = cc.interferingSubshapes(geompy.ShapeType["VERTEX], geompy.ShapeType["VERTEX"])
+        intersect = cc.selfIntersected2D()
+
+    """
+
+    def __init__(self, shape, geompy):
+        self.geompyD = geompy
+        self.myShape = shape
+        self.myIsChecked = False;
+        self.myResults = []
+      
+    ##  Perform analyse of shape.
+    #
+    #  @return New List, which contains pair: type of check and single of pair failed sub-shapes.
+    def __checkShape(self): 
+        """
+        Perform analyse of shape.
+
+        Returns:
+            New List, which contains pair: type of check and single of pair failed sub-shapes.
+        """
+        anOp = self.geompyD.GetIMeasureOperations()
+        self.myIsChecked = True
+        self.myResults = anOp.checkConformityShape(self.myShape)
+       
+    ## Check whether the shape is applicable for Boolean Operations.
+    #
+    #  @return Boolean value True if shape is applicable for Boolean Operations, otherwise - False
+    def isValid(self):
+        """
+        check whether the shape is applicable for Boolean Operations.
+
+        Returns:
+            Boolean value True if shape is applicable for Boolean Operations, otherwise - False.
+
+        Example of usage:
+            Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+            cc = CheckConformity(Box_1, geompy)
+            isValid = cc.isValid()
+        """
+        if not self.myIsChecked:
+            self.__checkShape()
+
+        anOp = self.geompyD.GetIMeasureOperations()
+        return len(self.myResults) == 0
+       
+    ## Find all self-intersected 2D curves.
+    #
+    #  @return New List, of pair sub-shape, which has self-intersected in 2D
+    def selfIntersected2D(self):
+        """
+        Find all self-intersected 2D curves.
+
+        Returns:
+            New List, of pair sub-shape, which has self-intersected in 2D/
+
+        Example of usage:
+            Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+            cc = CheckConformity(Box_1, geompy)
+            selfIntersected2D = cc.selfIntersected2D()
+        """
+        if not self.myIsChecked:
+            self.__checkShape()
+
+        anOp = self.geompyD.GetIMeasureOperations()
+        return anOp.selfIntersected2D(self.myResults)
+
+    ## Find pairs of interfering sub-shapes:
+    #  - vertices touched by tolerance;
+    #  - vertex touching an edge in the inner point;
+    #  - vertex lying on the inner point of a face;
+    #  - edges intersecting by inner points;
+    #  - edge touching/intersecting face in the inner point;
+    #  - faces intersection by inner point
+    #
+    # Types of interfering shapes could be specified,
+    # by default all pairs of interfering shapes are returned.
+    #
+    #  @param shapeType1 first type of shape
+    #  @param shapeType2 second type of shape
+    #
+    #  @return New List, of pairs of interfering shapes with given types (if they was specified)
+    def interferingSubshapes(self, shapeType1 = geompy.ShapeType["AUTO"], shapeType2 = geompy.ShapeType["AUTO"]):
+        """
+        Find pairs of interfering sub-shapes:
+         - vertices touched by tolerance
+         - vertex touching an edge in the inner point
+         - vertex lying on the inner point of a face
+         - edges intersecting by inner points
+         - edge touching/intersecting face in the inner point
+         - faces intersection by inner point
+        
+         Types of interfering shapes could be specified, by default all pairs of 
+         interfering shapes are returned.
+
+        Parameters:
+            shapeType1 first type of shape
+            shapeType2 second type of shape
+
+        Returns:
+            New List, of pairs of interfering shapes with given types (if they was specified)
+
+        Example of usage:
+            Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+            cc = CheckConformity(Box_1, geompy)
+            interferingSubshapes = cc.interferingSubshapes()
+            interferingSubshapesVV = cc.interferingSubshapes(geompy.ShapeType["VERTEX"], geompy.ShapeType["VERTEX"])
+        """
+        if not self.myIsChecked:
+            self.__checkShape()
+
+        anOp = self.geompyD.GetIMeasureOperations()
+        return anOp.interferingSubshapes(self.myResults, shapeType1, shapeType2)
+       
+    ## Find edges, which are fully covered by tolerances of vertices.
+    #
+    #  @return New List of edges, which are fully covered by tolerances of vertices
+    def smallEdges(self):
+        """
+        Find edges, which are fully covered by tolerances of vertices.
+
+        Returns:
+            New List of edges, which are fully covered by tolerances of vertices.
+
+        Example of usage:
+            Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+            cc = CheckConformity(Box_1, geompy)
+            smallEdges = cc.smallEdges()
+        """
+        if not self.myIsChecked:
+            self.__checkShape()
+
+        anOp = self.geompyD.GetIMeasureOperations()
+        return anOp.smallEdges(self.myResults)
+       
+    ## Find remote objects (sub-shape on a shape):
+    #  - vertex far from edge;
+    #  - vertex far from face;
+    #  - edge far from face
+    #
+    #  Sub-shape which are lying far from its parent shape more than the given tolerance.
+    #
+    #  @param shapeType type of shape
+    #  @param subShapeType type of sub-shape
+    #  @param tolerance available tolerance, by default used tolerance of sub-shape.
+    #
+    #  @return New List, of pair of sub-shape with given types,
+    #          that lying far from its parent shape more than the given tolerance.
+    def distantShapes(self, shapeType = geompy.ShapeType["AUTO"], subShapeType = geompy.ShapeType["AUTO"], tolerance = -1.0):
+        """
+        Find remote objects (sub-shape on a shape):
+         - vertex far from edge;
+         - vertex far from face;
+         - edge far from face
+
+        Sub-shape which are lying far from its parent shape more than the given tolerance.
+
+        Parameters:
+            shapeType type of shape
+            subShapeType type of sub-shape
+            tolerance available tolerance, by default used tolerance of sub-shape.
+
+        Returns:
+            New List, of pair of sub-shape with given types,
+                that lying far from its parent shape more than the given tolerance
+
+        Example of usage:
+            Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+            cc = CheckConformity(Box_1, geompy)
+            distantShapes = cc.distantShapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"])
+        """
+        anOp = self.geompyD.GetIMeasureOperations()
+        return anOp.distantShapes(self.myShape, shapeType, subShapeType, tolerance)
+        
+    ## Compute possible tolerance for the shape,
+         #   minimize tolerance of shape as well as tolerance of sub-shapes as much as possible  .
+    #
+    #  @return New value of tolerance.
+    def updateTolerance(self):
+        """
+        Compute possible tolerance for the shape,
+             minimize tolerance of shape as well as tolerance of sub-shapes as much as possible.
+
+        Returns:
+            New value of tolerance.
+
+        Example of usage:
+            Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+            cc = CheckConformity(Box_1, geompy)
+            toler = cc.updateTolerance()
+        """
+        anOp = self.geompyD.GetIMeasureOperations()
+        self.myIsChecked = False
+        print(anOp.updateTolerance(self.myShape))