diff --git a/doc/salome/examples/topological_geom_objs_ex03.py b/doc/salome/examples/topological_geom_objs_ex03.py index db2f060a9..972d81a6f 100644 --- a/doc/salome/examples/topological_geom_objs_ex03.py +++ b/doc/salome/examples/topological_geom_objs_ex03.py @@ -36,11 +36,13 @@ face1 = geompy.MakeFace(wire, isPlanarFace) # create faces from two wires face2 = geompy.MakeFaceWires([wire, sketcher1],isPlanarFace) face3 = geompy.MakeFaces([sketcher2, sketcher3],isPlanarFace) +face4 = geompy.MakeFaceFromSurface(face1, sketcher1) # add objects in the study id_face1 = geompy.addToStudy(face1,"Face1") id_face2 = geompy.addToStudy(face2,"Face2") id_face3 = geompy.addToStudy(face3,"Face3") +id_face4 = geompy.addToStudy(face4,"Face4") # display the faces gg.createAndDisplayGO(id_face1) @@ -52,3 +54,6 @@ gg.setTransparency(id_face2,0.2) gg.createAndDisplayGO(id_face3) gg.setDisplayMode(id_face3,1) gg.setTransparency(id_face3,0.2) +gg.createAndDisplayGO(id_face4) +gg.setDisplayMode(id_face4,1) +gg.setTransparency(id_face4,0.2) diff --git a/doc/salome/gui/GEOM/images/neo-obj4.png b/doc/salome/gui/GEOM/images/neo-obj4.png index 283601c26..9b0f84c13 100755 Binary files a/doc/salome/gui/GEOM/images/neo-obj4.png and b/doc/salome/gui/GEOM/images/neo-obj4.png differ diff --git a/doc/salome/gui/GEOM/images/neo-obj4_2.png b/doc/salome/gui/GEOM/images/neo-obj4_2.png new file mode 100644 index 000000000..233aa6fb4 Binary files /dev/null and b/doc/salome/gui/GEOM/images/neo-obj4_2.png differ diff --git a/doc/salome/gui/GEOM/input/creating_face.doc b/doc/salome/gui/GEOM/input/creating_face.doc index 1bfd520dd..5c27f5a0f 100644 --- a/doc/salome/gui/GEOM/input/creating_face.doc +++ b/doc/salome/gui/GEOM/input/creating_face.doc @@ -5,10 +5,12 @@ To create a \b Face in the Main Menu select New Entity - > Build - > Face -\n To create a \b Face you need to select input shape(s). The list of -input shapes can include shapes of any type; if the shapes are nor -wires or edges, the algorithm extracts all edges from -the input shapes and works on the obtaineed edges. +\n There are two algorithms to create a \b Face. +\n Each time the \b Result of the operation will be a GEOM_Object +(face). + +\n Firstly, to create a \b Face you need to select input shape(s). The list of +input shapes can include shapes of type \b Edge or \b Wire. \n The edges and wires do not necessarily have to be closed, the algorithm automatically builds a wire of maximum length from all given edges and wires. If it founds multiple closed wires, it can @@ -26,6 +28,15 @@ face or nothing if it is impossible. \image html neo-obj4.png +\n Secondly, it is possible to create a face based on another face's surface and bounded by a wire. + +\n The \b Result will be a \b GEOM_Object (FACE). + +\n TUI Command: geompy.MakeFaceFromSurface(theFace, theWire) +\n Arguments: Name + 1 face + 1 wire. + +\image html neo-obj4_2.png + \n Example: \image html facesn1.png diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 4de99775d..84d441015 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -1924,6 +1924,15 @@ module GEOM */ GEOM_Object MakeFaceWires (in ListOfGO theWires, in boolean isPlanarWanted); + /** + * \brief Create a face based on surface of theFace limited by theWire. + * \param theFace the face whose surface is used to create a new face. + * \param theWire closed Wire build the face. + * \return New GEOM_Object, containing the created face. + */ + GEOM_Object MakeFaceFromSurface(in GEOM_Object theFace, + in GEOM_Object theWire); + /*! * \brief Create a shell from the set of faces and shells. * \param theFacesAndShells List of faces and/or shells. diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 1fa4e9d9d..e3afdf6cb 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -54,6 +54,7 @@ SET( _res_files build_edge_wire.png build_edge_curve.png build_face.png + build_face_surface.png build_shell.png build_solid.png build_wire.png diff --git a/resources/build_face_surface.png b/resources/build_face_surface.png new file mode 100644 index 000000000..f77b0f5a8 Binary files /dev/null and b/resources/build_face_surface.png differ diff --git a/src/BuildGUI/BuildGUI_FaceDlg.cxx b/src/BuildGUI/BuildGUI_FaceDlg.cxx index bdd72265b..3420aa2af 100644 --- a/src/BuildGUI/BuildGUI_FaceDlg.cxx +++ b/src/BuildGUI/BuildGUI_FaceDlg.cxx @@ -49,18 +49,20 @@ // TRUE to construct a modal dialog. //================================================================================= BuildGUI_FaceDlg::BuildGUI_FaceDlg( GeometryGUI* theGeometryGUI, QWidget* parent ) - : GEOMBase_Skeleton( theGeometryGUI, parent ) + : GEOMBase_Skeleton( theGeometryGUI, parent ), + GroupWire (0), + myGroupSurf (0) { - QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BUILD_FACE" ) ) ); - QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); + QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); + QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BUILD_FACE" ) ) ); + QPixmap image2( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BUILD_FACE_SURFACE" ) ) ); setWindowTitle( tr( "GEOM_FACE_TITLE" ) ); /***************************************************************/ mainFrame()->GroupConstructors->setTitle( tr( "GEOM_FACE" ) ); - mainFrame()->RadioButton1->setIcon( image0 ); - mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose ); - mainFrame()->RadioButton2->close(); + mainFrame()->RadioButton1->setIcon( image1 ); + mainFrame()->RadioButton2->setIcon( image2 ); mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose ); mainFrame()->RadioButton3->close(); @@ -69,11 +71,20 @@ BuildGUI_FaceDlg::BuildGUI_FaceDlg( GeometryGUI* theGeometryGUI, QWidget* parent GroupWire->GroupBox1->setTitle( tr( "GEOM_FACE_FFW" ) ); GroupWire->TextLabel1->setText( tr( "GEOM_OBJECTS" ) ); GroupWire->CheckButton1->setText( tr( "GEOM_FACE_OPT" ) ); - GroupWire->PushButton1->setIcon( image1 ); + GroupWire->PushButton1->setIcon( image0 ); + + myGroupSurf = new DlgRef_2Sel(centralWidget()); + + myGroupSurf->GroupBox1->setTitle(tr("GEOM_FACE_FROM_SURFACE" ) ); + myGroupSurf->TextLabel1->setText(tr("GEOM_FACE")); + myGroupSurf->TextLabel2->setText(tr("GEOM_WIRE")); + myGroupSurf->PushButton1->setIcon(image0); + myGroupSurf->PushButton2->setIcon(image0); QVBoxLayout* layout = new QVBoxLayout( centralWidget() ); layout->setMargin( 0 ); layout->setSpacing( 6 ); layout->addWidget( GroupWire ); + layout->addWidget(myGroupSurf); /***************************************************************/ setHelpFileName("create_face_page.html"); @@ -102,27 +113,79 @@ void BuildGUI_FaceDlg::Init() /* init variables */ myEditCurrentArgument = GroupWire->LineEdit1; GroupWire->LineEdit1->setReadOnly( true ); + myGroupSurf->LineEdit1->setReadOnly( true ); + myGroupSurf->LineEdit2->setReadOnly( true ); GroupWire->CheckButton1->setChecked( true ); myWires.clear(); - - TColStd_MapOfInteger aMap; - aMap.Add( GEOM_EDGE ); - aMap.Add( GEOM_WIRE ); - globalSelection( aMap ); + myFace.nullify(); + myWire.nullify(); /* signals and slots connections */ + connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); + + connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int))); + connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); connect( GroupWire->LineEdit1, SIGNAL( returnPressed()), this, SLOT( LineEditReturnPressed() ) ); connect( GroupWire->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) ); + connect( myGroupSurf->LineEdit1, SIGNAL( returnPressed()), this, SLOT( LineEditReturnPressed() ) ); + connect( myGroupSurf->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) ); + connect( myGroupSurf->LineEdit2, SIGNAL( returnPressed()), this, SLOT( LineEditReturnPressed() ) ); + connect( myGroupSurf->PushButton2, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) ); connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); initName( tr( "GEOM_FACE" ) ); - SelectionIntoArgument(); + + ConstructorsClicked(0); } +//================================================================================= +// function : ConstructorsClicked() +// purpose : Radio button management +//================================================================================= +void BuildGUI_FaceDlg::ConstructorsClicked(int constructorId) +{ + switch (constructorId) { + case 0: + { + TColStd_MapOfInteger aMap; + + aMap.Add(GEOM_EDGE); + aMap.Add(GEOM_WIRE); + globalSelection(aMap); + + myEditCurrentArgument = GroupWire->LineEdit1; + GroupWire->LineEdit1->setText(""); + GroupWire->show(); + myGroupSurf->hide(); + break; + } + case 1: + { + globalSelection(GEOM_FACE); // For the first element. + + myEditCurrentArgument = myGroupSurf->LineEdit1; + myGroupSurf->LineEdit1->setText(""); + myGroupSurf->PushButton1->setDown(true); + myGroupSurf->PushButton2->setDown(false); + GroupWire->hide(); + myGroupSurf->show(); + break; + } + } + + myWires.clear(); + myFace.nullify(); + myWire.nullify(); + qApp->processEvents(); + updateGeometry(); + resize(minimumSizeHint()); + SelectionIntoArgument(); +} //================================================================================= // function : ClickOnOk() @@ -156,16 +219,44 @@ bool BuildGUI_FaceDlg::ClickOnApply() //================================================================================= void BuildGUI_FaceDlg::SelectionIntoArgument() { - myEditCurrentArgument->setText( "" ); + if (myEditCurrentArgument == GroupWire->LineEdit1) { + myEditCurrentArgument->setText( "" ); - QList types; - types << TopAbs_EDGE << TopAbs_WIRE; - myWires = getSelected( types, -1 ); + QList types; + types << TopAbs_EDGE << TopAbs_WIRE; + myWires = getSelected( types, -1 ); - if ( !myWires.isEmpty() ) { - QString aName = myWires.count() > 1 ? QString( "%1_objects").arg( myWires.count() ) : GEOMBase::GetName( myWires[0].get() ); - myEditCurrentArgument->setText( aName ); + if ( !myWires.isEmpty() ) { + QString aName = myWires.count() > 1 ? QString( "%1_objects").arg( myWires.count() ) : GEOMBase::GetName( myWires[0].get() ); + myEditCurrentArgument->setText( aName ); + } + } else if (myEditCurrentArgument == myGroupSurf->LineEdit1 || + myEditCurrentArgument == myGroupSurf->LineEdit2) { + const bool isEditFace = myEditCurrentArgument == myGroupSurf->LineEdit1; + const TopAbs_ShapeEnum aType = isEditFace ? TopAbs_FACE : TopAbs_WIRE; + GEOM::GeomObjPtr aSelectedObject = getSelected(aType); + GEOM::GeomObjPtr &anObj = isEditFace ? myFace : myWire; + + if (aSelectedObject) { + myEditCurrentArgument->setText(GEOMBase::GetName(aSelectedObject.get())); + anObj = aSelectedObject; + } else { + myEditCurrentArgument->setText(""); + anObj.nullify(); + } + + if (isEditFace) { + if (myFace && !myWire) { + myGroupSurf->PushButton2->click(); + } + } else { + if (!myFace && myWire) { + myGroupSurf->PushButton1->click(); + } + } } + + displayPreview(true); } @@ -176,18 +267,33 @@ void BuildGUI_FaceDlg::SelectionIntoArgument() void BuildGUI_FaceDlg::SetEditCurrentArgument() { QPushButton* send = (QPushButton*)sender(); - if ( send != GroupWire->PushButton1 ) - return; + + if (send == GroupWire->PushButton1) { + TColStd_MapOfInteger aMap; - TColStd_MapOfInteger aMap; - aMap.Add( GEOM_EDGE ); - aMap.Add( GEOM_WIRE ); - globalSelection( aMap ); - - myEditCurrentArgument = GroupWire->LineEdit1; + aMap.Add(GEOM_EDGE); + aMap.Add(GEOM_WIRE); + globalSelection(aMap); + myEditCurrentArgument = GroupWire->LineEdit1; + } + else if (send == myGroupSurf->PushButton1) { + globalSelection(GEOM_FACE); + myEditCurrentArgument = myGroupSurf->LineEdit1; + myGroupSurf->PushButton2->setDown(false); + myGroupSurf->LineEdit2->setEnabled(false); + } + else if (send == myGroupSurf->PushButton2) { + globalSelection(GEOM_WIRE); + myEditCurrentArgument = myGroupSurf->LineEdit2; + myGroupSurf->PushButton1->setDown(false); + myGroupSurf->LineEdit1->setEnabled(false); + } + // enable line edit + myEditCurrentArgument->setEnabled(true); myEditCurrentArgument->setFocus(); - SelectionIntoArgument(); + send->setDown(true); + displayPreview(true); } @@ -198,12 +304,11 @@ void BuildGUI_FaceDlg::SetEditCurrentArgument() void BuildGUI_FaceDlg::ActivateThisDialog() { GEOMBase_Skeleton::ActivateThisDialog(); - connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(), - SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); - TColStd_MapOfInteger aMap; - aMap.Add( GEOM_EDGE ); - aMap.Add( GEOM_WIRE ); - globalSelection( aMap ); + + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); + + ConstructorsClicked(getConstructorId()); } @@ -232,7 +337,20 @@ GEOM::GEOM_IOperations_ptr BuildGUI_FaceDlg::createOperation() //================================================================================= bool BuildGUI_FaceDlg::isValid( QString& ) { - return !myWires.isEmpty(); + bool ok = false; + + switch (getConstructorId()) { + case 0: + ok = !myWires.isEmpty(); + break; + case 1: + ok = myFace && myWire; + break; + default: + break; + } + + return ok; } //================================================================================= @@ -241,14 +359,32 @@ bool BuildGUI_FaceDlg::isValid( QString& ) //================================================================================= bool BuildGUI_FaceDlg::execute( ObjectList& objects ) { + bool res = false; GEOM::GEOM_IShapesOperations_var anOper = GEOM::GEOM_IShapesOperations::_narrow( getOperation() ); + GEOM::GEOM_Object_var anObj; - GEOM::ListOfGO_var objlist = new GEOM::ListOfGO(); - objlist->length( myWires.count() ); - for ( int i = 0; i < myWires.count(); i++ ) - objlist[i] = myWires[i].copy(); + switch (getConstructorId()) { + case 0: + { + GEOM::ListOfGO_var objlist = new GEOM::ListOfGO(); + + objlist->length( myWires.count() ); - GEOM::GEOM_Object_var anObj = anOper->MakeFaceWires( objlist.in(), GroupWire->CheckButton1->isChecked() ); + for ( int i = 0; i < myWires.count(); i++ ) { + objlist[i] = myWires[i].copy(); + } + + anObj = anOper->MakeFaceWires( objlist.in(), GroupWire->CheckButton1->isChecked() ); + res = true; + } + break; + case 1: + anObj = anOper->MakeFaceFromSurface(myFace.get(), myWire.get()); + res = true; + break; + default: + break; + } if (!anObj->_is_nil()) { objects.push_back(anObj._retn()); @@ -262,5 +398,5 @@ bool BuildGUI_FaceDlg::execute( ObjectList& objects ) } } - return true; + return res; } diff --git a/src/BuildGUI/BuildGUI_FaceDlg.h b/src/BuildGUI/BuildGUI_FaceDlg.h index d0e667072..570961c4c 100644 --- a/src/BuildGUI/BuildGUI_FaceDlg.h +++ b/src/BuildGUI/BuildGUI_FaceDlg.h @@ -31,6 +31,7 @@ #include "GEOM_GenericObjPtr.h" class DlgRef_1Sel1Check; +class DlgRef_2Sel; //================================================================================= // class : BuildGUI_FaceDlg @@ -56,10 +57,14 @@ private: private: QList myWires; + GEOM::GeomObjPtr myFace; + GEOM::GeomObjPtr myWire; DlgRef_1Sel1Check* GroupWire; + DlgRef_2Sel *myGroupSurf; private slots: + void ConstructorsClicked (int); void ClickOnOk(); bool ClickOnApply(); void ActivateThisDialog(); diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 115e51e67..900d965ad 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -159,6 +159,10 @@ ICON_DLG_BUILD_FACE build_face.png + + ICON_DLG_BUILD_FACE_SURFACE + build_face_surface.png + ICON_DLG_FACE_HW face_hw.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index 6fb476507..3a1336069 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -691,6 +691,10 @@ Please, select face, shell or solid and try again GEOM_FACE_FFW Face creation from wires and/or edges + + GEOM_FACE_FROM_SURFACE + Face creation from surface bounded by wire + GEOM_FACE_OPT Try to create a planar face diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index c0613097d..cf840bc75 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -548,6 +548,77 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires return aShape; } +//============================================================================= +/*! + * MakeFaceFromSurface + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface + (Handle(GEOM_Object) theFace, + Handle(GEOM_Object) theWire) +{ + SetErrorCode(KO); + + //Add a new object + Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE); + + //Add a new function + Handle(GEOM_Function) aFunction = + aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE); + + if (aFunction.IsNull()) { + return NULL; + } + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) { + return NULL; + } + + GEOMImpl_IShapes aCI (aFunction); + Handle(TColStd_HSequenceOfTransient) aShapesSeq = + new TColStd_HSequenceOfTransient; + Handle(GEOM_Function) aRefFace = theFace->GetLastFunction(); + Handle(GEOM_Function) aRefWire = theWire->GetLastFunction(); + + if (aRefFace.IsNull()) { + SetErrorCode("NULL argument face for the face construction"); + return NULL; + } + + if (aRefWire.IsNull()) { + SetErrorCode("NULL argument wire for the face construction"); + return NULL; + } + + aShapesSeq->Append(aRefFace); + aShapesSeq->Append(aRefWire); + + aCI.SetShapes(aShapesSeq); + + //Compute the face + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape 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 (aFunction) << aShape + << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")"; + + SetErrorCode(OK); + + return aShape; +} + //============================================================================= /*! * MakeShell diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index a5b6bc396..8c15f7190 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -85,6 +85,10 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations Standard_EXPORT Handle(GEOM_Object) MakeFaceWires (std::list theWires, const bool isPlanarWanted); + Standard_EXPORT Handle(GEOM_Object) MakeFaceFromSurface + (Handle(GEOM_Object) theFace, + Handle(GEOM_Object) theWire); + Standard_EXPORT Handle(GEOM_Object) MakeShell (std::list theShapes); Standard_EXPORT Handle(GEOM_Object) MakeSolidShells (std::list theShells); diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 037e62900..d09b3a329 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -315,6 +316,44 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = C; } } + else if (aType == FACE_FROM_SURFACE) { +#ifdef RESULT_TYPE_CHECK + anExpectedType = TopAbs_FACE; +#endif + + Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); + + if (aShapes.IsNull() == Standard_False) { + Standard_Integer aNbShapes = aShapes->Length(); + + if (aNbShapes == 2) { + Handle(GEOM_Function) aRefFace = + Handle(GEOM_Function)::DownCast(aShapes->Value(1)); + Handle(GEOM_Function) aRefWire = + Handle(GEOM_Function)::DownCast(aShapes->Value(2)); + + if (aRefFace.IsNull() == Standard_False && + aRefWire.IsNull() == Standard_False) { + TopoDS_Shape aShFace = aRefFace->GetValue(); + TopoDS_Shape aShWire = aRefWire->GetValue(); + + if (aShFace.IsNull() == Standard_False && + aShFace.ShapeType() == TopAbs_FACE && + aShWire.IsNull() == Standard_False && + aShWire.ShapeType() == TopAbs_WIRE) { + TopoDS_Face aFace = TopoDS::Face(aShFace); + TopoDS_Wire aWire = TopoDS::Wire(aShWire); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + BRepBuilderAPI_MakeFace aMkFace(aSurf, aWire); + + if (aMkFace.IsDone()) { + aShape = aMkFace.Shape(); + } + } + } + } + } + } else if (aType == SHELL_FACES) { #ifdef RESULT_TYPE_CHECK anExpectedType = TopAbs_SHELL; @@ -1268,6 +1307,25 @@ GetCreationInformation(std::string& theOperationName, AddParam( theParams, "Wires/edges", aCI.GetShapes() ); AddParam( theParams, "Is planar wanted", aCI.GetIsPlanar() ); break; + case FACE_FROM_SURFACE: + { + theOperationName = "FACE"; + + Handle(TColStd_HSequenceOfTransient) shapes = aCI.GetShapes(); + + if (shapes.IsNull() == Standard_False) { + Standard_Integer aNbShapes = shapes->Length(); + + if (aNbShapes > 0) { + AddParam(theParams, "Face", shapes->Value(1)); + + if (aNbShapes > 1) { + AddParam(theParams, "Wire", shapes->Value(2)); + } + } + } + break; + } case SHELL_FACES: theOperationName = "SHELL"; AddParam( theParams, "Objects", aCI.GetShapes() ); diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx old mode 100755 new mode 100644 index 0bc7505c1..419e10160 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -299,6 +299,7 @@ #define EDGE_CURVE_LENGTH 12 #define SHAPES_ON_SHAPE 13 #define SHAPE_ISOLINE 14 +#define FACE_FROM_SURFACE 15 #define ARCHIMEDE_TYPE 1 diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index 1e965a798..a03d84e47 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -246,6 +246,39 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFaceWires return GetObject(anObject); } +//============================================================================= +/*! + * MakeFaceFromSurface + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFaceFromSurface + (GEOM::GEOM_Object_ptr theFace, + GEOM::GEOM_Object_ptr theWire) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + //Get the reference face and wire + Handle(GEOM_Object) aFace = GetObjectImpl(theFace); + Handle(GEOM_Object) aWire = GetObjectImpl(theWire); + + if (aFace.IsNull() || aWire.IsNull()) { + return aGEOMObject._retn(); + } + + //Create the Face + Handle(GEOM_Object) anObject = + GetOperations()->MakeFaceFromSurface(aFace, aWire); + + if (anObject.IsNull()) { + return aGEOMObject._retn(); + } + + return GetObject(anObject); +} + //============================================================================= /*! * MakeShell diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index 8b18fe9f2..be9d5584c 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -64,6 +64,9 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : GEOM::GEOM_Object_ptr MakeFaceWires (const GEOM::ListOfGO& theWires, CORBA::Boolean isPlanarWanted); + GEOM::GEOM_Object_ptr MakeFaceFromSurface(GEOM::GEOM_Object_ptr theFace, + GEOM::GEOM_Object_ptr theWire); + GEOM::GEOM_Object_ptr MakeShell (const GEOM::ListOfGO& theFacesAndShells); GEOM::GEOM_Object_ptr MakeSolidShell (GEOM::GEOM_Object_ptr theShell); diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index b644c196b..a63590d52 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -178,6 +178,7 @@ def TestAll (geompy, math): Face2 = geompy.MakeFace(Sketcher, WantPlanarFace) Face3 = geompy.MakeFaceHW (100., 200., 1) #(2 Doubles, 1 Int)->GEOM_Object Face4 = geompy.MakeFaceObjHW (vz, 200., 100.) #(1 GEOM_Object, 2 Doubles)->GEOM_Object + Face5 = geompy.MakeFaceFromSurface(Face, Sketcher) #(2 GEOM_Objects)->GEOM_Object Disk = geompy.MakeDiskPntVecR (p0, vz, radius) #(2 GEOM_Object, 1 Double)->GEOM_Object Disk2 = geompy.MakeDiskThreePnt(p0, p200, pz) #(3 GEOM_Object)->GEOM_Object Disk3 = geompy.MakeDiskR(100., 1) #(1 Doubles, 1 Int)->GEOM_Object @@ -397,6 +398,7 @@ def TestAll (geompy, math): id_Face2 = geompy.addToStudy(Face2, "Face from Sketcher") id_Face3 = geompy.addToStudy(Face3, "Face Height Width") id_Face4 = geompy.addToStudy(Face4, "Face Plane_HW") + id_Face5 = geompy.addToStudy(Face5, "Face from surface and wire") id_Disk = geompy.addToStudy(Disk, "Disk PntVecR") id_Disk2 = geompy.addToStudy(Disk2, "Disk Three Points") id_Disk3 = geompy.addToStudy(Disk3, "Disk OXY Radius") diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index bd6a68a24..a0926791c 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -4504,6 +4504,39 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): anObj = self.MakeFaceWires(theWires, isPlanarWanted, theName) return anObj + ## Create a face based on a surface from given face bounded + # by given wire. + # @param theFace the face whose surface is used to create a new face. + # @param theWire the wire that will bound a new face. + # @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. + # + # @return New GEOM.GEOM_Object, containing the created face. + # + # @ref tui_creation_face "Example" + @ManageTransactions("ShapesOp") + def MakeFaceFromSurface(self, theFace, theWire, theName=None): + """ + Create a face based on a surface from given face bounded + by given wire. + + Parameters: + theFace the face whose surface is used to create a new face. + theWire the wire that will bound a new face. + 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. + + Returns: + New GEOM.GEOM_Object, containing the created face. + """ + # Example: see GEOM_TestAll.py + anObj = self.ShapesOp.MakeFaceFromSurface(theFace, theWire) + RaiseIfFailed("MakeFaceFromSurface", self.ShapesOp) + self._autoPublish(anObj, theName, "face") + return anObj + ## Create a shell from the set of faces and shells. # @param theFacesAndShells List of faces and/or shells. # @param theName Object name; when specified, this parameter is used