[bos #29471] [EDF] (2022-T1) Advanced geometry features: iterate through holes of a face

- Added python command PatchFace
- Add description for function into GEOM_Gen.idl
- Method PatchFace was added into Geom_Superv_i and Geom_Superv
This commit is contained in:
Alexey Sozinov 2022-04-07 13:43:09 +03:00 committed by azv
parent 1b56fc0813
commit 8764d771c0
15 changed files with 429 additions and 0 deletions

View File

@ -4659,6 +4659,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
*/

View 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 @@*/
};
};

View 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
)

View 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());

View File

@ -23,6 +23,10 @@
#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

View 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

View File

@ -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;
};

View File

@ -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)

View File

@ -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

View File

@ -121,6 +121,8 @@
#define GEOM_EXTRACTION 58
#define GEOM_PATCH_FACE 59
//GEOM_Function types
#define COPY_WITH_REF 1

View 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();
}
//=============================================================================
/*!

View 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,

View 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,

View 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;

View File

@ -11733,6 +11733,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.
#