Salome HOME
IMP 22635: EDF 8345 - Creation of group based on groups
authoreap <eap@opencascade.com>
Tue, 3 Mar 2015 12:03:38 +0000 (15:03 +0300)
committereap <eap@opencascade.com>
Tue, 3 Mar 2015 12:03:38 +0000 (15:03 +0300)
+ allow concatenating sub-meshes and groups
+ fix bugs in PythonDump

29 files changed:
doc/salome/examples/creating_meshes_ex07.py
doc/salome/examples/grouping_elements_ex08.py
doc/salome/gui/SMESH/images/buildcompound.png [changed mode: 0755->0644]
doc/salome/gui/SMESH/images/buildcompound_groups.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/dimgroup_2d.png
doc/salome/gui/SMESH/images/dimgroup_dlg.png
doc/salome/gui/SMESH/images/image160.gif [changed mode: 0755->0644]
doc/salome/gui/SMESH/input/about_meshes.doc
doc/salome/gui/SMESH/input/building_compounds.doc
doc/salome/gui/SMESH/input/group_of_underlying_elements.doc
idl/SMESH_Gen.idl
idl/SMESH_Mesh.idl
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESHDS/SMESHDS_Group.cxx
src/SMESHDS/SMESHDS_Group.hxx
src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx
src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h
src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx
src/SMESHGUI/SMESHGUI_GroupOpDlg.h
src/SMESHGUI/SMESH_msg_en.ts
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Gen_i.hxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Mesh_i.hxx
src/SMESH_SWIG/smeshBuilder.py

index 65a4f74..3b00396 100644 (file)
@@ -1,5 +1,4 @@
 # Building a compound of meshes
-# Note: it is a copy of 'SMESH_BuildCompound.py' from SMESH_SWIG
 
 import salome
 salome.salome_init()
@@ -69,11 +68,14 @@ Gsup2=Mesh_sup.Group(Fsup2, "Sup")
 Ginf2=Mesh_sup.Group(Finf2, "Inf")
 
 ## create compounds
-# create a compound of two meshes with renaming groups with the same names and
+# create a compound of two meshes with renaming namesake groups and
 # merging of elements with the given tolerance
-Compound1 = smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 0, 1, 1e-05)
-smesh.SetName(Compound1, 'Compound_with_RenamedGrps_and_MergeElems')
-# create a compound of two meshes with uniting groups with the same names and
+Compound1 = smesh.Concatenate([Mesh_inf, Mesh_sup], 0, 1, 1e-05,
+                              name='Compound_with_RenamedGrps_and_MergeElems')
+# create a compound of two meshes with uniting namesake groups and
 # creating groups of all elements
-Compound2 = smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 1, 0, 1e-05, True)
-smesh.SetName(Compound2, 'Compound_with_UniteGrps_and_GrpsOfAllElems')
+Compound2 = smesh.Concatenate([Mesh_inf, Mesh_sup], 1, 0, 1e-05, True,
+                              name='Compound_with_UniteGrps_and_GrpsOfAllElems')
+
+if salome.sg.hasDesktop():
+    salome.sg.updateObjBrowser(1)
index fa78d72..92dd71c 100644 (file)
@@ -1,4 +1,4 @@
-# Creating groups of entities from existing groups of superior dimensions
+# Creating groups of entities basing on nodes of other groups
 
 import SMESH_mechanic
 import SMESH
@@ -10,22 +10,17 @@ salome = SMESH_mechanic.salome
 # Criterion : AREA > 100
 aFilter = smesh.GetFilter(SMESH.FACE, SMESH.FT_Area, SMESH.FT_MoreThan, 100.)
 
-anIds = mesh.GetIdsFromFilter(aFilter)
-
-print "Criterion: Area > 100, Nb = ", len(anIds) 
-
 # create a group by adding elements with area > 100
-aSrcGroup1 = mesh.MakeGroupByIds("Area > 100", SMESH.FACE, anIds)
+aSrcGroup1 = mesh.GroupOnFilter(SMESH.FACE, "Area > 100", aFilter)
+print "Criterion: Area > 100, Nb = ", aSrcGroup1.Size()
 
 # Criterion : AREA < 30
 aFilter = smesh.GetFilter(SMESH.FACE, SMESH.FT_Area, SMESH.FT_LessThan, 30.)
 
-anIds = mesh.GetIdsFromFilter(aFilter)
-
-print "Criterion: Area < 30, Nb = ", len(anIds) 
-
 # create a group by adding elements with area < 30
-aSrcGroup2 = mesh.MakeGroupByIds("Area < 30", SMESH.FACE, anIds)
+aSrcGroup2 = mesh.GroupOnFilter(SMESH.FACE, "Area < 30", aFilter)
+print "Criterion: Area < 30, Nb = ", aSrcGroup2.Size()
+
 
 # Create group of edges using source groups of faces
 aGrp = mesh.CreateDimGroup( [aSrcGroup1, aSrcGroup2], SMESH.EDGE, "Edges" )
old mode 100755 (executable)
new mode 100644 (file)
index a618351..d3534fe
Binary files a/doc/salome/gui/SMESH/images/buildcompound.png and b/doc/salome/gui/SMESH/images/buildcompound.png differ
diff --git a/doc/salome/gui/SMESH/images/buildcompound_groups.png b/doc/salome/gui/SMESH/images/buildcompound_groups.png
new file mode 100644 (file)
index 0000000..ee12892
Binary files /dev/null and b/doc/salome/gui/SMESH/images/buildcompound_groups.png differ
index 6ca49a6..bbfa059 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/dimgroup_2d.png and b/doc/salome/gui/SMESH/images/dimgroup_2d.png differ
index 21cdb05..22bdbc6 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/dimgroup_dlg.png and b/doc/salome/gui/SMESH/images/dimgroup_dlg.png differ
old mode 100755 (executable)
new mode 100644 (file)
index 6baffdb..5aff389
Binary files a/doc/salome/gui/SMESH/images/image160.gif and b/doc/salome/gui/SMESH/images/image160.gif differ
index a69bd12..ebab52e 100644 (file)
@@ -65,7 +65,7 @@ the <a href="http://www.code-aster.org/outils/med/html/connectivites.html">
 the element basing on elements of lower dimension is NOT supported.
 
 \anchor mesh_entities
-The mesh can include the following entities:
+The mesh can include the following entities (also referred as \a elements):
 <ul>
 <li>\b Node &mdash; an entity of a mesh defining a position in 3D
   space with coordinates (x, y, z).</li>
index 8a89df1..fb48fdb 100644 (file)
@@ -1,13 +1,15 @@
 /*!
 
-\page building_compounds_page Building Compounds
+\page building_compounds_page Building Compound Meshes
 
 \n Compound Mesh is a combination of several meshes. All elements and
 groups present in input meshes are present in the compound
 mesh. Neither geometry nor hypotheses of initial meshes are used by
-the compound mesh.
+the compound mesh. No link between input meshes and a compound mesh is
+supported, so that modification of an input mesh does not lead to
+update of the compound mesh.
 
-<em>To Build a compound:</em>
+<em>To Build a compound mesh:</em>
 
 \par
 From the \b Mesh menu select <b>Build Compound</b> or click <em>"Build
@@ -24,23 +26,25 @@ The following dialog box will appear:
 \par
 <ul>
   <li>\b Name - allows selecting the name of the resulting \b Compound mesh.</li>
-  <li>\b Meshes - allows selecting the meshes which will be
-    concatenated. They can be chosen in the Object Browser while holding
-\b Ctrl button.</li>
+  <li><b>Meshes, sub-meshes, groups</b> - allows selecting the meshes,
+    sub-meshes and groups which will be concatenated. They can be
+    chosen in the Object Browser while holding \b Ctrl button.</li>
   <li><b>Processing identical groups</b> - allows selecting the method
-    of processing the namesake groups existing in the united meshes.
-\n They can be either</li>
-  <ul>
-    <li>\b United - all elements of Group1 of Mesh_1 and Group1 of Mesh_2
-      become the elements of Group1 of the Compound_Mesh, or</li>
-    <li>\b Renamed - Group1 of Mesh_1 becomes Group1_1 and Group1 of Mesh_2
-      becomes Group1_2.</li>
-  </ul>
-  See \ref grouping_elements_page "Creating Groups" for more information
-  about groups.
-  <li><b>Create common groups for initial meshes</b> check-box permits to
+    of processing the namesake groups existing in the input meshes.
+    They can be either <ul>
+      <li>\b United - all elements of Group1 of Mesh_1 and Group1 of Mesh_2
+        become the elements of Group1 of the Compound_Mesh, or</li>
+      <li>\b Renamed - Group1 of Mesh_1 becomes Group1_1 and Group1 of Mesh_2
+        becomes Group1_2.</li>
+    </ul>
+    See \ref grouping_elements_page "Creating Groups" for more information
+    about groups.</li>
+  <li><b>Create groups from input objects</b> check-box permits to
     automatically create groups corresponding to every initial mesh.
-  </li>
+
+\image html buildcompound_groups.png "Groups created from input meshes 'Box_large' and 'Box_small'"
+
+  <p></li>
   <li>You can choose to additionally
     \ref merging_nodes_page "Merge coincident nodes" 
     \ref merging_elements_page "and elements" in the compound mesh, in
index a6a1b91..e24cebd 100755 (executable)
@@ -1,22 +1,39 @@
 /*!
 
-\page group_of_underlying_elements_page Create Group of Underlying Elements
+\page group_of_underlying_elements_page Group Based on Nodes of Other Groups
 
 
-To create groups of entities from existing groups of superior dimensions, in the \b Mesh menu select <b>Group of underlying entities</b>.<br>
+To create a standalone group of entities basing on nodes of existing
+reference groups, in the \b Mesh menu select <b>Group of underlying entities</b>.
 
 The following dialog box will appear:
 
 \image html dimgroup_dlg.png
 
-In this dialog box specify the name of the resulting group, types of entities and set of source groups.
-
-In the figure below, there are two source Volume groups:
+In this dialog box specify <ul>
+  <li> the resulting <b>Group name</b>, </li>
+  <li> the <b>Elements Type</b> of entities of the resulting group,</li>
+  <li> the criterion of inclusion of a mesh entity to the result group,
+    which is <b>Number of common nodes</b> of the entity and the
+    reference groups: <ul>
+      <li>\b All - include if all nodes are common;</li>
+      <li>\b Main - include if all corner nodes are common (meaningful for
+        a quadratic mesh) </li>
+      <li><b>At least one</b> - include if one or more node is common</li>
+      <li>\b Majority - include if half of nodes or more is common</li></ul>
+  </li>
+  <li> select reference groups,</li>
+  <li> <b>Include underlying entities only</b> option if activated
+  allows inclusion of an entity provided that it is based on nodes of
+  one element of a reference group.</li>
+</ul>
+
+In the figure below, there are two reference Volume groups:
 
 \image html dimgroup_src.png
-<center>Source groups</center>
+<center>Reference groups</center>
 
-In this case the following results for Faces, Edges and Nodes are obtained: 
+In this case the following results for Faces, Edges and Nodes are obtained:
 
 \image html dimgroup_2d.png
 <center>Faces</center>
@@ -27,8 +44,8 @@ In this case the following results for Faces, Edges and Nodes are obtained:
 \image html dimgroup_0d.png
 <center>Nodes</center>
 
-<b>See Also</b> a sample TUI Script of a 
-\ref tui_create_dim_group "Creating groups of entities from existing groups of superior dimensions"
+<b>See Also</b> a sample TUI Script of a
+\ref tui_create_dim_group "Creating groups basing on nodes of other groups"
 operation.
 
 */
index 3a3cb2d..ef96258 100644 (file)
@@ -276,16 +276,16 @@ module SMESH
       raises ( SALOME::SALOME_Exception );
 
     /*!
-     * Concatenate the given meshes into one mesh.
+     * Concatenate the given meshes or groups into one mesh.
      * Union groups with the same name and type if
      * theUniteIdenticalGroups flag is true.
      * Merge coincident nodes and elements if
      * theMergeNodesAndElements flag is true.
      */
-    SMESH_Mesh Concatenate(in mesh_array theMeshesArray,
-                           in boolean    theUniteIdenticalGroups,
-                           in boolean    theMergeNodesAndElements,
-                           in double     theMergeTolerance)
+    SMESH_Mesh Concatenate(in ListOfIDSources theMeshesArray,
+                           in boolean         theUniteIdenticalGroups,
+                           in boolean         theMergeNodesAndElements,
+                           in double          theMergeTolerance)
       raises ( SALOME::SALOME_Exception );
 
     /*!
@@ -296,10 +296,10 @@ module SMESH
      * theMergeNodesAndElements flag is true.
      * Create the groups of all elements from initial meshes.
      */
-    SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray,
-                                     in boolean    theUniteIdenticalGroups,
-                                     in boolean    theMergeNodesAndElements,
-                                     in double     theMergeTolerance)
+    SMESH_Mesh ConcatenateWithGroups(in ListOfIDSources theMeshesArray,
+                                     in boolean         theUniteIdenticalGroups,
+                                     in boolean         theMergeNodesAndElements,
+                                     in double          theMergeTolerance)
       raises ( SALOME::SALOME_Exception );
 
     /*!
index aa7b848..bb193bc 100644 (file)
@@ -150,7 +150,8 @@ module SMESH
     Geom_PENTA,
     Geom_HEXAGONAL_PRISM,
     Geom_POLYHEDRA,
-    Geom_BALL
+    Geom_BALL,
+    Geom_LAST
   };
   
   /*!
@@ -253,6 +254,14 @@ module SMESH
   };
 
   /*!
+   * Enumeration for CreateDimGroup()
+   */
+  enum NB_COMMON_NODES_ENUM
+  {
+    ALL_NODES, MAIN, AT_LEAST_ONE, MAJORITY
+  };
+
+  /*!
    * Auxilary flags for advanced extrusion.
    * BOUNDARY: create or not boundary for result of extrusion
    * SEW:      try to use existing nodes or create new nodes in any case
@@ -497,14 +506,21 @@ module SMESH
       raises (SALOME::SALOME_Exception);
       
     /*!
-     *  Create groups of entities from existing groups of superior dimensions 
-     *  New group is created. System 
-     *  1) extracts all nodes from each group,
-     *  2) combines all elements of specified dimension laying on these nodes.
-     */
-    SMESH_Group CreateDimGroup( in ListOfGroups aListOfGroups,
-                                in ElementType  anElemType,
-                                in string       name )
+     *  Create a group of entities basing on nodes of other groups.
+     *  \param [in] aListOfGroups - list of either groups, sub-meshes or filters.
+     *  \param [in] anElemType - a type of elements to include to the new group.
+     *  \param [in] name - a name of the new group.
+     *  \param [in] nbCommonNodes - criterion of inclusion of an element to the new group.
+     *  \param [in] underlyingOnly - if \c True, an element is included to the 
+     *         new group provided that it is based on nodes of an element of
+     *         \a aListOfGroups
+     *  \return SMESH_Group - the created group
+     */
+    SMESH_Group CreateDimGroup( in ListOfIDSources      aListOfGroups,
+                                in ElementType          anElemType,
+                                in string               name,
+                                in NB_COMMON_NODES_ENUM nbCommonNodes,
+                                in boolean              underlyingOnly )
       raises (SALOME::SALOME_Exception);
 
     /*!
index 20aeb54..b3401c6 100644 (file)
@@ -131,7 +131,7 @@ SMESH_MeshEditor::SMESH_MeshEditor( SMESH_Mesh* theMesh )
  */
 //================================================================================
 
-void SMESH_MeshEditor::CrearLastCreated()
+void SMESH_MeshEditor::ClearLastCreated()
 {
   myLastCreatedNodes.Clear();
   myLastCreatedElems.Clear();
@@ -10338,7 +10338,7 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
 
 void SMESH_MeshEditor::DoubleElements( const TIDSortedElemSet& theElements )
 {
-  CrearLastCreated();
+  ClearLastCreated();
   SMESHDS_Mesh* mesh = GetMeshDS();
 
   // get an element type and an iterator over elements
index 4d9f807..23f3977 100644 (file)
@@ -70,7 +70,7 @@ public:
 
   const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; }
   const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; }
-  void                           CrearLastCreated();
+  void                           ClearLastCreated();
   SMESH_ComputeErrorPtr &        GetError() { return myError; }
 
   /*!
index 3f2fa3c..6e30e00 100644 (file)
@@ -98,7 +98,17 @@ bool SMESHDS_Group::Contains (const SMDS_MeshElement* elem)
 
 bool SMESHDS_Group::Add (const int theID)
 {
-  const SMDS_MeshElement* aElem = findInMesh (theID);
+  return Add( findInMesh( theID ));
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool SMESHDS_Group::Add (const SMDS_MeshElement* aElem )
+{
   if (!aElem || myGroup.Contains(aElem))
     return false;
 
index 366f53a..08ff29b 100644 (file)
@@ -60,6 +60,8 @@ class SMESHDS_EXPORT SMESHDS_Group : public SMESHDS_GroupBase
 
   bool Add (const int theID);
 
+  bool Add (const SMDS_MeshElement* theElem );
+
   bool Remove (const int theID);
 
   void Clear();
index 9b440ea..90f42ee 100644 (file)
@@ -200,11 +200,11 @@ void SMESHGUI_BuildCompoundDlg::Init()
 {
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
 
-  myMesh = SMESH::SMESH_Mesh::_nil();
+  myMesh = SMESH::SMESH_IDSource::_nil();
 
-  myMeshFilter = new SMESH_TypeFilter (SMESH::MESH);
+  myMeshFilter = new SMESH_TypeFilter (SMESH::IDSOURCE);
 
-  myMeshArray = new SMESH::mesh_array();
+  myMeshArray = new SMESH::ListOfIDSources();
 
   // signals and slots connections
   connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
@@ -289,7 +289,7 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
   if (!isValid())
     return false;
 
-  SMESH::SMESH_Mesh_var aCompoundMesh;
+  SMESH::SMESH_Mesh_var aMesh;
 
   if (!myMesh->_is_nil())
   {
@@ -300,22 +300,23 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
     try {
       SUIT_OverrideCursor aWaitCursor;
 
-      myMeshArray[0]->SetParameters( aParameters.join(":").toLatin1().constData() );
+      aMesh = myMeshArray[0]->GetMesh();
+      aMesh->SetParameters( aParameters.join(":").toLatin1().constData() );
 
       SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
       // concatenate meshes
       if(CheckBoxCommon->isChecked())
-        aCompoundMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray,
-                                                         !(ComboBoxUnion->currentIndex()),
-                                                         CheckBoxMerge->isChecked(),
-                                                         SpinBoxTol->GetValue());
+        aMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray,
+                                                 !(ComboBoxUnion->currentIndex()),
+                                                 CheckBoxMerge->isChecked(),
+                                                 SpinBoxTol->GetValue());
       else
-        aCompoundMesh = aSMESHGen->Concatenate(myMeshArray,
-                                               !(ComboBoxUnion->currentIndex()),
-                                               CheckBoxMerge->isChecked(),
-                                               SpinBoxTol->GetValue());
+        aMesh = aSMESHGen->Concatenate(myMeshArray,
+                                       !(ComboBoxUnion->currentIndex()),
+                                       CheckBoxMerge->isChecked(),
+                                       SpinBoxTol->GetValue());
 
-      _PTR(SObject) aSO = SMESH::FindSObject( aCompoundMesh );
+      _PTR(SObject) aSO = SMESH::FindSObject( aMesh );
       if( aSO ) {
         SMESH::SetName( aSO, LineEditName->text() );
         anEntryList.append( aSO->GetID().c_str() );
@@ -332,7 +333,7 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
       mySelectionMgr->clearSelected();
       SMESH::UpdateView();
 
-      _PTR(SObject) aSO = SMESH::FindSObject(aCompoundMesh.in());
+      _PTR(SObject) aSO = SMESH::FindSObject(aMesh.in());
       if ( SMESH_Actor* anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str()) ) {
         SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor);
         SMESH::UpdateView();
@@ -412,12 +413,12 @@ void SMESHGUI_BuildCompoundDlg::SelectionIntoArgument()
     for (int i = 0; nbSel != 0; i++, nbSel--) {
       Handle(SALOME_InteractiveObject) IO = aList.First();
       aList.RemoveFirst();
-      myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+      myMesh = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
       myMeshArray[i] = myMesh;
     }
   }
   else {
-    myMesh = SMESH::SMESH_Mesh::_nil();
+    myMesh = SMESH::SMESH_IDSource::_nil();
     aString = "";
   }
 
index 4f17bed..161d218 100644 (file)
@@ -80,9 +80,9 @@ private:
   SMESHGUI*               mySMESHGUI;     /* Current SMESHGUI object */
   LightApp_SelectionMgr*  mySelectionMgr; /* User shape selection */
 
-  SMESH::SMESH_Mesh_var   myMesh;
-  SUIT_SelectionFilter*   myMeshFilter;
-  SMESH::mesh_array_var   myMeshArray;
+  SMESH::SMESH_IDSource_var  myMesh;
+  SUIT_SelectionFilter*      myMeshFilter;
+  SMESH::ListOfIDSources_var myMeshArray;
 
   // Widgets
   QGroupBox*              GroupConstructors;
index 3462495..bfcf318 100644 (file)
 #include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
-
-#include <SMESH_TypeFilter.hxx>
-
-// SALOME GUI includes
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_Desktop.h>
-#include <SUIT_Session.h>
-#include <SUIT_MessageBox.h>
+#include "SMESH_TypeFilter.hxx"
 
 #include <LightApp_Application.h>
 #include <LightApp_SelectionMgr.h>
+#include <QtxColorButton.h>
+#include <SALOMEDSClient_SObject.hxx>
+#include <SALOME_ListIO.hxx>
+#include <SUIT_Desktop.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
 #include <SVTK_Selection.h>
 #include <SVTK_ViewWindow.h>
-#include <SALOME_ListIO.hxx>
-
-// SALOME KERNEL includes
-#include <SALOMEDSClient_SObject.hxx>
 
 // Qt includes
-#include <QHBoxLayout>
-#include <QVBoxLayout>
+#include <QButtonGroup>
+#include <QCheckBox>
+#include <QComboBox>
 #include <QGridLayout>
-#include <QPushButton>
 #include <QGroupBox>
+#include <QHBoxLayout>
+#include <QKeyEvent>
 #include <QLabel>
 #include <QLineEdit>
-#include <QKeyEvent>
 #include <QListWidget>
-#include <QButtonGroup>
-#include <QComboBox>
-#include <QtxColorButton.h>
+#include <QPushButton>
+#include <QVBoxLayout>
 
 #define SPACING 6
 #define MARGIN  11
@@ -110,7 +107,7 @@ QWidget* SMESHGUI_GroupOpDlg::createMainFrame( QWidget* theParent )
   aLay->setSpacing(SPACING);
   
   // ------------------------------------------------------
-  QGroupBox* aNameGrp = new QGroupBox(tr("NAME"), aMainGrp);
+  QGroupBox* aNameGrp = new QGroupBox(tr("RESULT"), aMainGrp);
   QHBoxLayout* aNameGrpLayout = new QHBoxLayout(aNameGrp);
   aNameGrpLayout->setMargin(MARGIN);
   aNameGrpLayout->setSpacing(SPACING);
@@ -312,6 +309,7 @@ bool SMESHGUI_GroupOpDlg::isValid( const QList<SMESH::SMESH_GroupBase_var>& theL
 */
 void SMESHGUI_GroupOpDlg::onOk()
 {
+  SUIT_OverrideCursor oc;
   setIsApplyAndClose( true );
   if ( onApply() )
     reject();
@@ -951,35 +949,55 @@ void SMESHGUI_CutGroupsDlg::onSelectionDone()
   \param theModule module
 */
 SMESHGUI_DimGroupDlg::SMESHGUI_DimGroupDlg( SMESHGUI* theModule )
-: SMESHGUI_GroupOpDlg( theModule )
+  : SMESHGUI_GroupOpDlg( theModule )
 {
   setWindowTitle( tr( "CREATE_GROUP_OF_UNDERLYING_ELEMS" ) );
   setHelpFileName( "group_of_underlying_elements_page.html" );
 
   QGroupBox* anArgGrp = getArgGrp();
 
-  QLabel* aLbl = new QLabel( tr( "ELEMENTS_TYPE" ), anArgGrp );
-  
-  myCombo = new QComboBox( anArgGrp );
-  static QStringList anItems;
-  if ( anItems.isEmpty() )
+  QLabel* aTypeLbl = new QLabel( tr( "ELEMENTS_TYPE" ), anArgGrp );
+
+  myTypeCombo = new QComboBox( anArgGrp );
+  QStringList anItems;
   {
-    anItems.append( tr( "NODE" ) );
-    anItems.append( tr( "EDGE" ) );
-    anItems.append( tr( "FACE" ) );
-    anItems.append( tr( "VOLUME" ) );
+    anItems.append( tr( "MESH_NODE" ) );
+    anItems.append( tr( "SMESH_EDGE" ) );
+    anItems.append( tr( "SMESH_FACE" ) );
+    anItems.append( tr( "SMESH_VOLUME" ) );
+    anItems.append( tr( "SMESH_ELEM0D" ) );
+    anItems.append( tr( "SMESH_BALL" ) );
   }
-  myCombo->addItems( anItems );
-  myCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
-  
+  myTypeCombo->addItems( anItems );
+  myTypeCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
+  QLabel* aNbNoLbl = new QLabel( tr( "NUMBER_OF_COMMON_NODES" ), anArgGrp );
+
+  myNbNoCombo = new QComboBox( anArgGrp );
+  anItems.clear();
+  {
+    anItems.append( tr( "ALL" ) );
+    anItems.append( tr( "MAIN" ) );
+    anItems.append( tr( "AT_LEAST_ONE" ) );
+    anItems.append( tr( "MAJORITY" ) );
+  }
+  myNbNoCombo->addItems( anItems );
+  myNbNoCombo->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+
   myListWg = new QListWidget( anArgGrp );
 
+  myUnderlOnlyChk = new QCheckBox( tr("UNDERLYING_ENTITIES_ONLY"), anArgGrp );
+  myUnderlOnlyChk->setChecked( false );
+
   // layout
   QGridLayout* aLay = new QGridLayout( anArgGrp );
   aLay->setSpacing( SPACING );
-  aLay->addWidget( aLbl, 0, 0 );
-  aLay->addWidget( myCombo, 0, 1 );
-  aLay->addWidget( myListWg, 1, 0, 1, 2 );
+  aLay->addWidget( aTypeLbl,        0, 0 );
+  aLay->addWidget( myTypeCombo,     0, 1 );
+  aLay->addWidget( aNbNoLbl,        1, 0 );
+  aLay->addWidget( myNbNoCombo,     1, 1 );
+  aLay->addWidget( myListWg,        2, 0, 1, 2 );
+  aLay->addWidget( myUnderlOnlyChk, 3, 0 );
 }
 
 /*!
@@ -1007,7 +1025,7 @@ void SMESHGUI_DimGroupDlg::reset()
 */
 SMESH::ElementType SMESHGUI_DimGroupDlg::getElementType() const
 {
-  return (SMESH::ElementType)( myCombo->currentIndex() + 1 );
+  return (SMESH::ElementType)( myTypeCombo->currentIndex() + 1 );
 }
 
 /*!
@@ -1017,7 +1035,7 @@ SMESH::ElementType SMESHGUI_DimGroupDlg::getElementType() const
 */
 void SMESHGUI_DimGroupDlg::setElementType( const SMESH::ElementType& theElemType )
 {
-  myCombo->setCurrentIndex( theElemType - 1 );
+  myTypeCombo->setCurrentIndex( theElemType - 1 );
 }
 
 /*!
@@ -1047,10 +1065,19 @@ bool SMESHGUI_DimGroupDlg::onApply()
   QStringList anEntryList;
   try
   {
-    SMESH::ListOfGroups_var aList = convert( myGroups );
+    SMESH::ListOfIDSources_var aList = new SMESH::ListOfIDSources();
+    aList->length( myGroups.count() );
+    QList<SMESH::SMESH_GroupBase_var>::const_iterator anIter = myGroups.begin();
+    for ( int i = 0; anIter != myGroups.end(); ++anIter, ++i )
+      aList[ i ] = SMESH::SMESH_IDSource::_narrow( *anIter );
+
     SMESH::ElementType anElemType = getElementType();
-    SMESH::SMESH_Group_var aNewGrp = 
-      aMesh->CreateDimGroup( aList, anElemType, aName.toLatin1().constData() );
+    SMESH::NB_COMMON_NODES_ENUM aNbCoNodes =
+      (SMESH::NB_COMMON_NODES_ENUM) myNbNoCombo->currentIndex();
+
+    SMESH::SMESH_Group_var aNewGrp =
+      aMesh->CreateDimGroup( aList, anElemType, aName.toLatin1().constData(),
+                             aNbCoNodes, myUnderlOnlyChk->isChecked() );
     if ( !CORBA::is_nil( aNewGrp ) )
     {
       aNewGrp->SetColor(  getColor() );
@@ -1092,5 +1119,3 @@ void SMESHGUI_DimGroupDlg::onSelectionDone()
   myListWg->clear();
   myListWg->addItems( aNames );
 }
-
-
index 3386c53..4acb868 100644 (file)
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Group)
 
-class QPushButton;
-class QtxColorButton;
+class LightApp_SelectionMgr;
+class QCheckBox;
 class QComboBox;
-class QListWidget;
 class QGroupBox;
 class QLineEdit;
+class QListWidget;
+class QPushButton;
+class QtxColorButton;
 class SMESHGUI;
-class LightApp_SelectionMgr;
 class SVTK_Selector;
 
 /*
@@ -235,8 +236,11 @@ protected slots:
   virtual void                      onSelectionDone();
 
 private:
-  QComboBox*                        myCombo;
+  QComboBox*                        myTypeCombo;
+  QComboBox*                        myNbNoCombo;
   QListWidget*                      myListWg;
+  QCheckBox*                        myUnderlOnlyChk;
+  
   QList<SMESH::SMESH_GroupBase_var> myGroups;
 };
 
index ca99ab6..a33acb1 100644 (file)
     </message>
     <message>
         <source>MEN_UNDERLYING_ELEMS</source>
-        <translation>Group of underlying entities</translation>
+        <translation>Group based on nodes of other groups</translation>
     </message>
     <message>
         <source>MEN_UPDATE</source>
@@ -3398,7 +3398,7 @@ Use Display Entity menu command to show them.
     </message>
     <message>
         <source>STB_UNDERLYING_ELEMS</source>
-        <translation>Create groups of entities from existing groups of superior dimensions</translation>
+        <translation>Create groups of entities basing on nodes of other groups</translation>
     </message>
     <message>
         <source>STB_UPDATE</source>
@@ -4050,7 +4050,7 @@ Use Display Entity menu command to show them.
     </message>
     <message>
         <source>TOP_UNDERLYING_ELEMS</source>
-        <translation>Create groups of entities from existing groups of superior dimensions</translation>
+        <translation>Create groups of entities basing on nodes of other groups</translation>
     </message>
     <message>
         <source>TOP_UPDATE</source>
@@ -4714,7 +4714,7 @@ Please, create VTK viewer and try again</translation>
     </message>
     <message>
         <source>CREATE_COMMON_GROUPS</source>
-        <translation>Create common groups for initial meshes</translation>
+        <translation>Create groups from input objects</translation>
     </message>
     <message>
         <source>MERGE_NODES_AND_ELEMENTS</source>
@@ -4722,7 +4722,7 @@ Please, create VTK viewer and try again</translation>
     </message>
     <message>
         <source>MESHES</source>
-        <translation>Meshes</translation>
+        <translation>Meshes, sub-meshes, groups</translation>
     </message>
     <message>
         <source>PROCESSING_IDENTICAL_GROUPS</source>
@@ -5810,8 +5810,8 @@ Please specify non-empty name and try again</translation>
 Please specify them and try again</translation>
     </message>
     <message>
-        <source>NAME</source>
-        <translation>Name</translation>
+        <source>RESULT</source>
+        <translation>Result</translation>
     </message>
     <message>
         <source>OBJECT_1</source>
@@ -5823,7 +5823,7 @@ Please specify them and try again</translation>
     </message>
     <message>
         <source>RESULT_NAME</source>
-        <translation>Result name</translation>
+        <translation>Group name</translation>
     </message>
     <message>
         <source>TOOL_OBJECT</source>
@@ -5845,27 +5845,35 @@ Please specify them and try again</translation>
     <name>SMESHGUI_DimGroupDlg</name>
     <message>
         <source>CREATE_GROUP_OF_UNDERLYING_ELEMS</source>
-        <translation>Create group of underlying entities</translation>
+        <translation>Group based on nodes of other groups</translation>
     </message>
     <message>
         <source>ELEMENTS_TYPE</source>
         <translation>Elements type</translation>
     </message>
     <message>
-        <source>NODE</source>
-        <translation>Node</translation>
+        <source>UNDERLYING_ENTITIES_ONLY</source>
+        <translation>Include underlying entities only</translation>
     </message>
     <message>
-        <source>EDGE</source>
-        <translation>Edge</translation>
+        <source>NUMBER_OF_COMMON_NODES</source>
+        <translation>Number of common nodes</translation>
     </message>
     <message>
-        <source>FACE</source>
-        <translation>Face</translation>
+        <source>ALL</source>
+        <translation>All</translation>
     </message>
     <message>
-        <source>VOLUME</source>
-        <translation>Volume</translation>
+        <source>MAIN</source>
+        <translation>Main</translation>
+    </message>
+    <message>
+        <source>AT_LEAST_ONE</source>
+        <translation>At least one</translation>
+    </message>
+    <message>
+        <source>MAJORITY</source>
+        <translation>Majority</translation>
     </message>
 </context>
 <context>
index 0924a5c..c680de4 100644 (file)
@@ -888,18 +888,22 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       if ( Type == "SMESH.FT_ElemGeomType" )
       {
         // set SMESH.GeometryType instead of a numerical Threshold
-        const int nbTypes = SMESH::Geom_BALL+1;
+        const int nbTypes = SMESH::Geom_LAST;
         const char* types[nbTypes] = {
           "Geom_POINT", "Geom_EDGE", "Geom_TRIANGLE", "Geom_QUADRANGLE", "Geom_POLYGON",
           "Geom_TETRA", "Geom_PYRAMID", "Geom_HEXA", "Geom_PENTA", "Geom_HEXAGONAL_PRISM",
           "Geom_POLYHEDRA", "Geom_BALL" };
         if ( -1 < iGeom && iGeom < nbTypes )
           Threshold = SMESH + types[ iGeom ];
+#ifdef _DEBUG_
+        // is types complete? (compilation failure mains that enum GeometryType changed)
+        int _assert[( sizeof(types) / sizeof(const char*) == nbTypes ) ? 1 : -1 ];
+#endif
       }
       if (Type == "SMESH.FT_EntityType")
       {
         // set SMESH.EntityType instead of a numerical Threshold
-        const int nbTypes = SMESH::Entity_Ball+1;
+        const int nbTypes = SMESH::Entity_Last;
         const char* types[nbTypes] = {
           "Entity_Node", "Entity_0D", "Entity_Edge", "Entity_Quad_Edge",
           "Entity_Triangle", "Entity_Quad_Triangle", "Entity_BiQuad_Triangle",
@@ -911,6 +915,10 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
           "Entity_Polyhedra", "Entity_Quad_Polyhedra", "Entity_Ball" };
         if ( -1 < iGeom && iGeom < nbTypes )
           Threshold = SMESH + types[ iGeom ];
+#ifdef _DEBUG_
+        // is types complete? (compilation failure mains that enum EntityType changed)
+        int _assert[( sizeof(types) / sizeof(const char*) == nbTypes ) ? 1 : -1 ];
+#endif
       }
     }
     if ( ThresholdID.Length() != 2 ) // neither '' nor ""
index 91a858a..a0d3c0a 100644 (file)
@@ -3790,7 +3790,7 @@ string_array* FilterLibrary_i::GetAllNames()
 
 static const char** getFunctNames()
 {
-  static const char* functName[ SMESH::FT_Undefined + 1 ] = {
+  static const char* functName[] = {
     // IT's necessary to update this array according to enum FunctorType (SMESH_Filter.idl)
     // The order is IMPORTANT !!!
     "FT_AspectRatio",
@@ -3840,6 +3840,13 @@ static const char** getFunctNames()
     "FT_LogicalAND",
     "FT_LogicalOR",
     "FT_Undefined"};
+
+#ifdef _DEBUG_
+  // check if functName is complete, compilation failure mains that enum FunctorType changed
+  const int nbFunctors = sizeof(functName) / sizeof(const char*);
+  int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 1 : -1 ];
+#endif
+
   return functName;
 }
 
index 3b7cc55..715d665 100644 (file)
@@ -2345,10 +2345,11 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
  */
 //================================================================================
 
-SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray,
-                                               CORBA::Boolean           theUniteIdenticalGroups,
-                                               CORBA::Boolean           theMergeNodesAndElements,
-                                               CORBA::Double            theMergeTolerance)
+SMESH::SMESH_Mesh_ptr
+SMESH_Gen_i::Concatenate(const SMESH::ListOfIDSources& theMeshesArray,
+                         CORBA::Boolean                theUniteIdenticalGroups,
+                         CORBA::Boolean                theMergeNodesAndElements,
+                         CORBA::Double                 theMergeTolerance)
   throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
@@ -2368,10 +2369,10 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshe
 //================================================================================
 
 SMESH::SMESH_Mesh_ptr
-SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
-                                   CORBA::Boolean           theUniteIdenticalGroups,
-                                   CORBA::Boolean           theMergeNodesAndElements,
-                                   CORBA::Double            theMergeTolerance)
+SMESH_Gen_i::ConcatenateWithGroups(const SMESH::ListOfIDSources& theMeshesArray,
+                                   CORBA::Boolean                theUniteIdenticalGroups,
+                                   CORBA::Boolean                theMergeNodesAndElements,
+                                   CORBA::Double                 theMergeTolerance)
   throw ( SALOME::SALOME_Exception )
 {
   return ConcatenateCommon(theMeshesArray,
@@ -2390,14 +2391,13 @@ SMESH_Gen_i::ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
 //================================================================================
 
 SMESH::SMESH_Mesh_ptr
-SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
-                               CORBA::Boolean           theUniteIdenticalGroups,
-                               CORBA::Boolean           theMergeNodesAndElements,
-                               CORBA::Double            theMergeTolerance,
-                               CORBA::Boolean           theCommonGroups)
+SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray,
+                               CORBA::Boolean                theUniteIdenticalGroups,
+                               CORBA::Boolean                theMergeNodesAndElements,
+                               CORBA::Double                 theMergeTolerance,
+                               CORBA::Boolean                theCommonGroups)
   throw ( SALOME::SALOME_Exception )
 {
-  typedef map<int, int> TIDsMap;
   typedef list<SMESH::SMESH_Group_var> TListOfNewGroups;
   typedef map< pair<string, SMESH::ElementType>, TListOfNewGroups > TGroupsMap;
 
@@ -2407,304 +2407,262 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
   // create mesh
   SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
 
-  SMESHDS_Mesh* aNewMeshDS = 0;
-  if ( !aNewMesh->_is_nil() ) {
-    SMESH_Mesh_i* aNewImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( aNewMesh ).in() );
-    if ( aNewImpl ) {
-      ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
-      aNewMeshDS = aLocMesh.GetMeshDS();
-
-      TGroupsMap aGroupsMap;
-      TListOfNewGroups aListOfNewGroups;
-      ::SMESH_MeshEditor aNewEditor(&aLocMesh);
-      SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
-
-      // loop on meshes
-      for ( int i = 0; i < theMeshesArray.length(); i++) {
-        SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i];
-        if ( !anInitMesh->_is_nil() ) {
-          SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
-          if ( anInitImpl ) {
-            ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
-            aInitLocMesh.Load();
-            SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
-
-            TIDsMap nodesMap;
-            TIDsMap elemsMap;
-
-            // loop on elements of mesh
-            SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator();
-            const SMDS_MeshElement* anElem = 0;
-            const SMDS_MeshElement* aNewElem = 0;
-            int anElemNbNodes = 0;
-
-            int anNbNodes   = 0;
-            int anNbEdges   = 0;
-            int anNbFaces   = 0;
-            int anNbVolumes = 0;
-            int aNbBalls    = 0;
-
-            SMESH::long_array_var anIDsNodes   = new SMESH::long_array();
-            SMESH::long_array_var anIDsEdges   = new SMESH::long_array();
-            SMESH::long_array_var anIDsFaces   = new SMESH::long_array();
-            SMESH::long_array_var anIDsVolumes = new SMESH::long_array();
-            SMESH::long_array_var anIDsBalls   = new SMESH::long_array();
-
-            if( theCommonGroups ) {
-              anIDsNodes->length(   anInitMeshDS->NbNodes()   );
-              anIDsEdges->length(   anInitMeshDS->NbEdges()   );
-              anIDsFaces->length(   anInitMeshDS->NbFaces()   );
-              anIDsVolumes->length( anInitMeshDS->NbVolumes() );
-              anIDsBalls->length(   anInitMeshDS->NbBalls() );
-            }
+  if ( aNewMesh->_is_nil() )
+    return aNewMesh._retn();
 
-            for ( int j = 0; itElems->more(); j++) {
-              anElem = itElems->next();
-              SMDSAbs_ElementType anElemType = anElem->GetType();
-              anElemNbNodes = anElem->NbNodes();
-              std::vector<const SMDS_MeshNode*> aNodesArray (anElemNbNodes);
-
-              // loop on nodes of element
-              const SMDS_MeshNode* aNode = 0;
-              const SMDS_MeshNode* aNewNode = 0;
-              SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
-
-              for ( int k = 0; itNodes->more(); k++) {
-                aNode = static_cast<const SMDS_MeshNode*>(itNodes->next());
-                if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) {
-                  aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
-                  nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
-                  if( theCommonGroups )
-                    anIDsNodes[anNbNodes++] = aNewNode->GetID();
-                }
-                else
-                  aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second );
-                aNodesArray[k] = aNewNode;
-              }//nodes loop
-
-              // creates a corresponding element on existent nodes in new mesh
-              switch ( anElem->GetEntityType() ) {
-              case SMDSEntity_Polyhedra:
-                if ( const SMDS_VtkVolume* aVolume =
-                     dynamic_cast<const SMDS_VtkVolume*> (anElem))
-                {
-                  aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray,
-                                                             aVolume->GetQuantities());
-                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-                  if( theCommonGroups )
-                    anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
-                }
-                break;
-              case SMDSEntity_Ball:
-                if ( const SMDS_BallElement* aBall =
-                     dynamic_cast<const SMDS_BallElement*> (anElem))
-                {
-                  aNewElem = aNewEditor.AddElement(aNodesArray, SMDSAbs_Ball,
-                                                   /*isPoly=*/false, /*id=*/0,
-                                                   aBall->GetDiameter() );
-                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-                  if( theCommonGroups )
-                    anIDsBalls[aNbBalls++] = aNewElem->GetID();
-                }
-                break;
-              default:
-                {
-                  aNewElem = aNewEditor.AddElement(aNodesArray,
-                                                   anElemType,
-                                                   anElem->IsPoly());
-                  elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
-                  if( theCommonGroups ) {
-                    if( anElemType == SMDSAbs_Edge )
-                      anIDsEdges[anNbEdges++] = aNewElem->GetID();
-                    else if( anElemType == SMDSAbs_Face )
-                      anIDsFaces[anNbFaces++] = aNewElem->GetID();
-                    else if( anElemType == SMDSAbs_Volume )
-                      anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
-                  }
-                }
-              }
-            } //elems loop
+  SMESH_Mesh_i* aNewImpl = SMESH::DownCast<SMESH_Mesh_i*>( aNewMesh );
+  if ( !aNewImpl )
+    return aNewMesh._retn();
 
-            aNewEditor.CrearLastCreated(); // forget the history
+  ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
+  SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS();
 
-            // copy orphan nodes
-            SMDS_NodeIteratorPtr  itNodes = anInitMeshDS->nodesIterator();
-            while ( itNodes->more() )
-            {
-              const SMDS_MeshNode* aNode = itNodes->next();
-              if ( aNode->NbInverseElements() == 0 )
-              {
-                const SMDS_MeshNode* aNewNode =
-                  aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
-                nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
-                if( theCommonGroups )
-                  anIDsNodes[anNbNodes++] = aNewNode->GetID();
-              }
-            }
+  TGroupsMap aGroupsMap;
+  TListOfNewGroups aListOfNewGroups;
+  ::SMESH_MeshEditor aNewEditor(&aLocMesh);
+  SMESH::ListOfGroups_var aListOfGroups;
 
+  std::vector<const SMDS_MeshNode*> aNodesArray;
 
-            aListOfGroups = anInitImpl->GetGroups();
-            SMESH::SMESH_GroupBase_ptr aGroup;
+  // loop on sub-meshes
+  for ( int i = 0; i < theMeshesArray.length(); i++)
+  {
+    SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i]->GetMesh();
+    if ( anInitMesh->_is_nil() ) continue;
+    SMESH_Mesh_i* anInitImpl = SMESH::DownCast<SMESH_Mesh_i*>( anInitMesh );
+    if ( !anInitImpl ) continue;
+    anInitImpl->Load();
+
+    ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
+    SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
+
+    // remember nb of elements before filling in
+    SMESH::long_array_var prevState =  aNewMesh->GetNbElementsByType();
+
+    typedef std::map<const SMDS_MeshElement*, const SMDS_MeshElement*, TIDCompare > TEEMap;
+    TEEMap elemsMap, nodesMap;
+
+    // loop on elements of a sub-mesh
+    SMDS_ElemIteratorPtr itElems = anInitImpl->GetElements( theMeshesArray[i], SMESH::ALL );
+    const SMDS_MeshElement* anElem;
+    const SMDS_MeshElement* aNewElem;
+    const SMDS_MeshNode*    aNode;
+    const SMDS_MeshNode*    aNewNode;
+    int anElemNbNodes;
+
+    while ( itElems->more() )
+    {
+      anElem = itElems->next();
+      anElemNbNodes = anElem->NbNodes();
+      aNodesArray.resize( anElemNbNodes );
 
-            // loop on groups of mesh
-            SMESH::long_array_var anInitIDs = new SMESH::long_array();
-            SMESH::long_array_var anNewIDs = new SMESH::long_array();
-            SMESH::SMESH_Group_var aNewGroup;
+      // loop on nodes of an element
+      SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
+      for ( int k = 0; itNodes->more(); k++)
+      {
+        aNode = static_cast<const SMDS_MeshNode*>( itNodes->next() );
+        TEEMap::iterator n2nnIt = nodesMap.find( aNode );
+        if ( n2nnIt == nodesMap.end() )
+        {
+          aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+          nodesMap.insert( make_pair( aNode, aNewNode ));
+        }
+        else
+        {
+          aNewNode = static_cast<const SMDS_MeshNode*>( n2nnIt->second );
+        }
+        aNodesArray[k] = aNewNode;
+      }
 
-            SMESH::ElementType aGroupType;
-            CORBA::String_var aGroupName;
-            if ( theCommonGroups ) {
-              for(aGroupType=SMESH::NODE;aGroupType<=SMESH::BALL;aGroupType=(SMESH::ElementType)(aGroupType+1)) {
-                string str = "Gr";
-                SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, anInitMesh );
-                if(aMeshSObj)
-                  str += aMeshSObj->GetName();
-                str += "_";
+      // creates a corresponding element on existent nodes in new mesh
+      aNewElem = 0;
+      switch ( anElem->GetEntityType() )
+      {
+      case SMDSEntity_Polyhedra:
+        if ( const SMDS_VtkVolume* aVolume =
+             dynamic_cast<const SMDS_VtkVolume*> (anElem))
+        {
+          aNewElem = aNewMeshDS->AddPolyhedralVolume( aNodesArray,
+                                                      aVolume->GetQuantities() );
+        }
+        break;
+      case SMDSEntity_Ball:
+        if ( const SMDS_BallElement* aBall =
+             dynamic_cast<const SMDS_BallElement*> (anElem))
+        {
+          aNewElem = aNewEditor.AddElement( aNodesArray, SMDSAbs_Ball,
+                                            /*isPoly=*/false, /*id=*/0,
+                                            aBall->GetDiameter() );
+        }
+        break;
+      case SMDSEntity_Node:
+        break;
+      default:
+        aNewElem = aNewEditor.AddElement( aNodesArray, anElem->GetType(), anElem->IsPoly() );
+      }
+      if ( aNewElem )
+        elemsMap.insert( make_pair( anElem, aNewElem ));
 
-                int anLen = 0;
+    } //elems loop
 
-                switch(aGroupType) {
-                case SMESH::NODE:
-                  str += "Nodes";
-                  anIDsNodes->length(anNbNodes);
-                  anLen = anNbNodes;
-                  break;
-                case SMESH::EDGE:
-                  str += "Edges";
-                  anIDsEdges->length(anNbEdges);
-                  anLen = anNbEdges;
-                  break;
-                case SMESH::FACE:
-                  str += "Faces";
-                  anIDsFaces->length(anNbFaces);
-                  anLen = anNbFaces;
-                  break;
-                case SMESH::VOLUME:
-                  str += "Volumes";
-                  anIDsVolumes->length(anNbVolumes);
-                  anLen = anNbVolumes;
-                  break;
-                case SMESH::BALL:
-                  str += "Balls";
-                  anIDsBalls->length(aNbBalls);
-                  anLen = aNbBalls;
-                  break;
-                default:
-                  break;
-                }
+    aNewEditor.ClearLastCreated(); // forget the history
 
-                if(anLen) {
-                  aGroupName = str.c_str();
 
-                  // add a new group in the mesh
-                  aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+    // create groups of just added elements
+    SMESH::SMESH_Group_var aNewGroup;
+    SMESH::ElementType aGroupType;
+    if ( theCommonGroups )
+    {
+      SMESH::long_array_var curState = aNewMesh->GetNbElementsByType();
 
-                  switch(aGroupType) {
-                  case SMESH::NODE:
-                    aNewGroup->Add( anIDsNodes );
-                    break;
-                  case SMESH::EDGE:
-                    aNewGroup->Add( anIDsEdges );
-                    break;
-                  case SMESH::FACE:
-                    aNewGroup->Add( anIDsFaces );
-                    break;
-                  case SMESH::VOLUME:
-                    aNewGroup->Add( anIDsVolumes );
-                    break;
-                  case SMESH::BALL:
-                    aNewGroup->Add( anIDsBalls );
-                    break;
-                  default:
-                    break;
-                  }
+      for( aGroupType = SMESH::NODE;
+           aGroupType < SMESH::NB_ELEMENT_TYPES;
+           aGroupType = (SMESH::ElementType)( aGroupType + 1 ))
+      {
+        if ( curState[ aGroupType ] <= prevState[ aGroupType ])
+          continue;
 
-                  aListOfNewGroups.clear();
-                  aListOfNewGroups.push_back(aNewGroup);
-                  aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
-                }
+        // make a group name
+        const char* typeNames[] = { "All","Nodes","Edges","Faces","Volumes","0DElems","Balls" };
+        { // check of typeNames, compilation failure mains that NB_ELEMENT_TYPES changed:
+          const int nbNames = sizeof(typeNames) / sizeof(const char*);
+          int _assert[( nbNames == SMESH::NB_ELEMENT_TYPES ) ? 1 : -1 ];
+        }
+        string groupName = "Gr";
+        SALOMEDS::SObject_wrap aMeshSObj = ObjectToSObject( myCurrentStudy, theMeshesArray[i] );
+        if ( aMeshSObj ) {
+          CORBA::String_var name = aMeshSObj->GetName();
+          groupName += name;
+        }
+        groupName += "_";
+        groupName += typeNames[ aGroupType ];
+
+        // make and fill a group
+        TEEMap & e2neMap = ( aGroupType == SMESH::NODE ) ? nodesMap : elemsMap;
+        aNewGroup = aNewImpl->CreateGroup( aGroupType, groupName.c_str() );
+        if ( SMESH_Group_i* grp_i = SMESH::DownCast<SMESH_Group_i*>( aNewGroup ))
+        {
+          if ( SMESHDS_Group* grpDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() ))
+          {
+            TEEMap::iterator e2neIt = e2neMap.begin();
+            for ( ; e2neIt != e2neMap.end(); ++e2neIt )
+            {
+              aNewElem = e2neIt->second;
+              if ( aNewElem->GetType() == grpDS->GetType() )
+              {
+                grpDS->Add( aNewElem );
+
+                if ( prevState[ aGroupType ]++ >= curState[ aGroupType ] )
+                  break;
               }
             }
+          }
+        }
+        aListOfNewGroups.clear();
+        aListOfNewGroups.push_back(aNewGroup);
+        aGroupsMap.insert(make_pair( make_pair(groupName, aGroupType), aListOfNewGroups ));
+      }
+    }
 
-            // check that current group name and type don't have identical ones in union mesh
-            for (int iG = 0; iG < aListOfGroups->length(); iG++) {
-              aGroup = aListOfGroups[iG];
-              aListOfNewGroups.clear();
-              aGroupType = aGroup->GetType();
-              aGroupName = aGroup->GetName();
-
-              TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType));
-
-              // convert a list of IDs
-              anInitIDs = aGroup->GetListOfID();
-              anNewIDs->length(anInitIDs->length());
-              if ( aGroupType == SMESH::NODE )
-                for (int j = 0; j < anInitIDs->length(); j++) {
-                  anNewIDs[j] = nodesMap.find(anInitIDs[j])->second;
-                }
-              else
-                for (int j = 0; j < anInitIDs->length(); j++) {
-                  anNewIDs[j] = elemsMap.find(anInitIDs[j])->second;
-                }
+    if ( SMESH_Mesh_i* anSrcImpl = SMESH::DownCast<SMESH_Mesh_i*>( theMeshesArray[i] ))
+    {
+      // copy orphan nodes
+      if ( anSrcImpl->NbNodes() > nodesMap.size() )
+      {
+        SMDS_ElemIteratorPtr itNodes = anInitImpl->GetElements( theMeshesArray[i], SMESH::NODE );
+        while ( itNodes->more() )
+        {
+          const SMDS_MeshNode* aNode = static_cast< const SMDS_MeshNode* >( itNodes->next() );
+          if ( aNode->NbInverseElements() == 0 )
+          {
+            aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+            nodesMap.insert( make_pair( aNode, aNewNode ));
+          }
+        }
+      }
 
-              // check that current group name and type don't have identical ones in union mesh
-              if ( anIter == aGroupsMap.end() ) {
-                // add a new group in the mesh
-                aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
-                // add elements into new group
-                aNewGroup->Add( anNewIDs );
+      // copy groups
 
-                aListOfNewGroups.push_back(aNewGroup);
-                aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
-              }
+      SMESH::SMESH_GroupBase_ptr aGroup;
+      CORBA::String_var aGroupName;
+      SMESH::long_array_var anNewIDs = new SMESH::long_array();
 
-              else if ( theUniteIdenticalGroups ) {
-                // unite identical groups
-                TListOfNewGroups& aNewGroups = anIter->second;
-                aNewGroups.front()->Add( anNewIDs );
-              }
+      // loop on groups of a source mesh
+      aListOfGroups = anSrcImpl->GetGroups();
+      for (int iG = 0; iG < aListOfGroups->length(); iG++)
+      {
+        aGroup = aListOfGroups[iG];
+        aGroupType = aGroup->GetType();
+        aGroupName = aGroup->GetName();
+
+        // convert a list of IDs
+        anNewIDs->length( aGroup->Size() );
+        TEEMap & e2neMap = ( aGroupType == SMESH::NODE ) ? nodesMap : elemsMap;
+        SMDS_ElemIteratorPtr itGrElems = anSrcImpl->GetElements( aGroup, SMESH::ALL );
+        int iElem = 0;
+        while ( itGrElems->more() )
+        {
+          anElem = itGrElems->next();
+          TEEMap::iterator e2neIt = e2neMap.find( anElem );
+          if ( e2neIt != e2neMap.end() )
+            anNewIDs[ iElem++ ] = e2neIt->second->GetID();
+        }
+        anNewIDs->length( iElem );
+
+        // check a current group name and type don't have identical ones in final mesh
+        aListOfNewGroups.clear();
+        TGroupsMap::iterator anIter = aGroupsMap.find( make_pair( aGroupName, aGroupType ));
+        if ( anIter == aGroupsMap.end() ) {
+          // add a new group in the mesh
+          aNewGroup = aNewImpl->CreateGroup( aGroupType, aGroupName );
+          // add elements into new group
+          aNewGroup->Add( anNewIDs );
+
+          aListOfNewGroups.push_back(aNewGroup);
+          aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
+        }
 
-              else {
-                // rename identical groups
-                aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
-                aNewGroup->Add( anNewIDs );
+        else if ( theUniteIdenticalGroups ) {
+          // unite identical groups
+          TListOfNewGroups& aNewGroups = anIter->second;
+          aNewGroups.front()->Add( anNewIDs );
+        }
 
-                TListOfNewGroups& aNewGroups = anIter->second;
-                string aNewGroupName;
-                if (aNewGroups.size() == 1) {
-                  aNewGroupName = string(aGroupName) + "_1";
-                  aNewGroups.front()->SetName(aNewGroupName.c_str());
-                }
-                char aGroupNum[128];
-                sprintf(aGroupNum, "%u", aNewGroups.size()+1);
-                aNewGroupName = string(aGroupName) + "_" + string(aGroupNum);
-                aNewGroup->SetName(aNewGroupName.c_str());
-                aNewGroups.push_back(aNewGroup);
-              }
-            }//groups loop
+        else {
+          // rename identical groups
+          aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+          aNewGroup->Add( anNewIDs );
+
+          TListOfNewGroups& aNewGroups = anIter->second;
+          string aNewGroupName;
+          if (aNewGroups.size() == 1) {
+            aNewGroupName = string(aGroupName) + "_1";
+            aNewGroups.front()->SetName(aNewGroupName.c_str());
           }
+          char aGroupNum[128];
+          sprintf(aGroupNum, "%u", aNewGroups.size()+1);
+          aNewGroupName = string(aGroupName) + "_" + string(aGroupNum);
+          aNewGroup->SetName(aNewGroupName.c_str());
+          aNewGroups.push_back(aNewGroup);
         }
-      }//meshes loop
-
-      if (theMergeNodesAndElements) {
-        // merge nodes
-        TIDSortedNodeSet aMeshNodes; // no input nodes
-        SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
-        aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
-        aNewEditor.MergeNodes( aGroupsOfNodes );
-        // merge elements
-        aNewEditor.MergeEqualElements();
-      }
-    }
+      } //groups loop
+    } // if an IDSource is a mesh
+  } //meshes loop
+
+  if (theMergeNodesAndElements) {
+    // merge nodes
+    TIDSortedNodeSet aMeshNodes; // no input nodes
+    SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
+    aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
+    aNewEditor.MergeNodes( aGroupsOfNodes );
+    // merge elements
+    aNewEditor.MergeEqualElements();
   }
 
   // Update Python script
-  aPythonDump << aNewMesh << " = " << this;
-  if( !theCommonGroups )
-    aPythonDump << ".Concatenate(";
-  else
-    aPythonDump << ".ConcatenateWithGroups(";
-  aPythonDump << "[";
+  aPythonDump << aNewMesh << " = " << this << "."
+              << ( theCommonGroups ? "ConcatenateWithGroups" : "Concatenate" )
+              << "([";
   for ( int i = 0; i < theMeshesArray.length(); i++) {
     if (i > 0) aPythonDump << ", ";
     aPythonDump << theMeshesArray[i];
@@ -2728,6 +2686,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
 
   if (aNewMeshDS)
     aNewMeshDS->Modified();
+
   return aNewMesh._retn();
 }
 
index e95895d..1c33f73 100644 (file)
@@ -356,26 +356,26 @@ public:
     throw ( SALOME::SALOME_Exception );
 
   // Concatenate the given meshes into one mesh
-  SMESH::SMESH_Mesh_ptr ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
-                                          CORBA::Boolean           theUniteIdenticalGroups,
-                                          CORBA::Boolean           theMergeNodesAndElements,
-                                          CORBA::Double            theMergeTolerance,
-                                          CORBA::Boolean           theCommonGroups)
+  SMESH::SMESH_Mesh_ptr ConcatenateCommon(const SMESH::ListOfIDSources& meshesArray,
+                                          CORBA::Boolean                uniteIdenticalGroups,
+                                          CORBA::Boolean                mergeNodesAndElements,
+                                          CORBA::Double                 mergeTolerance,
+                                          CORBA::Boolean                commonGroups)
     throw ( SALOME::SALOME_Exception );
 
   // Concatenate the given meshes into one mesh
-  SMESH::SMESH_Mesh_ptr Concatenate(const SMESH::mesh_array& theMeshesArray,
-                                    CORBA::Boolean           theUniteIdenticalGroups,
-                                    CORBA::Boolean           theMergeNodesAndElements,
-                                    CORBA::Double            theMergeTolerance)
+  SMESH::SMESH_Mesh_ptr Concatenate(const SMESH::ListOfIDSources& meshesArray,
+                                    CORBA::Boolean                uniteIdenticalGroups,
+                                    CORBA::Boolean                mergeNodesAndElements,
+                                    CORBA::Double                 mergeTolerance)
     throw ( SALOME::SALOME_Exception );
 
   // Concatenate the given meshes into one mesh
   // Create the groups of all elements from initial meshes
-  SMESH::SMESH_Mesh_ptr ConcatenateWithGroups(const SMESH::mesh_array& theMeshesArray,
-                                              CORBA::Boolean           theUniteIdenticalGroups,
-                                              CORBA::Boolean           theMergeNodesAndElements,
-                                              CORBA::Double            theMergeTolerance)
+  SMESH::SMESH_Mesh_ptr ConcatenateWithGroups(const SMESH::ListOfIDSources& meshesArray,
+                                              CORBA::Boolean                uniteIdenticalGroups,
+                                              CORBA::Boolean                mergeNodesAndElements,
+                                              CORBA::Double                 mergeTolerance)
     throw ( SALOME::SALOME_Exception );
 
   // Get MED version of the file by its name
index 534580c..ba49626 100644 (file)
@@ -513,7 +513,7 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers)
       TSearchersDeleter::Delete();
   }
   getEditor().GetError().reset();
-  getEditor().CrearLastCreated();
+  getEditor().ClearLastCreated();
 }
 
 //================================================================================
@@ -712,7 +712,7 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
 void SMESH_MeshEditor_i::ClearLastCreated() throw (SALOME::SALOME_Exception)
 {
   SMESH_TRY;
-  getEditor().CrearLastCreated();
+  getEditor().ClearLastCreated();
   SMESH_CATCH( SMESH::throwCorbaException );
 }
 
index 5669a0b..0e1a130 100644 (file)
@@ -1568,25 +1568,52 @@ SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
   return aResGrp._retn();
 }
 
+namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
+{
+  bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
+                        bool & toStopChecking )
+  {
+    toStopChecking = ( nbCommon < nbChecked );
+    return nbCommon == nbNodes;
+  }
+  bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
+                         bool & toStopChecking )
+  {
+    toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
+    return nbCommon == nbCorners;
+  }
+  bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
+                              bool & toStopChecking )
+  {
+    return nbCommon > 0;
+  }
+  bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
+                               bool & toStopChecking )
+  {
+    return nbCommon >= nbNodes / 2;
+  }
+}
+
 //=============================================================================
 /*!
-  \brief Create groups of entities from existing groups of superior dimensions 
-  System
-  1) extract all nodes from each group,
-  2) combine all elements of specified dimension laying on these nodes.
-  \param theGroups list of source groups 
-  \param theElemType dimension of elements 
-  \param theName name of new group
-  \return pointer on new group
-  *
-  IMP 19939
+ * Create a group of entities basing on nodes of other groups.
+ *  \param [in] theGroups - list of either groups, sub-meshes or filters.
+ *  \param [in] anElemType - a type of elements to include to the new group.
+ *  \param [in] theName - a name of the new group.
+ *  \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
+ *  \param [in] theUnderlyingOnly - if \c True, an element is included to the
+ *         new group provided that it is based on nodes of an element of \a aListOfGroups
+ *  \return SMESH_Group - the created group
 */
+// IMP 19939, bug 22010, IMP 22635
 //=============================================================================
 
 SMESH::SMESH_Group_ptr
-SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups, 
-                             SMESH::ElementType         theElemType, 
-                             const char*                theName )
+SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
+                             SMESH::ElementType            theElemType,
+                             const char*                   theName,
+                             SMESH::NB_COMMON_NODES_ENUM   theNbCommonNodes,
+                             CORBA::Boolean                theUnderlyingOnly)
   throw (SALOME::SALOME_Exception)
 {
   SMESH::SMESH_Group_var aResGrp;
@@ -1602,6 +1629,17 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
 
   SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
 
+  bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
+  SMESH_Comment nbCoNoStr( "SMESH.");
+  switch ( theNbCommonNodes ) {
+  case SMESH::ALL_NODES   : isToInclude = isAllNodesCommon;        nbCoNoStr<<"ALL_NODES"   ;break;
+  case SMESH::MAIN        : isToInclude = isMainNodesCommon;       nbCoNoStr<<"MAIN"        ;break;
+  case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon;  nbCoNoStr<<"AT_LEAST_ONE";break;
+  case SMESH::MAJORITY    : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY"    ;break;
+  default: return aResGrp._retn();
+  }
+  int nbChecked, nbCommon, nbNodes, nbCorners;
+
   // Create a group
 
   TPythonDump pyDump;
@@ -1614,14 +1652,19 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
     SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
   SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
 
+  vector<bool> isNodeInGroups;
+
   for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
   {
-    SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
+    SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
     if ( CORBA::is_nil( aGrp ) )
       continue;
+    SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
+    if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
+      continue;
 
-    groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
-    SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
+    SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
+    if ( !elIt ) continue;
 
     if ( theElemType == SMESH::NODE ) // get all nodes of elements
     {
@@ -1632,30 +1675,93 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
           resGroupCore.Add( nIt->next() );
       }
     }
-    else // get elements of theElemType based on nodes of every element of group
+    // get elements of theElemType based on nodes of every element of group
+    else if ( theUnderlyingOnly )
     {
       while ( elIt->more() )
       {
-        const SMDS_MeshElement* el = elIt->next(); // an element of group
+        const SMDS_MeshElement* el = elIt->next(); // an element of ref group
         TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
         TIDSortedElemSet checkedElems;
-        SMDS_ElemIteratorPtr nIt = el->nodesIterator();
+        SMDS_NodeIteratorPtr nIt = el->nodeIterator();
         while ( nIt->more() )
         {
-          const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
+          const SMDS_MeshNode* n = nIt->next();
           SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
           // check nodes of elements of theElemType around el
           while ( elOfTypeIt->more() )
           {
             const SMDS_MeshElement* elOfType = elOfTypeIt->next();
             if ( !checkedElems.insert( elOfType ).second ) continue;
-
+            nbNodes   = elOfType->NbNodes();
+            nbCorners = elOfType->NbCornerNodes();
+            nbCommon  = 0;
+            bool toStopChecking = false;
             SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
-            bool allNodesOK = true;
-            while ( nIt2->more() && allNodesOK )
-              allNodesOK = elNodes.count( nIt2->next() );
-            if ( allNodesOK )
-              resGroupCore.Add( elOfType );
+            for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
+              if ( elNodes.count( nIt2->next() ) &&
+                   isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
+              {
+                resGroupCore.Add( elOfType );
+                break;
+              }
+          }
+        }
+      }
+    }
+    // get all nodes of elements of groups
+    else
+    {
+      while ( elIt->more() )
+      {
+        const SMDS_MeshElement* el = elIt->next(); // an element of group
+        SMDS_NodeIteratorPtr nIt = el->nodeIterator();
+        while ( nIt->more() )
+        {
+          const SMDS_MeshNode* n = nIt->next();
+          if ( n->GetID() >= isNodeInGroups.size() )
+            isNodeInGroups.resize( n->GetID() + 1, false );
+          isNodeInGroups[ n->GetID() ] = true;
+        }
+      }
+    }
+  }
+
+  // Get elements of theElemType based on a certain number of nodes of elements of groups
+  if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
+  {
+    const SMDS_MeshNode* n;
+    vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
+    const int isNodeInGroupsSize = isNodeInGroups.size();
+    for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
+    {
+      if ( !isNodeInGroups[ iN ] ||
+           !( n = aMeshDS->FindNode( iN )))
+        continue;
+
+      // check nodes of elements of theElemType around n
+      SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
+      while ( elOfTypeIt->more() )
+      {
+        const SMDS_MeshElement*  elOfType = elOfTypeIt->next();
+        vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
+        if ( isChecked )
+          continue;
+        isChecked = true;
+
+        nbNodes   = elOfType->NbNodes();
+        nbCorners = elOfType->NbCornerNodes();
+        nbCommon  = 0;
+        bool toStopChecking = false;
+        SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
+        for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
+        {
+          const int nID = nIt->next()->GetID();
+          if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
+               isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
+          {
+            resGroupCore.Add( elOfType );
+            break;
           }
         }
       }
@@ -1665,7 +1771,8 @@ SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
   // Update Python script
   pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
          << ".CreateDimGroup( "
-         << theGroups << ", " << theElemType << ", '" << theName << "' )";
+         << theGroups << ", " << theElemType << ", '" << theName << "', "
+         << nbCoNoStr << ", " << theUnderlyingOnly << ")";
 
   SMESH_CATCH( SMESH::throwCorbaException );
 
@@ -5168,7 +5275,7 @@ namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_v
           _elem = _mesh->FindNode( *_idPtr++ );
         }
         else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
-                 _elem->GetType() != _type )
+                 (_elem->GetType() != _type && _type != SMDSAbs_All ))
         {
           _elem = 0;
         }
@@ -5248,7 +5355,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
     if ( sm )
     {
       elemIt = sm->GetElements();
-      if ( elemType != SMDSAbs_Node )
+      if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
       {
         typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
         elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
@@ -5258,15 +5365,19 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
   else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
   {
     SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
-    if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
+    if ( groupDS && ( elemType == groupDS->GetType()  ||
+                      elemType == SMDSAbs_Node ||
+                      elemType == SMDSAbs_All ))
     {
       elemIt = groupDS->GetElements();
-      typeOK = ( groupDS->GetType() == elemType );
+      typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
     }
   }
   else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
   {
-    if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
+    if ( filter_i->GetElementType() == theType ||
+         elemType == SMDSAbs_Node ||
+         elemType == SMDSAbs_All)
     {
       SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
       if ( pred_i && pred_i->GetPredicate() )
@@ -5274,7 +5385,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
         SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
         SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
         elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
-        typeOK = ( filterType == elemType );
+        typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
       }
     }
   }
@@ -5282,7 +5393,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
   {
     SMESH::array_of_ElementType_var types = theObject->GetTypes();
     const bool                    isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
-    if ( isNodes && elemType != SMDSAbs_Node )
+    if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
       return elemIt;
     if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
     {
@@ -5295,7 +5406,7 @@ SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObje
       SMESH::long_array_var ids = theObject->GetIDs();
       elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
     }
-    typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
+    typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
   }
 
   if ( elemIt && elemIt->more() && !typeOK )
index 987f80f..45d01b1 100644 (file)
@@ -160,9 +160,11 @@ public:
                                           const char* theName )
     throw (SALOME::SALOME_Exception);
 
-  SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups,
-                                         SMESH::ElementType theElemType,
-                                         const char* theName )
+  SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfIDSources& theGroups,
+                                         SMESH::ElementType            theElemType,
+                                         const char*                   theName,
+                                         SMESH::NB_COMMON_NODES_ENUM   theNbCommonNodes,
+                                         CORBA::Boolean                theUnderlyingOnly )
     throw (SALOME::SALOME_Exception);
 
 
index b4f79d7..9e4386d 100644 (file)
@@ -604,7 +604,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
 
     ## Concatenate the given meshes into one mesh. All groups of input meshes will be
     #  present in the new mesh.
-    #  @param meshes the meshes to combine into one mesh
+    #  @param meshes the meshes, sub-meshes and groups to combine into one mesh
     #  @param uniteIdenticalGroups if true, groups with same names are united, else they are renamed
     #  @param mergeNodesAndElements if true, equal nodes and elements are merged
     #  @param mergeTolerance tolerance for merging nodes
@@ -738,7 +738,9 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
                     if not name:
                         name = "%s_%s"%(aThreshold.GetShapeType(), id(aThreshold)%10000)
                     aCriterion.ThresholdID = self.geompyD.addToStudy( aThreshold, name )
-                    #raise RuntimeError, "Threshold shape must be published"
+            # or a name of GEOM object
+            elif isinstance( aThreshold, str ):
+                aCriterion.ThresholdStr = aThreshold
             else:
                 print "Error: The Threshold should be a shape."
                 return None
@@ -1960,7 +1962,8 @@ class Mesh:
     def RemoveGroupWithContents(self, group):
         self.mesh.RemoveGroupWithContents(group)
 
-    ## Gets the list of groups existing in the mesh in the order of creation (starting from the oldest one)
+    ## Gets the list of groups existing in the mesh in the order
+    #  of creation (starting from the oldest one)
     #  @return a sequence of SMESH_GroupBase
     #  @ingroup l2_grps_create
     def GetGroups(self):
@@ -1982,7 +1985,7 @@ class Mesh:
             names.append(group.GetName())
         return names
 
-    ## Produces a union of two groups
+    ## Produces a union of two groups.
     #  A new group is created. All mesh elements that are
     #  present in the initial groups are added to the new one
     #  @return an instance of SMESH_Group
@@ -1990,7 +1993,7 @@ class Mesh:
     def UnionGroups(self, group1, group2, name):
         return self.mesh.UnionGroups(group1, group2, name)
 
-    ## Produces a union list of groups
+    ## Produces a union list of groups.
     #  New group is created. All mesh elements that are present in
     #  initial groups are added to the new one
     #  @return an instance of SMESH_Group
@@ -1998,7 +2001,7 @@ class Mesh:
     def UnionListOfGroups(self, groups, name):
       return self.mesh.UnionListOfGroups(groups, name)
 
-    ## Prodices an intersection of two groups
+    ## Prodices an intersection of two groups.
     #  A new group is created. All mesh elements that are common
     #  for the two initial groups are added to the new one.
     #  @return an instance of SMESH_Group
@@ -2006,7 +2009,7 @@ class Mesh:
     def IntersectGroups(self, group1, group2, name):
         return self.mesh.IntersectGroups(group1, group2, name)
 
-    ## Produces an intersection of groups
+    ## Produces an intersection of groups.
     #  New group is created. All mesh elements that are present in all
     #  initial groups simultaneously are added to the new one
     #  @return an instance of SMESH_Group
@@ -2014,7 +2017,7 @@ class Mesh:
     def IntersectListOfGroups(self, groups, name):
       return self.mesh.IntersectListOfGroups(groups, name)
 
-    ## Produces a cut of two groups
+    ## Produces a cut of two groups.
     #  A new group is created. All mesh elements that are present in
     #  the main group but are not present in the tool group are added to the new one
     #  @return an instance of SMESH_Group
@@ -2022,22 +2025,35 @@ class Mesh:
     def CutGroups(self, main_group, tool_group, name):
         return self.mesh.CutGroups(main_group, tool_group, name)
 
-    ## Produces a cut of groups
+    ## Produces a cut of groups.
     #  A new group is created. All mesh elements that are present in main groups
     #  but do not present in tool groups are added to the new one
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
     def CutListOfGroups(self, main_groups, tool_groups, name):
-      return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
+        return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
 
-    ## Produces a group of elements of specified type using list of existing groups
-    #  A new group is created. System
-    #  1) extracts all nodes on which groups elements are built
-    #  2) combines all elements of specified dimension laying on these nodes
+    ##
+    #  Create a standalone group of entities basing on nodes of other groups.
+    #  \param groups - list of groups, sub-meshes or filters, of any type.
+    #  \param elemType - a type of elements to include to the new group.
+    #  \param name - a name of the new group.
+    #  \param nbCommonNodes - a criterion of inclusion of an element to the new group
+    #         basing on number of element nodes common with reference \a groups.
+    #         Meaning of possible values are:
+    #         - SMESH.ALL_NODES - include if all nodes are common,
+    #         - SMESH.MAIN - include if all corner nodes are common (meaningful for a quadratic mesh),
+    #         - SMESH.AT_LEAST_ONE - include if one or more node is common,
+    #         - SMEHS.MAJORITY - include if half of nodes or more are common.
+    #  \param underlyingOnly - if \c True (default), an element is included to the
+    #         new group provided that it is based on nodes of one element of \a groups.
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
-    def CreateDimGroup(self, groups, elem_type, name):
-      return self.mesh.CreateDimGroup(groups, elem_type, name)
+    def CreateDimGroup(self, groups, elemType, name,
+                       nbCommonNodes = SMESH.ALL_NODES, underlyingOnly = True):
+        if isinstance( groups, SMESH._objref_SMESH_IDSource ):
+            groups = [groups]
+        return self.mesh.CreateDimGroup(groups, elemType, name, nbCommonNodes, underlyingOnly)
 
 
     ## Convert group on geom into standalone group