Salome HOME
Fix for imp 0020876: EDF 1246 SMESH: DoubleNodes fonctions available in the GUI.
authormzn <mzn@opencascade.com>
Mon, 30 Aug 2010 10:57:47 +0000 (10:57 +0000)
committermzn <mzn@opencascade.com>
Mon, 30 Aug 2010 10:57:47 +0000 (10:57 +0000)
20 files changed:
doc/salome/gui/SMESH/images/duplicate01.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/duplicate02.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/duplicate_nodes.png [new file with mode: 0644]
doc/salome/gui/SMESH/input/double_nodes_page.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/modifying_meshes.doc
doc/salome/gui/SMESH/input/tui_transforming_meshes.doc
idl/SMESH_MeshEditor.idl
resources/Makefile.am
resources/mesh_duplicate_nodes.png [new file with mode: 0644]
resources/mesh_duplicate_nodes_with_elem.png [new file with mode: 0644]
src/SMESHGUI/Makefile.am
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI.h
src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESH_images.ts
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_SWIG/smeshDC.py

diff --git a/doc/salome/gui/SMESH/images/duplicate01.png b/doc/salome/gui/SMESH/images/duplicate01.png
new file mode 100644 (file)
index 0000000..b35c778
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 (file)
index 0000000..1b5cfab
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 (file)
index 0000000..61ff32b
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 (file)
index 0000000..eb41ee7
--- /dev/null
@@ -0,0 +1,67 @@
+/*!
+
+\page double_nodes_page Duplicating Nodes
+
+\n This operation allows to duplicate nodes of your mesh.
+
+<em>To duplicate nodes:</em>
+<ol>
+<li>From the \b Modification menu choose \b Transformation -> \b Duplicate
+\b Nodes item or click <em>"Duplicate Nodes"</em> button in the toolbar.
+<br>
+\image html duplicate_nodes.png "Duplicate Nodes button"
+</li>
+<li>Check in the dialog box one of two radio buttons corresponding to
+the type of nodes duplication operation you would like to perform.</li>
+<li>Fill the other fields available in the dialog box (depends on the chosen
+ operation mode).</li>
+<li>Click the \b Apply or <b>Apply and Close</b> button to perform the operation of nodes
+ duplication.</li>
+</ol>
+
+\n "Duplicate Nodes" dialog has two working modes:
+<ul>
+<li>\ref mode_without_elem_anchor "Without the duplication of border elements"</li>
+<li>\ref mode_with_elem_anchor "With the duplication of border elements"</li>
+</ul>
+
+<br>
+\anchor mode_without_elem_anchor
+<h2>Without duplication of border elements</h2>
+
+In this mode the dialog looks like:
+
+\image html duplicate01.png
+
+Parameters to be defined in this mode:
+<ol>
+<li><b>Group of nodes to duplicate</b> (<em>mandatory</em>): these nodes will be duplicated.</li>
+<li><b>Group of elements to replace nodes with new ones</b> (<em>optional</em>): the duplicated nodes
+ will be associated with these elements.</li>
+<li><b>Construct group with newly created nodes</b> option (<em>checked by default</em>): 
+ if checked - the group with just created nodes will be builded.</li>
+</ol>
+
+<br>
+\anchor mode_with_elem_anchor
+<h2>With duplication of border elements</h2>
+
+In this mode the dialog looks like:
+
+\image html duplicate02.png
+
+Parameters to be defined in this mode:
+<ol>
+<li><b>Group of elements to duplicate</b> (<em>mandatory</em>): these elements will be duplicated.</li>
+<li><b>Group of nodes at not to duplicate</b> (<em>optional</em>): group of nodes at crack bottom
+ which will not be duplicated.</li>
+<li><b>Group of elements to replace nodes with new ones</b> (<em>mandatory</em>): the duplicated nodes
+ will be associated with these elements.</li>
+<li><b>Construct group with newly created elements</b> option (<em>checked by default</em>): 
+ if checked - the group with just created elements will be builded.</li>
+</ol>
+
+
+<br><b>See Also</b> a sample TUI Script of a \ref tui_duplicate_nodes "Duplicate nodes" operation.  
+
+*/
index b086cf915bb7223bcc7ce1d070939163fe93e60a..8d5875a9c2fc2c6b18c5af487143e783b1dbaab2 100644 (file)
@@ -45,6 +45,7 @@ of the selected node or edge.</li>
 <li>Apply \subpage pattern_mapping_page "pattern mapping".</li>
 <li>\subpage convert_to_from_quadratic_mesh_page "Convert regular mesh to quadratic", 
 or vice versa.</li>
+<li>Create \subpage double_nodes_page "double nodes".</li>
 <li>\subpage make_2dmesh_from_3d_page "Create 2D mesh from 3D".</li>
 
 </ul>
index c55b2a492852c870a3d786873bc38a01b8427629..25f5a7ec8f19aecc39f78dc063de8bf23ff026ef 100644 (file)
@@ -350,4 +350,73 @@ mesh.Compute()
 mesh.SewSideElements([69, 70, 71, 72], [91, 92, 89, 90], 8, 38, 23, 58)
 \endcode
 
+<br>
+\anchor tui_duplicate_nodes
+<h3>Duplicate nodes</h3>
+
+\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
+
 */
index 0038beee7e5a63fbf58fca2d8a170856a69106e1..2fc9ae303c9a0fc6d58952b61bb4e742b28ade8a 100644 (file)
@@ -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.
index d3407f02e682226f2d4a5dcc8a76ed274f4ec9ce..ed3f5aff7f32166ccacfab60e107025e13f5191f 100644 (file)
@@ -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 (file)
index 0000000..0f800f7
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 (file)
index 0000000..7a313aa
Binary files /dev/null and b/resources/mesh_duplicate_nodes_with_elem.png differ
index c96383c3e4d390edc68b9e9e8bc14f264e9585db..031665392261d668eb5c3eecae5519313f4f016e 100644 (file)
@@ -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 \
index 088574558b99d90921b3fccb5ed228004cec016a..ee07cc36ffc2855548ab7d21b6bee141f54c403c 100644 (file)
@@ -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<int> 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 );
index 0099a20bde8d21b9e66304cf128dbe1e0abb291c..d901ea68cee82e0cbcb394d37a2380b727eeee48 100644 (file)
@@ -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 (file)
index 0000000..c817323
--- /dev/null
@@ -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 <SMESH_TypeFilter.hxx>
+
+// SALOME GUI includes
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+
+#include <SalomeApp_Tools.h>
+
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIO.hxx>
+
+// Qt includes
+#include <QApplication>
+#include <QButtonGroup>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QKeyEvent>
+
+#include <utilities.h>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#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<SMESH::SMESH_GroupBase>(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 (file)
index 0000000..974b7d7
--- /dev/null
@@ -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 <QDialog>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#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
index 95a9c6881c456bffed61d6bdc455bf6af9d9b2a0..c22f4e96e906a5d232333e2a101e99d4035214da 100644 (file)
             <source>ICON_DLG_SCALE_ALONG_AXES</source>
             <translation>scale_along_axes.png</translation>
         </message>
+       <message>
+            <source>ICON_SMESH_DUPLICATE_NODES</source>
+            <translation>mesh_duplicate_nodes.png</translation>
+        </message>
+       <message>
+            <source>ICON_SMESH_DUPLICATE_NODES_WITH_ELEM</source>
+            <translation>mesh_duplicate_nodes_with_elem.png</translation>
+        </message>
         <message>
             <source>ICON_SMESH_TREE_ALGO</source>
             <translation>mesh_tree_algo.png</translation>
index 00d0f4ca9d4dffcbaed032eeed08456202325a95..111042c822ac9a18cb87a91942f6c0a9abdc2474 100644 (file)
             <source>MEN_SCALE</source>
             <translation>Scale Transform</translation>
         </message>
+       <message>
+            <source>MEN_DUPLICATE_NODES</source>
+            <translation>Duplicate Nodes</translation>
+        </message>
         <message>
             <source>MEN_TRANSF</source>
             <translation>Transformation</translation>
@@ -1949,6 +1953,10 @@ add the exported data to its contents?</translation>
             <source>SMESH_SCALE_TITLE</source>
             <translation>Scale Transform</translation>
         </message>
+       <message>
+            <source>SMESH_DUPLICATE_TITLE</source>
+            <translation>Duplicate Nodes</translation>
+        </message>
         <message>
             <source>SMESH_SCALE</source>
             <translation>Scale</translation>
@@ -2553,6 +2561,10 @@ Consider saving your work before application crash</translation>
             <source>STB_SCALE</source>
             <translation>Scale Transform</translation>
         </message>
+       <message>
+            <source>STB_DUPLICATE_NODES</source>
+            <translation>Duplicate Nodes</translation>
+        </message>
         <message>
             <source>STB_TRANSP</source>
             <translation>Transparency</translation>
@@ -3071,6 +3083,10 @@ Consider saving your work before application crash</translation>
             <source>TOP_SCALE</source>
             <translation>Scale Transform</translation>
         </message>
+       <message>
+            <source>TOP_DUPLICATE_NODES</source>
+            <translation>Duplicate Nodes</translation>
+        </message>
         <message>
             <source>TOP_TRANSP</source>
             <translation>Transparency</translation>
@@ -5211,4 +5227,47 @@ It is impossible to read point coordinates from file</translation>
             <translation>No planes</translation>
         </message>
     </context>
+    <context>
+        <name>SMESHGUI_DuplicateNodesDlg</name>
+        <message>
+            <source>DUPLICATION_MODE</source>
+            <translation>Duplication mode</translation>
+        </message>
+       <message>
+            <source>DUPLICATION_WITHOUT_ELEMS</source> 
+            <translation>Without duplication of border elements</translation>
+        </message>
+       <message>
+            <source>GROUP_NODES_TO_DUPLICATE</source>
+            <translation>Group of nodes to duplicate</translation>
+        </message>
+       <message>
+            <source>GROUP_NODES_TO_REPLACE</source>
+            <translation>Group of elements to replace nodes with new ones</translation>
+        </message>
+       <message>
+            <source>DUPLICATION_WITH_ELEMS</source>    
+            <translation>With duplication of border elements</translation>
+        </message>
+       <message>
+            <source>GROUP_ELEMS_TO_DUPLICATE</source>
+            <translation>Group of elements to duplicate</translation>
+        </message>
+       <message>
+            <source>GROUP_NODES_NOT_DUPLICATE</source>
+            <translation>Group of nodes not to duplicate</translation>
+        </message>
+       <message>
+            <source>GROUP_ELEMS_TO_REPLACE</source>
+            <translation>Group of elements to replace nodes with new ones</translation>
+        </message>
+       <message>
+            <source>CONSTRUCT_NEW_GROUP_NODES</source>
+            <translation>Construct group with newly created nodes</translation>
+        </message>
+       <message>
+            <source>CONSTRUCT_NEW_GROUP_ELEMENTS</source>
+            <translation>Construct group with newly created elements</translation>
+        </message>
+    </context>
 </TS>
index eefc4372c624c13ddf579221cc1df2078447c83b..6eda92776599c25724e157fb35e79d3bc6b6c036 100644 (file)
@@ -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<string> 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
index f5bebdc0a9983bb74133a24cec7451d94853fec3..281394374ee712c3be6c14d5de83d39ba9d63f7c 100644 (file)
@@ -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;
index 5586b0d1499a041870e52b0d0bc1afdee927bb6b..d8e0dde74de2a9e09b1a6f37a74232e8169031e9 100644 (file)
@@ -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.