Salome HOME
[bos #29471] [EDF] (2022-T1) Advanced geometry features: iterate through holes of...
authorAlexey Sozinov <alexey.sozinov@opencascade.com>
Thu, 7 Apr 2022 10:43:09 +0000 (13:43 +0300)
committerjfa <jfa@opencascade.com>
Tue, 30 Aug 2022 13:34:10 +0000 (16:34 +0300)
16 files changed:
idl/GEOM_Gen.idl
idl/GEOM_Superv.idl
src/GEOMImpl/CMakeLists.txt
src/GEOMImpl/GEOMImpl_Gen.cxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
src/GEOMImpl/GEOMImpl_IPatchFace.hxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_PatchFaceDriver.cxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_PatchFaceDriver.hxx [new file with mode: 0644]
src/GEOMImpl/GEOMImpl_Types.hxx
src/GEOM_I/GEOM_IMeasureOperations_i.cc
src/GEOM_I/GEOM_IMeasureOperations_i.hh
src/GEOM_I_Superv/GEOM_Superv_i.cc
src/GEOM_I_Superv/GEOM_Superv_i.hh
src/GEOM_SWIG/geomBuilder.py
test/test_patch_face_01.py [new file with mode: 0644]

index b83b75d282474319c2617f5f8ab373483ed0cb0e..98b0086b9b60f12c7a2d3e96d04d82f1a05db7c7 100644 (file)
@@ -4660,6 +4660,16 @@ module GEOM
      */
     double GetAngleBtwVectors (in GEOM_Object theShape1, in GEOM_Object theShape2);
 
+    /*!
+     *  \brief The function takes a single face with holes and returns a list of faces,
+     *  first of them is the original face without holes, and the other faces are placed
+     *  on the same surface as the original face but bounded by each hole wire.
+     *  If the original face has no holes, it will be returned as an output
+     *  \param theShape face, to perform operation.
+     *  \return ListOfGO, containing the result original face and faces from holes.
+     */
+    ListOfGO PatchFace(in GEOM_Object theShape);
+
     /*!
      *  \brief Get point coordinates
      */
index 0b59d2672933e84258c22e8c7ab3f3ea0e8092f4..0ae258e6c87a58d342cfa08cf853fba4483644d7 100644 (file)
@@ -675,6 +675,11 @@ module GEOM
                            in string            theFileName,
                            in double            theDeflection );
 
+    //-----------------------------------------------------------//
+    // Measure Operations                                        //
+    //-----------------------------------------------------------//
+    GEOM_List PatchFace(in GEOM_Object theShape);
+
     /*@@ insert new functions before this line @@ do not remove this line @@*/
  };
 };
index 26d37c40f7c038220227d5482f9e725b8bd0c555..43faf7ab824395a301409d4eeddb0c390fcd8c54 100644 (file)
@@ -93,6 +93,7 @@ SET(GEOMImpl_HEADERS
   GEOMImpl_IDisk.hxx
   GEOMImpl_IFace.hxx
   GEOMImpl_ILine.hxx
+  GEOMImpl_IPatchFace.hxx
   GEOMImpl_IPlane.hxx
   GEOMImpl_IMarker.hxx
   GEOMImpl_ITranslate.hxx
@@ -178,6 +179,7 @@ SET(GEOMImpl_HEADERS
   GEOMImpl_HealingDriver.hxx
   GEOMImpl_FillingDriver.hxx
   GEOMImpl_GlueDriver.hxx
+  GEOMImpl_PatchFaceDriver.hxx
   GEOMImpl_Types.hxx
   GEOM_GEOMImpl.hxx
   )
@@ -253,6 +255,7 @@ SET(GEOMImpl_SOURCES
   GEOMImpl_HealingDriver.cxx
   GEOMImpl_FillingDriver.cxx
   GEOMImpl_GlueDriver.cxx
+  GEOMImpl_PatchFaceDriver.cxx
   GEOMImpl_FieldDriver.cxx
   )
 
index e61e220a80c9321437c51e85b6bafd556474ccdf..867f7b9eb2535c0b1799f076ccfe6ff9ec02d137 100644 (file)
@@ -65,6 +65,7 @@
 #include <GEOMImpl_FilletDriver.hxx>
 #include <GEOMImpl_Fillet1dDriver.hxx>
 #include <GEOMImpl_Fillet2dDriver.hxx>
+#include <GEOMImpl_PatchFaceDriver.hxx>
 #include <GEOMImpl_TranslateDriver.hxx>
 #include <GEOMImpl_RotateDriver.hxx>
 #include <GEOMImpl_MirrorDriver.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_PatchFaceDriver::GetID(), new GEOMImpl_PatchFaceDriver());
 
    // Field
    TFunction_DriverTable::Get()->AddDriver(GEOMImpl_FieldDriver::GetID(), new GEOMImpl_FieldDriver());
index ff539a6c9391443252da49203e758154334d3a7d..aa141c2888c9a1ba326fda763f96b421452dbc61 100644 (file)
 #include <GEOMImpl_IMeasureOperations.hxx>
 #include <GEOMImpl_IMeasure.hxx>
 #include <GEOMImpl_MeasureDriver.hxx>
+
+#include <GEOMImpl_IPatchFace.hxx>
+#include <GEOMImpl_PatchFaceDriver.hxx>
+
 #include <GEOMImpl_Types.hxx>
 
 #include <GEOMUtils.hxx>
@@ -2358,6 +2362,74 @@ Standard_Real GEOMImpl_IMeasureOperations::GetAngleBtwVectors (Handle(GEOM_Objec
 }
 
 
+//=============================================================================
+/*!
+ *  PatchFace
+ */
+ //=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IMeasureOperations::PatchFace(Handle(GEOM_Object) theShape)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull()) return NULL;
+
+  Handle(GEOM_Object) aPatchFace = GetEngine()->AddObject(GEOM_PATCH_FACE);
+  Handle(GEOM_Function) aFunction = aPatchFace->AddFunction(GEOMImpl_PatchFaceDriver::GetID(), 1);
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_PatchFaceDriver::GetID()) return NULL;
+
+  GEOMImpl_IPatchFace aPI(aFunction);
+  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+  if (aRefShape.IsNull()) return NULL;
+
+  aPI.SetShape(aRefShape);
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  // Perform
+  try
+  {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction))
+    {
+      SetErrorCode("patch face driver failed");
+      return NULL;
+    }
+
+    // Get result compound and collect all faces 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);
+      }
+    }
+  }
+  catch (Standard_Failure& aFail)
+  {
+    SetErrorCode(aFail.GetMessageString());
+    return aSeq;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump(aFunction, true)
+    << "[" << aSeq << "] = geompy.PatchFace(" << theShape << ")";
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
 //=============================================================================
 /*!
  *  CurveCurvatureByParam
index 2d2002613b03e837fdb5d9df5ed20ae4415c525b..827f695fff310e441679ea5952ac548558e1b196 100644 (file)
@@ -198,6 +198,7 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
 
   Standard_EXPORT Standard_Real GetAngleBtwVectors (Handle(GEOM_Object) theVec1, Handle(GEOM_Object) theVec2);
 
+  Standard_EXPORT Handle(TColStd_HSequenceOfTransient) PatchFace(Handle(GEOM_Object) theShape);
 
   // Methods for receiving radiuses of curvature of curves and surfaces
   // in the given point
diff --git a/src/GEOMImpl/GEOMImpl_IPatchFace.hxx b/src/GEOMImpl/GEOMImpl_IPatchFace.hxx
new file mode 100644 (file)
index 0000000..2058d7c
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright (C) 2007-2021  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
+//
+
+//NOTE: This is an interface to a function for the patch face.
+//
+#include "GEOM_Function.hxx"
+
+#include <TColStd_HSequenceOfTransient.hxx>
+
+#define PATCHFACE_ARG_FACE 1
+
+class GEOMImpl_IPatchFace
+{
+ public:
+
+  GEOMImpl_IPatchFace(Handle(GEOM_Function) theFunction): _func(theFunction) {}
+
+  void SetShape(Handle(GEOM_Function) theRef) 
+  {
+    _func->SetReference(PATCHFACE_ARG_FACE, theRef);
+  }
+
+  Handle(GEOM_Function) GetShape()
+  {
+    return _func->GetReference(PATCHFACE_ARG_FACE);
+  }
+
+ private:
+
+  Handle(GEOM_Function) _func;
+};
diff --git a/src/GEOMImpl/GEOMImpl_PatchFaceDriver.cxx b/src/GEOMImpl/GEOMImpl_PatchFaceDriver.cxx
new file mode 100644 (file)
index 0000000..4aa496c
--- /dev/null
@@ -0,0 +1,140 @@
+// Copyright (C) 2007-2021  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_PatchFaceDriver.hxx>
+#include <GEOMImpl_IPatchFace.hxx>
+#include <GEOMImpl_Types.hxx>
+#include <GEOM_Function.hxx>
+#include <GEOMUtils.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepTools.hxx>
+
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopAbs.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+
+#include <StdFail_NotDone.hxx>
+
+//=======================================================================
+//function : GetID
+//purpose  :
+//=======================================================================
+const Standard_GUID& GEOMImpl_PatchFaceDriver::GetID()
+{
+  static Standard_GUID aPatchFaceDriver("6E0A4C17-9E56-4739-8C67-B37C01C47ED6");
+  return aPatchFaceDriver;
+}
+
+
+//=======================================================================
+//function : GEOMImpl_PatchFaceDriver
+//purpose  :
+//=======================================================================
+GEOMImpl_PatchFaceDriver::GEOMImpl_PatchFaceDriver()
+{
+}
+
+//=======================================================================
+//function : Execute
+//purpose  :
+//=======================================================================
+Standard_Integer GEOMImpl_PatchFaceDriver::Execute(Handle(TFunction_Logbook)& log) const
+{
+  if (Label().IsNull()) return 0;
+  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+  GEOMImpl_IPatchFace aCI(aFunction);
+
+  Handle(GEOM_Function) aRefShape = aCI.GetShape();
+  if (aRefShape.IsNull()) return 0;
+
+  TopoDS_Shape aFaceShape = aRefShape->GetValue();
+
+  TopoDS_Compound aCompound;
+  if (aFaceShape.ShapeType() == TopAbs_FACE)
+  {
+    if (aFaceShape.Orientation() == TopAbs_Orientation::TopAbs_REVERSED)
+      aFaceShape.Reverse();
+
+    // Colect all Wires from face
+    TopTools_ListOfShape aWires;
+    TopoDS_Wire anOuterWire = BRepTools::OuterWire(TopoDS::Face(aFaceShape));
+    aWires.Append(anOuterWire);
+    for (TopExp_Explorer anExpW(aFaceShape, TopAbs_WIRE); anExpW.More(); anExpW.Next())
+    {
+      TopoDS_Wire aWire = TopoDS::Wire(anExpW.Current());
+      if (anOuterWire.IsSame(aWire))
+        continue;
+
+      aWire.Reverse();
+      aWires.Append(aWire);
+    }
+
+    BRep_Builder aBrepBuilder;
+    TopLoc_Location aLocation;
+    Handle(Geom_Surface) aSurface = BRep_Tool::Surface(TopoDS::Face(aFaceShape), aLocation);
+
+    // Create result compound from all faces
+    aBrepBuilder.MakeCompound(aCompound);
+    TopTools_ListIteratorOfListOfShape anIterWires(aWires);
+    for (; anIterWires.More(); anIterWires.Next())
+    {
+      // Create face on surface from wire 
+      TopoDS_Face aFace;
+      aBrepBuilder.MakeFace(aFace, aSurface, aLocation, 1.e-7);
+      aBrepBuilder.Add(aFace, anIterWires.Value());
+
+      // Add created face to compound
+      aBrepBuilder.Add(aCompound, aFace);
+    }
+  }
+  else
+  {
+    Standard_ConstructionError::Raise("Wrong arguments: a face must be given");
+  }
+
+  if (aCompound.IsNull()) return 0;
+
+  aFunction->SetValue(aCompound);
+  log->SetTouched(Label());
+  
+  return 1;
+}
+
+//================================================================================
+/*!
+ * \brief Returns a name of creation operation and names and values of creation parameters
+ */
+ //================================================================================
+
+bool GEOMImpl_PatchFaceDriver::
+GetCreationInformation(std::string&             /*theOperationName*/,
+                       std::vector<GEOM_Param>& /*theParams*/)
+{
+  return false;
+}
+
+IMPLEMENT_STANDARD_RTTIEXT(GEOMImpl_PatchFaceDriver, GEOM_BaseDriver)
diff --git a/src/GEOMImpl/GEOMImpl_PatchFaceDriver.hxx b/src/GEOMImpl/GEOMImpl_PatchFaceDriver.hxx
new file mode 100644 (file)
index 0000000..7bc6af4
--- /dev/null
@@ -0,0 +1,49 @@
+// Copyright (C) 2007-2021  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
+//
+
+//  File   : GEOMImpl_PatchFaceDriver.hxx
+//  Module : GEOMImpl
+//
+#ifndef _GEOMImpl_PatchFaceDriver_HeaderFile
+#define _GEOMImpl_PatchFaceDriver_HeaderFile
+
+#include <GEOM_BaseDriver.hxx>
+
+DEFINE_STANDARD_HANDLE(GEOMImpl_PatchFaceDriver, GEOM_BaseDriver )
+
+class GEOMImpl_PatchFaceDriver : public GEOM_BaseDriver {
+
+public:
+
+  Standard_EXPORT GEOMImpl_PatchFaceDriver();
+  Standard_EXPORT virtual Standard_Integer Execute(Handle(TFunction_Logbook)& log) const;
+  Standard_EXPORT virtual void Validate(Handle(TFunction_Logbook)&) const {}
+  Standard_EXPORT Standard_Boolean MustExecute(const Handle(TFunction_Logbook)&) const { return Standard_True; }
+
+  Standard_EXPORT static const Standard_GUID& GetID();
+  Standard_EXPORT ~GEOMImpl_PatchFaceDriver() {};
+
+  Standard_EXPORT virtual
+  bool GetCreationInformation(std::string&             theOperationName,
+                              std::vector<GEOM_Param>& params);
+
+  DEFINE_STANDARD_RTTIEXT(GEOMImpl_PatchFaceDriver,GEOM_BaseDriver)
+};
+
+#endif
index faa8f99535901478593461a1d205f49928ab024a..af37b6dcf59a8452aace7026cac3ea2ef1c8097c 100644 (file)
 
 #define GEOM_CURVATURE_VEC 59
 
+#define GEOM_PATCH_FACE 60
+
 //GEOM_Function types
 
 #define COPY_WITH_REF    1
index ccc759c3e485dada79b4aa319bf570040861b23f..0c09e09c4b1ebaccdf503e5e29c0762917fdee19 100644 (file)
@@ -1072,6 +1072,32 @@ CORBA::Double GEOM_IMeasureOperations_i::GetAngleBtwVectors (GEOM::GEOM_Object_p
   return GetOperations()->GetAngleBtwVectors(aShape1, aShape2);
 }
 
+//=============================================================================
+/*!
+*  PatchFace
+*/
+//=============================================================================
+GEOM::ListOfGO* GEOM_IMeasureOperations_i::PatchFace(GEOM::GEOM_Object_ptr theShape)
+{
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
+
+  //Get the reference shape
+  Handle(::GEOM_Object) aShapeRef = GetObjectImpl(theShape);
+  if (aShapeRef.IsNull()) return aSeq._retn();
+
+  // Perform patch face operation
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->PatchFace(aShapeRef);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i - 1] = GetObject(Handle(::GEOM_Object)::DownCast(aHSeq->Value(i)));
+
+  return aSeq._retn();
+}
 
 //=============================================================================
 /*!
index 30b89faeb9b2a92f9457deba15c6549c22714192..6a5aa39ee22c4119d21ba710fde7aa9cddc61595 100644 (file)
@@ -142,6 +142,8 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
   CORBA::Double GetAngleBtwVectors (GEOM::GEOM_Object_ptr theShape1,
                                     GEOM::GEOM_Object_ptr theShape2);
 
+  GEOM::ListOfGO* PatchFace(GEOM::GEOM_Object_ptr theShape);
+
   // Methods for receiving radiuses of curvature of curves and surfaces
   // in the given point
   CORBA::Double CurveCurvatureByParam (GEOM::GEOM_Object_ptr theCurve,
index adb77cca48e9ac264c580082c94b01bed747a385..7c3f7299e8b507b5af5e8cd14a95fae792555ba1 100644 (file)
@@ -61,6 +61,7 @@ GEOM_Superv_i::GEOM_Superv_i(CORBA::ORB_ptr orb,
   myBlocksOp = GEOM::GEOM_IBlocksOperations::_nil();
   myCurvesOp = GEOM::GEOM_ICurvesOperations::_nil();
   myLocalOp = GEOM::GEOM_ILocalOperations::_nil();
+  myMeasureOp = GEOM::GEOM_IMeasureOperations::_nil();
   myGroupOp = GEOM::GEOM_IGroupOperations::_nil();
 }
 
@@ -299,6 +300,20 @@ void GEOM_Superv_i::getLocalOp()
   }
 }
 
+//=============================================================================
+//  getMeasureOp:
+//=============================================================================
+void GEOM_Superv_i::getMeasureOp()
+{
+  if (CORBA::is_nil(myGeomEngine))
+    setGeomEngine();
+  // get GEOM_IMeasureOperations interface
+  if (CORBA::is_nil(myMeasureOp))
+  {
+    myMeasureOp = myGeomEngine->GetIMeasureOperations();
+  }
+}
+
 //=============================================================================
 //  getGroupOp:
 //=============================================================================
@@ -3743,6 +3758,21 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeSmoothingSurface (GEOM::GEOM_List_ptr t
   return NULL;
 }
 
+//=============================================================================
+//  PatchFace:
+//=============================================================================
+GEOM::GEOM_List_ptr GEOM_Superv_i::PatchFace(GEOM::GEOM_Object_ptr theShape)
+{
+  beginService(" GEOM_Superv_i::PatchFace");
+  MESSAGE("GEOM_Superv_i::PatchFace");
+  getLocalOp();
+
+  GEOM::ListOfGO* aList = myMeasureOp->PatchFace(theShape);
+  GEOM_List_i<GEOM::ListOfGO>* aListPtr = new GEOM_List_i<GEOM::ListOfGO>(*(aList));
+  endService(" GEOM_Superv_i::PatchFace");
+  return aListPtr->_this();
+}
+
 /*@@ insert new functions before this line @@ do not remove this line @@*/
 
 GEOM_Superv_i_With_Session::GEOM_Superv_i_With_Session(CORBA::ORB_ptr orb,
index caaa9fe645e0c3410e739355d3591cc8233c9864..e35a40aaf981319bbc4c12e6f03dbd6f9af2a27b 100644 (file)
@@ -69,6 +69,7 @@ public:
   void getBlocksOp();
   void getCurvesOp();
   void getLocalOp();
+  void getMeasureOp();
   void getGroupOp();
   void getAdvancedOp();
   void getSTLPluginOp();
@@ -780,6 +781,11 @@ public:
                                              CORBA::Double theH,
                                              GEOM::pattern thePattern);
   GEOM::GEOM_Object_ptr MakeSmoothingSurface (GEOM::GEOM_List_ptr thelPoints);
+
+  //-----------------------------------------------------------//
+  // Measure Operations                                        //
+  //-----------------------------------------------------------//
+  GEOM::GEOM_List_ptr PatchFace(GEOM::GEOM_Object_ptr theShape);
   /*@@ insert new functions before this line @@ do not remove this line @@*/
 
 protected:
@@ -797,6 +803,7 @@ private:
   GEOM::GEOM_IBlocksOperations_var    myBlocksOp;
   GEOM::GEOM_ICurvesOperations_var    myCurvesOp;
   GEOM::GEOM_ILocalOperations_var     myLocalOp;
+  GEOM::GEOM_IMeasureOperations_var   myMeasureOp;
   GEOM::GEOM_IGroupOperations_var     myGroupOp;
   GEOM::IAdvancedOperations_var       myAdvancedOp;
   GEOM::ISTLOperations_var            mySTLOp;
index 9c8ad7f7c7e50b3f3a0d3da4d4ade1aed12e3989..e80d9f60ac9c4f6121570b9c8e8174b7436b05f4 100644 (file)
@@ -11784,6 +11784,39 @@ class geomBuilder(GEOM._objref_GEOM_Gen):
 
             return aKindTuple
 
+        ## The function takes a single face with holes and returns a list of faces,
+        #  first of them is the original face without holes, and the other faces are placed
+        #  on the same surface as the original face but bounded by each hole wire.
+        #  If the original face has no holes, it will be returned as an output
+        #  @param theShape Face to perform operation on.
+        #
+        #  @return GEOM.ListOfGO, list created faces, where first of them is the original face without holes
+        @ManageTransactions("MeasuOp")
+        def PatchFace(self, theShape):
+            """
+            The function takes a single face with holes and returns a list of faces,
+            first of them is the original face without holes, and the other faces are placed
+            on the same surface as the original face but bounded by each hole wire.
+            If the original face has no holes, it will be returned as an output
+
+            Parameters:
+                theShape  Face to perform operation on.
+
+            Returns:
+                GEOM.ListOfGO, list created faces, where first of them is the original face without holes
+
+            Example of usage:
+                Circle_1 = geompy.MakeCircle(None, None, 190)
+                Circle_2 = geompy.MakeCircle(None, None, 100)
+                Face_1 = geompy.MakeFaceWires([Circle_1], 1)
+                Face_2 = geompy.MakeFaceWires([Circle_2], 1)
+                Cut_1 = geompy.MakeCutList(Face_1, [Face_2], True)
+                faces = geompy.PatchFace(Cut_1)
+            """
+            aList = self.MeasuOp.PatchFace(theShape)
+            RaiseIfFailed("PatchFace", self.MeasuOp)
+            return aList
+
         ## Returns the string that describes if the shell is good for solid.
         #  This is a support method for MakeSolid.
         #
diff --git a/test/test_patch_face_01.py b/test/test_patch_face_01.py
new file mode 100644 (file)
index 0000000..1d0d288
--- /dev/null
@@ -0,0 +1,71 @@
+# Check patch face functionality
+
+def CheckFacesOnHoles( faces ):
+        """
+        check that none of the faces in the list have holes
+        param faces - list of faces
+        return bool - *True* if all faces not have hole; *False* otherwise
+        """
+        for face in faces:
+            newFaces = geompy.PatchFace(face)
+            if len(newFaces) != 1:
+                return False
+        return True
+
+def CompareAreaAfterPatchFace( originalFace, patchFaceResult, eps=1e-06 ):
+        """
+        Specific function for check result of PatchFace operation.
+        Check that area of original face equal area first face from list (face by outer wire of original face)
+        minus the areas of the rest elements from list (holes)
+        param originalFace - original face
+        param patchFaceResult - list of faces result PatchFace operation. 
+                              First element - face from outer wire of original face,
+                              other elements - faces from holes on original face
+        param eps - defines tolerance for comparison
+        return bool - *True* if area of original face is equal of area face[0] minus area of holes; *False* otherwise
+        """
+        areaOfHoles = 0.
+        for index in range(1, len(patchFaceResult)):
+            areaOfHoles += geompy.BasicProperties(patchFaceResult[index])[1]
+        return geompy.BasicProperties(originalFace)[1] - (geompy.BasicProperties(patchFaceResult[0])[1] - areaOfHoles) <= eps
+
+import math
+import salome
+salome.salome_init_without_session()
+import GEOM
+from salome.geom import geomBuilder
+geompy = geomBuilder.New()
+
+# Create shape
+vz = geompy.MakeVectorDXDYDZ(0, 0, 1)
+pyz = geompy.MakeVertex(0, -150, 100)
+
+geomObj = geompy.MakeMarker(0, 0, 0, 1, 0, 0, 0, 1, 0)
+sk = geompy.Sketcher2D()
+sk.addPoint(30.0000000, 50.0000000)
+sk.addArcAbsolute(70.0000000, 20.0000000)
+sk.addSegmentAbsolute(0.0000000, 0.0000000)
+sk.close()
+sketch = sk.wire(geomObj)
+face_1 = geompy.MakeFaceWires([sketch], 1)
+multiTranslation = geompy.MakeMultiTranslation1D(face_1, None, 105, 3)
+[face_2,face_3,face_4] = geompy.ExtractShapes(multiTranslation, geompy.ShapeType["FACE"], True)
+scale_1 = geompy.MakeScaleTransform(face_3, None, 0.3)
+scale_2 = geompy.MakeScaleTransform(face_4, None, 0.3)
+
+translation_1 = geompy.MakeTranslation(scale_1, -10, 25, 0)
+translation_2 = geompy.MakeTranslation(scale_2, -25, 20, 0)
+
+rotation_1 = geompy.MakeRotation(translation_1, vz, -19*math.pi/180.0)
+rotation_2 = geompy.MakeRotation(translation_2, vz, 15*math.pi/180.0)
+
+cut = geompy.MakeCutList(face_1, [rotation_2, rotation_1], True)
+
+#Perform oepration
+faces = geompy.PatchFace(cut)
+
+# Check, that result faces haven't holes
+assert(CheckFacesOnHoles(faces))
+
+#Check area
+assert(CompareAreaAfterPatchFace(cut, faces))