diff --git a/doc/salome/examples/topological_geom_objs_ex07.py b/doc/salome/examples/topological_geom_objs_ex07.py new file mode 100644 index 000000000..f1e646a74 --- /dev/null +++ b/doc/salome/examples/topological_geom_objs_ex07.py @@ -0,0 +1,46 @@ +# Creation of a Solid(s) from connected faces + +import salome +salome.salome_init() +import GEOM +from salome.geom import geomBuilder +geompy = geomBuilder.New(salome.myStudy) +gg = salome.ImportComponentGUI("GEOM") + +# create a box +box = geompy.MakeBoxDXDYDZ(200, 200, 200) + +# make a copy of a box translated by X coordinate +box_translation = geompy.MakeTranslation(box, 200, 0, 0) + +# extract shells from boxes +box_shell = geompy.SubShapeAllSorted(box, geompy.ShapeType["SHELL"])[0] +box_translation_shell = geompy.SubShapeAllSorted(box_translation, geompy.ShapeType["SHELL"])[0] + +# extract faces from boxes +box_faces = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"]) +box_translation_faces = geompy.SubShapeAllSorted(box_translation, geompy.ShapeType["FACE"]) + +# create solids from shells +msf_shells_noint = geompy.MakeSolidFromConnectedFaces([box_shell, box_translation_shell],0) +msf_shells_int = geompy.MakeSolidFromConnectedFaces([box_shell, box_translation_shell], 1) + +# create solids from faces +msf_faces_noint = geompy.MakeSolidFromConnectedFaces(box_faces+box_translation_faces, 0) +msf_faces_int = geompy.MakeSolidFromConnectedFaces(box_faces+box_translation_faces, 1) + +# add objects in the study +id_solid_shells_noint = geompy.addToStudy(msf_shells_noint,"Solid_from_shells_no_intersect") +id_solid_shells_int = geompy.addToStudy(msf_shells_int,"Solid_from_shells_intersect") +id_solid_faces_noint = geompy.addToStudy(msf_faces_noint,"Solid_from_faces_no_intersect") +id_solid_faces_int = geompy.addToStudy(msf_faces_int,"Solid_from_faces_intersect") + +# display the results +gg.createAndDisplayGO(id_solid_shells_noint) +gg.setDisplayMode(id_solid_shells_noint,1) +gg.createAndDisplayGO(id_solid_shells_int) +gg.setDisplayMode(id_solid_shells_int,1) +gg.createAndDisplayGO(id_solid_faces_noint) +gg.setDisplayMode(id_solid_faces_noint,1) +gg.createAndDisplayGO(id_solid_faces_int) +gg.setDisplayMode(id_solid_faces_int,1) diff --git a/doc/salome/gui/GEOM/images/neo-obj6.png b/doc/salome/gui/GEOM/images/neo-obj6.png old mode 100755 new mode 100644 index fd8af0811..9a38edaa1 Binary files a/doc/salome/gui/GEOM/images/neo-obj6.png and b/doc/salome/gui/GEOM/images/neo-obj6.png differ diff --git a/doc/salome/gui/GEOM/images/neo-obj6_2.png b/doc/salome/gui/GEOM/images/neo-obj6_2.png new file mode 100644 index 000000000..8fac38f4e Binary files /dev/null and b/doc/salome/gui/GEOM/images/neo-obj6_2.png differ diff --git a/doc/salome/gui/GEOM/input/creating_solid.doc b/doc/salome/gui/GEOM/input/creating_solid.doc index 48a05750e..3108535e8 100644 --- a/doc/salome/gui/GEOM/input/creating_solid.doc +++ b/doc/salome/gui/GEOM/input/creating_solid.doc @@ -2,24 +2,40 @@ \page create_solid_page Solid -\n To create a \b Solid in the Main Menu select New Entity - > Build - > +To create a \b Solid in the Main Menu select New Entity - > Build - > Solid. -You can create a \b Solid from a list of shells. +Firstly, you can create a \b Solid from a list of shells. The \b Result will be a \b GEOM_Object (SOLID). -\n TUI Command: geompy.MakeSolid(ListOfShape), where -ListOfShape is a list of shells from which the solid is constructed. -\n Arguments: Name + A closed shell or a list of closed shells. +TUI Command: geompy.MakeSolid(ListOfShape), where +\c ListOfShape is a list of shells from which the solid is constructed. + +Arguments: Name + A closed shell or a list of closed shells. \image html neo-obj6.png -\n Example: +Example: \image html solidsn.png "Solid" +Secondly, it is possible to create a \b Solid (or a compound of solids) from a list of +connected faces or shells. + +The \b Result will be a \b GEOM_Object (SOLID or COMPOUND). + +TUI Command: geompy.MakeSolidFromConnectedFaces(ListOfShape, isIntersect), where +\c ListOfShape is a list of faces and/or shells from which the solid is constructed and +\c isIntersect is a boolean flag which, when set to \c True, forces performing intersection +between arguments + +Arguments: Name + A set of connected faces and/or shells + Boolean flag. + +\image html neo-obj6_2.png + Our TUI Scripts provide you with useful examples of creation of -\ref tui_creation_solid "Advanced Geometric Objects". +\ref tui_creation_solid "Solid from shell" and +\ref tui_creation_solid_from_faces "Solid from connected faces". */ diff --git a/doc/salome/gui/GEOM/input/tui_topological_geom_objs.doc b/doc/salome/gui/GEOM/input/tui_topological_geom_objs.doc index 9576e47a8..b643ac9a6 100644 --- a/doc/salome/gui/GEOM/input/tui_topological_geom_objs.doc +++ b/doc/salome/gui/GEOM/input/tui_topological_geom_objs.doc @@ -22,6 +22,10 @@

Creation of a Solid

\tui_script{topological_geom_objs_ex05.py} +\anchor tui_creation_solid_from_faces +

Creation of a Solid from the set of connected faces

+\tui_script{topological_geom_objs_ex07.py} + \anchor tui_creation_compound

Creation of a Compound

\tui_script{topological_geom_objs_ex06.py} diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index abf0b7347..0b24f8c7d 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -1966,6 +1966,15 @@ module GEOM */ GEOM_Object MakeCompound (in ListOfGO theShapes); + /*! + * \brief Make a solid (or solids) from connected set of faces and/or shells. + * \param theFacesOrShells List of faces and/or shells. + * \param isIntersect If TRUE, forces performing intersections between arguments. + * + * \return New GEOM_Object, containing the created solid (or compound of solids). + */ + GEOM_Object MakeSolidFromConnectedFaces (in ListOfGO theFacesOrShells, in boolean isIntersect); + /*! * \brief Replace coincident faces in \a theShapes by one face. * \param theShapes Initial shapes. diff --git a/idl/GEOM_Superv.idl b/idl/GEOM_Superv.idl index 3bf0fea3f..4843422c5 100644 --- a/idl/GEOM_Superv.idl +++ b/idl/GEOM_Superv.idl @@ -395,6 +395,8 @@ module GEOM GEOM_Object MakeSolidShell (in GEOM_Object theShell) ; GEOM_Object MakeSolidShells (in GEOM_List theShells) ; GEOM_Object MakeCompound (in GEOM_List theShapes) ; + GEOM_Object MakeSolidFromConnectedFaces (in GEOM_List theFacesOrShells, + in boolean isIntersect); GEOM_Object MakeGlueFaces (in GEOM_Object theShape, in double theTolerance, in boolean doKeepNonSolids); diff --git a/resources/CMakeLists.txt b/resources/CMakeLists.txt index 7a6644562..d841d3612 100755 --- a/resources/CMakeLists.txt +++ b/resources/CMakeLists.txt @@ -169,6 +169,7 @@ SET( _res_files shapesonshape.png shared_shapes.png sketch.png + solid_from_faces.png sphere.png spheredxyz.png spherepoint.png diff --git a/resources/GEOMCatalog.xml.in b/resources/GEOMCatalog.xml.in index bb07e4de7..eeed1d6b1 100644 --- a/resources/GEOMCatalog.xml.in +++ b/resources/GEOMCatalog.xml.in @@ -4327,6 +4327,33 @@ + + MakeSolidFromConnectedFaces + SALOME team + @SALOMEGEOM_VERSION@ + unknown + 0 + + + theFacesOrShells + GEOM/GEOM_List + unknown + + + isIntersect + boolean + unknown + + + + + return + GEOM/GEOM_Object + unknown + + + + MakeCompound SALOME team diff --git a/resources/solid_from_faces.png b/resources/solid_from_faces.png new file mode 100644 index 000000000..f3ce5329e Binary files /dev/null and b/resources/solid_from_faces.png differ diff --git a/src/BuildGUI/BuildGUI_SolidDlg.cxx b/src/BuildGUI/BuildGUI_SolidDlg.cxx index 75eedd5f9..6d0b3fb42 100644 --- a/src/BuildGUI/BuildGUI_SolidDlg.cxx +++ b/src/BuildGUI/BuildGUI_SolidDlg.cxx @@ -50,30 +50,37 @@ BuildGUI_SolidDlg::BuildGUI_SolidDlg( GeometryGUI* theGeometryGUI, QWidget* parent ) : GEOMBase_Skeleton( theGeometryGUI, parent ) { - QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BUILD_SOLID" ) ) ); - 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_SOLID" ) ) ); + QPixmap image2( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_SOLID_FROM_FACES" ) ) ); setWindowTitle( tr( "GEOM_SOLID_TITLE" ) ); /***************************************************************/ mainFrame()->GroupConstructors->setTitle( tr( "GEOM_SOLID" ) ); - 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(); GroupSolid = new DlgRef_1Sel1Check( centralWidget() ); - - GroupSolid->GroupBox1->setTitle( tr( "GEOM_ARGUMENTS" ) ); + GroupSolid->GroupBox1->setTitle( tr( "GEOM_SOLID_SHELLS" ) ); GroupSolid->TextLabel1->setText( tr( "GEOM_OBJECTS" ) ); GroupSolid->CheckButton1->setText( tr( "GEOM_CREATE_SINGLE_SOLID" ) ); - GroupSolid->PushButton1->setIcon( image1 ); + GroupSolid->PushButton1->setIcon( image0 ); GroupSolid->LineEdit1->setReadOnly( true ); + GroupFaces = new DlgRef_1Sel1Check( centralWidget() ); + GroupFaces->GroupBox1->setTitle( tr( "GEOM_SOLID_FACES" ) ); + GroupFaces->TextLabel1->setText( tr( "GEOM_OBJECTS" ) ); + GroupFaces->CheckButton1->setText( tr( "GEOM_SOLID_FROM_FACE_OPT" ) ); + GroupFaces->PushButton1->setIcon( image0 ); + GroupFaces->LineEdit1->setReadOnly( true ); + QVBoxLayout* layout = new QVBoxLayout( centralWidget() ); layout->setMargin( 0 ); layout->setSpacing( 6 ); layout->addWidget( GroupSolid ); + layout->addWidget( GroupFaces ); /***************************************************************/ setHelpFileName("create_solid_page.html"); @@ -118,7 +125,10 @@ void BuildGUI_SolidDlg::Init() connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) ); connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) ); + connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int))); + connect( GroupSolid->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) ); + connect( GroupFaces->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) ); connect( GroupSolid->CheckButton1, SIGNAL( toggled( bool ) ), this, SLOT( EnableNameField( bool ) ) ); connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(), @@ -126,6 +136,8 @@ void BuildGUI_SolidDlg::Init() initName( tr( "GEOM_SOLID" ) ); SelectionIntoArgument(); + + ConstructorsClicked(0); } @@ -150,9 +162,45 @@ bool BuildGUI_SolidDlg::ClickOnApply() return false; initName(); + + myEditCurrentArgument->setText(""); + ConstructorsClicked(getConstructorId()); + return true; } +//================================================================================= +// function : ConstructorsClicked() +// purpose : Radio button management +//================================================================================= +void BuildGUI_SolidDlg::ConstructorsClicked(int constructorId) +{ + switch (constructorId) { + case 0: + { + globalSelection(); + GroupFaces->hide(); + GroupSolid->show(); + myEditCurrentArgument = GroupSolid->LineEdit1; + GroupSolid->LineEdit1->setText(""); + break; + } + case 1: + { + globalSelection(); + GroupSolid->hide(); + GroupFaces->show(); + myEditCurrentArgument = GroupFaces->LineEdit1; + GroupFaces->LineEdit1->setText(""); + break; + } + } + + qApp->processEvents(); + updateGeometry(); + resize(minimumSizeHint()); + SelectionIntoArgument(); +} //================================================================================= // function : SelectionIntoArgument() @@ -164,7 +212,10 @@ void BuildGUI_SolidDlg::SelectionIntoArgument() //myShells = getSelected( TopAbs_SHELL, -1 ); QList types; + if (myEditCurrentArgument == GroupSolid->LineEdit1) types << TopAbs_SHELL << TopAbs_COMPOUND; + else if (myEditCurrentArgument == GroupFaces->LineEdit1) + types << TopAbs_FACE << TopAbs_SHELL << TopAbs_COMPOUND; myShells = getSelected( types, -1 ); if ( !myShells.isEmpty() ) { @@ -180,18 +231,25 @@ void BuildGUI_SolidDlg::SelectionIntoArgument() void BuildGUI_SolidDlg::SetEditCurrentArgument() { QPushButton* send = (QPushButton*)sender(); - if ( send != GroupSolid->PushButton1 ) - return; - //globalSelection( GEOM_SHELL ); TColStd_MapOfInteger aMap; - aMap.Add( GEOM_SHELL ); - aMap.Add( GEOM_COMPOUNDFILTER ); QList aSubShapes; - aSubShapes.append( GEOM_SHELL ); - globalSelection( aMap, aSubShapes ); + aMap.Add( GEOM_COMPOUNDFILTER ); - myEditCurrentArgument = GroupSolid->LineEdit1; + if (send == GroupSolid->PushButton1) { + aMap.Add( GEOM_SHELL ); + aSubShapes.append( GEOM_SHELL ); + globalSelection( aMap, aSubShapes ); + myEditCurrentArgument = GroupSolid->LineEdit1; + } + else if (send == GroupFaces->PushButton1) { + aMap.Add( GEOM_SHELL ); + aMap.Add( GEOM_FACE ); + aSubShapes.append( GEOM_SHELL ); + aSubShapes.append( GEOM_FACE ); + globalSelection( aMap, aSubShapes ); + myEditCurrentArgument = GroupFaces->LineEdit1; + } myEditCurrentArgument->setFocus(); SelectionIntoArgument(); @@ -205,16 +263,10 @@ void BuildGUI_SolidDlg::SetEditCurrentArgument() void BuildGUI_SolidDlg::ActivateThisDialog() { GEOMBase_Skeleton::ActivateThisDialog(); - connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(), - SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) ); + connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), + this, SLOT(SelectionIntoArgument())); - //globalSelection( GEOM_SHELL ); - TColStd_MapOfInteger aMap; - aMap.Add( GEOM_SHELL ); - aMap.Add( GEOM_COMPOUNDFILTER ); - QList aSubShapes; - aSubShapes.append( GEOM_SHELL ); - globalSelection( aMap, aSubShapes ); + ConstructorsClicked(getConstructorId()); } @@ -257,15 +309,14 @@ bool BuildGUI_SolidDlg::isValid (QString& msg) GEOM::MeasureOpPtr anOp; anOp.take(myGeomGUI->GetGeomGen()->GetIMeasureOperations(getStudyId())); - - if (!GroupSolid->CheckButton1->isChecked() || myShells.count() == 1) { - for (int i = 0, n = myShells.count(); i < n && ok; i++) { - CORBA::String_var aRes = anOp->IsGoodForSolid(myShells[i].get()); - if (strlen(aRes.in())) { - msg = QObject::tr(aRes.in()).arg(GEOMBase::GetName(myShells[i].get())); - ok = false; - } - } + if (getConstructorId() == 0 && (!GroupSolid->CheckButton1->isChecked() || myShells.count() == 1)) { + for (int i = 0, n = myShells.count(); i < n && ok; i++) { + CORBA::String_var aRes = anOp->IsGoodForSolid(myShells[i].get()); + if (strlen(aRes.in())) { + msg = QObject::tr(aRes.in()).arg(GEOMBase::GetName(myShells[i].get())); + ok = false; + } + } } return ok; } @@ -315,24 +366,41 @@ bool BuildGUI_SolidDlg::isClosed( GEOM::GEOM_Object_ptr shell ) bool BuildGUI_SolidDlg::execute( ObjectList& objects ) { GEOM::GEOM_IShapesOperations_var anOper = GEOM::GEOM_IShapesOperations::_narrow( getOperation() ); + GEOM::GEOM_Object_var anObj; - if ( GroupSolid->CheckButton1->isChecked() ) { - GEOM::ListOfGO_var objlist = new GEOM::ListOfGO(); - objlist->length( myShells.count() ); - for ( int i = 0; i < myShells.count(); i++ ) - objlist[i] = myShells[i].copy(); + switch (getConstructorId()) { + case 0: + { + if ( GroupSolid->CheckButton1->isChecked() ) { + GEOM::ListOfGO_var objlist = new GEOM::ListOfGO(); + objlist->length( myShells.count() ); + for ( int i = 0; i < myShells.count(); i++ ) + objlist[i] = myShells[i].copy(); - GEOM::GEOM_Object_var anObj = anOper->MakeSolidShells( objlist.in() ); + anObj = anOper->MakeSolidShells( objlist.in() ); - if ( !anObj->_is_nil() ) - objects.push_back( anObj._retn() ); - } - else { - for ( int i = 0, n = myShells.count(); i< n; i++ ) { - GEOM::GEOM_Object_var anObj = anOper->MakeSolidShell( myShells[ i ].get() ); + if ( !anObj->_is_nil() ) objects.push_back( anObj._retn() ); + } + else { + for ( int i = 0, n = myShells.count(); i< n; i++ ){ + anObj = anOper->MakeSolidShell( myShells[ i ].get() ); - if ( !anObj->_is_nil() ) - objects.push_back( anObj._retn() ); + if ( !anObj->_is_nil() ) objects.push_back( anObj._retn() ); + } + } + break; + } + case 1: + { + GEOM::ListOfGO_var objlist = new GEOM::ListOfGO(); + objlist->length( myShells.count() ); + for ( int i = 0; i < myShells.count(); i++ ) + objlist[i] = myShells[i].copy(); + + anObj = anOper->MakeSolidFromConnectedFaces( objlist.in(), GroupFaces->CheckButton1->isChecked() ); + + if ( !anObj->_is_nil() ) objects.push_back( anObj._retn() ); + break; } } diff --git a/src/BuildGUI/BuildGUI_SolidDlg.h b/src/BuildGUI/BuildGUI_SolidDlg.h index 6be374c6f..7a70f085a 100644 --- a/src/BuildGUI/BuildGUI_SolidDlg.h +++ b/src/BuildGUI/BuildGUI_SolidDlg.h @@ -59,12 +59,14 @@ private: QList myShells; DlgRef_1Sel1Check* GroupSolid; + DlgRef_1Sel1Check* GroupFaces; private slots: void ClickOnOk(); bool ClickOnApply(); void SetEditCurrentArgument(); void SelectionIntoArgument(); + void ConstructorsClicked( int ); void ActivateThisDialog(); void EnableNameField( bool ); }; diff --git a/src/GEOMGUI/GEOM_images.ts b/src/GEOMGUI/GEOM_images.ts index 67ed0460e..c8c70c163 100644 --- a/src/GEOMGUI/GEOM_images.ts +++ b/src/GEOMGUI/GEOM_images.ts @@ -175,6 +175,10 @@ ICON_DLG_BUILD_SHELL build_shell.png + + ICON_DLG_SOLID_FROM_FACES + solid_from_faces.png + ICON_DLG_BUILD_SOLID build_solid.png @@ -1267,6 +1271,10 @@ ICO_SOLID build_solid.png + + ICO_SOLID_FROM_FACES + solid_from_face.png + ICO_SOLID_SEL_ONLY build_solid.png diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts index a3de0e031..27690e1f5 100644 --- a/src/GEOMGUI/GEOM_msg_en.ts +++ b/src/GEOMGUI/GEOM_msg_en.ts @@ -707,6 +707,10 @@ Please, select face, shell or solid and try again GEOM_FACE_OPT Try to create a planar face + + GEOM_SOLID_FROM_FACE_OPT + Intersect shapes + MAKE_FACE_TOLERANCE_TOO_BIG Cannot build a planar face: required tolerance is @@ -1944,6 +1948,14 @@ Please, select face, shell or solid and try again GEOM_SOLID_TITLE Solid Construction + + GEOM_SOLID_SHELLS + Make Solid From Shells + + + GEOM_SOLID_FACES + Make Solid From Connected Set Of Faces/Shells + GEOM_SPHERE Sphere @@ -3004,6 +3016,10 @@ Please, select face, shell or solid and try again MEN_SOLID Solid + + MEN_SOLID_FROM_FACES + Solid from connected faces + MEN_SOLID_SEL_ONLY Solid diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts index 45f12ad4f..037d015c5 100644 --- a/src/GEOMGUI/GEOM_msg_fr.ts +++ b/src/GEOMGUI/GEOM_msg_fr.ts @@ -723,6 +723,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_FACE_OPT Privilégier la création d'une face plane + + GEOM_SOLID_FROM_FACE_OPT + Intersect shapes + MAKE_FACE_TOLERANCE_TOO_BIG Impossible de construire une face plane: @@ -1944,6 +1948,14 @@ Choisissez une face, une coque ou un solide et essayez de nouveau GEOM_SOLID_TITLE Construction d'un solide + + GEOM_SOLID_SHELLS + Make Solid From Shells + + + GEOM_SOLID_FACES + Make Solid From Connected Set Of Faces/Shells + GEOM_SPHERE Sphère @@ -2988,6 +3000,10 @@ Choisissez une face, une coque ou un solide et essayez de nouveau MEN_SOLID Solide + + MEN_SOLID_FROM_FACES + Solid from connected faces + MEN_SOLID_SEL_ONLY Solide diff --git a/src/GEOMGUI/GEOM_msg_ja.ts b/src/GEOMGUI/GEOM_msg_ja.ts index f68d1c4b9..65c9fcd45 100644 --- a/src/GEOMGUI/GEOM_msg_ja.ts +++ b/src/GEOMGUI/GEOM_msg_ja.ts @@ -703,6 +703,10 @@ GEOM_FACE_OPT 平らなフェースを作成 + + GEOM_SOLID_FROM_FACE_OPT + Intersect shapes + MAKE_FACE_TOLERANCE_TOO_BIG 平坦な面を作成できません: 作成された顔があまりにも高い耐性 @@ -1923,6 +1927,14 @@ GEOM_SOLID_TITLE ソリッドの構築 + + GEOM_SOLID_SHELLS + Make Solid From Shells + + + GEOM_SOLID_FACES + Make Solid From Connected Set Of Faces/Shells + GEOM_SPHERE Sphere @@ -2971,6 +2983,10 @@ MEN_SOLID ソリッド + + MEN_SOLID_FROM_FACES + Solid from connected faces + MEN_SOLID_SEL_ONLY ソリッド diff --git a/src/GEOMImpl/GEOMImpl_IShapes.hxx b/src/GEOMImpl/GEOMImpl_IShapes.hxx index a43024b78..54357bef6 100644 --- a/src/GEOMImpl/GEOMImpl_IShapes.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapes.hxx @@ -36,6 +36,7 @@ class GEOMImpl_IShapes SHAPE_ARG_SHAPES = 1, // for Wire, Shell, Solid and Compound SHAPE_ARG_BASE = 2, // for Face, Solid and Sub-shape SHAPE_ARG_PLANAR = 3, // for Face + SHAPE_ARG_INTERSECT = 3, // for Solid From Connected Faces (NOTE: same value as SHAPE_ARG_PLANAR is used!) SHAPE_ARG_SUBTYPE = 4, // for Sub-shape SHAPE_ARG_INDICES = 5, // for Sub-shape SHAPE_ARG_TOLERANCE = 6, // linear tolerance (for Wire, Edge) @@ -81,6 +82,11 @@ class GEOMImpl_IShapes Standard_Real GetAngularTolerance() { return _func->GetReal(SHAPE_ARG_ANGLE_TOL); } + void SetIsIntersect(const Standard_Boolean isIntersect) + {_func->SetInteger(SHAPE_ARG_INTERSECT, isIntersect ? 1 : 0);} + + Standard_Boolean GetIsIntersect() { return (_func->GetInteger(SHAPE_ARG_INTERSECT) == 1); } + private: Handle(GEOM_Function) _func; diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index ae755770c..da8445efc 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -782,6 +782,77 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape return aShape; } +//============================================================================= +/*! + * MakeSolidFromConnectedFaces + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces + (std::list theFacesOrShells, + const Standard_Boolean isIntersect) +{ + SetErrorCode(KO); + + //Add a new object + Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID); + + //Add a new function + Handle(GEOM_Function) aFunction = + aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES); + 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; + + // Shapes + std::list::iterator it = theFacesOrShells.begin(); + for (; it != theFacesOrShells.end(); it++) { + Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction(); + if (aRefSh.IsNull()) { + SetErrorCode("NULL argument shape for the shape construction"); + return NULL; + } + aShapesSeq->Append(aRefSh); + } + aCI.SetShapes(aShapesSeq); + aCI.SetIsIntersect(isIntersect); + + //Compute the shape + 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 pd (aFunction); + pd << aSolid << " = geompy.MakeSolidFromConnectedFaces(["; + + // Shapes + it = theFacesOrShells.begin(); + if (it != theFacesOrShells.end()) { + pd << (*it++); + while (it != theFacesOrShells.end()) { + pd << ", " << (*it++); + } + } + pd << "]," << (isIntersect ? "True" : "False") << ")"; + + SetErrorCode(OK); + return aSolid; +} + //============================================================================= /*! * MakeGlueFaces diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 025646331..dca4233a9 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -95,6 +95,9 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations Standard_EXPORT Handle(GEOM_Object) MakeCompound (std::list theShapes); + Standard_EXPORT Handle(GEOM_Object) MakeSolidFromConnectedFaces (std::list theFacesOrShells, + const Standard_Boolean isIntersect); + Standard_EXPORT Handle(GEOM_Object) MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes, const Standard_Real theTolerance, const Standard_Boolean doKeepNonSolids); diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index c220237e9..9e8f83b06 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -98,6 +98,11 @@ #include #include +#include +#include + +#include + //modified by NIZNHY-PKV Wed Dec 28 13:48:20 2011f //static // void KeepEdgesOrder(const Handle(TopTools_HSequenceOfShape)& aEdges, @@ -137,12 +142,12 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aShape; TCollection_AsciiString aWarning; - TopAbs_ShapeEnum anExpectedType = TopAbs_SHAPE; + std::list anExpectedType; BRep_Builder B; if (aType == WIRE_EDGES) { - anExpectedType = TopAbs_WIRE; + anExpectedType.push_back(TopAbs_WIRE); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); @@ -153,7 +158,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = MakeWireFromEdges(aShapes, aTolerance); } else if (aType == FACE_WIRE) { - anExpectedType = TopAbs_FACE; + anExpectedType.push_back(TopAbs_FACE); Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); @@ -188,7 +193,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } else if (aType == FACE_WIRES) { - anExpectedType = TopAbs_FACE; + anExpectedType.push_back(TopAbs_FACE); // Try to build a face from a set of wires and edges int ind; @@ -310,9 +315,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } else if (aType == FACE_FROM_SURFACE) { -#ifdef RESULT_TYPE_CHECK - anExpectedType = TopAbs_FACE; -#endif + anExpectedType.push_back(TopAbs_FACE); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); @@ -348,7 +351,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } else if (aType == SHELL_FACES) { - anExpectedType = TopAbs_SHELL; + anExpectedType.push_back(TopAbs_SHELL); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -407,7 +410,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } else if (aType == SOLID_SHELLS) { - anExpectedType = TopAbs_SOLID; + anExpectedType.push_back(TopAbs_SOLID); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -441,7 +444,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = Sol; } else if (aType == COMPOUND_SHAPES) { - anExpectedType = TopAbs_COMPOUND; + anExpectedType.push_back(TopAbs_COMPOUND); Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -462,7 +465,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } else if (aType == EDGE_WIRE) { - anExpectedType = TopAbs_EDGE; + anExpectedType.push_back(TopAbs_EDGE); Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aWire = aRefBase->GetValue(); @@ -472,8 +475,35 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = MakeEdgeFromWire(aWire, LinTol, AngTol); } + else if (aType == SOLID_FACES) { + anExpectedType.push_back(TopAbs_SOLID); + anExpectedType.push_back(TopAbs_COMPOUND); + anExpectedType.push_back(TopAbs_COMPSOLID); + + Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); + unsigned int ind, nbshapes = aShapes->Length(); + + // add faces + BOPCol_ListOfShape aLS; + for (ind = 1; ind <= nbshapes; ind++) { + Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); + TopoDS_Shape aShape_i = aRefShape->GetValue(); + if (aShape_i.IsNull()) { + Standard_NullObject::Raise("Shape for solid construction is null"); + } + aLS.Append(aShape_i); + } + + BOPAlgo_MakerVolume aMV; + aMV.SetArguments(aLS); + aMV.SetIntersect(aCI.GetIsIntersect()); + aMV.Perform(); + if (aMV.ErrorStatus()) return 0; + + aShape = aMV.Shape(); + } else if (aType == EDGE_CURVE_LENGTH) { - anExpectedType = TopAbs_EDGE; + anExpectedType.push_back(TopAbs_EDGE); GEOMImpl_IVector aVI (aFunction); @@ -575,9 +605,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const ("Shape for isoline construction is not a face"); } } else if (aType == EDGE_UV) { -#ifdef RESULT_TYPE_CHECK - anExpectedType = TopAbs_EDGE; -#endif + anExpectedType.push_back(TopAbs_EDGE); GEOMImpl_IShapeExtend aSE (aFunction); Handle(GEOM_Function) aRefEdge = aSE.GetShape(); TopoDS_Shape aShapeEdge = aRefEdge->GetValue(); @@ -588,9 +616,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = ExtendEdge(anEdge, aSE.GetUMin(), aSE.GetUMax()); } } else if (aType == FACE_UV) { -#ifdef RESULT_TYPE_CHECK - anExpectedType = TopAbs_FACE; -#endif + anExpectedType.push_back(TopAbs_FACE); GEOMImpl_IShapeExtend aSE (aFunction); Handle(GEOM_Function) aRefFace = aSE.GetShape(); @@ -604,9 +630,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aSE.GetVMin(), aSE.GetVMax()); } } else if (aType == SURFACE_FROM_FACE) { -#ifdef RESULT_TYPE_CHECK - anExpectedType = TopAbs_FACE; -#endif + anExpectedType.push_back(TopAbs_FACE); GEOMImpl_IShapeExtend aSE (aFunction); Handle(GEOM_Function) aRefFace = aSE.GetShape(); @@ -663,8 +687,13 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const // Check if the result shape type is compatible with the expected. const TopAbs_ShapeEnum aShType = aShape.ShapeType(); - if (anExpectedType != TopAbs_SHAPE && anExpectedType != aShType) { - Standard_ConstructionError::Raise("Result type check failed"); + if (!anExpectedType.empty()) { + bool ok = false; + std::list::const_iterator it; + for (it = anExpectedType.begin(); it != anExpectedType.end() && !ok; ++it) + ok = (*it == TopAbs_SHAPE || *it == aShType); + if (!ok) + Standard_ConstructionError::Raise("Result type check failed"); } aFunction->SetValue(aShape); @@ -1516,6 +1545,11 @@ GetCreationInformation(std::string& theOperationName, theOperationName = "SOLID"; AddParam( theParams, "Objects", aCI.GetShapes() ); break; + case SOLID_FACES: + theOperationName = "SOLID_FROM_FACES"; + AddParam( theParams, "Objects", aCI.GetShapes() ); + AddParam( theParams, "Is intersect", aCI.GetIsIntersect() ); + break; case COMPOUND_SHAPES: theOperationName = "COMPOUND"; AddParam( theParams, "Objects", aCI.GetShapes() ); diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx index 556255ae8..f7f329ebb 100644 --- a/src/GEOMImpl/GEOMImpl_Types.hxx +++ b/src/GEOMImpl/GEOMImpl_Types.hxx @@ -311,7 +311,7 @@ #define EDGE_UV 16 #define FACE_UV 17 #define SURFACE_FROM_FACE 18 - +#define SOLID_FACES 19 #define ARCHIMEDE_TYPE 1 diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index 4e619573c..dce57e0aa 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -406,6 +406,40 @@ GEOM_IShapesOperations_i::MakeCompound (const GEOM::ListOfGO& theShapes) return GetObject(anObject); } +//============================================================================= +/*! + * MakeSolidFromConnectedFaces + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeSolidFromConnectedFaces + (const GEOM::ListOfGO& theFacesOrShells, + const CORBA::Boolean isIntersect) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + int ind, aLen; + std::list aShapes; + + //Get the shapes + aLen = theFacesOrShells.length(); + for (ind = 0; ind < aLen; ind++) { + Handle(GEOM_Object) aSh = GetObjectImpl(theFacesOrShells[ind]); + if (aSh.IsNull()) return aGEOMObject._retn(); + aShapes.push_back(aSh); + } + + // Make Solid + Handle(GEOM_Object) anObject = + GetOperations()->MakeSolidFromConnectedFaces(aShapes, isIntersect); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + //============================================================================= /*! * MakeGlueFaces diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index 7587a6a2d..5ba281994 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -75,6 +75,9 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : GEOM::GEOM_Object_ptr MakeCompound (const GEOM::ListOfGO& theShapes); + GEOM::GEOM_Object_ptr MakeSolidFromConnectedFaces (const GEOM::ListOfGO& theFacesOrShells, + CORBA::Boolean isIntersect); + GEOM::GEOM_Object_ptr MakeGlueFaces (const GEOM::ListOfGO& theShape, CORBA::Double theTolerance, CORBA::Boolean doKeepNonSolids); diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index 98cc96638..266252668 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -2341,6 +2341,25 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeCompound (GEOM::GEOM_List_ptr theShapes return NULL; } +//============================================================================= +// MakeSolidFromConnectedFaces: +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeSolidFromConnectedFaces (GEOM::GEOM_List_ptr theFacesOrShells, + CORBA::Boolean isIntersect) +{ + beginService( " GEOM_Superv_i::MakeSolidFromConnectedFaces" ); + MESSAGE("GEOM_Superv_i::MakeSolidFromConnectedFaces"); + if (GEOM_List_i* aListImpl = + dynamic_cast*>(GetServant(theFacesOrShells, myPOA).in())) { + getShapesOp(); + GEOM::GEOM_Object_ptr anObj = myShapesOp->MakeSolidFromConnectedFaces(aListImpl->GetList(), isIntersect); + endService( " GEOM_Superv_i::MakeSolidFromConnectedFaces" ); + return anObj; + } + endService( " GEOM_Superv_i::MakeSolidFromConnectedFaces" ); + return NULL; +} + //============================================================================= // MakeGlueFaces: //============================================================================= diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.hh b/src/GEOM_I_Superv/GEOM_Superv_i.hh index f33f4f8bb..a41e6b32f 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.hh +++ b/src/GEOM_I_Superv/GEOM_Superv_i.hh @@ -507,6 +507,8 @@ public: GEOM::GEOM_Object_ptr MakeSolidShell (GEOM::GEOM_Object_ptr theShell); GEOM::GEOM_Object_ptr MakeSolidShells (GEOM::GEOM_List_ptr theShells); GEOM::GEOM_Object_ptr MakeCompound (GEOM::GEOM_List_ptr theShapes); + GEOM::GEOM_Object_ptr MakeSolidFromConnectedFaces (GEOM::GEOM_List_ptr theFacesOrShells, + CORBA::Boolean isIntersect); GEOM::GEOM_Object_ptr MakeGlueFaces (GEOM::GEOM_Object_ptr theShape, CORBA::Double theTolerance, CORBA::Boolean doKeepNonSolids); @@ -534,7 +536,6 @@ public: CORBA::Short theShapeType, GEOM::shape_state theState); - //-----------------------------------------------------------// // BlocksOperations // //-----------------------------------------------------------// diff --git a/src/GEOM_SWIG/GEOM_TestAll.py b/src/GEOM_SWIG/GEOM_TestAll.py index cb9a9720a..6dafa5265 100644 --- a/src/GEOM_SWIG/GEOM_TestAll.py +++ b/src/GEOM_SWIG/GEOM_TestAll.py @@ -190,7 +190,13 @@ def TestAll (geompy, math): prism1_faces[3], prism1_faces[4], prism1_faces[5], prism1_faces[2]]) Solid = geompy.MakeSolid([Shell1]) #(List of GEOM_Object)->GEOM_Object - + + Box1_translation = geompy.MakeTranslation(Box1, 10, 0, 0) + Box1_shell = geompy.SubShapeAllSorted(Box1, geompy.ShapeType["SHELL"])[0] + Box1_translation_shell = geompy.SubShapeAllSorted(Box1_translation, geompy.ShapeType["SHELL"])[0] + + Solid_from_shells = geompy.MakeSolidFromConnectedFaces([Box1_shell, Box1_translation_shell], 1) #(List of GEOM_Object, Boolean)->GEOM_Object + # Create Isoline Isoline = geompy.MakeIsoline(Face1, True, 0.5) #(1 GEOM_Object, Boolean, Double)->GEOM_Object @@ -416,6 +422,8 @@ def TestAll (geompy, math): id_Prism1 = geompy.addToStudy(Prism1, "Prism by Two Pnt") id_Shell1 = geompy.addToStudy(Shell1, "Shell from Prism1 faces") id_Solid = geompy.addToStudy(Solid, "Solid") + id_Solid1 = geompy.addToStudy(Solid_from_shells, "Solid1") + id_Compound = geompy.addToStudy(Compound, "Compound") id_Plane2 = geompy.addToStudy(Plane2, "Plane on Face") @@ -497,7 +505,7 @@ def TestAll (geompy, math): id_Partition = geompy.addToStudy(Partition, "Partition") id_Partition1 = geompy.addToStudy(Partition1, "Half Partition") - + #Decompose objects # SubShape diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 08b4811ec..ec10f2467 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -4649,6 +4649,39 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): RaiseIfFailed("MakeCompound", self.ShapesOp) self._autoPublish(anObj, theName, "compound") return anObj + + ## Create a solid (or solids) from the set of faces and/or shells. + # @param theFacesOrShells List of faces and/or shells. + # @param isIntersect If TRUE, forces performing intersections + # between arguments; otherwise (default) intersection is not performed. + # @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 solid (or compound of solids). + # + # @ref tui_creation_solid_from_faces "Example" + @ManageTransactions("ShapesOp") + def MakeSolidFromConnectedFaces(self, theFacesOrShells, isIntersect = False, theName=None): + """ + Create a solid (or solids) from the set of connected faces and/or shells. + + Parameters: + theFacesOrShells List of faces and/or shells. + isIntersect If TRUE, forces performing intersections + between arguments; otherwise (default) intersection is not performed + 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 solid (or compound of solids). + """ + # Example: see GEOM_TestAll.py + anObj = self.ShapesOp.MakeSolidFromConnectedFaces(theFacesOrShells, isIntersect) + RaiseIfFailed("MakeSolidFromConnectedFaces", self.ShapesOp) + self._autoPublish(anObj, theName, "solid") + return anObj # end of l3_advanced ## @}