From: eap Date: Fri, 18 Jan 2019 18:31:22 +0000 (+0300) Subject: 23617: EDF 14133 - Complete Merge Nodes / Merge Elements operations X-Git-Tag: V9_3_0a1~18 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=64680c27c16f878decc136ec6c38dc9a72f12f3b;p=modules%2Fsmesh.git 23617: EDF 14133 - Complete Merge Nodes / Merge Elements operations + 1) fix bug that SMESH_MeshEditor::DoubleElements() can't duplicate all elements if they are of different dimension 2) Add QString GetName( Handle(SALOME_InteractiveObject)& ) that gets missing name from SObject. --- diff --git a/doc/salome/examples/transforming_meshes_ex05.py b/doc/salome/examples/transforming_meshes_ex05.py index deba1c407..0adf0247c 100644 --- a/doc/salome/examples/transforming_meshes_ex05.py +++ b/doc/salome/examples/transforming_meshes_ex05.py @@ -1,14 +1,24 @@ # Merging Nodes import SMESH_mechanic, SMESH -mesh = SMESH_mechanic.mesh +mesh = SMESH_mechanic.mesh +smesh = SMESH_mechanic.smesh -# merge nodes +# criterion of coincidence Tolerance = 4.0 +# find close nodes of triangle elements only +triangleFilter = smesh.GetFilter( SMESH.FACE, SMESH.FT_ElemGeomType,'=', SMESH.Geom_TRIANGLE ) +GroupsOfNodesOfTriangles = mesh.FindCoincidentNodesOnPart([triangleFilter],Tolerance) + # prevent nodes located on geom edges from removal during merge: # create a group including all nodes on edges allSegs = mesh.MakeGroup( "all segments", SMESH.EDGE, SMESH.FT_ElemGeomType,'=', SMESH.Geom_EDGE ) -GroupsOfNodes = mesh.FindCoincidentNodes(Tolerance) +mesh.MergeNodes(GroupsOfNodesOfTriangles, NodesToKeep=allSegs) + + +# find close nodes in the whole mesh +GroupsOfNodes = mesh.FindCoincidentNodes(Tolerance) + mesh.MergeNodes(GroupsOfNodes, NodesToKeep=allSegs) diff --git a/doc/salome/examples/transforming_meshes_ex06.py b/doc/salome/examples/transforming_meshes_ex06.py index 1d973dadb..433ae1928 100644 --- a/doc/salome/examples/transforming_meshes_ex06.py +++ b/doc/salome/examples/transforming_meshes_ex06.py @@ -3,11 +3,10 @@ import salome salome.salome_init() -import GEOM from salome.geom import geomBuilder geompy = geomBuilder.New() -import SMESH, SALOMEDS +import SMESH from salome.smesh import smeshBuilder smesh = smeshBuilder.New() @@ -43,6 +42,9 @@ algo2D.LengthFromEdges() trias.Compute() +# create a group of all triangles currently present in the mesh +faceTriGroup = trias.Group( face1, "face triangles" ) + # create a path mesh circlemesh = smesh.Mesh(circle, "Path mesh") algo = circlemesh.Segment() @@ -50,14 +52,19 @@ algo.NumberOfSegments(10) circlemesh.Compute() # extrusion of the mesh -trias.ExtrusionAlongPath([], circlemesh, circle, - 1, 0, [], 0, SMESH.PointStruct(0, 0, 0)) +trias.ExtrusionAlongPath([], circlemesh, circle, 1, MakeGroups=True ) + +# get a group "opposite" to faceTriGroup within the generated prismatic mesh +oppositeGroup = trias.GetGroupByName( faceTriGroup.GetName() + "_top" )[0] + +# get edges of the groups +edgeGroup = trias.CreateDimGroup([ faceTriGroup, oppositeGroup ], SMESH.EDGE, "face edges") -# merge nodes +# merge nodes of the groups only print("Number of nodes before MergeNodes:", end=' ') trias.NbNodes() tolerance = 0.001 -array_of_nodes_groups = trias.FindCoincidentNodes(tolerance) +array_of_nodes_groups = trias.FindCoincidentNodesOnPart([faceTriGroup, oppositeGroup], tolerance) trias.MergeNodes(array_of_nodes_groups) @@ -65,16 +72,15 @@ print("Number of nodes after MergeNodes:", trias.NbNodes()) print("") print("Number of elements before MergeEqualElements:") print("Edges : ", trias.NbEdges()) -print("Triangles : ", trias.NbTriangles()) -print("Quadrangles: ", trias.NbQuadrangles()) +print("Faces : ", trias.NbFaces()) print("Volumes : ", trias.NbVolumes()) -# merge elements -trias.MergeEqualElements() +# merge elements of the groups +equalFaces = trias.FindEqualElements( [faceTriGroup, oppositeGroup, edgeGroup] ) +trias.MergeElements( equalFaces ) print("Number of elements after MergeEqualElements:") print("Edges : ", trias.NbEdges()) -print("Triangles : ", trias.NbTriangles()) -print("Quadrangles: ", trias.NbQuadrangles()) +print("Faces : ", trias.NbFaces()) print("Volumes : ", trias.NbVolumes()) salome.sg.updateObjBrowser() diff --git a/doc/salome/gui/SMESH/images/mergeelems.png b/doc/salome/gui/SMESH/images/mergeelems.png index 40d614f5e..f35955aed 100644 Binary files a/doc/salome/gui/SMESH/images/mergeelems.png and b/doc/salome/gui/SMESH/images/mergeelems.png differ diff --git a/doc/salome/gui/SMESH/images/mergeelems_auto.png b/doc/salome/gui/SMESH/images/mergeelems_auto.png index 6e2b30697..ffbb0923e 100644 Binary files a/doc/salome/gui/SMESH/images/mergeelems_auto.png and b/doc/salome/gui/SMESH/images/mergeelems_auto.png differ diff --git a/doc/salome/gui/SMESH/images/mergenodes.png b/doc/salome/gui/SMESH/images/mergenodes.png index fc75f70dd..267602507 100644 Binary files a/doc/salome/gui/SMESH/images/mergenodes.png and b/doc/salome/gui/SMESH/images/mergenodes.png differ diff --git a/doc/salome/gui/SMESH/images/mergenodes_auto.png b/doc/salome/gui/SMESH/images/mergenodes_auto.png index e27046908..e01aaccb6 100644 Binary files a/doc/salome/gui/SMESH/images/mergenodes_auto.png and b/doc/salome/gui/SMESH/images/mergenodes_auto.png differ diff --git a/doc/salome/gui/SMESH/input/merging_elements.rst b/doc/salome/gui/SMESH/input/merging_elements.rst index 43a27090e..628e364a8 100644 --- a/doc/salome/gui/SMESH/input/merging_elements.rst +++ b/doc/salome/gui/SMESH/input/merging_elements.rst @@ -17,10 +17,23 @@ To merge elements choose in the main menu **Modification** -> **Transformation** .. image:: ../images/mergeelems_auto.png :align: center +.. |ad| image:: ../images/add.png +.. |rm| image:: ../images/remove.png +.. |mv| image:: ../images/sort.png + In this dialog: - * **Name** is the name of the mesh object whose elements will be merged. + * **Names** contains names of the selected mesh objects whose elements will be merged. * **Automatic** or **Manual** Mode allows choosing how the elements are processed. In the **Automatic** Mode all elements created on the same nodes will be merged. In **Manual** mode you can adjust groups of coincident elements detected by the program. + * **Exclude groups from detection** group allows to ignore the elements which belong to the specified mesh groups. This control is active provided that the mesh includes groups. + * **Elements to keep during the merge** group allows to specify elements to keep in the mesh. (By default an element being the first in a group of coincident elements is kept.) It is possible to either select elements in the Viewer or select groups whose elements will be kept. + + * *Selection* button activates selection of elements to keep. + * **Elements** button activates selection of elements in the Viewer. + * **Groups and sub-meshes** button activates selection of groups and sub-meshes. + * **Add** button adds selected elements or groups to the list. + * Elements or groups selected in the list can be removed using **Remove** button. + If the **Manual** Mode is selected, additional controls are available: @@ -36,20 +49,9 @@ In this dialog: * **Show double elements IDs** check-box shows/hides identifiers of elements of the selected groups in the 3D viewer. * **Edit selected group of coincident elements** list allows editing the selected group: - .. image:: ../images/add.png - :align: center - - * adds to the group the elements selected in the viewer. - - .. image:: ../images/remove.png - :align: center - - * removes the selected elements from the group. - - .. image:: ../images/sort.png - :align: center - - * moves the selected element to the first position in the group in order to keep it in the mesh. + * |ad| adds to the group the elements selected in the viewer. + * |rm| removes the selected elements from the group. + * |mv| moves the selected element to the first position in the group in order to keep it in the mesh. diff --git a/doc/salome/gui/SMESH/input/merging_nodes.rst b/doc/salome/gui/SMESH/input/merging_nodes.rst index e7bba52d4..18096ba22 100644 --- a/doc/salome/gui/SMESH/input/merging_nodes.rst +++ b/doc/salome/gui/SMESH/input/merging_nodes.rst @@ -12,14 +12,18 @@ This functionality allows user to detect groups of coincident nodes with specifi .. centered:: *"Merge nodes"* menu button +.. |ad| image:: ../images/add.png +.. |rm| image:: ../images/remove.png +.. |mv| image:: ../images/sort.png + *To merge nodes of your mesh:* #. Choose **Modification** -> **Transformation** -> **Merge nodes** menu item. The following dialog box shall appear: .. image:: ../images/mergenodes_auto.png :align: center - - * **Name** is the name of the mesh whose nodes will be merged. + + * **Names** contains names of the selected mesh objects whose nodes will be merged. * **Automatic** or **Manual** mode allows choosing how the nodes are processed. In **Manual** mode you can adjust groups of coincident nodes detected by the program and/or select any nodes to be merged. * **Tolerance** is a maximum distance between nodes sufficient for merging. * Activation of **No merge of corner and medium nodes of quadratic cells** check-box prevents merging medium nodes of quadratic elements with corner nodes. This check-box is enabled provided that the selected mesh includes quadratic elements. @@ -53,20 +57,9 @@ This functionality allows user to detect groups of coincident nodes with specifi * **Edit selected group of coincident nodes** list allows editing the selected group: - .. image:: ../images/add.png - :align: center - - * adds to the group the nodes selected in the viewer. - - .. image:: ../images/remove.png - :align: center - - * removes from the group the selected nodes. - - .. image:: ../images/sort.png - :align: center - - * moves the selected node to the first position in the group in order to keep it in the mesh. + * |ad| adds to the group the nodes selected in the viewer. + * |rm| removes from the group the selected nodes. + * |mv| moves the selected node to the first position in the group in order to keep it in the mesh. #. To confirm your choice click **Apply** or **Apply and Close** button. diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index 9491b9214..482f8e9b6 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -723,7 +723,7 @@ module SMESH in boolean SeparateCornersAndMedium) raises (SALOME::SALOME_Exception); - void FindCoincidentNodesOnPartBut (in SMESH_IDSource SubMeshOrGroup, + void FindCoincidentNodesOnPartBut (in ListOfIDSources SubMeshOrGroup, in double Tolerance, out array_of_long_array GroupsOfNodes, in ListOfIDSources ExceptSubMeshOrGroups, @@ -740,7 +740,8 @@ module SMESH * \param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching. * \return List of groups of equal elements. */ - void FindEqualElements (in SMESH_IDSource MeshOrSubMeshOrGroup, + void FindEqualElements (in ListOfIDSources MeshOrSubMeshOrGroup, + in ListOfIDSources ExceptSubMeshOrGroups, out array_of_long_array GroupsOfElementsID) raises (SALOME::SALOME_Exception); @@ -748,7 +749,8 @@ module SMESH * \brief Merge elements in each given group. * \param GroupsOfElementsID Groups of elements for merging. */ - void MergeElements(in array_of_long_array GroupsOfElementsID) + void MergeElements(in array_of_long_array GroupsOfElementsID, + in SMESH::ListOfIDSources ElementsToKeep) raises (SALOME::SALOME_Exception); /*! diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 6ec53053c..81db6b65f 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -10941,7 +10941,7 @@ void SMESH_MeshEditor::DoubleElements( const TIDSortedElemSet& theElements ) } else { - type = (*theElements.begin())->GetType(); + //type = (*theElements.begin())->GetType(); elemIt = SMESHUtils::elemSetIterator( theElements ); } @@ -10956,7 +10956,8 @@ void SMESH_MeshEditor::DoubleElements( const TIDSortedElemSet& theElements ) while ( elemIt->more() ) { const SMDS_MeshElement* elem = elemIt->next(); - if ( elem->GetType() != type || elem->isMarked() ) + if (( type != SMDSAbs_All && elem->GetType() != type ) || + ( elem->isMarked() )) continue; elemType.Init( elem, /*basicOnly=*/false ); diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.cxx b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx index 6bba06313..f76bab499 100644 --- a/src/SMESHGUI/SMESHGUI_MergeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx @@ -114,9 +114,10 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) mySelectionMgr(SMESH::GetSelectionMgr(theModule)), myAction(theAction) { + const bool isElems = ( myAction == MERGE_ELEMENTS ); setModal(false); setAttribute(Qt::WA_DeleteOnClose, true); - setWindowTitle(myAction == MERGE_ELEMENTS ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES")); + setWindowTitle( isElems ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES")); myIdPreview = new SMESHGUI_IdPreview(SMESH::GetViewWindow( mySMESHGUI )); @@ -155,7 +156,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) GroupMeshLayout->setSpacing(SPACING); GroupMeshLayout->setMargin(MARGIN); - TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh); + TextLabelName = new QLabel(tr("SMESH_NAMES"), GroupMesh); SelectMeshButton = new QPushButton(GroupMesh); SelectMeshButton->setIcon(IconSelect); LineEditMesh = new QLineEdit(GroupMesh); @@ -168,10 +169,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) /***************************************************************/ // Controls for coincident elements detecting - GroupCoincident = new QGroupBox(myAction == MERGE_ELEMENTS ? - tr("COINCIDENT_ELEMENTS") : - tr("COINCIDENT_NODES"), - this); + GroupCoincident = new QGroupBox(tr(isElems ? "COINCIDENT_ELEMENTS" : "COINCIDENT_NODES"), this); QGridLayout* aCoincidentLayout = new QGridLayout(GroupCoincident); aCoincidentLayout->setSpacing(SPACING); @@ -202,55 +200,6 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) NodeSpecLayout->addWidget(SpinBoxTolerance, 0, 1 ); NodeSpecLayout->addWidget(SeparateCornersAndMedium, 1, 0, 1, 2 ); NodeSpecLayout->addWidget(AvoidMakingHoles, 2, 0, 1, 2 ); - - /***************************************************************/ - // Exclude groups - - GroupExclude = new QGroupBox(tr("EXCLUDE_GROUPS"), this ); - GroupExclude->setCheckable( true ); - GroupExclude->setChecked( false ); - ListExclude = new QListWidget( GroupExclude ); - QVBoxLayout* GroupExcludeLayout = new QVBoxLayout(GroupExclude); - GroupExcludeLayout->setSpacing(SPACING); - GroupExcludeLayout->setMargin(MARGIN); - GroupExcludeLayout->addWidget(ListExclude); - - /***************************************************************/ - // Nodes to keep - - GroupKeep = new QGroupBox(tr("KEEP_NODES"), this); - SelectKeepNodesButton = new QPushButton( GroupKeep ); - SelectKeepNodesButton->setIcon( IconSelect ); - QLabel* selectLabel = new QLabel(tr("SELECT")); - QRadioButton* idsButton = new QRadioButton(tr("SMESH_NODES"), GroupKeep); - QRadioButton* groupButton = new QRadioButton(tr("GROUP_SUBMESH"), GroupKeep); - KeepFromButGroup = new QButtonGroup( this ); - KeepFromButGroup->addButton( idsButton, 0 ); - KeepFromButGroup->addButton( groupButton, 1 ); - groupButton->setChecked( true ); - KeepList = new QListWidget( GroupKeep ); - KeepList->setSelectionMode(QAbstractItemView::ExtendedSelection); - KeepList->setFlow(QListView::TopToBottom); - AddKeepNodesButton = new QPushButton(tr("SMESH_BUT_ADD"), GroupKeep ); - RemoveKeepNodesButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupKeep ); - QGridLayout* GroupKeepLayout = new QGridLayout(GroupKeep); - GroupKeepLayout->setSpacing( SPACING ); - GroupKeepLayout->setMargin ( MARGIN ); - GroupKeepLayout->addWidget( SelectKeepNodesButton, 0, 0 ); - GroupKeepLayout->addWidget( selectLabel, 0, 1 ); - GroupKeepLayout->addWidget( idsButton, 0, 2 ); - GroupKeepLayout->addWidget( groupButton, 0, 3, 1, 2 ); - GroupKeepLayout->addWidget( KeepList, 1, 0, 3, 4 ); - GroupKeepLayout->addWidget( AddKeepNodesButton, 1, 4, 1, 1 ); - GroupKeepLayout->addWidget( RemoveKeepNodesButton, 2, 4, 1, 1 ); - GroupKeepLayout->setRowStretch(3, 5); - - // Costruction of the logical filter - QList aListOfFilters; - aListOfFilters << new SMESH_TypeFilter (SMESH::SUBMESH) - << new SMESH_TypeFilter (SMESH::GROUP); - mySubMeshOrGroupFilter = - new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true); } else { NodeSpecWidget = 0; @@ -258,13 +207,63 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) GroupExclude = 0; ListExclude = 0; KeepFromButGroup = 0; - SelectKeepNodesButton = 0; - AddKeepNodesButton = 0; - RemoveKeepNodesButton = 0; + SelectKeepButton = 0; + AddKeepButton = 0; + RemoveKeepButton = 0; KeepList = 0; mySubMeshOrGroupFilter = 0; } + /***************************************************************/ + // Exclude groups + + GroupExclude = new QGroupBox(tr("EXCLUDE_GROUPS"), this ); + GroupExclude->setCheckable( true ); + GroupExclude->setChecked( false ); + ListExclude = new QListWidget( GroupExclude ); + QVBoxLayout* GroupExcludeLayout = new QVBoxLayout(GroupExclude); + GroupExcludeLayout->setSpacing(SPACING); + GroupExcludeLayout->setMargin(MARGIN); + GroupExcludeLayout->addWidget(ListExclude); + + /***************************************************************/ + // Nodes/elements to keep + + GroupKeep = new QGroupBox(tr( isElems ? "KEEP_ELEMENTS" : "KEEP_NODES"), this); + SelectKeepButton = new QPushButton( GroupKeep ); + SelectKeepButton->setIcon( IconSelect ); + QLabel* selectLabel = new QLabel(tr("SELECT")); + QRadioButton* idsButton = new QRadioButton(tr(isElems ? "SMESH_ELEMENTS" : "SMESH_NODES"), + GroupKeep); + QRadioButton* groupButton = new QRadioButton(tr("GROUP_SUBMESH"), GroupKeep); + KeepFromButGroup = new QButtonGroup( this ); + KeepFromButGroup->addButton( idsButton, 0 ); + KeepFromButGroup->addButton( groupButton, 1 ); + groupButton->setChecked( true ); + KeepList = new QListWidget( GroupKeep ); + KeepList->setSelectionMode(QAbstractItemView::ExtendedSelection); + KeepList->setFlow(QListView::TopToBottom); + AddKeepButton = new QPushButton(tr("SMESH_BUT_ADD"), GroupKeep ); + RemoveKeepButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupKeep ); + QGridLayout* GroupKeepLayout = new QGridLayout(GroupKeep); + GroupKeepLayout->setSpacing( SPACING ); + GroupKeepLayout->setMargin ( MARGIN ); + GroupKeepLayout->addWidget( SelectKeepButton, 0, 0 ); + GroupKeepLayout->addWidget( selectLabel, 0, 1 ); + GroupKeepLayout->addWidget( idsButton, 0, 2 ); + GroupKeepLayout->addWidget( groupButton, 0, 3, 1, 2 ); + GroupKeepLayout->addWidget( KeepList, 1, 0, 3, 4 ); + GroupKeepLayout->addWidget( AddKeepButton, 1, 4, 1, 1 ); + GroupKeepLayout->addWidget( RemoveKeepButton, 2, 4, 1, 1 ); + GroupKeepLayout->setRowStretch(3, 5); + + // Costruction of the logical filter + QList aListOfFilters; + aListOfFilters << new SMESH_TypeFilter (SMESH::SUBMESH) + << new SMESH_TypeFilter (SMESH::GROUP); + mySubMeshOrGroupFilter = + new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true); + ListCoincident = new QListWidget(GroupCoincident); ListCoincident->setSelectionMode(QListWidget::ExtendedSelection); @@ -273,7 +272,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincident); SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincident); - ShowIDs = new QCheckBox(myAction == MERGE_ELEMENTS ? tr("SHOW_ELEMS_IDS") : tr("SHOW_NODES_IDS"), GroupCoincident); + ShowIDs = new QCheckBox( isElems ? tr("SHOW_ELEMS_IDS") : tr("SHOW_NODES_IDS"), GroupCoincident); aCoincidentLayout->addWidget(ListCoincident, 0, 0, 4, 2); aCoincidentLayout->addWidget(DetectButton, 0, 2); @@ -287,9 +286,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) /***************************************************************/ // Controls for editing the selected group - GroupEdit = new QGroupBox(myAction == MERGE_NODES ? - tr("EDIT_SELECTED_NODE_GROUP") : - tr("EDIT_SELECTED_ELEM_GROUP"), this); + GroupEdit = new QGroupBox( tr(isElems ? "EDIT_SELECTED_ELEM_GROUP" : "EDIT_SELECTED_NODE_GROUP"), this); QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit); GroupEditLayout->setSpacing(SPACING); GroupEditLayout->setMargin(MARGIN); @@ -338,7 +335,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) GroupButtonsLayout->addWidget(buttonHelp); /***************************************************************/ - if (myAction == MERGE_NODES) + //if (myAction == MERGE_NODES) { QWidget* LeftWdg = new QWidget( this ); QVBoxLayout* LeftLayout = new QVBoxLayout(LeftWdg); @@ -346,7 +343,8 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) LeftLayout->setMargin(0); LeftLayout->addWidget(TypeBox); LeftLayout->addWidget(GroupMesh); - LeftLayout->addWidget(NodeSpecWidget); + if ( !isElems ) + LeftLayout->addWidget(NodeSpecWidget); LeftLayout->addWidget(GroupCoincident); LeftLayout->addStretch(); LeftLayout->addWidget(GroupButtons); @@ -368,17 +366,17 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) DlgLayout->addWidget( LeftWdg ); DlgLayout->addWidget( RightWdg ); } - else - { - QVBoxLayout* DlgLayout = new QVBoxLayout(this); - DlgLayout->setSpacing(SPACING); - DlgLayout->setMargin(MARGIN); - DlgLayout->addWidget(TypeBox); - DlgLayout->addWidget(GroupMesh); - DlgLayout->addWidget(GroupCoincident); - DlgLayout->addWidget(GroupEdit); - DlgLayout->addWidget(GroupButtons); - } + // else + // { + // QVBoxLayout* DlgLayout = new QVBoxLayout(this); + // DlgLayout->setSpacing(SPACING); + // DlgLayout->setMargin(MARGIN); + // DlgLayout->addWidget(TypeBox); + // DlgLayout->addWidget(GroupMesh); + // DlgLayout->addWidget(GroupCoincident); + // DlgLayout->addWidget(GroupEdit); + // DlgLayout->addWidget(GroupButtons); + // } GroupCoincident->hide(); GroupEdit->hide(); @@ -415,7 +413,7 @@ void SMESHGUI_MergeDlg::Init() myEditCurrentArgument = (QWidget*)LineEditMesh; myActor = 0; - mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil(); + mySubMeshOrGroups = new SMESH::ListOfIDSources; mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); @@ -430,11 +428,11 @@ void SMESHGUI_MergeDlg::Init() if ( KeepList ) { - connect(SelectKeepNodesButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); - connect(KeepFromButGroup, SIGNAL (buttonClicked(int)), SLOT(onKeepNodeSourceChanged(int))); - connect(AddKeepNodesButton, SIGNAL (clicked()), this, SLOT(onAddKeepNode())); - connect(RemoveKeepNodesButton, SIGNAL (clicked()), this, SLOT(onRemoveKeepNode())); - connect(KeepList, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectKeepNode())); + connect(SelectKeepButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); + connect(KeepFromButGroup, SIGNAL (buttonClicked(int)), SLOT(onKeepSourceChanged(int))); + connect(AddKeepButton, SIGNAL (clicked()), this, SLOT(onAddKeep())); + connect(RemoveKeepButton, SIGNAL (clicked()), this, SLOT(onRemoveKeep())); + connect(KeepList, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectKeep())); } connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect())); @@ -539,7 +537,8 @@ bool SMESHGUI_MergeDlg::ClickOnApply() aGroupsOfElements->length(ListCoincident->count()); int anArrayNum = 0; - for (int i = 0; i < ListCoincident->count(); i++) { + for (int i = 0; i < ListCoincident->count(); i++) + { QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts); anIds->length(aListIds.count()); @@ -549,13 +548,13 @@ bool SMESHGUI_MergeDlg::ClickOnApply() aGroupsOfElements[anArrayNum++] = anIds.inout(); } - SMESH::ListOfIDSources_var nodesToKeep; + SMESH::ListOfIDSources_var toKeep; SMESH::IDSource_wrap tmpIdSource; - if ( myAction == MERGE_NODES ) + //if ( myAction == MERGE_NODES ) { - nodesToKeep = new SMESH::ListOfIDSources(); + toKeep = new SMESH::ListOfIDSources(); int i, nb = KeepList->count(); - if ( isKeepNodesIDsSelection() ) + if ( isKeepIDsSelection() ) { SMESH::long_array_var anIdList = new SMESH::long_array(); anIdList->length(nb); @@ -565,13 +564,13 @@ bool SMESHGUI_MergeDlg::ClickOnApply() if ( nb > 0 ) { tmpIdSource = aMeshEditor->MakeIDSource( anIdList, SMESH::NODE ); - nodesToKeep->length( 1 ); - nodesToKeep[0] = SMESH::SMESH_IDSource::_duplicate( tmpIdSource.in() ); + toKeep->length( 1 ); + toKeep[0] = SMESH::SMESH_IDSource::_duplicate( tmpIdSource.in() ); } } else { - nodesToKeep->length( nb ); + toKeep->length( nb ); int nbObj = 0; for (i = 0; i < nb; i++) { @@ -581,17 +580,17 @@ bool SMESHGUI_MergeDlg::ClickOnApply() SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface( anIO ); if ( !idSrc->_is_nil() ) - nodesToKeep[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( idSrc ); + toKeep[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( idSrc ); } - nodesToKeep->length( nbObj ); + toKeep->length( nbObj ); } KeepList->clear(); } if( myAction == MERGE_NODES ) - aMeshEditor->MergeNodes( aGroupsOfElements.inout(), nodesToKeep, AvoidMakingHoles->isChecked() ); + aMeshEditor->MergeNodes( aGroupsOfElements.inout(), toKeep, AvoidMakingHoles->isChecked() ); else - aMeshEditor->MergeElements( aGroupsOfElements.inout() ); + aMeshEditor->MergeElements( aGroupsOfElements.inout(), toKeep ); if ( myTypeId == TYPE_AUTO ) { if ( myAction == MERGE_NODES ) @@ -601,8 +600,8 @@ bool SMESHGUI_MergeDlg::ClickOnApply() SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data())); } - if ( & nodesToKeep.in() ) - nodesToKeep->length(0); // release before tmpIdSource calls UnRegister() + if ( & toKeep.in() ) + toKeep->length(0); // release before tmpIdSource calls UnRegister() } catch(...) { @@ -747,11 +746,12 @@ void SMESHGUI_MergeDlg::updateControls() myMesh->NbVolumesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 )); SeparateCornersAndMedium->setEnabled( has2ndOrder ); - + } + { if ( myEditCurrentArgument != KeepList ) { - AddKeepNodesButton->setEnabled( false ); - RemoveKeepNodesButton->setEnabled( false ); + AddKeepButton->setEnabled( false ); + RemoveKeepButton->setEnabled( false ); KeepList->clearSelection(); } } @@ -776,38 +776,38 @@ void SMESHGUI_MergeDlg::onDetect() SMESH::array_of_long_array_var aGroupsArray; SMESH::ListOfIDSources_var aExcludeGroups = new SMESH::ListOfIDSources; - SMESH::SMESH_IDSource_var src; - if ( mySubMeshOrGroup->_is_nil() ) src = SMESH::SMESH_IDSource::_duplicate( myMesh ); - else src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup ); + for ( int i = 0; GroupExclude->isChecked() && i < ListExclude->count(); i++ ) { + if ( ListExclude->item( i )->checkState() == Qt::Checked ) { + aExcludeGroups->length( aExcludeGroups->length()+1 ); + aExcludeGroups[ aExcludeGroups->length()-1 ] = SMESH::SMESH_IDSource::_narrow( myGroups[i] ); + } + } switch (myAction) { case MERGE_NODES : - for ( int i = 0; GroupExclude->isChecked() && i < ListExclude->count(); i++ ) { - if ( ListExclude->item( i )->checkState() == Qt::Checked ) { - aExcludeGroups->length( aExcludeGroups->length()+1 ); - aExcludeGroups[ aExcludeGroups->length()-1 ] = SMESH::SMESH_IDSource::_duplicate( myGroups[i] ); - } - } - aMeshEditor->FindCoincidentNodesOnPartBut(src.in(), - SpinBoxTolerance->GetValue(), + aMeshEditor->FindCoincidentNodesOnPartBut(mySubMeshOrGroups.in(), + SpinBoxTolerance->GetValue(), aGroupsArray.out(), aExcludeGroups.in(), SeparateCornersAndMedium->isEnabled() && SeparateCornersAndMedium->isChecked()); break; case MERGE_ELEMENTS : - aMeshEditor->FindEqualElements(src.in(), aGroupsArray.out()); + aMeshEditor->FindEqualElements(mySubMeshOrGroups.in(), + aExcludeGroups.in(), + aGroupsArray.out()); break; } - - for (int i = 0; i < (int)aGroupsArray->length(); i++) { + + for ( CORBA::ULong i = 0; i < aGroupsArray->length(); i++) + { SMESH::long_array& aGroup = aGroupsArray[i]; QStringList anIDs; - for (int j = 0; j < (int)aGroup.length(); j++) - anIDs.append(QString::number(aGroup[j])); + for ( CORBA::ULong j = 0; j < aGroup.length(); j++ ) + anIDs.append( QString::number( aGroup[j] )); - ListCoincident->addItem(anIDs.join(" ")); + ListCoincident->addItem( anIDs.join(" ")); } } catch(...) { } @@ -830,7 +830,7 @@ void SMESHGUI_MergeDlg::onSelectGroup() SelectAllCB->setChecked( false ); if ( myEditCurrentArgument == (QWidget*)KeepList && KeepList && - !isKeepNodesIDsSelection() ) + !isKeepIDsSelection() ) { // restore selection of nodes after selection of sub-meshes mySelectionMgr->clearFilters(); @@ -938,7 +938,7 @@ void SMESHGUI_MergeDlg::onSelectElementFromGroup() myIdPreview->SetPointsLabeled(false); if ( myEditCurrentArgument == (QWidget*)KeepList && KeepList && - !isKeepNodesIDsSelection() ) + !isKeepIDsSelection() ) { // restore selection of nodes after selection of sub-meshes mySelectionMgr->clearFilters(); @@ -1113,15 +1113,16 @@ void SMESHGUI_MergeDlg::SetEditCurrentArgument() if (myTypeId == TYPE_MANUAL) mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); } - else if ( send == SelectKeepNodesButton && send ) + else if ( send == SelectKeepButton && send ) { myEditCurrentArgument = (QWidget*)KeepList; - KeepList->setWrapping( isKeepNodesIDsSelection() ); - if ( isKeepNodesIDsSelection() ) + KeepList->setWrapping( isKeepIDsSelection() ); + if ( isKeepIDsSelection() ) { - SMESH::SetPointRepresentation( true ); + bool isElems = ( myAction == MERGE_ELEMENTS ); + SMESH::SetPointRepresentation( !isElems ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode( NodeSelection ); + aViewWindow->SetSelectionMode( isElems ? CellSelection : NodeSelection ); } else { @@ -1150,12 +1151,13 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument() ListCoincident->clear(); ListEdit->clear(); + ListExclude->clear(); myActor = 0; myMesh = SMESH::SMESH_Mesh::_nil(); QString aCurrentEntry = myEntry; int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); - if (nbSel != 1) { + if (nbSel == 0) { myIdPreview->SetPointsLabeled(false); SMESH::SetPointRepresentation(false); mySelectionMgr->clearFilters(); @@ -1177,43 +1179,72 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument() if (myMesh->_is_nil()) return; - LineEditMesh->setText(aString); - myActor = SMESH::FindActorByEntry(IO->getEntry()); if (!myActor) myActor = SMESH::FindActorByObject(myMesh); - if ( myActor && myTypeId == TYPE_MANUAL && mySelector->IsSelectionEnabled() ) { - mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil(); - mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); + mySubMeshOrGroups->length( nbSel ); + nbSel = 0; + bool isMeshSelected = false; + while ( !aList.IsEmpty() ) + { + IO = aList.First(); + aList.RemoveFirst(); + SMESH::SMESH_IDSource_var idSrc = SMESH::IObjectToInterface(IO); + if ( !idSrc->_is_nil() ) + { + SMESH::SMESH_Mesh_var mesh = idSrc->GetMesh(); + if ( !mesh->_is_equivalent( myMesh )) + { + nbSel = 0; + break; + } + mySubMeshOrGroups[ nbSel++ ] = idSrc; + if ( idSrc->_is_equivalent( myMesh )) + { + isMeshSelected = true; + mySubMeshOrGroups[ 0 ] = idSrc; + aString = SMESH::GetName( IO ); + // break; -- to check if other selected belongs to myMesh + } + } + } - if ((!SMESH::IObjectToInterface(IO)->_is_nil() || //SUBMESH OR GROUP - !SMESH::IObjectToInterface(IO)->_is_nil()) && - !SMESH::IObjectToInterface(IO)->_is_nil()) - mySubMeshOrGroup = SMESH::IObjectToInterface(IO); + if ( isMeshSelected && nbSel > 1 ) + nbSel = 1; + mySubMeshOrGroups->length( nbSel ); - if (myAction == MERGE_NODES) { - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - } - else - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(CellSelection); + if ( nbSel == 0 ) + { + LineEditMesh->setText(""); + return; + } + + LineEditMesh->setText( aString ); + + if (myAction == MERGE_NODES) { + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); } + else + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(CellSelection); // process groups - if ( myAction == MERGE_NODES && !myMesh->_is_nil() && myEntry != aCurrentEntry ) { - myGroups.clear(); - ListExclude->clear(); + myGroups.clear(); + if ( isMeshSelected ) + { SMESH::ListOfGroups_var aListOfGroups = myMesh->GetGroups(); GroupExclude->setEnabled( aListOfGroups->length() > 0 ); - for( int i = 0, n = aListOfGroups->length(); i < n; i++ ) { + for ( int i = 0, n = aListOfGroups->length(); i < n; i++ ) { SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; - if ( !aGroup->_is_nil() ) { // && aGroup->GetType() == SMESH::NODE + if ( !aGroup->_is_nil() ) { + if ( myAction == MERGE_ELEMENTS && aGroup->GetType() == SMESH::NODE ) + continue; QString aGroupName( aGroup->GetName() ); if ( !aGroupName.isEmpty() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + myGroups.append( aGroup ); QListWidgetItem* item = new QListWidgetItem( aGroupName ); item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ); item->setCheckState( Qt::Unchecked ); @@ -1228,9 +1259,9 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument() else if (myEditCurrentArgument == (QWidget*)KeepList && KeepList) { - AddKeepNodesButton->setEnabled( false ); - RemoveKeepNodesButton->setEnabled( false ); - if ( isKeepNodesIDsSelection() ) + AddKeepButton->setEnabled( false ); + RemoveKeepButton->setEnabled( false ); + if ( isKeepIDsSelection() ) { if (!myMesh->_is_nil() && !myActor) myActor = SMESH::FindActorByObject(myMesh); @@ -1258,9 +1289,9 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument() KeepList->blockSignals(true); foreach(anItem, listItemsToSel) anItem->setSelected(true); KeepList->blockSignals(blocked); - //onSelectKeepNode(); - AddKeepNodesButton->setEnabled( nbFound < aNbNodes ); - RemoveKeepNodesButton->setEnabled( nbFound > 0 ); + //onSelectKeep(); + AddKeepButton->setEnabled( nbFound < aNbNodes ); + RemoveKeepButton->setEnabled( nbFound > 0 ); } } } @@ -1272,10 +1303,10 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument() SALOME_ListIteratorOfListIO anIt (aList); for ( ; anIt.More() && !hasNewSelected; anIt.Next()) if ( anIt.Value()->hasEntry() ) - hasNewSelected = isNewKeepNodesGroup( anIt.Value()->getEntry() ); + hasNewSelected = isNewKeepGroup( anIt.Value()->getEntry() ); - AddKeepNodesButton->setEnabled( hasNewSelected ); - //RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() ); + AddKeepButton->setEnabled( hasNewSelected ); + //RemoveKeepButton->setEnabled( KeepList->selectedItems().count() ); } } } @@ -1292,7 +1323,7 @@ void SMESHGUI_MergeDlg::DeactivateActiveDialog() GroupCoincident->setEnabled(false); GroupEdit->setEnabled(false); GroupButtons->setEnabled(false); - if (myAction == MERGE_NODES) + //if (myAction == MERGE_NODES) { GroupExclude->setEnabled(false); GroupKeep->setEnabled(false); @@ -1318,7 +1349,7 @@ void SMESHGUI_MergeDlg::ActivateThisDialog() GroupCoincident->setEnabled(true); GroupEdit->setEnabled(true); GroupButtons->setEnabled(true); - if (myAction == MERGE_NODES) + //if (myAction == MERGE_NODES) { GroupExclude->setEnabled(false); GroupKeep->setEnabled(false); @@ -1390,16 +1421,7 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id) SMESH::UpdateView(); - // Costruction of the logical filter - SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (SMESH::MESHorSUBMESH); - SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (SMESH::GROUP); - - QList aListOfFilters; - if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter); - if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); - - myMeshOrSubMeshOrGroupFilter = - new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, true); + myMeshOrSubMeshOrGroupFilter = new SMESH_TypeFilter (SMESH::IDSOURCE); if (myAction == MERGE_NODES) { SMESH::SetPointRepresentation(true); @@ -1426,23 +1448,23 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id) } //======================================================================= -//function : isKeepNodesIDsSelection +//function : isKeepIDsSelection //purpose : Return true of Nodes to keep are selected by IDs //======================================================================= -bool SMESHGUI_MergeDlg::isKeepNodesIDsSelection() +bool SMESHGUI_MergeDlg::isKeepIDsSelection() { return KeepFromButGroup && KeepFromButGroup->checkedId() == 0; } //======================================================================= -//function : isNewKeepNodesGroup +//function : isNewKeepGroup //purpose : Return true if an object with given entry is NOT present in KeepList //======================================================================= -bool SMESHGUI_MergeDlg::isNewKeepNodesGroup( const char* entry ) +bool SMESHGUI_MergeDlg::isNewKeepGroup( const char* entry ) { - if ( !entry || isKeepNodesIDsSelection() ) + if ( !entry || isKeepIDsSelection() ) return false; for ( int i = 0; i < KeepList->count(); i++ ) @@ -1453,17 +1475,17 @@ bool SMESHGUI_MergeDlg::isNewKeepNodesGroup( const char* entry ) } //======================================================================= -//function : onAddKeepNode +//function : onAddKeep //purpose : SLOT called when [Add] of Nodes To Keep group is pressed //======================================================================= -void SMESHGUI_MergeDlg::onAddKeepNode() +void SMESHGUI_MergeDlg::onAddKeep() { if ( myIsBusy ) return; myIsBusy = true; - if ( isKeepNodesIDsSelection() ) + if ( isKeepIDsSelection() ) { //KeepList->clearSelection(); QString anIDs = ""; @@ -1494,9 +1516,9 @@ void SMESHGUI_MergeDlg::onAddKeepNode() KeepList->blockSignals(true); foreach(anItem, listItemsToSel) anItem->setSelected(true); KeepList->blockSignals(blocked); - //onSelectKeepNode(); + //onSelectKeep(); } - RemoveKeepNodesButton->setEnabled( aNbNodes > 0 ); + RemoveKeepButton->setEnabled( aNbNodes > 0 ); } else { @@ -1505,29 +1527,29 @@ void SMESHGUI_MergeDlg::onAddKeepNode() SALOME_ListIteratorOfListIO anIt (aList); for ( ; anIt.More(); anIt.Next()) { Handle(SALOME_InteractiveObject) anIO = anIt.Value(); - if ( isNewKeepNodesGroup( anIO->getEntry() )) + if ( isNewKeepGroup( anIO->getEntry() )) { QListWidgetItem* anItem = new QListWidgetItem( anIO->getName() ); anItem->setData( Qt::UserRole, QString( anIO->getEntry() )); KeepList->addItem(anItem); } } - //RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() ); + //RemoveKeepButton->setEnabled( KeepList->selectedItems().count() ); } - AddKeepNodesButton->setEnabled( false ); + AddKeepButton->setEnabled( false ); myIsBusy = false; } //======================================================================= -//function : onRemoveKeepNode +//function : onRemoveKeep //purpose : SLOT called when [Remove] of Nodes To Keep group is pressed //======================================================================= -void SMESHGUI_MergeDlg::onRemoveKeepNode() +void SMESHGUI_MergeDlg::onRemoveKeep() { - // if ( isKeepNodesIDsSelection() ) + // if ( isKeepIDsSelection() ) // { // } // else @@ -1536,24 +1558,24 @@ void SMESHGUI_MergeDlg::onRemoveKeepNode() QListWidgetItem* item; foreach(item, selItems) delete item; } - if ( isKeepNodesIDsSelection() ) + if ( isKeepIDsSelection() ) { - AddKeepNodesButton->setEnabled( false ); + AddKeepButton->setEnabled( false ); } - RemoveKeepNodesButton->setEnabled( false ); + RemoveKeepButton->setEnabled( false ); } //======================================================================= -//function : onSelectKeepNode +//function : onSelectKeep //purpose : SLOT called when selection in KeepList changes //======================================================================= -void SMESHGUI_MergeDlg::onSelectKeepNode() +void SMESHGUI_MergeDlg::onSelectKeep() { if ( myIsBusy || !isEnabled() ) return; myIsBusy = true; - if ( isKeepNodesIDsSelection() ) + if ( isKeepIDsSelection() ) { if ( myActor ) { @@ -1567,25 +1589,25 @@ void SMESHGUI_MergeDlg::onSelectKeepNode() aList.Append(myActor->getIO()); mySelectionMgr->setSelectedObjects(aList,false); - AddKeepNodesButton->setEnabled( false ); - RemoveKeepNodesButton->setEnabled( aIndexes.Extent() > 0 ); + AddKeepButton->setEnabled( false ); + RemoveKeepButton->setEnabled( aIndexes.Extent() > 0 ); } } else { - RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() ); + RemoveKeepButton->setEnabled( KeepList->selectedItems().count() ); } myIsBusy = false; } //======================================================================= -//function : onKeepNodeSourceChanged +//function : onKeepSourceChanged //purpose : SLOT called when type of source of Nodes To Keep change from // IDs to groups or vice versa //======================================================================= -void SMESHGUI_MergeDlg::onKeepNodeSourceChanged(int isGroup) +void SMESHGUI_MergeDlg::onKeepSourceChanged(int isGroup) { KeepList->clear(); - SelectKeepNodesButton->click(); + SelectKeepButton->click(); } diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.h b/src/SMESHGUI/SMESHGUI_MergeDlg.h index 6b087b631..f9af9af73 100644 --- a/src/SMESHGUI/SMESHGUI_MergeDlg.h +++ b/src/SMESHGUI/SMESHGUI_MergeDlg.h @@ -85,8 +85,8 @@ private: void enterEvent( QEvent* ); /* mouse enter the QWidget */ void keyPressEvent( QKeyEvent* ); void onEditGroup(); - bool isKeepNodesIDsSelection(); - bool isNewKeepNodesGroup( const char* entry ); + bool isKeepIDsSelection(); + bool isNewKeepGroup( const char* entry ); void FindGravityCenter( TColStd_MapOfInteger&, std::vector& , @@ -96,23 +96,29 @@ private: private: typedef QList GrpList; - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ - LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ - SVTK_Selector* mySelector; + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ + LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + SVTK_Selector* mySelector; - QWidget* myEditCurrentArgument; + QWidget* myEditCurrentArgument; - SMESH::SMESH_Mesh_var myMesh; - SMESH::SMESH_IDSource_var mySubMeshOrGroup; - SMESH_Actor* myActor; - SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter; - SUIT_SelectionFilter* mySubMeshOrGroupFilter; + SMESH::SMESH_Mesh_var myMesh; + SMESH::ListOfIDSources_var mySubMeshOrGroups; + GrpList myGroups; + QString myEntry; - SMESHGUI_IdPreview* myIdPreview; + SMESH_Actor* myActor; + SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter; + SUIT_SelectionFilter* mySubMeshOrGroupFilter; + + SMESHGUI_IdPreview* myIdPreview; + QString myHelpFileName; + + int myAction; + bool myIsBusy; + int myTypeId; // manual(1) or automatic(0) + - int myAction; - bool myIsBusy; - int myTypeId; // manual(1) or automatic(0) // Widgets @@ -152,18 +158,13 @@ private: QGroupBox* GroupKeep; QButtonGroup* KeepFromButGroup; - QPushButton* SelectKeepNodesButton; - QPushButton* AddKeepNodesButton; - QPushButton* RemoveKeepNodesButton; + QPushButton* SelectKeepButton; + QPushButton* AddKeepButton; + QPushButton* RemoveKeepButton; QListWidget* KeepList; QGroupBox* TypeBox; QButtonGroup* GroupType; - - QString myHelpFileName; - - QString myEntry; - GrpList myGroups; protected slots: virtual void reject(); @@ -174,10 +175,10 @@ protected slots: void ClickOnHelp(); void updateControls(); void onDetect(); - void onAddKeepNode(); - void onRemoveKeepNode(); - void onSelectKeepNode(); - void onKeepNodeSourceChanged(int); + void onAddKeep(); + void onRemoveKeep(); + void onSelectKeep(); + void onKeepSourceChanged(int); void onAddGroup(); void onRemoveGroup(); void onSelectGroup(); diff --git a/src/SMESHGUI/SMESHGUI_Utils.cxx b/src/SMESHGUI/SMESHGUI_Utils.cxx index 5721e5301..11d10cb68 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.cxx +++ b/src/SMESHGUI/SMESHGUI_Utils.cxx @@ -242,13 +242,30 @@ namespace SMESH int aNbSel = selected.Extent(); if (aNbSel == 1) { Handle(SALOME_InteractiveObject) anIObject = selected.First(); - theName = QString( anIObject->getName() ).trimmed(); + theName = GetName( anIObject ); } else { theName = QObject::tr("SMESH_OBJECTS_SELECTED").arg(aNbSel); } return aNbSel; } + QString GetName( const Handle(SALOME_InteractiveObject)& theIO ) + { + QString name; + if ( !theIO.IsNull() ) + { + name = QString( theIO->getName() ).trimmed(); + + if ( name.isEmpty() && theIO->hasEntry() ) + { + _PTR(SObject) sObj = getStudy()->FindObjectID( theIO->getEntry() ); + if ( sObj ) + name = sObj->GetName().c_str(); + } + } + return name.trimmed(); + } + _PTR(SObject) GetMeshOrSubmesh (_PTR(SObject) theSObject) { GEOM::GEOM_Object_var aShape = SObjectToInterface(theSObject); diff --git a/src/SMESHGUI/SMESHGUI_Utils.h b/src/SMESHGUI/SMESHGUI_Utils.h index 41d2e674e..a403da868 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.h +++ b/src/SMESHGUI/SMESHGUI_Utils.h @@ -167,6 +167,9 @@ SMESHGUI_EXPORT SMESHGUI_EXPORT int GetNameOfSelectedIObjects( LightApp_SelectionMgr*, QString& ); +SMESHGUI_EXPORT + QString GetName( const Handle(SALOME_InteractiveObject)& theIO ); + SMESHGUI_EXPORT _PTR(SObject) GetMeshOrSubmesh( _PTR(SObject) ); diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index c4ffdde6f..222fa1e06 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -2292,6 +2292,10 @@ Check algorithm documentation for supported geometry SMESH_NAME Name + + SMESH_NAMES + Names + SMESH_NODES Nodes @@ -5490,6 +5494,10 @@ Please select a group and try again KEEP_NODES Nodes to keep during the merge + + KEEP_ELEMENTS + Elements to keep during the merge + GROUP_SUBMESH Groups and sub-meshes diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index f1e40ec43..b03eca37d 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -298,33 +298,35 @@ namespace MeshEditor_I { */ //================================================================================ - void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject, - const SMESHDS_Mesh* theMeshDS, - TIDSortedNodeSet& theNodeSet) + void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject, + const SMESHDS_Mesh* theMeshDS, + TIDSortedNodeSet& theNodeSet) { if ( CORBA::is_nil( theObject ) ) return; - SMESH::array_of_ElementType_var types = theObject->GetTypes(); - SMESH::long_array_var aElementsId = theObject->GetIDs(); - if ( types->length() == 1 && types[0] == SMESH::NODE) + if ( SMESH::DownCast( theObject )) { - for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ ) - if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] )) - theNodeSet.insert( theNodeSet.end(), n); - } - else if ( SMESH::DownCast( theObject )) - { - SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator(); - while ( nIt->more( )) + for ( SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator(); nIt->more(); ) if ( const SMDS_MeshElement * elem = nIt->next() ) theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); } else { - for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ ) - if ( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] )) - theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + SMESH::long_array_var aElementsId = theObject->GetIDs(); + if ( types->length() == 1 && types[0] == SMESH::NODE) + { + for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ ) + if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] )) + theNodeSet.insert( theNodeSet.end(), n); + } + else + { + for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ ) + if ( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] )) + theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); + } } } @@ -4199,13 +4201,13 @@ FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject, //================================================================================ /*! - * \brief Finds nodes coincident with Tolerance within Object excluding nodes within + * \brief Finds nodes coincident with Tolerance within Objects excluding nodes within * ExceptSubMeshOrGroups */ //================================================================================ void SMESH_MeshEditor_i:: -FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject, +FindCoincidentNodesOnPartBut(const SMESH::ListOfIDSources& theObjects, CORBA::Double theTolerance, SMESH::array_of_long_array_out theGroupsOfNodes, const SMESH::ListOfIDSources& theExceptSubMeshOrGroups, @@ -4216,9 +4218,11 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject, initData(); TIDSortedNodeSet nodes; - prepareIdSource( theObject ); - idSourceToNodeSet( theObject, getMeshDS(), nodes ); - + for ( CORBA::ULong i = 0; i < theObjects.length(); ++i ) + { + prepareIdSource( theObjects[i] ); + idSourceToNodeSet( theObjects[i], getMeshDS(), nodes ); + } for ( CORBA::ULong i = 0; i < theExceptSubMeshOrGroups.length(); ++i ) { if ( SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( theExceptSubMeshOrGroups[i], @@ -4229,7 +4233,7 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject, findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium ); TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( " - << theObject<<", " + << theObjects <<", " << theTolerance << ", " << theExceptSubMeshOrGroups << ", " << theSeparateCornersAndMedium << " )"; @@ -4302,30 +4306,47 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN //purpose : //======================================================================= -void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObject, - SMESH::array_of_long_array_out GroupsOfElementsID) +void SMESH_MeshEditor_i::FindEqualElements(const SMESH::ListOfIDSources& theObjects, + const SMESH::ListOfIDSources& theExceptObjects, + SMESH::array_of_long_array_out theGroupsOfElementsID) throw (SALOME::SALOME_Exception) { SMESH_TRY; initData(); - SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject); - if ( !( !group->_is_nil() && group->GetType() == SMESH::NODE )) + theGroupsOfElementsID = new SMESH::array_of_long_array; + + TIDSortedElemSet elems; + bool hasOkObject = false; + bool emptyIfIsMesh= ( theObjects.length() == 1 && theExceptObjects.length() == 0 ); + + for ( CORBA::ULong i = 0; i < theObjects.length(); ++i ) { - TIDSortedElemSet elems; - idSourceToSet( theObject, getMeshDS(), elems, SMDSAbs_All, /*emptyIfIsMesh=*/true); + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow( theObjects[i] ); + if ( !( !group->_is_nil() && group->GetType() == SMESH::NODE )) + if ( idSourceToSet( theObjects[i], getMeshDS(), elems, SMDSAbs_All, emptyIfIsMesh )) + hasOkObject = true; + } + + if ( hasOkObject ) + { + for ( CORBA::ULong i = 0; i < theExceptObjects.length(); ++i ) + { + if ( SMDS_ElemIteratorPtr elemIt = myMesh_i->GetElements( theExceptObjects[i], SMESH::ALL )) + while ( elemIt->more() ) + elems.erase( elemIt->next() ); + } ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; getEditor().FindEqualElements( elems, aListOfListOfElementsID ); - GroupsOfElementsID = new SMESH::array_of_long_array; - GroupsOfElementsID->length( aListOfListOfElementsID.size() ); + theGroupsOfElementsID->length( aListOfListOfElementsID.size() ); ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin(); for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) { - SMESH::long_array& aGroup = (*GroupsOfElementsID)[ j ]; + SMESH::long_array& aGroup = (*theGroupsOfElementsID)[ j ]; list& listOfIDs = *arraysIt; aGroup.length( listOfIDs.size() ); list::iterator idIt = listOfIDs.begin(); @@ -4334,7 +4355,8 @@ void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr theObj } TPythonDump() << "equal_elements = " << this << ".FindEqualElements( " - < idsToKeep; + for ( CORBA::ULong i = 0; i < theElementsToKeep.length(); i++ ) + { + if ( CORBA::is_nil( theElementsToKeep[i] )) + continue; + SMESH::array_of_ElementType_var elemTypes = theElementsToKeep[i]->GetTypes(); + if ( elemTypes->length() == 1 && elemTypes[0] == SMESH::NODE ) + continue; + SMESH::long_array_var elementsId = theElementsToKeep[i]->GetIDs(); + for ( CORBA::ULong j = 0; j < elementsId->length(); ++j ) + idsToKeep.Add( elementsId[ j ]); + } + ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID; - for ( CORBA::ULong i = 0; i < GroupsOfElementsID.length(); i++ ) { - const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ]; + for ( CORBA::ULong i = 0; i < theGroupsOfElementsID.length(); i++ ) + { + const SMESH::long_array& anElemsIDGroup = theGroupsOfElementsID[ i ]; aListOfListOfElementsID.push_back( list< int >() ); list< int >& aListOfElemsID = aListOfListOfElementsID.back(); - for ( CORBA::ULong j = 0; j < anElemsIDGroup.length(); j++ ) { + for ( CORBA::ULong j = 0; j < anElemsIDGroup.length(); j++ ) + { CORBA::Long id = anElemsIDGroup[ j ]; - aListOfElemsID.push_back( id ); + if ( idsToKeep.Contains( id )) aListOfElemsID.push_front( id ); + else aListOfElemsID.push_back( id ); } if ( aListOfElemsID.size() < 2 ) aListOfListOfElementsID.pop_back(); @@ -4374,7 +4413,7 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO declareMeshModified( /*isReComputeSafe=*/true ); - aTPythonDump << "] )"; + aTPythonDump << "], " << theElementsToKeep << " )"; SMESH_CATCH( SMESH::throwCorbaException ); } @@ -5809,10 +5848,21 @@ bool SMESH_MeshEditor_i::idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource, } if ( emptyIfIsMesh && SMESH::DownCast( theIDSource )) { - if ( error && getMeshDS()->GetMeshInfo().NbElements( theType ) == 0 ) + if ( error && theMeshDS->GetMeshInfo().NbElements( theType ) == 0 ) *error = IDSource_EMPTY; return true; } + if ( getMeshDS() == theMeshDS ) // check if theIDSource belongs to myMesh + { + SMESH::SMESH_Mesh_var mesh = theIDSource->GetMesh(); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh ); + if ( mesh_i && mesh_i != myMesh_i ) + { + if ( error ) + *error = IDSource_INVALID; + return false; + } + } prepareIdSource( theIDSource ); SMESH::long_array_var anIDs = theIDSource->GetIDs(); if ( anIDs->length() == 0 ) diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 462d42db2..d8c46a64f 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -501,7 +501,7 @@ public: SMESH::array_of_long_array_out GroupsOfNodes, CORBA::Boolean SeparateCornersAndMedium) throw (SALOME::SALOME_Exception); - void FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr Object, + void FindCoincidentNodesOnPartBut(const SMESH::ListOfIDSources& Objects, CORBA::Double Tolerance, SMESH::array_of_long_array_out GroupsOfNodes, const SMESH::ListOfIDSources& ExceptSubMeshOrGroups, @@ -511,10 +511,12 @@ public: const SMESH::ListOfIDSources& NodesToKeep, CORBA::Boolean AvoidMakingHoles ) throw (SALOME::SALOME_Exception); - void FindEqualElements(SMESH::SMESH_IDSource_ptr Object, + void FindEqualElements(const SMESH::ListOfIDSources& Objects, + const SMESH::ListOfIDSources& ExceptSubMeshOrGroups, SMESH::array_of_long_array_out GroupsOfElementsID) throw (SALOME::SALOME_Exception); - void MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID) + void MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID, + const SMESH::ListOfIDSources& ElementsToKeep) throw (SALOME::SALOME_Exception); void MergeEqualElements() throw (SALOME::SALOME_Exception); diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 026858782..20b7bc038 100755 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -5680,6 +5680,8 @@ class Mesh(metaclass = MeshMeta): Example: :ref:`tui_extrusion_along_path` """ + if not IDsOfElements: + IDsOfElements = [ self.GetMesh() ] n,e,f = [],IDsOfElements,IDsOfElements gr,er = self.ExtrusionAlongPathObjects(n,e,f, PathMesh, PathShape, NodeStart, HasAngles, Angles, @@ -6239,7 +6241,7 @@ class Mesh(metaclass = MeshMeta): Parameters: Tolerance: the value of tolerance - SubMeshOrGroup: :class:`sub-mesh, group or filter ` or node IDs + SubMeshOrGroup: list of :class:`sub-meshes, groups or filters ` or of node IDs exceptNodes: list of either SubMeshes, Groups or node IDs to exclude from search SeparateCornerAndMediumNodes: if *True*, in quadratic mesh puts corner and medium nodes in separate groups thus preventing @@ -6250,11 +6252,16 @@ class Mesh(metaclass = MeshMeta): """ unRegister = genObjUnRegister() - if (isinstance( SubMeshOrGroup, Mesh )): - SubMeshOrGroup = SubMeshOrGroup.GetMesh() - if isinstance( SubMeshOrGroup, list ): - SubMeshOrGroup = self.GetIDSource( SubMeshOrGroup, SMESH.NODE ) - unRegister.set( SubMeshOrGroup ) + if not isinstance( SubMeshOrGroup, list ): + SubMeshOrGroup = [ SubMeshOrGroup ] + for i,obj in enumerate( SubMeshOrGroup ): + if isinstance( obj, Mesh ): + SubMeshOrGroup = [ obj.GetMesh() ] + break + if isinstance( obj, int ): + SubMeshOrGroup = self.GetIDSource( SubMeshOrGroup, SMESH.NODE ) + unRegister.set( SubMeshOrGroup ) + break if not isinstance( exceptNodes, list ): exceptNodes = [ exceptNodes ] @@ -6272,44 +6279,72 @@ class Mesh(metaclass = MeshMeta): Parameters: GroupsOfNodes: a list of groups of nodes IDs for merging. E.g. [[1,12,13],[25,4]] means that nodes 12, 13 and 4 will be removed and replaced - in all elements and groups by nodes 1 and 25 correspondingly + in all elements and mesh groups by nodes 1 and 25 correspondingly NodesToKeep: nodes to keep in the mesh: a list of groups, sub-meshes or node IDs. If *NodesToKeep* does not include a node to keep for some group to merge, then the first node in the group is kept. AvoidMakingHoles: prevent merging nodes which cause removal of elements becoming invalid """ - # NodesToKeep are converted to SMESH.SMESH_IDSource in meshEditor.MergeNodes() self.editor.MergeNodes( GroupsOfNodes, NodesToKeep, AvoidMakingHoles ) - def FindEqualElements (self, MeshOrSubMeshOrGroup=None): + def FindEqualElements (self, MeshOrSubMeshOrGroup=None, exceptElements=[]): """ Find the elements built on the same nodes. Parameters: - MeshOrSubMeshOrGroup: :class:`mesh, sub-mesh, group or filter ` + MeshOrSubMeshOrGroup: :class:`mesh, sub-meshes, groups or filters ` or element IDs to check for equal elements + exceptElements: list of either SubMeshes, Groups or elements IDs to exclude from search + Returns: the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]]) """ - if not MeshOrSubMeshOrGroup: - MeshOrSubMeshOrGroup=self.mesh + unRegister = genObjUnRegister() + if MeshOrSubMeshOrGroup is None: + MeshOrSubMeshOrGroup = [ self.mesh ] elif isinstance( MeshOrSubMeshOrGroup, Mesh ): - MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh() - return self.editor.FindEqualElements( MeshOrSubMeshOrGroup ) - - def MergeElements(self, GroupsOfElementsID): + MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup.GetMesh() ] + elif not isinstance( MeshOrSubMeshOrGroup, list ): + MeshOrSubMeshOrGroup = [ MeshOrSubMeshOrGroup ] + if isinstance( MeshOrSubMeshOrGroup[0], int ): + MeshOrSubMeshOrGroup = [ self.GetIDSource( MeshOrSubMeshOrGroup, SMESH.ALL )] + unRegister.set( MeshOrSubMeshOrGroup ) + for item in MeshOrSubMeshOrGroup: + if isinstance( item, Mesh ): + MeshOrSubMeshOrGroup = [ item.GetMesh() ] + + if not isinstance( exceptElements, list ): + exceptElements = [ exceptElements ] + if exceptElements and isinstance( exceptElements[0], int ): + exceptElements = [ self.GetIDSource( exceptElements, SMESH.ALL )] + unRegister.set( exceptElements ) + + return self.editor.FindEqualElements( MeshOrSubMeshOrGroup, exceptElements ) + + def MergeElements(self, GroupsOfElementsID, ElementsToKeep=[]): """ Merge elements in each given group. Parameters: GroupsOfElementsID: a list of groups (lists) of elements IDs for merging (e.g. [[1,12,13],[25,4]] means that elements 12, 13 and 4 will be removed and - replaced in all groups by elements 1 and 25) + replaced in all mesh groups by elements 1 and 25) + ElementsToKeep: elements to keep in the mesh: a list of groups, sub-meshes or node IDs. + If *ElementsToKeep* does not include an element to keep for some group to merge, + then the first element in the group is kept. """ - self.editor.MergeElements(GroupsOfElementsID) + unRegister = genObjUnRegister() + if ElementsToKeep: + if not isinstance( ElementsToKeep, list ): + ElementsToKeep = [ ElementsToKeep ] + if isinstance( ElementsToKeep[0], int ): + ElementsToKeep = [ self.GetIDSource( ElementsToKeep, SMESH.ALL )] + unRegister.set( ElementsToKeep ) + + self.editor.MergeElements( GroupsOfElementsID, ElementsToKeep ) def MergeEqualElements(self): """