From ef95b8ac70d50ab64058ffcc124ef9f2cf7ba9cc Mon Sep 17 00:00:00 2001 From: skv Date: Thu, 27 Mar 2014 11:59:05 +0400 Subject: [PATCH] 0022471: EDF 2604 GEOM: Suppress the boundary edges of the tools in the fuse operation --- doc/salome/gui/GEOM/images/bool1.png | Bin 24359 -> 25953 bytes doc/salome/gui/GEOM/input/fuse_operation.doc | 11 ++- .../GEOM/input/using_boolean_operations.doc | 15 +++- idl/GEOM_Gen.idl | 19 ++++- src/BooleanGUI/BooleanGUI_Dialog.cxx | 35 ++++++-- src/BooleanGUI/BooleanGUI_Dialog.h | 4 +- src/GEOMGUI/GEOM_msg_en.ts | 4 + src/GEOMImpl/GEOMImpl_BooleanDriver.cxx | 67 ++++++++++++++- src/GEOMImpl/GEOMImpl_IBoolean.hxx | 5 ++ src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx | 80 ++++++++++++++++-- src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx | 9 +- src/GEOM_I/GEOM_IBooleanOperations_i.cc | 37 +++++++- src/GEOM_I/GEOM_IBooleanOperations_i.hh | 8 +- src/GEOM_SWIG/geomBuilder.py | 28 ++++-- 14 files changed, 284 insertions(+), 38 deletions(-) diff --git a/doc/salome/gui/GEOM/images/bool1.png b/doc/salome/gui/GEOM/images/bool1.png index cc89563870ceffd760b42ae11822dbe546b1e491..c259c3fcc4a4d628486fae165d135e3d8943bf14 100755 GIT binary patch literal 25953 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 a`@!f(AKYRscj3!U5L#-ws-?;{;r{~*fGA`D literal 24359 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 PmFTgehC(sK{Pn*9mEm@Q diff --git a/doc/salome/gui/GEOM/input/fuse_operation.doc b/doc/salome/gui/GEOM/input/fuse_operation.doc index 95dc6ce06..e0a31b777 100644 --- a/doc/salome/gui/GEOM/input/fuse_operation.doc +++ b/doc/salome/gui/GEOM/input/fuse_operation.doc @@ -12,6 +12,7 @@ In this dialog: - Input or accept the default \b Name of the resulting shape. - Click the arrow button and select in the Object Browser or in the Viewer the Objects to be fused. - Activate the corresponding check-box if you wish to Detect Self-intersections . +- Activate the corresponding check-box if you wish to remove extra edges . - Activate \ref restore_presentation_parameters_page "Advanced options" if required. - Press "Apply" or "Apply & Close" button to get the result (GEOM_Object). @@ -24,15 +25,17 @@ In this dialog: This operation can be performed using a TUI Command: -geompy.MakeFuseList(theShapesList, checkSelfInte) +geompy.MakeFuseList(theShapesList, checkSelfInte, rmExtraEdges) -Arguments: Name + a list of shapes + an optional flag for self-intersection check. +Arguments: Name + a list of shapes + an optional flag for +self-intersection check + an optional flag to remove extra edges. There is also a special TUI Command for \b Fuse operation on two shapes : -geompy.MakeFuse(s1, s2, checkSelfInte) +geompy.MakeFuse(s1, s2, checkSelfInte, rmExtraEdges) -Arguments: Name + 2 shapes + an optional flag for self-intersection check. +Arguments: Name + 2 shapes + an optional flag for self-intersection +check + an optional flag to remove extra edges. Example: diff --git a/doc/salome/gui/GEOM/input/using_boolean_operations.doc b/doc/salome/gui/GEOM/input/using_boolean_operations.doc index 74acd1e8b..02a30251d 100644 --- a/doc/salome/gui/GEOM/input/using_boolean_operations.doc +++ b/doc/salome/gui/GEOM/input/using_boolean_operations.doc @@ -23,7 +23,7 @@ a list of others. You can use advanced TUI commands performing these operations independently from each other: \par -geompy.MakeFuseList(theShapesList, checkSelfInte), where \em theShapesList is +geompy.MakeFuseList(theShapesList, checkSelfInte, rmExtraEdges), where \em theShapesList is the list of shapes for Fuse operation; \par geompy.MakeCommonList(theShapesList, checkSelfInte), where \em theShapesList is @@ -51,7 +51,7 @@ a Boolean operation, \em Operation is the type of a Boolean operation (1 Besides, you can use advanced TUI commands performing these operations independently from each other: \par -geompy.MakeFuse(Shape1, Shape2, checkSelfInte), where \em Shape1 is the first +geompy.MakeFuse(Shape1, Shape2, checkSelfInte, rmExtraEdges), where \em Shape1 is the first argument and \em Shape2 is the second argument of Fuse operation; \par geompy.MakeCommon(Shape1, Shape2, checkSelfInte), where \em Shape1 is the first @@ -73,6 +73,17 @@ not valid for boolean operations. all self-intersections use \ref check_self_intersections_page "Detect Self-intersection tool". +The flag \em rmExtraEdges is used for \em MakeFuseList and \em MakeFuse +operations only. It indicates if Remove Extra Edges operation should be +performed during the operation. Its default value is \em False, which +means that there is no need to do it. + +\note \em rmExtraEdges is not available for \em MakeBoolean call with + operation type 3 (Fuse). \em MakeBoolean operation doesn't perform + Remove Extra Edges. So the call geompy.MakeBoolean(Shape1, Shape2, + 3, checkSelfInte) is equivalent to geompy.MakeFuse(Shape1, + Shape2, checkSelfInte, False). + Our TUI Scripts provide you with useful examples of the use of \ref tui_boolean_operations_page "Boolean Operations". diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 921e35995..542a1e8e8 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -2917,16 +2917,33 @@ module GEOM in GEOM_Object theShape2, in long theOperation, in boolean IsCheckSelfInte); + /*! + * \brief Perform fusion boolean operation on two given shapes. + * \param theShape1 First argument for fuse operation. + * \param theShape2 Second argument for fuse operation. + * \param IsCheckSelfInte If TRUE, perform check self intersection + * of arguments before an operation. + * \param IsRmExtraEdges If TRUE, perform removal of extra edges + * during an operation. + * \return New GEOM_Object, containing the result shape. + */ + GEOM_Object MakeFuse (in GEOM_Object theShape1, + in GEOM_Object theShape2, + in boolean IsCheckSelfInte, + in boolean IsRmExtraEdges); /*! * \brief Perform fusion boolean operation on list of objects. * \param theShapes Shapes to be fused. * \param IsCheckSelfInte If TRUE, perform check self intersection * of arguments before an operation. + * \param IsRmExtraEdges If TRUE, perform removal of extra edges + * during an operation. * \return New GEOM_Object, containing the result shape. */ GEOM_Object MakeFuseList (in ListOfGO theShapes, - in boolean IsCheckSelfInte); + in boolean IsCheckSelfInte, + in boolean IsRmExtraEdges); /*! * \brief Perform common boolean operation on list of objects. diff --git a/src/BooleanGUI/BooleanGUI_Dialog.cxx b/src/BooleanGUI/BooleanGUI_Dialog.cxx index 3b57da1ca..3ee6ba47c 100644 --- a/src/BooleanGUI/BooleanGUI_Dialog.cxx +++ b/src/BooleanGUI/BooleanGUI_Dialog.cxx @@ -93,7 +93,7 @@ BooleanGUI_Dialog::BooleanGUI_Dialog (const int theOperation, GeometryGUI* theGe mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose); mainFrame()->RadioButton3->close(); - myGroup = new DlgRef_2Sel2Spin1Check(centralWidget()); + myGroup = new DlgRef_2Sel2Spin3Check(centralWidget()); myGroup->GroupBox1->setTitle(tr("GEOM_ARGUMENTS")); if (myOperation == BooleanGUI::CUT) { @@ -108,21 +108,30 @@ BooleanGUI_Dialog::BooleanGUI_Dialog (const int theOperation, GeometryGUI* theGe myGroup->TextLabel2->hide(); myGroup->PushButton2->hide(); myGroup->LineEdit2->hide(); + + if (myOperation == BooleanGUI::FUSE) { + myGroup->CheckBox2->setText(tr("GEOM_BOOL_REMOVE_EXTRA_EDGES")); + } } myGroup->PushButton1->setIcon(image1); myGroup->LineEdit1->setReadOnly(true); - if (myOperation != BooleanGUI::FUSE && myOperation != BooleanGUI::COMMON) { - myGroup->PushButton2->setIcon(image1); - myGroup->LineEdit2->setReadOnly(true); + if (myOperation != BooleanGUI::FUSE) { + myGroup->CheckBox2->hide(); + + if (myOperation != BooleanGUI::COMMON) { + myGroup->PushButton2->setIcon(image1); + myGroup->LineEdit2->setReadOnly(true); + } } myGroup->TextLabel3->hide(); myGroup->TextLabel4->hide(); myGroup->SpinBox_DX->hide(); myGroup->SpinBox_DY->hide(); - myGroup->CheckButton1->setText(tr("GEOM_CHECK_SELF_INTERSECTIONS")); + myGroup->CheckBox3->hide(); + myGroup->CheckBox1->setText(tr("GEOM_CHECK_SELF_INTERSECTIONS")); QVBoxLayout* layout = new QVBoxLayout(centralWidget()); layout->setMargin(0); layout->setSpacing(6); @@ -158,7 +167,12 @@ void BooleanGUI_Dialog::Init() myGroup->LineEdit1->setText(""); myGroup->LineEdit2->setText(""); - myGroup->CheckButton1->setChecked(true); + myGroup->CheckBox1->setChecked(true); + + if (myOperation == BooleanGUI::FUSE) { + myGroup->CheckBox2->setChecked(true); + } + myObject1.nullify(); reset(); @@ -409,11 +423,16 @@ bool BooleanGUI_Dialog::execute (ObjectList& objects) GEOM::GEOM_Object_var anObj; GEOM::GEOM_IBooleanOperations_var anOper = GEOM::GEOM_IBooleanOperations::_narrow(getOperation()); - const bool isCheckSelfInte = myGroup->CheckButton1->isChecked(); + const bool isCheckSelfInte = myGroup->CheckBox1->isChecked(); switch (myOperation) { case BooleanGUI::FUSE: - anObj = anOper->MakeFuseList(myObjects, isCheckSelfInte); + { + const bool isRmExtraEdges = myGroup->CheckBox2->isChecked(); + + anObj = anOper->MakeFuseList + (myObjects, isCheckSelfInte, isRmExtraEdges); + } break; case BooleanGUI::COMMON: anObj = anOper->MakeCommonList(myObjects, isCheckSelfInte); diff --git a/src/BooleanGUI/BooleanGUI_Dialog.h b/src/BooleanGUI/BooleanGUI_Dialog.h index f7726a72c..99ead05a6 100644 --- a/src/BooleanGUI/BooleanGUI_Dialog.h +++ b/src/BooleanGUI/BooleanGUI_Dialog.h @@ -30,7 +30,7 @@ #include "GEOMBase_Skeleton.h" #include "GEOM_GenericObjPtr.h" -class DlgRef_2Sel2Spin1Check; +class DlgRef_2Sel2Spin3Check; //================================================================================= // class : BooleanGUI_Dialog @@ -65,7 +65,7 @@ private: GEOM::GeomObjPtr myObject1; GEOM::ListOfGO_var myObjects; - DlgRef_2Sel2Spin1Check* myGroup; + DlgRef_2Sel2Spin3Check* myGroup; private slots: void ClickOnOk(); diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index d57c18ef5..35cf49d7f 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -4640,6 +4640,10 @@ Please, select face, shell or solid and try again GEOM_REMOVE_EXTRA_EDGES_TITLE Remove extra edges + + GEOM_BOOL_REMOVE_EXTRA_EDGES + Remove extra edges + GEOM_REMOVE_EXTRA_EDGES Object to remove extra edges diff --git a/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx b/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx index 99c2ab976..32b0b04fa 100644 --- a/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include @@ -61,6 +63,49 @@ // here check level is decreased to more appropriate value to avoid problems with performance). #define BOP_SELF_INTERSECTIONS_LEVEL 4 +/** + * This function performs extra edges removal. + * + * \param theShape the shape to be processed. + * \return the modified shape or null shape in case of failure. + */ +static TopoDS_Shape RemoveExtraEdges(const TopoDS_Shape &theShape) +{ + TopoDS_Shape aResult; + + if (theShape.IsNull() == Standard_False) { + BlockFix_BlockFixAPI aTool; + + aTool.OptimumNbFaces() = 0; + aTool.SetShape(theShape); + aTool.Perform(); + aResult = aTool.Shape(); + + // Repair result + BRepCheck_Analyzer anAna (aResult, false); + Standard_Boolean isValid = anAna.IsValid(); + + if (!isValid) { + TopoDS_Shape aFixed; + ShHealOper_ShapeProcess aHealer; + + aHealer.Perform(aResult, aFixed); + + if (aHealer.isDone()) { + aResult = aFixed; + anAna.Init(aResult, false); + isValid = anAna.IsValid(); + } + } + + if (!isValid) { + aResult.Nullify(); + } + } + + return aResult; +} + //======================================================================= //function : GetID //purpose : @@ -91,6 +136,7 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const GEOMImpl_IBoolean aCI (aFunction); Standard_Integer aType = aFunction->GetType(); const Standard_Boolean isCheckSelfInte = aCI.GetCheckSelfIntersection(); + const Standard_Boolean isRmExtraEdges = aCI.GetRmExtraEdges(); TopoDS_Shape aShape; @@ -139,8 +185,13 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const aShape = performOperation (aShapeCopy1, aShapeCopy2, aType); - if (aShape.IsNull()) + if (isRmExtraEdges) { + aShape = RemoveExtraEdges(aShape); + } + + if (aShape.IsNull()) { return 0; + } } } break; @@ -208,6 +259,10 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const aShapeCopy.Nullify(); TNaming_CopyShape::CopyTool(aShape2, aMapTShapes, aShapeCopy); aShape = performOperation (aShape, aShapeCopy, aSimpleType); + + if (isRmExtraEdges) { + aShape = RemoveExtraEdges(aShape); + } if (aShape.IsNull()) { return 0; @@ -621,40 +676,50 @@ GetCreationInformation(std::string& theOperationName, GEOMImpl_IBoolean aCI (function); Standard_Integer aType = function->GetType(); + Standard_Boolean isCheckSelfInte = aCI.GetCheckSelfIntersection(); switch ( aType ) { case BOOLEAN_COMMON: theOperationName = "COMMON"; AddParam( theParams, "Object 1", aCI.GetShape1() ); AddParam( theParams, "Object 2", aCI.GetShape2() ); + AddParam( theParams, "Check self-intersections", isCheckSelfInte ); break; case BOOLEAN_CUT: theOperationName = "CUT"; AddParam( theParams, "Main Object", aCI.GetShape1() ); AddParam( theParams, "Tool Object", aCI.GetShape2() ); + AddParam( theParams, "Check self-intersections", isCheckSelfInte ); break; case BOOLEAN_FUSE: theOperationName = "FUSE"; AddParam( theParams, "Object 1", aCI.GetShape1() ); AddParam( theParams, "Object 2", aCI.GetShape2() ); + AddParam( theParams, "Check self-intersections", isCheckSelfInte ); + AddParam( theParams, "Remove extra edges", aCI.GetRmExtraEdges() ); break; case BOOLEAN_SECTION: theOperationName = "SECTION"; AddParam( theParams, "Object 1", aCI.GetShape1() ); AddParam( theParams, "Object 2", aCI.GetShape2() ); + AddParam( theParams, "Check self-intersections", isCheckSelfInte ); break; case BOOLEAN_COMMON_LIST: theOperationName = "COMMON"; AddParam( theParams, "Selected objects", aCI.GetShapes() ); + AddParam( theParams, "Check self-intersections", isCheckSelfInte ); break; case BOOLEAN_FUSE_LIST: theOperationName = "FUSE"; AddParam( theParams, "Selected objects", aCI.GetShapes() ); + AddParam( theParams, "Check self-intersections", isCheckSelfInte ); + AddParam( theParams, "Remove extra edges", aCI.GetRmExtraEdges() ); break; case BOOLEAN_CUT_LIST: theOperationName = "CUT"; AddParam( theParams, "Main Object", aCI.GetShape1() ); AddParam( theParams, "Tool Objects", aCI.GetShapes() ); + AddParam( theParams, "Check self-intersections", isCheckSelfInte ); break; default: return false; diff --git a/src/GEOMImpl/GEOMImpl_IBoolean.hxx b/src/GEOMImpl/GEOMImpl_IBoolean.hxx index 1985e1afa..7d9460fce 100644 --- a/src/GEOMImpl/GEOMImpl_IBoolean.hxx +++ b/src/GEOMImpl/GEOMImpl_IBoolean.hxx @@ -29,6 +29,7 @@ #define BOOL_ARG_SHAPE2 2 #define BOOL_ARG_SHAPES 3 #define BOOL_ARG_CHECK_SELF_INTERSECTION 4 +#define BOOL_ARG_RM_EXTRA_EDGES 5 class GEOMImpl_IBoolean { @@ -42,6 +43,8 @@ class GEOMImpl_IBoolean { _func->SetReferenceList(BOOL_ARG_SHAPES, theShapes); } void SetCheckSelfIntersection (Standard_Boolean theFlag) { _func->SetInteger(BOOL_ARG_CHECK_SELF_INTERSECTION, theFlag ? 1 : 0); } + void SetRmExtraEdges (Standard_Boolean theFlag) + { _func->SetInteger(BOOL_ARG_RM_EXTRA_EDGES, theFlag ? 1 : 0); } Handle(GEOM_Function) GetShape1() { return _func->GetReference(BOOL_ARG_SHAPE1); } Handle(GEOM_Function) GetShape2() { return _func->GetReference(BOOL_ARG_SHAPE2); } @@ -49,6 +52,8 @@ class GEOMImpl_IBoolean { return _func->GetReferenceList(BOOL_ARG_SHAPES); } Standard_Boolean GetCheckSelfIntersection() { return (_func->GetInteger(BOOL_ARG_CHECK_SELF_INTERSECTION) != 0); } + Standard_Boolean GetRmExtraEdges() + { return (_func->GetInteger(BOOL_ARG_RM_EXTRA_EDGES) != 0); } private: diff --git a/src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx b/src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx index a503e4c09..644422c4c 100644 --- a/src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx @@ -148,6 +148,72 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean return aBool; } +//============================================================================= +/*! + * MakeFuse + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeFuse + (Handle(GEOM_Object) theShape1, + Handle(GEOM_Object) theShape2, + const bool IsCheckSelfInte, + const bool IsRmExtraEdges) +{ + SetErrorCode(KO); + + if (theShape1.IsNull() || theShape2.IsNull()) return NULL; + + //Add a new Boolean object + Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN); + + //Add a new Boolean function + Handle(GEOM_Function) aFunction = + aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE); + + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL; + + GEOMImpl_IBoolean aCI (aFunction); + + Handle(GEOM_Function) aRef1 = theShape1->GetLastFunction(); + Handle(GEOM_Function) aRef2 = theShape2->GetLastFunction(); + + if (aRef1.IsNull() || aRef2.IsNull()) return NULL; + + aCI.SetShape1(aRef1); + aCI.SetShape2(aRef2); + aCI.SetCheckSelfIntersection(IsCheckSelfInte); + aCI.SetRmExtraEdges(IsRmExtraEdges); + + //Compute the Boolean value + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Boolean driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump pd (aFunction); + + pd << aBool << " = geompy.MakeFuse("; + pd << theShape1 << ", " << theShape2 << ", " + << IsCheckSelfInte << ", " << IsRmExtraEdges << ")"; + + SetErrorCode(OK); + return aBool; +} + //============================================================================= /*! * MakeFuseList @@ -155,7 +221,8 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean //============================================================================= Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeFuseList (const Handle(TColStd_HSequenceOfTransient)& theShapes, - const Standard_Boolean IsCheckSelfInte) + const bool IsCheckSelfInte, + const bool IsRmExtraEdges) { SetErrorCode(KO); @@ -183,6 +250,7 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeFuseList aCI.SetShapes(aShapesSeq); aCI.SetCheckSelfIntersection(IsCheckSelfInte); + aCI.SetRmExtraEdges(IsRmExtraEdges); //Compute the Boolean value try { @@ -203,14 +271,8 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeFuseList //Make a Python command GEOM::TPythonDump pd (aFunction); - pd << aBool << - " = geompy.MakeFuseList([" << aDescription.ToCString() << "]"; - - if (IsCheckSelfInte) { - pd << ", True"; - } - - pd << ")"; + pd << aBool << " = geompy.MakeFuseList([" << aDescription.ToCString() << "], " + << IsCheckSelfInte << ", " << IsRmExtraEdges << ")"; SetErrorCode(OK); return aBool; diff --git a/src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx b/src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx index 8db023a01..75c230e2c 100644 --- a/src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx @@ -42,9 +42,16 @@ class GEOMImpl_IBooleanOperations : public GEOM_IOperations { const Standard_Integer theOp, const Standard_Boolean IsCheckSelfInte); + Standard_EXPORT Handle(GEOM_Object) MakeFuse + (Handle(GEOM_Object) theShape1, + Handle(GEOM_Object) theShape2, + const bool IsCheckSelfInte, + const bool IsRmExtraEdges); + Standard_EXPORT Handle(GEOM_Object) MakeFuseList (const Handle(TColStd_HSequenceOfTransient)& theShapes, - const Standard_Boolean IsCheckSelfInte); + const bool IsCheckSelfInte, + const bool IsRmExtraEdges); Standard_EXPORT Handle(GEOM_Object) MakeCommonList (const Handle(TColStd_HSequenceOfTransient)& theShapes, diff --git a/src/GEOM_I/GEOM_IBooleanOperations_i.cc b/src/GEOM_I/GEOM_IBooleanOperations_i.cc index 66dbcd625..2df45a9f2 100644 --- a/src/GEOM_I/GEOM_IBooleanOperations_i.cc +++ b/src/GEOM_I/GEOM_IBooleanOperations_i.cc @@ -87,6 +87,38 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeBoolean return GetObject(anObject); } +//============================================================================= +/*! + * MakeFuse + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeFuse + (GEOM::GEOM_Object_ptr theShape1, + GEOM::GEOM_Object_ptr theShape2, + CORBA::Boolean IsCheckSelfInte, + CORBA::Boolean IsRmExtraEdges) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference shapes + Handle(GEOM_Object) aSh1 = GetObjectImpl(theShape1); + Handle(GEOM_Object) aSh2 = GetObjectImpl(theShape2); + + if (aSh1.IsNull() || aSh2.IsNull()) return aGEOMObject._retn(); + + // Make Boolean + Handle(GEOM_Object) anObject = GetOperations()->MakeFuse + (aSh1, aSh2, IsCheckSelfInte, IsRmExtraEdges); + + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + //============================================================================= /*! * MakeFuseList @@ -94,7 +126,8 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeBoolean //============================================================================= GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeFuseList (const GEOM::ListOfGO& theShapes, - CORBA::Boolean IsCheckSelfInte) + CORBA::Boolean IsCheckSelfInte, + CORBA::Boolean IsRmExtraEdges) { GEOM::GEOM_Object_var aGEOMObject; @@ -110,7 +143,7 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeFuseList // Make fusion Handle(GEOM_Object) anObject = - GetOperations()->MakeFuseList(aShapes, IsCheckSelfInte); + GetOperations()->MakeFuseList(aShapes, IsCheckSelfInte, IsRmExtraEdges); if (!GetOperations()->IsDone() || anObject.IsNull()) return aGEOMObject._retn(); diff --git a/src/GEOM_I/GEOM_IBooleanOperations_i.hh b/src/GEOM_I/GEOM_IBooleanOperations_i.hh index dea57d833..943f6cb9b 100644 --- a/src/GEOM_I/GEOM_IBooleanOperations_i.hh +++ b/src/GEOM_I/GEOM_IBooleanOperations_i.hh @@ -47,8 +47,14 @@ class GEOM_I_EXPORT GEOM_IBooleanOperations_i : CORBA::Long theOp, CORBA::Boolean IsCheckSelfInte); + GEOM::GEOM_Object_ptr MakeFuse (GEOM::GEOM_Object_ptr theShape1, + GEOM::GEOM_Object_ptr theShape2, + CORBA::Boolean IsCheckSelfInte, + CORBA::Boolean IsRmExtraEdges); + GEOM::GEOM_Object_ptr MakeFuseList (const GEOM::ListOfGO& theShapes, - CORBA::Boolean IsCheckSelfInte); + CORBA::Boolean IsCheckSelfInte, + CORBA::Boolean IsRmExtraEdges); GEOM::GEOM_Object_ptr MakeCommonList (const GEOM::ListOfGO& theShapes, CORBA::Boolean IsCheckSelfInte); diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index c269bc765..057e6b064 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -6846,6 +6846,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @param theShape2 Second argument for boolean operation. # @param checkSelfInte The flag that tells if the arguments should # be checked for self-intersection prior to the operation. + # @param rmExtraEdges The flag that tells if Remove Extra Edges + # operation should be performed during the operation. # @param theName Object name; when specified, this parameter is used # for result publication in the study. Otherwise, if automatic # publication is switched on, default value is used for result name. @@ -6862,7 +6864,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # # @ref tui_fuse "Example 1" # \n @ref swig_MakeCommon "Example 2" - def MakeFuse(self, theShape1, theShape2, checkSelfInte=False, theName=None): + def MakeFuse(self, theShape1, theShape2, checkSelfInte=False, + rmExtraEdges=False, theName=None): """ Perform Fuse boolean operation on two given shapes. @@ -6872,6 +6875,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): checkSelfInte The flag that tells if the arguments should be checked for self-intersection prior to the operation. + rmExtraEdges The flag that tells if Remove Extra Edges + operation should be performed during the operation. theName Object name; when specified, this parameter is used for result publication in the study. Otherwise, if automatic publication is switched on, default value is used for result name. @@ -6890,8 +6895,11 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): """ # Example: see GEOM_TestOthers.py - # note: auto-publishing is done in self.MakeBoolean() - return self.MakeBoolean(theShape1, theShape2, 3, checkSelfInte, theName) + anObj = self.BoolOp.MakeFuse(theShape1, theShape2, + checkSelfInte, rmExtraEdges) + RaiseIfFailed("MakeFuse", self.BoolOp) + self._autoPublish(anObj, theName, "fuse") + return anObj ## Perform Section boolean operation on two given shapes. # @param theShape1 First argument for boolean operation. @@ -6949,6 +6957,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # @param theShapesList Shapes to be fused. # @param checkSelfInte The flag that tells if the arguments should # be checked for self-intersection prior to the operation. + # @param rmExtraEdges The flag that tells if Remove Extra Edges + # operation should be performed during the operation. # @param theName Object name; when specified, this parameter is used # for result publication in the study. Otherwise, if automatic # publication is switched on, default value is used for result name. @@ -6965,7 +6975,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # # @ref tui_fuse "Example 1" # \n @ref swig_MakeCommon "Example 2" - def MakeFuseList(self, theShapesList, checkSelfInte=False, theName=None): + def MakeFuseList(self, theShapesList, checkSelfInte=False, + rmExtraEdges=False, theName=None): """ Perform Fuse boolean operation on the list of shapes. @@ -6974,6 +6985,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): checkSelfInte The flag that tells if the arguments should be checked for self-intersection prior to the operation. + rmExtraEdges The flag that tells if Remove Extra Edges + operation should be performed during the operation. theName Object name; when specified, this parameter is used for result publication in the study. Otherwise, if automatic publication is switched on, default value is used for result name. @@ -6992,7 +7005,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): """ # Example: see GEOM_TestOthers.py - anObj = self.BoolOp.MakeFuseList(theShapesList, checkSelfInte) + anObj = self.BoolOp.MakeFuseList(theShapesList, checkSelfInte, + rmExtraEdges) RaiseIfFailed("MakeFuseList", self.BoolOp) self._autoPublish(anObj, theName, "fuse") return anObj @@ -12662,8 +12676,8 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): Returns: New GEOM_Object, containing the created shape. """ - anObj = self.AdvOp.MakeSmoothingSurface - (thelPoints, theNbMax, theDegMax, theDMax) + anObj = self.AdvOp.MakeSmoothingSurface(thelPoints, theNbMax, + theDegMax, theDMax) RaiseIfFailed("MakeSmoothingSurface", self.AdvOp) self._autoPublish(anObj, theName, "smoothing") return anObj -- 2.39.2