From: mzn Date: Mon, 30 Aug 2010 10:57:47 +0000 (+0000) Subject: Fix for imp 0020876: EDF 1246 SMESH: DoubleNodes fonctions available in the GUI. X-Git-Tag: end_translate_resources_09Jul10~5 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=cc203f62c374a9c2daa29f1acea1a239024c6996;p=modules%2Fsmesh.git Fix for imp 0020876: EDF 1246 SMESH: DoubleNodes fonctions available in the GUI. --- diff --git a/doc/salome/gui/SMESH/images/duplicate01.png b/doc/salome/gui/SMESH/images/duplicate01.png new file mode 100644 index 000000000..b35c7785f Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate01.png differ diff --git a/doc/salome/gui/SMESH/images/duplicate02.png b/doc/salome/gui/SMESH/images/duplicate02.png new file mode 100644 index 000000000..1b5cfabc5 Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate02.png differ diff --git a/doc/salome/gui/SMESH/images/duplicate_nodes.png b/doc/salome/gui/SMESH/images/duplicate_nodes.png new file mode 100644 index 000000000..61ff32bcd Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate_nodes.png differ diff --git a/doc/salome/gui/SMESH/input/double_nodes_page.doc b/doc/salome/gui/SMESH/input/double_nodes_page.doc new file mode 100644 index 000000000..eb41ee747 --- /dev/null +++ b/doc/salome/gui/SMESH/input/double_nodes_page.doc @@ -0,0 +1,67 @@ +/*! + +\page double_nodes_page Duplicating Nodes + +\n This operation allows to duplicate nodes of your mesh. + +To duplicate nodes: +
    +
  1. From the \b Modification menu choose \b Transformation -> \b Duplicate +\b Nodes item or click "Duplicate Nodes" button in the toolbar. +
    +\image html duplicate_nodes.png "Duplicate Nodes button" +
  2. +
  3. Check in the dialog box one of two radio buttons corresponding to +the type of nodes duplication operation you would like to perform.
  4. +
  5. Fill the other fields available in the dialog box (depends on the chosen + operation mode).
  6. +
  7. Click the \b Apply or Apply and Close button to perform the operation of nodes + duplication.
  8. +
+ +\n "Duplicate Nodes" dialog has two working modes: + + +
+\anchor mode_without_elem_anchor +

Without duplication of border elements

+ +In this mode the dialog looks like: + +\image html duplicate01.png + +Parameters to be defined in this mode: +
    +
  1. Group of nodes to duplicate (mandatory): these nodes will be duplicated.
  2. +
  3. Group of elements to replace nodes with new ones (optional): the duplicated nodes + will be associated with these elements.
  4. +
  5. Construct group with newly created nodes option (checked by default): + if checked - the group with just created nodes will be builded.
  6. +
+ +
+\anchor mode_with_elem_anchor +

With duplication of border elements

+ +In this mode the dialog looks like: + +\image html duplicate02.png + +Parameters to be defined in this mode: +
    +
  1. Group of elements to duplicate (mandatory): these elements will be duplicated.
  2. +
  3. Group of nodes at not to duplicate (optional): group of nodes at crack bottom + which will not be duplicated.
  4. +
  5. Group of elements to replace nodes with new ones (mandatory): the duplicated nodes + will be associated with these elements.
  6. +
  7. Construct group with newly created elements option (checked by default): + if checked - the group with just created elements will be builded.
  8. +
+ + +
See Also a sample TUI Script of a \ref tui_duplicate_nodes "Duplicate nodes" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/modifying_meshes.doc b/doc/salome/gui/SMESH/input/modifying_meshes.doc index b086cf915..8d5875a9c 100644 --- a/doc/salome/gui/SMESH/input/modifying_meshes.doc +++ b/doc/salome/gui/SMESH/input/modifying_meshes.doc @@ -45,6 +45,7 @@ of the selected node or edge.
  • Apply \subpage pattern_mapping_page "pattern mapping".
  • \subpage convert_to_from_quadratic_mesh_page "Convert regular mesh to quadratic", or vice versa.
  • +
  • Create \subpage double_nodes_page "double nodes".
  • \subpage make_2dmesh_from_3d_page "Create 2D mesh from 3D".
  • diff --git a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc index c55b2a492..25f5a7ec8 100644 --- a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc @@ -350,4 +350,73 @@ mesh.Compute() mesh.SewSideElements([69, 70, 71, 72], [91, 92, 89, 90], 8, 38, 23, 58) \endcode +
    +\anchor tui_duplicate_nodes +

    Duplicate nodes

    + +\code +import salome +import smesh +import SMESH_test1 + +mesh = SMESH_test1.mesh + +# Compute mesh +mesh.Compute() + +# Without the duplication of border elements + +# Nodes to duplicate +nodes1 = mesh.CreateEmptyGroup( smesh.NODE, 'nodes1' ) +nodes1.Add( [ 289, 278, 302, 285 ] ) + +# Group of faces to replace nodes with new ones +faces1 = mesh.CreateEmptyGroup( smesh.FACE, 'faces1' ) +faces1.Add( [ 519, 556, 557 ] ) + +# Duplicate nodes +print "\nMesh before the first nodes duplication:" +print "Nodes : ", mesh.NbNodes() +print "Edges : ", mesh.NbEdges() +print "Triangles : ", mesh.NbTriangles() + +createdNodes = mesh.DoubleNodeGroupNew(nodes1, faces1) + +print "\nMesh after the first nodes duplication:" +print "Nodes : ", mesh.NbNodes() +print "Edges : ", mesh.NbEdges() +print "Triangles : ", mesh.NbTriangles() + +# With the duplication of border elements + +# Edges to duplicate +edges = mesh.CreateEmptyGroup( smesh.EDGE, 'edges' ) +edges.Add( [ 29, 30, 31 ] ) + +# Nodes not to duplicate +nodes2 = mesh.CreateEmptyGroup( smesh.NODE, 'nodes2' ) +nodes2.Add( [ 32, 5 ] ) + +# Group of faces to replace nodes with new ones +faces2 = mesh.CreateEmptyGroup( smesh.FACE, 'faces2' ) +faces2.Add( [ 576, 578, 580 ] ) + +# Duplicate nodes +print "\nMesh before the second nodes duplication:" +print "Nodes : ", mesh.NbNodes() +print "Edges : ", mesh.NbEdges() +print "Triangles : ", mesh.NbTriangles() + +mesh_editor = mesh.DoubleNodeElemGroupNew( edges, nodes2, faces2 ) + +print "\nMesh after the second nodes duplication:" +print "Nodes : ", mesh.NbNodes() +print "Edges : ", mesh.NbEdges() +print "Triangles : ", mesh.NbTriangles() + +# Update object browser +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(0) +\endcode + */ diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index 0038beee7..2fc9ae303 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -784,11 +784,23 @@ module SMESH * \param theNodes - group of nodes to be doubled. * \param theModifiedElems - group of elements to be updated. * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups() + * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups(), DoubleNodeGroupNew() */ boolean DoubleNodeGroup( in SMESH_GroupBase theNodes, in SMESH_GroupBase theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup() described above, but returns a new group with + * newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ + SMESH_Group DoubleNodeGroupNew( in SMESH_GroupBase theNodes, + in SMESH_GroupBase theModifiedElems ); + /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements This method provided for convenience works as DoubleNodes() described above. @@ -837,12 +849,27 @@ module SMESH * \param theAffectedElems - group of elements to which the replicated nodes * should be associated to. * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNodes(), DoubleNodeGroups() + * \sa DoubleNodes(), DoubleNodeGroups(), DoubleNodeElemGroupNew() */ boolean DoubleNodeElemGroup( in SMESH_GroupBase theElems, in SMESH_GroupBase theNodesNot, in SMESH_GroupBase theAffectedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeElemGroup() described above, but returns a new group with + * newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ + SMESH_Group DoubleNodeElemGroupNew( in SMESH_GroupBase theElems, + in SMESH_GroupBase theNodesNot, + in SMESH_GroupBase theAffectedElems ); + /*! * \brief Creates a hole in a mesh by doubling the nodes of some particular elements * This method provided for convenience works as DoubleNodes() described above. diff --git a/resources/Makefile.am b/resources/Makefile.am index d3407f02e..ed3f5aff7 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -173,7 +173,9 @@ dist_salomeres_DATA = \ mesh_free_faces.png \ scale.png \ scale_along_axes.png \ - split_into_tetra.png + split_into_tetra.png \ + mesh_duplicate_nodes.png \ + mesh_duplicate_nodes_with_elem.png # VSR: little trick to avoid putting if SMESHCatalog.xml to the distribution archive nodist_salomeres_SCRIPTS = SMESHCatalog.xml diff --git a/resources/mesh_duplicate_nodes.png b/resources/mesh_duplicate_nodes.png new file mode 100644 index 000000000..0f800f7a2 Binary files /dev/null and b/resources/mesh_duplicate_nodes.png differ diff --git a/resources/mesh_duplicate_nodes_with_elem.png b/resources/mesh_duplicate_nodes_with_elem.png new file mode 100644 index 000000000..7a313aa14 Binary files /dev/null and b/resources/mesh_duplicate_nodes_with_elem.png differ diff --git a/src/SMESHGUI/Makefile.am b/src/SMESHGUI/Makefile.am index c96383c3e..031665392 100644 --- a/src/SMESHGUI/Makefile.am +++ b/src/SMESHGUI/Makefile.am @@ -71,6 +71,7 @@ salomeinclude_HEADERS = \ SMESHGUI_ScaleDlg.h \ SMESHGUI_SymmetryDlg.h \ SMESHGUI_SewingDlg.h \ + SMESHGUI_DuplicateNodesDlg.h \ SMESHGUI_EditMeshDlg.h \ SMESHGUI_MeshUtils.h \ SMESHGUI_CreatePolyhedralVolumeDlg.h \ @@ -134,6 +135,7 @@ dist_libSMESH_la_SOURCES = \ SMESHGUI_ScaleDlg.cxx \ SMESHGUI_SymmetryDlg.cxx \ SMESHGUI_SewingDlg.cxx \ + SMESHGUI_DuplicateNodesDlg.cxx \ SMESHGUI_EditMeshDlg.cxx \ SMESHGUI_Utils.cxx \ SMESHGUI_GEOMGenUtils.cxx \ @@ -203,6 +205,7 @@ MOC_FILES = \ SMESHGUI_ScaleDlg_moc.cxx \ SMESHGUI_SymmetryDlg_moc.cxx \ SMESHGUI_SewingDlg_moc.cxx \ + SMESHGUI_DuplicateNodesDlg_moc.cxx \ SMESHGUI_EditMeshDlg_moc.cxx \ SMESHGUI_CreatePolyhedralVolumeDlg_moc.cxx \ SMESHGUI_Operation_moc.cxx \ diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 088574558..ee07cc36f 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -71,6 +71,7 @@ #include "SMESHGUI_ScaleDlg.h" #include "SMESHGUI_TransparencyDlg.h" #include "SMESHGUI_WhatIsDlg.h" +#include "SMESHGUI_DuplicateNodesDlg.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_MeshUtils.h" @@ -2728,6 +2729,20 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) break; } + case 4069: // DUPLICATE NODES + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + ( new SMESHGUI_DuplicateNodesDlg( this ) )->show(); + } + else { + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + } + break; + } + case 5105: // Library of selection filters { static QList aTypes; @@ -2876,7 +2891,8 @@ void SMESHGUI::BuildPresentation( const Handle(SALOME_InteractiveObject) & theIO // function : createSMESHAction // purpose : //======================================================================= -void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, const int key, const bool toggle ) +void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, + const int key, const bool toggle, const QString& shortcutAction ) { QIcon icon; QWidget* parent = application()->desktop(); @@ -2893,7 +2909,8 @@ void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QStr menu = tr( QString( "MEN_%1" ).arg( po_id ).toLatin1().data() ), status_bar = tr( QString( "STB_%1" ).arg( po_id ).toLatin1().data() ); - createAction( id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT( OnGUIEvent() ) ); + createAction( id, tooltip, icon, menu, status_bar, key, parent, + toggle, this, SLOT( OnGUIEvent() ), shortcutAction ); } //======================================================================= @@ -3024,6 +3041,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 4066, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" ); createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MOVE_NODE" ); createSMESHAction( 4068, "SCALE", "ICON_DLG_MESH_SCALE" ); + createSMESHAction( 4069, "DUPLICATE_NODES", "ICON_SMESH_DUPLICATE_NODES" ); createSMESHAction( 407, "INV", "ICON_DLG_MESH_DIAGONAL" ); createSMESHAction( 408, "UNION2", "ICON_UNION2TRI" ); createSMESHAction( 409, "ORIENT", "ICON_DLG_MESH_ORIENTATION" ); @@ -3197,6 +3215,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 4065, transfId, -1 ); createMenu( 4066, transfId, -1 ); createMenu( 4068, transfId, -1 ); + createMenu( 4069, transfId, -1 ); createMenu( 4067,modifyId, -1 ); createMenu( 407, modifyId, -1 ); @@ -3297,6 +3316,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 4065, addRemTb ); createTool( 4066, addRemTb ); createTool( 4068, addRemTb ); + createTool( 4069, addRemTb ); createTool( separator(), addRemTb ); createTool( 4067,modifyTb ); diff --git a/src/SMESHGUI/SMESHGUI.h b/src/SMESHGUI/SMESHGUI.h index 0099a20bd..d901ea68c 100644 --- a/src/SMESHGUI/SMESHGUI.h +++ b/src/SMESHGUI/SMESHGUI.h @@ -145,7 +145,8 @@ protected: const QString&, const QString& = QString(), const int = 0, - const bool = false ); + const bool = false, + const QString& = QString() ); void createPopupItem( const int, const QString&, const QString&, diff --git a/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx new file mode 100644 index 000000000..c81732323 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx @@ -0,0 +1,580 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_DuplicateNodesDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. + +// SMESH includes +#include "SMESHGUI_DuplicateNodesDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" + +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +#define SPACING 6 +#define MARGIN 11 + + +/*! + \brief Constructor + \param theModule Mesh module instance +*/ +SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule ) + : QDialog( SMESH::GetDesktop( theModule ) ), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) +{ + // Dialog attributes + setModal(false); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(tr("SMESH_DUPLICATE_TITLE")); + setSizeGripEnabled(true); + + // Icons for the dialog operation modes and selection button + SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI ); + QPixmap iconWithoutElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES"))); + QPixmap iconWithElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES_WITH_ELEM"))); + QPixmap iconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT"))); + + // Main layout + QVBoxLayout* aMainLayout = new QVBoxLayout(this); + aMainLayout->setSpacing(SPACING); + aMainLayout->setMargin(MARGIN); + + // Operation modes selector + QGroupBox* aConstructorsBox = new QGroupBox(tr("DUPLICATION_MODE"), this); + myGroupConstructors = new QButtonGroup(this); + QHBoxLayout* aConstructorsBoxLayout = new QHBoxLayout(aConstructorsBox); + aConstructorsBoxLayout->setSpacing(SPACING); + aConstructorsBoxLayout->setMargin(MARGIN); + + QRadioButton* aRadioButton1 = new QRadioButton(aConstructorsBox); + aRadioButton1->setIcon(iconWithoutElem); + QRadioButton* aRadioButton2 = new QRadioButton(aConstructorsBox); + aRadioButton2->setIcon(iconWithElem); + + aConstructorsBoxLayout->addWidget(aRadioButton1); + aConstructorsBoxLayout->addWidget(aRadioButton2); + myGroupConstructors->addButton(aRadioButton1, 0); + myGroupConstructors->addButton(aRadioButton2, 1); + + // Arguments + myGroupArguments = new QGroupBox(this); + QGridLayout* aGroupArgumentsLayout = new QGridLayout(myGroupArguments); + aGroupArgumentsLayout->setSpacing(SPACING); + aGroupArgumentsLayout->setMargin(MARGIN); + + myTextLabel1 = new QLabel(myGroupArguments); + mySelectButton1 = new QPushButton(myGroupArguments); + mySelectButton1->setIcon(iconSelect); + myLineEdit1 = new QLineEdit(myGroupArguments); + myLineEdit1->setReadOnly(true); + + myTextLabel2 = new QLabel(myGroupArguments); + mySelectButton2 = new QPushButton(myGroupArguments); + mySelectButton2->setIcon(iconSelect); + myLineEdit2 = new QLineEdit(myGroupArguments); + myLineEdit2->setReadOnly(true); + + myTextLabel3 = new QLabel(myGroupArguments); + mySelectButton3 = new QPushButton(myGroupArguments); + mySelectButton3->setIcon(iconSelect); + myLineEdit3 = new QLineEdit(myGroupArguments); + myLineEdit3->setReadOnly(true); + + myCheckBoxNewGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments); + + aGroupArgumentsLayout->addWidget(myTextLabel1, 0, 0); + aGroupArgumentsLayout->addWidget(mySelectButton1, 0, 1); + aGroupArgumentsLayout->addWidget(myLineEdit1, 0, 2); + aGroupArgumentsLayout->addWidget(myTextLabel2, 1, 0); + aGroupArgumentsLayout->addWidget(mySelectButton2, 1, 1); + aGroupArgumentsLayout->addWidget(myLineEdit2, 1, 2); + aGroupArgumentsLayout->addWidget(myTextLabel3, 2, 0); + aGroupArgumentsLayout->addWidget(mySelectButton3, 2, 1); + aGroupArgumentsLayout->addWidget(myLineEdit3, 2, 2); + aGroupArgumentsLayout->addWidget(myCheckBoxNewGroup, 3, 0); + aGroupArgumentsLayout->setRowStretch(4, 1); + + // Buttons + QGroupBox* aGroupButtons = new QGroupBox(this); + QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(aGroupButtons); + aGroupButtonsLayout->setSpacing(SPACING); + aGroupButtonsLayout->setMargin(MARGIN); + + myButtonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGroupButtons); + myButtonOk->setAutoDefault(true); + myButtonOk->setDefault(true); + myButtonApply = new QPushButton(tr("SMESH_BUT_APPLY"), aGroupButtons); + myButtonApply->setAutoDefault(true); + myButtonClose = new QPushButton(tr("SMESH_BUT_CLOSE"), aGroupButtons); + myButtonClose->setAutoDefault(true); + myButtonHelp = new QPushButton(tr("SMESH_BUT_HELP"), aGroupButtons); + myButtonHelp->setAutoDefault(true); + + aGroupButtonsLayout->addWidget(myButtonOk); + aGroupButtonsLayout->addSpacing(10); + aGroupButtonsLayout->addWidget(myButtonApply); + aGroupButtonsLayout->addSpacing(10); + aGroupButtonsLayout->addStretch(); + aGroupButtonsLayout->addWidget(myButtonClose); + aGroupButtonsLayout->addWidget(myButtonHelp); + + // Add mode selector, arguments and buttons to the main layout + aMainLayout->addWidget(aConstructorsBox); + aMainLayout->addWidget(myGroupArguments); + aMainLayout->addWidget(aGroupButtons); + + // Initialize the dialog + Init(); + + // Help file name + myHelpFileName = "double_nodes_page.html"; + + // Signals and slots connections + connect(myGroupConstructors, SIGNAL(buttonClicked(int)), SLOT(onConstructorsClicked(int))); + + connect(mySelectButton1, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + connect(mySelectButton2, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + connect(mySelectButton3, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + + connect(myButtonOk, SIGNAL(clicked()), this, SLOT(onOk())); + connect(myButtonClose, SIGNAL(clicked()), this, SLOT(onClose())); + connect(myButtonApply, SIGNAL(clicked()), this, SLOT(onApply())); + connect(myButtonHelp, SIGNAL(clicked()), this, SLOT(onHelp())); + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionChanged())); + + connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(onDeactivate())); + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(onClose())); +} + +/*! + \brief Destructor +*/ +SMESHGUI_DuplicateNodesDlg::~SMESHGUI_DuplicateNodesDlg() +{ +} + +/*! + \brief Destructor +*/ +void SMESHGUI_DuplicateNodesDlg::Init() +{ + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + // Set initial parameters + myBusy = false; + myCurrentLineEdit = myLineEdit1; + + myGroup1 = SMESH::SMESH_GroupBase::_nil(); + myGroup2 = SMESH::SMESH_GroupBase::_nil(); + myGroup3 = SMESH::SMESH_GroupBase::_nil(); + + // Set selection mode + mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP)); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + + // Set construction mode + int operationMode = myGroupConstructors->checkedId(); + if (operationMode < 0) { + // The dialog has been just displayed + operationMode = 0; + myGroupConstructors->button(0)->setChecked(true); + } + onConstructorsClicked(operationMode); +} + +/*! + \brief SLOT called to change the dialog operation mode. + \param constructorId id of the radio button in mode selector button group +*/ +void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId) +{ + // Clear all fields + myLineEdit1->clear(); + myLineEdit2->clear(); + myLineEdit3->clear(); + + // Checkbox should be checked by default + myCheckBoxNewGroup->setChecked(true); + + // Set the first field as current + myCurrentLineEdit = myLineEdit1; + myCurrentLineEdit->setFocus(); + + switch (constructorId) { + case 0: + { + // Set text to the group of arguments and to the first two labels + myGroupArguments->setTitle(tr("DUPLICATION_WITHOUT_ELEMS")); + myTextLabel1->setText(tr("GROUP_NODES_TO_DUPLICATE")); + myTextLabel2->setText(tr("GROUP_NODES_TO_REPLACE")); + + // Set checkbox title + myCheckBoxNewGroup->setText(tr("CONSTRUCT_NEW_GROUP_NODES")); + + // Hide the third field + myTextLabel3->hide(); + mySelectButton3->hide(); + myLineEdit3->hide(); + + break; + } + case 1: + { + // Set text to the group of arguments and to all the labels + myGroupArguments->setTitle(tr("DUPLICATION_WITH_ELEMS")); + myTextLabel1->setText(tr("GROUP_ELEMS_TO_DUPLICATE")); + myTextLabel2->setText(tr("GROUP_NODES_NOT_DUPLICATE")); + myTextLabel3->setText(tr("GROUP_ELEMS_TO_REPLACE")); + + // Set checkbox title + myCheckBoxNewGroup->setText(tr("CONSTRUCT_NEW_GROUP_ELEMENTS")); + + // Show the third field + myTextLabel3->show(); + mySelectButton3->show(); + myLineEdit3->show(); + + break; + } + } + + // Process selection + onSelectionChanged(); +} + +/*! + \brief SLOT called to apply changes. +*/ +bool SMESHGUI_DuplicateNodesDlg::onApply() +{ + if (mySMESHGUI->isActiveStudyLocked() || !isValid()) + return false; + + myBusy = true; + + bool toCreateGroup = myCheckBoxNewGroup->isChecked(); + int operationMode = myGroupConstructors->checkedId(); + + // Apply changes + bool result = false; + SUIT_OverrideCursor aWaitCursor; + + try { + SMESH::SMESH_Mesh_ptr aMesh = myGroup1->GetMesh(); + SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); + + if (operationMode == 0) { + if (toCreateGroup) { + SMESH::SMESH_GroupBase_ptr aNewGroup = + aMeshEditor->DoubleNodeGroupNew(myGroup1, myGroup2); + if (!CORBA::is_nil(aNewGroup)) + result = true; + } + else + result = aMeshEditor->DoubleNodeGroup(myGroup1, myGroup2); + } + else { + if (toCreateGroup) { + SMESH::SMESH_GroupBase_ptr aNewGroup = + aMeshEditor->DoubleNodeElemGroupNew(myGroup1, myGroup2, myGroup3); + if (!CORBA::is_nil(aNewGroup)) + result = true; + } + else + result = aMeshEditor->DoubleNodeElemGroup(myGroup1, myGroup2, myGroup3); + } + } + catch (const SALOME::SALOME_Exception& S_ex) { + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + catch ( const std::exception& exc ) { + INFOS( "Follow exception was cought:\n\t" << exc.what() ); + } + catch (...){ + INFOS( "Unknown exception was cought !!!" ); + } + + if (!result) { + SUIT_MessageBox::warning(this, + tr("SMESH_WRN_WARNING"), + tr("SMESH_OPERATION_FAILED")); + myBusy = false; + return false; + } + + // Update GUI + mySelectionMgr->clearSelected(); + SMESH::UpdateView(); + SMESHGUI::Modified(); + mySMESHGUI->updateObjBrowser(true); + + // Reinitialize the dialog + Init(); + + return true; +} + +/*! + \brief SLOT called to apply changes and close the dialog. +*/ +void SMESHGUI_DuplicateNodesDlg::onOk() +{ + if (onApply()) + onClose(); +} + +/*! + \brief SLOT called to close the dialog. +*/ +void SMESHGUI_DuplicateNodesDlg::onClose() +{ + disconnect(mySelectionMgr, 0, this, 0); + disconnect(mySMESHGUI, 0, this, 0); + mySMESHGUI->ResetState(); + mySelectionMgr->clearFilters(); + reject(); +} + +/*! + \brief SLOT called when selection changed. +*/ +void SMESHGUI_DuplicateNodesDlg::onSelectionChanged() +{ + if (myBusy || !isEnabled()) return; + + // Try to get selected group + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + int aNbSel = aList.Extent(); + + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_nil(); + if (aNbSel == 1) { + Handle(SALOME_InteractiveObject) IO = aList.First(); + aGroup = SMESH::IObjectToInterface(IO); + + // Check group type + if (!CORBA::is_nil(aGroup)) { + int operationMode = myGroupConstructors->checkedId(); + SMESH::ElementType aGroupType = aGroup->GetType(); + bool isTypeValid = true; + + if (operationMode == 0) { + if ( (myCurrentLineEdit == myLineEdit1 && aGroupType != SMESH::NODE) || + (myCurrentLineEdit == myLineEdit2 && aGroupType == SMESH::NODE) ) + isTypeValid = false; + } + else if (operationMode == 1) { + if ( (myCurrentLineEdit == myLineEdit1 && aGroupType != SMESH::EDGE && + aGroupType != SMESH::FACE) || + (myCurrentLineEdit == myLineEdit2 && aGroupType != SMESH::NODE) || + (myCurrentLineEdit == myLineEdit3 && aGroupType == SMESH::NODE) ) + isTypeValid = false; + } + + if (!isTypeValid) + aGroup = SMESH::SMESH_GroupBase::_nil(); + } + } + + // Clear current field + myCurrentLineEdit->clear(); + + // Set corresponding SMESH group + if (myCurrentLineEdit == myLineEdit1) { + myGroup1 = SMESH::SMESH_Group::_narrow(aGroup); + } + else if (myCurrentLineEdit == myLineEdit2) { + myGroup2 = SMESH::SMESH_Group::_narrow(aGroup); + } + else if (myCurrentLineEdit == myLineEdit3) { + myGroup3 = SMESH::SMESH_Group::_narrow(aGroup); + } + + // Set group name + if (!CORBA::is_nil(aGroup)) + myCurrentLineEdit->setText(aGroup->GetName()); + + // Enable/disable "Apply and Close" and "Apply" buttons + bool isDataValid = isValid(); + myButtonOk->setEnabled(isDataValid); + myButtonApply->setEnabled(isDataValid); +} + +/*! + \brief SLOT called when selection button clicked. +*/ +void SMESHGUI_DuplicateNodesDlg::onEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + // Set current field for edition + if (send == mySelectButton1) { + myCurrentLineEdit = myLineEdit1; + } + else if (send == mySelectButton2) { + myCurrentLineEdit = myLineEdit2; + } + else if (send == mySelectButton3) { + myCurrentLineEdit = myLineEdit3; + } + + myCurrentLineEdit->setFocus(); + onSelectionChanged(); +} + +/*! + \brief Check if the input data is valid. + \return \c true id the data is valid +*/ +bool SMESHGUI_DuplicateNodesDlg::isValid() +{ + // Only first group (nodes/elemets to duplicate) is mandatory + bool isValid = !CORBA::is_nil(myGroup1); + + // First (elements to duplicate) and last groups should be defined in the second operation mode + if (isValid && myGroupConstructors->checkedId() == 1) + isValid = !CORBA::is_nil(myGroup3); + + return isValid; +} + + +/*! + \brief SLOT called when dialog shoud be deativated. +*/ +void SMESHGUI_DuplicateNodesDlg::onDeactivate() +{ + if (isEnabled()) { + mySelectionMgr->clearFilters(); + setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + } +} + +/*! + \brief Receive dialog enter events. + Activates the dialog when the mouse cursor enters. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::enterEvent (QEvent*) +{ + if ( !isEnabled() ) { + mySMESHGUI->EmitSignalDeactivateDialog(); + setEnabled(true); + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + // Set selection mode + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP)); + } +} + +/*! + \brief Receive close events. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::closeEvent (QCloseEvent*) +{ + onClose(); +} + +/*! + \brief Receive key press events. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + onHelp(); + } +} + +/*! + \brief Show the dialog help page. +*/ +void SMESHGUI_DuplicateNodesDlg::onHelp() +{ + LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); + if (app) + app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); + else { + QString platform; +#ifdef WIN32 + platform = "winapplication"; +#else + platform = "application"; +#endif + SUIT_MessageBox::warning(this, tr("WRN_WARNING"), + tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). + arg(app->resourceMgr()->stringValue("ExternalBrowser", + platform)). + arg(myHelpFileName)); + } +} diff --git a/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h new file mode 100644 index 000000000..974b7d7fa --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h @@ -0,0 +1,119 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_DuplicateNodesDlg.h +// Author : Michael ZORIN, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_DUPLICATENODESDLG_H +#define SMESHGUI_DUPLICATENODESDLG_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) + +class QButtonGroup; +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QCheckBox; + +class LightApp_SelectionMgr; + +class SMESHGUI; + +/*! + \class SMESHGUI_DuplicateNodesDlg + \brief Dialog for duplication of nodes. +*/ +class SMESHGUI_EXPORT SMESHGUI_DuplicateNodesDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_DuplicateNodesDlg( SMESHGUI* ); + ~SMESHGUI_DuplicateNodesDlg(); + +private: + void Init(); + + bool isValid(); + + void closeEvent( QCloseEvent* ); + void enterEvent( QEvent* ); + void keyPressEvent( QKeyEvent* ); + +private slots: + void onConstructorsClicked( int ); + + void onOk(); + void onClose(); + bool onApply(); + void onHelp(); + + void onEditCurrentArgument(); + void onSelectionChanged(); + + void onDeactivate(); + +private: + QLineEdit* myCurrentLineEdit; + + QButtonGroup* myGroupConstructors; + + QGroupBox* myGroupArguments; + QLabel* myTextLabel1; + QLabel* myTextLabel2; + QLabel* myTextLabel3; + QPushButton* mySelectButton1; + QPushButton* mySelectButton2; + QPushButton* mySelectButton3; + QLineEdit* myLineEdit1; + QLineEdit* myLineEdit2; + QLineEdit* myLineEdit3; + QCheckBox* myCheckBoxNewGroup; + + QPushButton* myButtonOk; + QPushButton* myButtonApply; + QPushButton* myButtonClose; + QPushButton* myButtonHelp; + + SMESHGUI* mySMESHGUI; + LightApp_SelectionMgr* mySelectionMgr; + + SMESH::SMESH_GroupBase_var myGroup1; + SMESH::SMESH_GroupBase_var myGroup2; + SMESH::SMESH_GroupBase_var myGroup3; + + bool myBusy; + + QString myHelpFileName; +}; + +#endif // SMESHGUI_DUPLICATENODESDLG_H diff --git a/src/SMESHGUI/SMESH_images.ts b/src/SMESHGUI/SMESH_images.ts index 95a9c6881..c22f4e96e 100644 --- a/src/SMESHGUI/SMESH_images.ts +++ b/src/SMESHGUI/SMESH_images.ts @@ -385,6 +385,14 @@ ICON_DLG_SCALE_ALONG_AXES scale_along_axes.png + + ICON_SMESH_DUPLICATE_NODES + mesh_duplicate_nodes.png + + + ICON_SMESH_DUPLICATE_NODES_WITH_ELEM + mesh_duplicate_nodes_with_elem.png + ICON_SMESH_TREE_ALGO mesh_tree_algo.png diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 00d0f4ca9..111042c82 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -650,6 +650,10 @@ MEN_SCALE Scale Transform + + MEN_DUPLICATE_NODES + Duplicate Nodes + MEN_TRANSF Transformation @@ -1949,6 +1953,10 @@ add the exported data to its contents? SMESH_SCALE_TITLE Scale Transform + + SMESH_DUPLICATE_TITLE + Duplicate Nodes + SMESH_SCALE Scale @@ -2553,6 +2561,10 @@ Consider saving your work before application crash STB_SCALE Scale Transform + + STB_DUPLICATE_NODES + Duplicate Nodes + STB_TRANSP Transparency @@ -3071,6 +3083,10 @@ Consider saving your work before application crash TOP_SCALE Scale Transform + + TOP_DUPLICATE_NODES + Duplicate Nodes + TOP_TRANSP Transparency @@ -5211,4 +5227,47 @@ It is impossible to read point coordinates from file No planes + + SMESHGUI_DuplicateNodesDlg + + DUPLICATION_MODE + Duplication mode + + + DUPLICATION_WITHOUT_ELEMS + Without duplication of border elements + + + GROUP_NODES_TO_DUPLICATE + Group of nodes to duplicate + + + GROUP_NODES_TO_REPLACE + Group of elements to replace nodes with new ones + + + DUPLICATION_WITH_ELEMS + With duplication of border elements + + + GROUP_ELEMS_TO_DUPLICATE + Group of elements to duplicate + + + GROUP_NODES_NOT_DUPLICATE + Group of nodes not to duplicate + + + GROUP_ELEMS_TO_REPLACE + Group of elements to replace nodes with new ones + + + CONSTRUCT_NEW_GROUP_NODES + Construct group with newly created nodes + + + CONSTRUCT_NEW_GROUP_ELEMENTS + Construct group with newly created elements + + diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index eefc4372c..6eda92776 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -4469,6 +4469,46 @@ void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPytho } } +//================================================================================ +/*! + \brief Generates the unique group name. + \param thePrefix name prefix + \return unique name +*/ +//================================================================================ +string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix) +{ + SMESH::ListOfGroups_var groups = myMesh_i->GetGroups(); + set groupNames; + + // Get existing group names + for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = groups[i]; + if (CORBA::is_nil(aGroup)) + continue; + + groupNames.insert(aGroup->GetName()); + } + + // Find new name + string name = thePrefix; + int index = 0; + + while (!groupNames.insert(name).second) { + if (index == 0) { + name += "_1"; + } + else { + TCollection_AsciiString nbStr(index+1); + name.resize( name.rfind('_')+1 ); + name += nbStr.ToCString(); + } + ++index; + } + + return name; +} + //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements @@ -4564,6 +4604,53 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( return done; } +/*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup(), but returns a new group with newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ +SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, + SMESH::SMESH_GroupBase_ptr theModifiedElems ) +{ + if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE ) + return false; + + SMESH::SMESH_Group_var aNewGroup; + + // Duplicate nodes + SMESH::long_array_var aNodes = theNodes->GetListOfID(); + SMESH::long_array_var aModifiedElems; + if ( !CORBA::is_nil( theModifiedElems ) ) + aModifiedElems = theModifiedElems->GetListOfID(); + else { + aModifiedElems = new SMESH::long_array; + aModifiedElems->length( 0 ); + } + + bool aResult = DoubleNodes( aNodes, aModifiedElems ); + + if ( aResult ) { + myMesh->SetIsModified( true ); + + // Create group with newly created nodes + SMESH::long_array_var anIds = GetLastCreatedNodes(); + if (anIds->length() > 0) { + string anUnindexedName (theNodes->GetName()); + string aNewName = generateGroupName(anUnindexedName + "_double"); + aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); + aNewGroup->Add(anIds); + } + } + + // Update Python script + TPythonDump() << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", " + << theModifiedElems << " )"; + return aNewGroup._retn(); +} + //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements @@ -4756,6 +4843,60 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_pt return aResult; } +/*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ +SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems) +{ + if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) + return false; + + SMESH::SMESH_Group_var aNewGroup; + + initData(); + + ::SMESH_MeshEditor aMeshEditor( myMesh ); + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + groupToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + groupToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + groupToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All ); + + + bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( aMeshEditor) ; + + if ( aResult ) { + myMesh->SetIsModified( true ); + + // Create group with newly created elements + SMESH::long_array_var anIds = GetLastCreatedElems(); + if (anIds->length() > 0) { + SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true); + string anUnindexedName (theElems->GetName()); + string aNewName = generateGroupName(anUnindexedName + "_double"); + aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str()); + aNewGroup->Add(anIds); + } + } + + // Update Python script + TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", " + << theNodesNot << ", " << theAffectedElems << " )"; + return aNewGroup._retn(); +} + //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index f5bebdc0a..281394374 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -552,6 +552,17 @@ public: CORBA::Boolean DoubleNodeGroup( SMESH::SMESH_GroupBase_ptr theNodes, SMESH::SMESH_GroupBase_ptr theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup(), but returns a new group with newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ + SMESH::SMESH_Group_ptr DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, + SMESH::SMESH_GroupBase_ptr theModifiedElems ); + CORBA::Boolean DoubleNodeGroups( const SMESH::ListOfGroups& theNodes, const SMESH::ListOfGroups& theModifiedElems); @@ -596,6 +607,20 @@ public: CORBA::Boolean DoubleNodeElemGroup( SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theNodesNot, SMESH::SMESH_GroupBase_ptr theAffectedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ + SMESH::SMESH_Group_ptr DoubleNodeElemGroupNew( SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems ); /*! * \brief Creates a hole in a mesh by doubling the nodes of some particular elements @@ -737,6 +762,8 @@ public: void DumpGroupsList(SMESH::TPythonDump & theDumpPython, const SMESH::ListOfGroups * theGroupList); + string generateGroupName(const string& thePrefix); + private: //!< fields SMESH_Mesh_i* myMesh_i; diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index 5586b0d14..d8e0dde74 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -3694,6 +3694,16 @@ class Mesh: # @ingroup l2_modif_edit def DoubleNodeGroup(self, theNodes, theModifiedElems): return self.editor.DoubleNodeGroup(theNodes, theModifiedElems) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # Works as DoubleNodeGroup() described above, but returns a new group with + # newly created nodes. + # @param theNodes group of nodes to be doubled + # @param theModifiedElems group of elements to be updated. + # @return a new group with newly created nodes + # @ingroup l2_modif_edit + def DoubleNodeGroupNew(self, theNodes, theModifiedElems): + return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems) ## Creates a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. @@ -3736,6 +3746,18 @@ class Mesh: # @ingroup l2_modif_edit def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems): return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems) + + ## Creates a hole in a mesh by doubling the nodes of some particular elements + # Works as DoubleNodeElemGroup() described above, but returns a new group with + # newly created elements. + # @param theElems - group of of elements (edges or faces) to be replicated + # @param theNodesNot - group of nodes not to replicated + # @param theAffectedElems - group of elements to which the replicated nodes + # should be associated to. + # @return a new group with newly created elements + # @ingroup l2_modif_edit + def DoubleNodeElemGroupNew(self, theElems, theNodesNot, theAffectedElems): + return self.editor.DoubleNodeElemGroupNew(theElems, theNodesNot, theAffectedElems) ## Creates a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above.