*/
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
*/
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 @@*/
};
};
GEOMImpl_IDisk.hxx
GEOMImpl_IFace.hxx
GEOMImpl_ILine.hxx
+ GEOMImpl_IPatchFace.hxx
GEOMImpl_IPlane.hxx
GEOMImpl_IMarker.hxx
GEOMImpl_ITranslate.hxx
GEOMImpl_HealingDriver.hxx
GEOMImpl_FillingDriver.hxx
GEOMImpl_GlueDriver.hxx
+ GEOMImpl_PatchFaceDriver.hxx
GEOMImpl_Types.hxx
GEOM_GEOMImpl.hxx
)
GEOMImpl_HealingDriver.cxx
GEOMImpl_FillingDriver.cxx
GEOMImpl_GlueDriver.cxx
+ GEOMImpl_PatchFaceDriver.cxx
GEOMImpl_FieldDriver.cxx
)
#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>
// 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());
#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>
}
+//=============================================================================
+/*!
+ * 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
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
--- /dev/null
+// 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;
+};
--- /dev/null
+// 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)
--- /dev/null
+// 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
#define GEOM_CURVATURE_VEC 59
+#define GEOM_PATCH_FACE 60
+
//GEOM_Function types
#define COPY_WITH_REF 1
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();
+}
//=============================================================================
/*!
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,
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();
}
}
}
+//=============================================================================
+// 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:
//=============================================================================
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,
void getBlocksOp();
void getCurvesOp();
void getLocalOp();
+ void getMeasureOp();
void getGroupOp();
void getAdvancedOp();
void getSTLPluginOp();
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:
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;
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.
#
--- /dev/null
+# 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))