]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
[bos #43130] [EDF] (2024) Geometry Analysis Tool
authormbs <martin.bernhard@opencascade.com>
Wed, 13 Nov 2024 09:35:20 +0000 (09:35 +0000)
committerjfa <jfa@opencascade.com>
Fri, 22 Nov 2024 12:23:52 +0000 (12:23 +0000)
idl/GEOM_Gen.idl
src/GEOMImpl/CMakeLists.txt
src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
src/GEOM_I/GEOM_IMeasureOperations_i.cc
src/GEOM_I/GEOM_IMeasureOperations_i.hh
src/GEOM_SWIG/geomBuilder.py

index 1d6abe8c3f06b4080aa31df0cd39a1c1c41b931c..d4d2eed32fd08c9aa5fe2e931957093beb3a99bd 100644 (file)
@@ -4797,6 +4797,25 @@ module GEOM
     string PrintShapeErrors (in GEOM_Object theShape,
                              in ShapeErrors theErrors);
 
+    // /*!
+    //  *  \brief Extract and identify any problem in the source shapes used in a Boolean Operation.
+    //  *  \param theShapes Shapes being used in the Boolean Operation
+    //  *  \param theUseTimer Whether to chronometrize computation time
+    //  *  \param theTopoOnly Whether to check topology only
+    //  *  \param theShortReport Whether to display the error report in short format
+    //  *  \param theRunParallel Whether to run the computations in parallel
+    //  *  \param theDoExact Whether to perform exact checking
+    //  *  \param theErrors Structure, containing discovered errors and incriminated sub-shapes.
+    //  *  \return TRUE, if the input shapes "seem to be valid" for BOP.
+    //  */
+    boolean ExtractBOPFailure (in ListOfGO     theShapes,
+                               in boolean      theUseTimer,
+                               in boolean      theTopoOnly,
+                               in boolean      theShortReport,
+                               in boolean      theRunParallel,
+                               in boolean      theDoExact,
+                               out ShapeErrors theErrors);
+
     /*!
      *  \brief Check a topology of the given shape on self-intersections presence.
      *  \param theShape Shape to check validity of.
index 64228aa7c2a1e46ff65baeb93ebf792c1e96a2c4..1f24e459a417b0bdc1c542c98d31b082974ce02e 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
+## FIXME
+SET(COMMONGEOMLIB_ROOT_DIR "/hdd2/S2/SALOME-MBS-DB11/INSTALL/CommonGeomLib")
+##
+message(STATUS "COMMONGEOMLIB_ROOT_DIR: ${COMMONGEOMLIB_ROOT_DIR}")
+SET(COMMONGEOMLIB_INCLUDE_DIR "${COMMONGEOMLIB_ROOT_DIR}/${SALOME_INSTALL_HEADERS}")
+SET(COMMONGEOMLIB_LIBRARY_DIR "${COMMONGEOMLIB_ROOT_DIR}/${SALOME_INSTALL_LIBS}")
+SET(COMMOMGEOMLIB_LIBRARIES GeomAnaTool)
+message(STATUS "COMMONGEOMLIB_INCLUDE_DIR: ${COMMONGEOMLIB_INCLUDE_DIR}")
+message(STATUS "COMMONGEOMLIB_LIBRARY_DIR: ${COMMONGEOMLIB_LIBRARY_DIR}")
+message(STATUS "COMMOMGEOMLIB_LIBRARIES: ${COMMOMGEOMLIB_LIBRARIES}")
+
 # --- options ---
 
 # additional include directories
@@ -26,6 +37,7 @@ INCLUDE_DIRECTORIES(
   ${KERNEL_INCLUDE_DIRS}
   ${PYTHON_INCLUDE_DIRS}
   ${EIGEN3_INCLUDE_DIR}
+  ${COMMONGEOMLIB_INCLUDE_DIR}
   ${PROJECT_SOURCE_DIR}/src/ShHealOper
   ${PROJECT_SOURCE_DIR}/src/GEOM 
   ${PROJECT_SOURCE_DIR}/src/BlockFix
@@ -45,7 +57,16 @@ ADD_DEFINITIONS(
   )
 
 # libraries to link to
+message(STATUS "----------------------------------------")
+message(STATUS "COMMONGEOMLIB_LIBRARIES: ${COMMOMGEOMLIB_LIBRARIES}")
+message(STATUS "OpenCASCADE_ModelingAlgorithms_LIBRARIES: ${OpenCASCADE_ModelingAlgorithms_LIBRARIES}")
+message(STATUS "PYTHON_LIBRARIES: ${PYTHON_LIBRARIES}")
+message(STATUS "KERNEL_SALOMELocalTrace: ${KERNEL_SALOMELocalTrace}")
+message(STATUS "----------------------------------------")
 SET(_link_LIBRARIES
+  ##FIXME:
+  ## The following line works only for Linux, not for Windows
+  ${COMMONGEOMLIB_LIBRARY_DIR}/libGeomAnaTool.so
   ${OpenCASCADE_ModelingAlgorithms_LIBRARIES}
   ${PYTHON_LIBRARIES}
   ShHealOper GEOMbasic BlockFix GEOMAlgo GEOMUtils GEOMSketcher GEOMArchimede XAO
index 56d5d592bddc47a589972f1074385b03b20d8332..11c27b5346f9c00fd38f697f015292986c147ef7 100644 (file)
 
 #include <Basics_OCCTVersion.hxx>
 
+// CommonGeomLib Includes
+#include <GeomAnaTool_Tools.hxx>
+#include <GeomAnaTool_ExtractBOPFailure.hxx>
+
 // OCCT Includes
 #include <Bnd_Box.hxx>
 #include <BOPAlgo_CheckerSI.hxx>
@@ -1713,6 +1717,130 @@ TCollection_AsciiString GEOMImpl_IMeasureOperations::PrintShapeErrors
   return aDump;
 }
 
+
+//=============================================================================
+/*!
+ *  ExtractBOPFailure
+ */
+//=============================================================================
+bool GEOMImpl_IMeasureOperations::ExtractBOPFailure
+                          (const Handle(TColStd_HSequenceOfTransient)&  theShapes,
+                           const bool                                   theUseTimer,
+                           const bool                                   theTopoOnly,
+                           const bool                                   theShortReport,
+                           const bool                                   theRunParallel,
+                           const bool                                   theDoExact,
+                           std::list<ShapeError>&                       theErrors)
+{
+  SetErrorCode(KO);
+  theErrors.clear();
+
+  if (theShapes.IsNull()) return false;
+
+  Standard_Integer aNbShapes = theShapes->Length();
+  if (!aNbShapes) return false;
+
+  TopTools_ListOfShape aList;
+  for (int i=1; i<=aNbShapes; i++) {
+    Handle(GEOM_Object) aGeomObj = Handle(GEOM_Object)::DownCast(theShapes->Value(i));
+    if (aGeomObj.IsNull())
+      continue;
+
+    Handle(GEOM_Function) aRefShape = aGeomObj->GetLastFunction();
+    if (aRefShape.IsNull())
+      continue;
+
+    TopoDS_Shape aShape = aRefShape->GetValue();
+    if (aShape.IsNull())
+      continue;
+
+    aList.Append(aShape);
+  }
+
+  // Call the GeomAnaTool API to extract BOP failures
+  // TopTools_ListOfShape aFailuresList = GeomAnaTool::ExtractBOPFailure(aList, theUseTimer, theTopoOnly, theShortReport, theRunParallel, theDoExact);
+  // std::cout << "ExtractBOPFailure: " << aFailuresList.Extent() << " failures" << std::endl;
+
+  //TopTools_ListOfShape aResult;
+  bool isValid = false;
+  try
+  {
+    OCC_CATCH_SIGNALS;
+    GeomAnaTool_ExtractBOPFailure aTool(aList);
+    aTool.SetUseTimer(theUseTimer);
+    aTool.SetCheckGeometry(!theTopoOnly); // Either topo only or topo+geometry
+    aTool.SetShortOutput(theShortReport);
+    aTool.SetRunParallel(theRunParallel);
+    aTool.SetExactCheck(theDoExact);
+    aTool.Perform();
+    if (aTool.HasFailures())
+    {
+      std::cout << "--- The operation has failures ---" << std::endl;
+      //aResult = aTool.Failures();
+      //std::cout << "#Failures = " << aResult.Extent() << std::endl;
+      const std::list<GAT_ShapeError>& errors = aTool.ShapeErrors();
+      std::cout << "#Failures = " << errors.size() << std::endl;
+      for (std::list<GAT_ShapeError>::const_iterator it = errors.begin(); it != errors.end(); ++it)
+      {
+        ShapeError aError;
+        aError.error = it->error;
+        aError.incriminated = it->incriminated;
+        theErrors.push_back(aError);
+      }
+    }
+    else
+    {
+      std::cout << "+++ The operation has no failures +++" << std::endl;
+      isValid = true;
+    }
+  }
+  catch(Standard_Failure& aFail)
+  {
+    SetErrorCode(aFail.GetMessageString());
+    std::cout << "Exception: " << GetErrorCode() << std::endl;
+    return false;
+  }
+
+  // Handle(TColStd_HSequenceOfTransient) aFailures = new TColStd_HSequenceOfTransient;
+  //
+  // // Convert each failure shape to a GEOM_Object and add to the sequence
+  // Handle(GEOM_Object) aFailureObj = GetEngine()->AddObject(GEOM_BOP_FAILURE);
+  // if (!aFailureObj.IsNull())
+  // {
+  //   for (TopTools_ListIteratorOfListOfShape it(aFailuresList); it.More(); it.Next()) {
+  //     TopoDS_Shape aFailureShape = it.Value();
+  //
+  //     Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(aFailureObj, anArray);
+  //     if (!anObj.IsNull())
+  //     {
+  //       aFailures->Append(anObj);
+  //     }
+  //   }
+  // }
+
+  // // Get result compound and collect all subshapes into result sequence
+  // TopoDS_Shape aResCompound = aFunction->GetValue();
+  // TopTools_IndexedMapOfShape anIndices;
+  // TopExp::MapShapes(aResCompound, anIndices);
+
+  // Handle(TColStd_HArray1OfInteger) anArray;
+  // for (TopExp_Explorer anExpW(aResCompound, TopAbs_FACE); anExpW.More(); anExpW.Next())
+  // {
+  //   TopoDS_Shape aValue = anExpW.Value();
+  //   anArray = new TColStd_HArray1OfInteger(1, 1);
+  //   anArray->SetValue(1, anIndices.FindIndex(aValue));
+
+  //   Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(aPatchFace, anArray);
+  //   if (!anObj.IsNull())
+  //   {
+  //     aSeq->Append(anObj);
+  //   }
+  // }
+
+  SetErrorCode(OK);
+  return isValid;
+}
+
 //=============================================================================
 /*!
  *  CheckSelfIntersections
index e13d8a5e77e396d5f800e01e672eb1384454e80c..8b677de56091617eb7c848e98a633ba1faf61a64 100644 (file)
@@ -162,6 +162,15 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
                                   (Handle(GEOM_Object)          theShape,
                                    const std::list<ShapeError> &theErrors);
 
+  Standard_EXPORT bool ExtractBOPFailure
+                                  (const Handle(TColStd_HSequenceOfTransient)&  theShapes,
+                                   const bool                                   theUseTimer,
+                                   const bool                                   theTopoOnly,
+                                   const bool                                   theShortReport,
+                                   const bool                                   theRunParallel,
+                                   const bool                                   theDoExact,
+                                   std::list<ShapeError>&                       theErrors);
+
   Standard_EXPORT bool CheckSelfIntersections (Handle(GEOM_Object) theShape,
                                                const SICheckLevel  theCheckLevel,
                                                Handle(TColStd_HSequenceOfInteger)& theIntersections);
index 0acbdb36c94f474915affff79fa9cc414e5a7ad8..1feb907c88763f0728725703c70eceda71510596 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <Standard_Stream.hxx>
 #include <TColStd_HArray1OfReal.hxx>
+#include <TColStd_HSequenceOfTransient.hxx>
 
 #include "GEOM_IMeasureOperations_i.hh"
 
@@ -709,6 +710,58 @@ char* GEOM_IMeasureOperations_i::PrintShapeErrors
   return CORBA::string_dup(aDescr.ToCString());
 }
 
+//=============================================================================
+/*!
+ *  ExtractBOPFailure
+ */
+//=============================================================================
+CORBA::Boolean GEOM_IMeasureOperations_i::ExtractBOPFailure
+             (const GEOM::ListOfGO&                                theShapes,
+                    CORBA::Boolean                                 theUseTimer,
+                    CORBA::Boolean                                 theTopoOnly,
+                    CORBA::Boolean                                 theShortReport,
+                    CORBA::Boolean                                 theRunParallel,
+                    CORBA::Boolean                                 theDoExact,
+                    GEOM::GEOM_IMeasureOperations::ShapeErrors_out theErrors)
+{
+  // Set the not done flag
+  GetOperations()->SetNotDone();
+
+  // Check for existing shapes
+  int aNbShapes = theShapes.length();
+  if (!aNbShapes)
+  {
+    return 0;
+  }
+
+  // Create the sequence of GEOM objects for the failure shapes
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
+  Handle(TColStd_HSequenceOfTransient) aSeqShapes = new TColStd_HSequenceOfTransient;
+  for (int i = 0; i < aNbShapes; i++)
+  {
+    Handle(::GEOM_Object) aShape = GetObjectImpl(theShapes[i]);
+    if (!aShape.IsNull())
+    {
+      aSeqShapes->Append(aShape);
+    }
+  }
+
+  if (!aSeqShapes->Length())
+  {
+    return 0;
+  }
+
+  // Perform partition operation and check for failures
+  std::list<GEOMImpl_IMeasureOperations::ShapeError> anErrList;
+  bool isOk = GetOperations()->ExtractBOPFailure(aSeqShapes, theUseTimer, theTopoOnly,
+                                                 theShortReport, theRunParallel, theDoExact,
+                                                 anErrList);
+
+  ConvertShapeError(anErrList, theErrors);
+
+  return isOk;
+}
+
 //=============================================================================
 /*!
  *  CheckSelfIntersections
index e1cd715ad8320990c82b468005a3b8acf9733133..3b346e7960d8d0779b8575809af8bff163e4421d 100644 (file)
@@ -98,6 +98,15 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
              (      GEOM::GEOM_Object_ptr                       theShape,
               const GEOM::GEOM_IMeasureOperations::ShapeErrors &theErrors);
 
+  CORBA::Boolean ExtractBOPFailure
+             (const GEOM::ListOfGO&                                theShapes,
+                    CORBA::Boolean                                 theUseTimer,
+                    CORBA::Boolean                                 theTopoOnly,
+                    CORBA::Boolean                                 theShortReport,
+                    CORBA::Boolean                                 theRunParallel,
+                    CORBA::Boolean                                 theDoExact,
+                    GEOM::GEOM_IMeasureOperations::ShapeErrors_out theErrors);
+
   CORBA::Boolean CheckSelfIntersections (GEOM::GEOM_Object_ptr theShape,
                                          CORBA::Long           theCheckLevel,
                                          GEOM::ListOfLong_out  theIntersections);
index e9cf78b474ea1ac71a8b25d74d767576b2ebe71a..04cad8817eadb1487f1ed2bf120e1088980beaca 100644 (file)
@@ -11982,6 +11982,40 @@ class geomBuilder(GEOM._objref_GEOM_Gen):
             """
             return self.MeasuOp.CheckBOPArguments(theShape)
 
+
+        def ExtractBOPFailure(self, lFaces, timer=None, topo=None, short=None, parallel=None, exact=None):
+            """
+            Extracts the BOP failure information from the given list of faces.
+        
+            Parameters:
+                lFaces - list of faces to extract the BOP failure information from.
+                timer - if True, the time of the operation is measured.
+                topo - if True, only the topological entities will be checked.
+                short - if True, the error report will be in short format.
+                parallel - if True, the operation will be executed in parallel.
+                exact - if True, an exact check will be performed.
+        
+            Returns:
+                the list of failed shapes.
+            """
+            # Check for default parameter values
+            if timer is None:
+              timer = False     # default: do not measure execution time
+            if topo is None:
+              topo = False      # default: check geometry & topology
+            if short is None:
+              short = False     # default: show full error report
+            if parallel is None:
+              parallel = False  # default: run operation sequentially
+            if exact is None:
+              exact = False     # default: do not perform exact check
+            # (IsValid, ShapeErrors) = self.MeasuOp.ExtractBOPFailure(lFaces, timer, topo, short, parallel, exact)
+            # if IsValid == 0:
+            #   Descr = self.MeasuOp.PrintShapeErrors(lFaces[0], ShapeErrors)
+            #   print(Descr)
+            # return IsValid
+            return self.MeasuOp.ExtractBOPFailure(lFaces, timer, topo, short, parallel, exact)
+
         ## Detect intersections of the given shapes with algorithm based on mesh intersections.
         #  @param theShape1 First source object
         #  @param theShape2 Second source object