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:
+
+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"
+
+Check in the dialog box one of two radio buttons corresponding to
+the type of nodes duplication operation you would like to perform.
+Fill the other fields available in the dialog box (depends on the chosen
+ operation mode).
+Click the \b Apply or Apply and Close button to perform the operation of nodes
+ duplication.
+
+
+\n "Duplicate Nodes" dialog has two working modes:
+
+\ref mode_without_elem_anchor "Without the duplication of border elements"
+\ref mode_with_elem_anchor "With the duplication of border elements"
+
+
+
+\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:
+
+Group of nodes to duplicate (mandatory ): these nodes will be duplicated.
+Group of elements to replace nodes with new ones (optional ): the duplicated nodes
+ will be associated with these elements.
+Construct group with newly created nodes option (checked by default ):
+ if checked - the group with just created nodes will be builded.
+
+
+
+\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:
+
+Group of elements to duplicate (mandatory ): these elements will be duplicated.
+Group of nodes at not to duplicate (optional ): group of nodes at crack bottom
+ which will not be duplicated.
+Group of elements to replace nodes with new ones (mandatory ): the duplicated nodes
+ will be associated with these elements.
+Construct group with newly created elements option (checked by default ):
+ if checked - the group with just created elements will be builded.
+
+
+
+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.