23081: [CEA 1496] Control merge nodes behaviour: set fixed nodes

This commit is contained in:
eap 2015-07-10 19:39:03 +03:00
parent 38f832b912
commit de00066f64
16 changed files with 466 additions and 51 deletions

View File

@ -1,10 +1,14 @@
# Merging Nodes # Merging Nodes
import SMESH_mechanic import SMESH_mechanic, SMESH
mesh = SMESH_mechanic.mesh mesh = SMESH_mechanic.mesh
# merge nodes # merge nodes
Tolerance = 25.0 Tolerance = 4.0
# 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) GroupsOfNodes = mesh.FindCoincidentNodes(Tolerance)
mesh.MergeNodes(GroupsOfNodes) mesh.MergeNodes(GroupsOfNodes, NodesToKeep=allSegs)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 32 KiB

BIN
doc/salome/gui/SMESH/images/merging_nodes1.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 12 KiB

BIN
doc/salome/gui/SMESH/images/merging_nodes2.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -26,7 +26,23 @@ merging.</li>
nodes. This check-box is enabled provided that the selected mesh nodes. This check-box is enabled provided that the selected mesh
includes quadratic elements.</li> includes quadratic elements.</li>
<li><b>Exclude Groups</b> group box allows to ignore the nodes which <li><b>Exclude Groups</b> group box allows to ignore the nodes which
belong to the specified mesh groups. belong to the specified mesh groups.</li>
<li><b>Nodes to keep</b> group box allows to specify nodes to keep in
the mesh. (By default a node being the first in a group of
coincident nodes is kept.) It is possible to either select nodes in
the Viewer or select groups of any element type whose nodes will be
kept.
<ol>
<li>\a Selection button activates selection of nodes to keep.</li>
<li><b>Node IDs</b> button activates selection of nodes in the
Viewer.</li>
<li><b>Groups and Sub-meshes</b> button activates selection of
groups and sub-meshes.</li>
<li>\b Add button adds selected nodes or groups to the list.</li>
<li> Nodes or groups selected in the list can be removed using \b
Remove button.</li>
</ol>
</li>
</ul> </ul>
<li><b>Automatic mode:</b> <li><b>Automatic mode:</b>
@ -79,7 +95,7 @@ nodes of selected groups in the 3D viewer.</li>
\image html merging_nodes1.png "The initial object" \image html merging_nodes1.png "The initial object"
\image html merging_nodes2.png "The object has been merged with a very big tolerance" \image html merging_nodes2.png "The object has been merged"
<br><b>See Also</b> a sample TUI Script of a <br><b>See Also</b> a sample TUI Script of a
\ref tui_merging_nodes "Merge Nodes" operation. \ref tui_merging_nodes "Merge Nodes" operation.

View File

@ -10,7 +10,7 @@ So that
- bi-quadratic quadrangle will be split into 4 linear quadrangles; - bi-quadratic quadrangle will be split into 4 linear quadrangles;
- tri-quadratic hexahedron will be split into 8 linear hexahedra; - tri-quadratic hexahedron will be split into 8 linear hexahedra;
- quadratic segments adjacent to the split bi-quadratic element will - quadratic segments adjacent to the split bi-quadratic element will
be split into 2 liner segment. be split into 2 liner segments.
\image html split_biquad_to_linear_mesh.png "Mesh before and after splitting" \image html split_biquad_to_linear_mesh.png "Mesh before and after splitting"

View File

@ -658,7 +658,8 @@ module SMESH
in boolean SeparateCornersAndMedium) in boolean SeparateCornersAndMedium)
raises (SALOME::SALOME_Exception); raises (SALOME::SALOME_Exception);
void MergeNodes (in array_of_long_array GroupsOfNodes) void MergeNodes (in array_of_long_array GroupsOfNodes,
in SMESH::ListOfIDSources NodesToKeep)
raises (SALOME::SALOME_Exception); raises (SALOME::SALOME_Exception);
/*! /*!

View File

@ -1334,7 +1334,7 @@ bool SMESH_Mesh::HasModificationsToDiscard() const
// return true if the next Compute() will be partial and // return true if the next Compute() will be partial and
// existing but changed elements may prevent successful re-compute // existing but changed elements may prevent successful re-compute
bool hasComputed = false, hasNotComputed = false; bool hasComputed = false, hasNotComputed = false;
SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() );
while ( smIt->more() ) while ( smIt->more() )
{ {
const SMESH_subMesh* aSubMesh = smIt->next(); const SMESH_subMesh* aSubMesh = smIt->next();

View File

@ -7334,16 +7334,17 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
// Fill nodeNodeMap and elems // Fill nodeNodeMap and elems
TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin(); TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin();
for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) { for ( ; grIt != theGroupsOfNodes.end(); grIt++ )
{
list<const SMDS_MeshNode*>& nodes = *grIt; list<const SMDS_MeshNode*>& nodes = *grIt;
list<const SMDS_MeshNode*>::iterator nIt = nodes.begin(); list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
const SMDS_MeshNode* nToKeep = *nIt; const SMDS_MeshNode* nToKeep = *nIt;
//MESSAGE("node to keep " << nToKeep->GetID()); for ( ++nIt; nIt != nodes.end(); nIt++ )
for ( ++nIt; nIt != nodes.end(); nIt++ ) { {
const SMDS_MeshNode* nToRemove = *nIt; const SMDS_MeshNode* nToRemove = *nIt;
nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep )); nodeNodeMap.insert( make_pair( nToRemove, nToKeep ));
if ( nToRemove != nToKeep ) { if ( nToRemove != nToKeep )
//MESSAGE(" node to remove " << nToRemove->GetID()); {
rmNodeIds.push_back( nToRemove->GetID() ); rmNodeIds.push_back( nToRemove->GetID() );
AddToSameGroups( nToKeep, nToRemove, aMesh ); AddToSameGroups( nToKeep, nToRemove, aMesh );
// set _alwaysComputed to a sub-mesh of VERTEX to enable mesh computing // set _alwaysComputed to a sub-mesh of VERTEX to enable mesh computing
@ -7353,7 +7354,6 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() )) if ( SMESH_subMesh* sm = myMesh->GetSubMeshContaining( nToRemove->getshapeId() ))
sm->SetIsAlwaysComputed( true ); sm->SetIsAlwaysComputed( true );
} }
SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator(); SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
while ( invElemIt->more() ) { while ( invElemIt->more() ) {
const SMDS_MeshElement* elem = invElemIt->next(); const SMDS_MeshElement* elem = invElemIt->next();

View File

@ -95,7 +95,7 @@
namespace namespace
{ {
enum ActionType { MERGE_NODES, MERGE_ELEMENTS }; enum ActionType { MERGE_NODES, MERGE_ELEMENTS, TYPE_AUTO=0, TYPE_MANUAL };
} }
namespace SMESH namespace SMESH
{ {
@ -363,7 +363,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
GroupMeshLayout->addWidget(LineEditMesh); GroupMeshLayout->addWidget(LineEditMesh);
/***************************************************************/ /***************************************************************/
// Controls for switch dialog behaviour // Controls for switch dialog behaviour (myTypeId)
TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this ); TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this );
GroupType = new QButtonGroup( this ); GroupType = new QButtonGroup( this );
@ -378,7 +378,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
aTypeBoxLayout->addWidget( rb1 ); aTypeBoxLayout->addWidget( rb1 );
aTypeBoxLayout->addWidget( rb2 ); aTypeBoxLayout->addWidget( rb2 );
myTypeId = 0; myTypeId = TYPE_AUTO;
/***************************************************************/ /***************************************************************/
// Controls for coincident elements detecting // Controls for coincident elements detecting
@ -410,6 +410,32 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
GroupExcludeLayout->setMargin(MARGIN); GroupExcludeLayout->setMargin(MARGIN);
GroupExcludeLayout->addWidget(ListExclude); GroupExcludeLayout->addWidget(ListExclude);
QGroupBox* GroupKeep = new QGroupBox(tr("KEEP_NODES"), foo);
SelectKeepNodesButton = new QPushButton( GroupKeep );
SelectKeepNodesButton->setIcon( IconSelect );
QLabel* selectLabel = new QLabel(tr("SELECT"));
QRadioButton* idsButton = new QRadioButton(tr("NODE_IDS"), 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, 2, 4 );
GroupKeepLayout->addWidget( AddKeepNodesButton, 1, 4, 1, 1 );
GroupKeepLayout->addWidget( RemoveKeepNodesButton, 2, 4, 1, 1 );
QGridLayout* fooLayout = new QGridLayout( foo ); QGridLayout* fooLayout = new QGridLayout( foo );
fooLayout->setSpacing(SPACING); fooLayout->setSpacing(SPACING);
fooLayout->setMargin(0); fooLayout->setMargin(0);
@ -417,13 +443,27 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
fooLayout->addWidget(SpinBoxTolerance, 0, 1 ); fooLayout->addWidget(SpinBoxTolerance, 0, 1 );
fooLayout->addWidget(SeparateCornersAndMedium, 1, 0 ); fooLayout->addWidget(SeparateCornersAndMedium, 1, 0 );
fooLayout->addWidget(GroupExclude, 2, 0, 1, 2 ); fooLayout->addWidget(GroupExclude, 2, 0, 1, 2 );
fooLayout->addWidget(GroupKeep, 3, 0, 1, 2 );
aCoincidentLayout->addWidget(foo); aCoincidentLayout->addWidget(foo);
// Costruction of the logical filter
QList<SUIT_SelectionFilter*> aListOfFilters;
aListOfFilters << new SMESH_TypeFilter (SMESH::SUBMESH)
<< new SMESH_TypeFilter (SMESH::GROUP);
mySubMeshOrGroupFilter =
new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR, /*takeOwnership=*/true);
} }
else { else {
TextLabelTolerance = 0; TextLabelTolerance = 0;
SpinBoxTolerance = 0; SpinBoxTolerance = 0;
GroupExclude = 0; GroupExclude = 0;
ListExclude = 0; ListExclude = 0;
KeepFromButGroup = 0;
SelectKeepNodesButton = 0;
AddKeepNodesButton = 0;
RemoveKeepNodesButton = 0;
KeepList = 0;
mySubMeshOrGroupFilter = 0;
} }
GroupCoincidentWidget = new QWidget(GroupCoincident); GroupCoincidentWidget = new QWidget(GroupCoincident);
@ -562,6 +602,14 @@ void SMESHGUI_MergeDlg::Init()
connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
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(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect())); connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup())); connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup()));
@ -572,7 +620,7 @@ void SMESHGUI_MergeDlg::Init()
connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup())); connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup()));
connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement())); connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement()));
connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement())); connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement()));
connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) ); connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst()));
connect(GroupType, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int))); connect(GroupType, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int)));
connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
@ -638,7 +686,7 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
return false; return false;
try { try {
if (myTypeId == 0) if (myTypeId == TYPE_AUTO)
onDetect(); onDetect();
SUIT_OverrideCursor aWaitCursor; SUIT_OverrideCursor aWaitCursor;
@ -672,12 +720,51 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
aGroupsOfElements[anArrayNum++] = anIds.inout(); aGroupsOfElements[anArrayNum++] = anIds.inout();
} }
SMESH::ListOfIDSources_var nodesToKeep;
SMESH::IDSource_wrap tmpIdSource;
if ( myAction == MERGE_NODES )
{
nodesToKeep = new SMESH::ListOfIDSources();
int i, nb = KeepList->count();
if ( isKeepNodesIDsSelection() )
{
SMESH::long_array_var anIdList = new SMESH::long_array();
anIdList->length(nb);
for (i = 0; i < nb; i++)
anIdList[i] = KeepList->item(i)->text().toInt();
if ( nb > 0 )
{
tmpIdSource = aMeshEditor->MakeIDSource( anIdList, SMESH::NODE );
nodesToKeep->length( 1 );
nodesToKeep[0] = SMESH::SMESH_IDSource::_duplicate( tmpIdSource.in() );
}
}
else
{
nodesToKeep->length( nb );
int nbObj = 0;
for (i = 0; i < nb; i++)
{
QString entry = KeepList->item( i )->data( Qt::UserRole ).toString();
Handle(SALOME_InteractiveObject) anIO =
new SALOME_InteractiveObject( entry.toStdString().c_str(), "SMESH" );
SMESH::SMESH_IDSource_var idSrc =
SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( anIO );
if ( !idSrc->_is_nil() )
nodesToKeep[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( idSrc );
}
nodesToKeep->length( nbObj );
}
KeepList->clear();
}
if( myAction == MERGE_NODES ) if( myAction == MERGE_NODES )
aMeshEditor->MergeNodes (aGroupsOfElements.inout()); aMeshEditor->MergeNodes (aGroupsOfElements.inout(), nodesToKeep);
else else
aMeshEditor->MergeElements (aGroupsOfElements.inout()); aMeshEditor->MergeElements (aGroupsOfElements.inout());
if ( myTypeId == 0 ) { if ( myTypeId == TYPE_AUTO ) {
if (myAction == MERGE_NODES ) if (myAction == MERGE_NODES )
SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
tr("SMESH_MERGED_NODES").arg(QString::number(ListCoincident->count()).toLatin1().data())); tr("SMESH_MERGED_NODES").arg(QString::number(ListCoincident->count()).toLatin1().data()));
@ -685,9 +772,10 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data())); tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data()));
} }
nodesToKeep->length(0); // release before tmpIdSource calls UnRegister()
}
} catch(...) { catch(...) {
} }
ListCoincident->clear(); ListCoincident->clear();
@ -810,7 +898,7 @@ void SMESHGUI_MergeDlg::updateControls()
{ {
if (ListEdit->count() == 0) if (ListEdit->count() == 0)
SetFirstButton->setEnabled(false); SetFirstButton->setEnabled(false);
bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == 0)); bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == TYPE_AUTO));
buttonOk->setEnabled(enable); buttonOk->setEnabled(enable);
buttonApply->setEnabled(enable); buttonApply->setEnabled(enable);
DetectButton->setEnabled( !myMesh->_is_nil() ); DetectButton->setEnabled( !myMesh->_is_nil() );
@ -823,6 +911,13 @@ void SMESHGUI_MergeDlg::updateControls()
myMesh->NbVolumesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 )); myMesh->NbVolumesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 ));
SeparateCornersAndMedium->setEnabled( has2ndOrder ); SeparateCornersAndMedium->setEnabled( has2ndOrder );
if ( myEditCurrentArgument != KeepList )
{
AddKeepNodesButton->setEnabled( false );
RemoveKeepNodesButton->setEnabled( false );
KeepList->clearSelection();
}
} }
} }
@ -1149,14 +1244,32 @@ void SMESHGUI_MergeDlg::SetEditCurrentArgument()
mySelectionMgr->clearSelected(); mySelectionMgr->clearSelected();
mySelectionMgr->clearFilters(); mySelectionMgr->clearFilters();
if (send == SelectMeshButton) { if (send == SelectMeshButton)
{
myEditCurrentArgument = (QWidget*)LineEditMesh; myEditCurrentArgument = (QWidget*)LineEditMesh;
SMESH::SetPointRepresentation(false); SMESH::SetPointRepresentation(false);
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode(ActorSelection); aViewWindow->SetSelectionMode(ActorSelection);
if (myTypeId == 1) if (myTypeId == TYPE_MANUAL)
mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
} }
else if ( send == SelectKeepNodesButton && send )
{
myEditCurrentArgument = (QWidget*)KeepList;
KeepList->setWrapping( isKeepNodesIDsSelection() );
if ( isKeepNodesIDsSelection() )
{
SMESH::SetPointRepresentation( true );
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode( NodeSelection );
}
else
{
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
aViewWindow->SetSelectionMode( ActorSelection );
mySelectionMgr->installFilter( mySubMeshOrGroupFilter );
}
}
myEditCurrentArgument->setFocus(); myEditCurrentArgument->setFocus();
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
@ -1165,11 +1278,12 @@ void SMESHGUI_MergeDlg::SetEditCurrentArgument()
//================================================================================= //=================================================================================
// function : SelectionIntoArgument() // function : SelectionIntoArgument()
// purpose : Called when selection as changed or other case // purpose : Called when selection has changed or other case
//================================================================================= //=================================================================================
void SMESHGUI_MergeDlg::SelectionIntoArgument() void SMESHGUI_MergeDlg::SelectionIntoArgument()
{ {
if (myEditCurrentArgument == (QWidget*)LineEditMesh) { if (myEditCurrentArgument == (QWidget*)LineEditMesh)
{
QString aString = ""; QString aString = "";
LineEditMesh->setText(aString); LineEditMesh->setText(aString);
@ -1196,6 +1310,9 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
myEntry = IO->getEntry(); myEntry = IO->getEntry();
myMesh = SMESH::GetMeshByIO(IO); myMesh = SMESH::GetMeshByIO(IO);
if ( myEntry != aCurrentEntry && KeepList )
KeepList->clear();
if (myMesh->_is_nil()) if (myMesh->_is_nil())
return; return;
@ -1205,7 +1322,7 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
if (!myActor) if (!myActor)
myActor = SMESH::FindActorByObject(myMesh); myActor = SMESH::FindActorByObject(myMesh);
if ( myActor && myTypeId == 1 && mySelector->IsSelectionEnabled() ) { if ( myActor && myTypeId == TYPE_MANUAL && mySelector->IsSelectionEnabled() ) {
mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil(); mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
@ -1246,6 +1363,59 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
updateControls(); updateControls();
} }
else if (myEditCurrentArgument == (QWidget*)KeepList && KeepList)
{
AddKeepNodesButton->setEnabled( false );
RemoveKeepNodesButton->setEnabled( false );
if ( isKeepNodesIDsSelection() )
{
if (!myMesh->_is_nil() && !myActor)
myActor = SMESH::FindActorByObject(myMesh);
if ( mySelector && myActor )
{
KeepList->clearSelection();
QString anIDs = "";
int aNbNodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
if (aNbNodes > 0)
{
QStringList anNodes = anIDs.split( " ", QString::SkipEmptyParts);
QList<QListWidgetItem*> listItemsToSel;
QListWidgetItem* anItem;
int nbFound = 0;
for (QStringList::iterator it = anNodes.begin(); it != anNodes.end(); ++it)
{
QList<QListWidgetItem*> found = KeepList->findItems(*it, Qt::MatchExactly);
foreach(anItem, found)
if (!anItem->isSelected())
listItemsToSel.push_back(anItem);
nbFound += found.count();
}
bool blocked = KeepList->signalsBlocked();
KeepList->blockSignals(true);
foreach(anItem, listItemsToSel) anItem->setSelected(true);
KeepList->blockSignals(blocked);
//onSelectKeepNode();
AddKeepNodesButton->setEnabled( nbFound < aNbNodes );
RemoveKeepNodesButton->setEnabled( nbFound > 0 );
}
}
}
else if ( !myMesh->_is_nil() )
{
SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList);
bool hasNewSelected = false;
SALOME_ListIteratorOfListIO anIt (aList);
for ( ; anIt.More() && !hasNewSelected; anIt.Next())
if ( anIt.Value()->hasEntry() )
hasNewSelected = isNewKeepNodesGroup( anIt.Value()->getEntry() );
AddKeepNodesButton->setEnabled( hasNewSelected );
//RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() );
}
}
} }
//================================================================================= //=================================================================================
@ -1332,7 +1502,8 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id)
myTypeId = id; myTypeId = id;
switch (id) switch (id)
{ {
case 0: // automatic case TYPE_AUTO: // automatic
myIdPreview->SetPointsLabeled(false); myIdPreview->SetPointsLabeled(false);
SMESH::SetPointRepresentation(false); SMESH::SetPointRepresentation(false);
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
@ -1345,7 +1516,8 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id)
GroupEdit->hide(); GroupEdit->hide();
break; break;
case 1: // manual case TYPE_MANUAL: // manual
SMESH::UpdateView(); SMESH::UpdateView();
// Costruction of the logical filter // Costruction of the logical filter
@ -1383,3 +1555,168 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id)
SelectionIntoArgument(); SelectionIntoArgument();
} }
//=======================================================================
//function : isKeepNodesIDsSelection
//purpose : Return true of Nodes to keep are selected by IDs
//=======================================================================
bool SMESHGUI_MergeDlg::isKeepNodesIDsSelection()
{
return KeepFromButGroup && KeepFromButGroup->checkedId() == 0;
}
//=======================================================================
//function : isNewKeepNodesGroup
//purpose : Return true if an object with given entry is NOT present in KeepList
//=======================================================================
bool SMESHGUI_MergeDlg::isNewKeepNodesGroup( const char* entry )
{
if ( !entry || isKeepNodesIDsSelection() )
return false;
for ( int i = 0; i < KeepList->count(); i++ )
if ( KeepList->item( i )->data( Qt::UserRole ).toString() == entry )
return false;
return true;
}
//=======================================================================
//function : onAddKeepNode
//purpose : SLOT called when [Add] of Nodes To Keep group is pressed
//=======================================================================
void SMESHGUI_MergeDlg::onAddKeepNode()
{
if ( myIsBusy )
return;
myIsBusy = true;
if ( isKeepNodesIDsSelection() )
{
//KeepList->clearSelection();
QString anIDs = "";
int aNbNodes = 0;
if ( myActor )
aNbNodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
if (aNbNodes > 0)
{
QStringList anNodes = anIDs.split( " ", QString::SkipEmptyParts);
QList<QListWidgetItem*> listItemsToSel;
QListWidgetItem* anItem;
for (QStringList::iterator it = anNodes.begin(); it != anNodes.end(); ++it)
{
QList<QListWidgetItem*> found = KeepList->findItems(*it, Qt::MatchExactly);
if (found.count() == 0) {
anItem = new QListWidgetItem(*it);
KeepList->addItem(anItem);
if (!anItem->isSelected())
listItemsToSel.push_back(anItem);
}
else {
foreach(anItem, found)
if (!anItem->isSelected())
listItemsToSel.push_back(anItem);
}
}
bool blocked = KeepList->signalsBlocked();
KeepList->blockSignals(true);
foreach(anItem, listItemsToSel) anItem->setSelected(true);
KeepList->blockSignals(blocked);
//onSelectKeepNode();
}
RemoveKeepNodesButton->setEnabled( aNbNodes > 0 );
}
else
{
SALOME_ListIO aList;
mySelectionMgr->selectedObjects(aList);
SALOME_ListIteratorOfListIO anIt (aList);
for ( ; anIt.More(); anIt.Next()) {
Handle(SALOME_InteractiveObject) anIO = anIt.Value();
if ( isNewKeepNodesGroup( anIO->getEntry() ))
{
QListWidgetItem* anItem = new QListWidgetItem( anIO->getName() );
anItem->setData( Qt::UserRole, QString( anIO->getEntry() ));
KeepList->addItem(anItem);
}
}
//RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() );
}
AddKeepNodesButton->setEnabled( false );
myIsBusy = false;
}
//=======================================================================
//function : onRemoveKeepNode
//purpose : SLOT called when [Remove] of Nodes To Keep group is pressed
//=======================================================================
void SMESHGUI_MergeDlg::onRemoveKeepNode()
{
// if ( isKeepNodesIDsSelection() )
// {
// }
// else
{
QList<QListWidgetItem*> selItems = KeepList->selectedItems();
QListWidgetItem* item;
foreach(item, selItems) delete item;
}
if ( isKeepNodesIDsSelection() )
{
AddKeepNodesButton->setEnabled( false );
}
RemoveKeepNodesButton->setEnabled( false );
}
//=======================================================================
//function : onSelectKeepNode
//purpose : SLOT called when selection in KeepList changes
//=======================================================================
void SMESHGUI_MergeDlg::onSelectKeepNode()
{
if ( myIsBusy || !isEnabled() ) return;
myIsBusy = true;
if ( isKeepNodesIDsSelection() )
{
if ( myActor )
{
mySelectionMgr->clearSelected();
TColStd_MapOfInteger aIndexes;
QList<QListWidgetItem*> selItems = KeepList->selectedItems();
QListWidgetItem* anItem;
foreach(anItem, selItems) aIndexes.Add(anItem->text().toInt());
mySelector->AddOrRemoveIndex(myActor->getIO(), aIndexes, false);
SALOME_ListIO aList;
aList.Append(myActor->getIO());
mySelectionMgr->setSelectedObjects(aList,false);
AddKeepNodesButton->setEnabled( false );
RemoveKeepNodesButton->setEnabled( aIndexes.Extent() > 0 );
}
}
else
{
RemoveKeepNodesButton->setEnabled( KeepList->selectedItems().count() );
}
myIsBusy = false;
}
//=======================================================================
//function : onKeepNodeSourceChanged
//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)
{
KeepList->clear();
SelectKeepNodesButton->click();
}

View File

@ -81,6 +81,8 @@ private:
void enterEvent( QEvent* ); /* mouse enter the QWidget */ void enterEvent( QEvent* ); /* mouse enter the QWidget */
void keyPressEvent( QKeyEvent* ); void keyPressEvent( QKeyEvent* );
void onEditGroup(); void onEditGroup();
bool isKeepNodesIDsSelection();
bool isNewKeepNodesGroup( const char* entry );
void FindGravityCenter( TColStd_MapOfInteger&, void FindGravityCenter( TColStd_MapOfInteger&,
std::list<gp_XYZ>& ); std::list<gp_XYZ>& );
@ -99,12 +101,13 @@ private:
SMESH::SMESH_IDSource_var mySubMeshOrGroup; SMESH::SMESH_IDSource_var mySubMeshOrGroup;
SMESH_Actor* myActor; SMESH_Actor* myActor;
SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter; SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter;
SUIT_SelectionFilter* mySubMeshOrGroupFilter;
SMESH::TIdPreview* myIdPreview; SMESH::TIdPreview* myIdPreview;
int myAction; int myAction;
bool myIsBusy; bool myIsBusy;
int myTypeId; int myTypeId; // manual(1) or automatic(0)
// Widgets // Widgets
QGroupBox* GroupConstructors; QGroupBox* GroupConstructors;
@ -142,6 +145,12 @@ private:
QGroupBox* GroupExclude; QGroupBox* GroupExclude;
QListWidget* ListExclude; QListWidget* ListExclude;
QButtonGroup* KeepFromButGroup;
QPushButton* SelectKeepNodesButton;
QPushButton* AddKeepNodesButton;
QPushButton* RemoveKeepNodesButton;
QListWidget* KeepList;
QGroupBox* TypeBox; QGroupBox* TypeBox;
QButtonGroup* GroupType; QButtonGroup* GroupType;
@ -159,6 +168,10 @@ protected slots:
void ClickOnHelp(); void ClickOnHelp();
void updateControls(); void updateControls();
void onDetect(); void onDetect();
void onAddKeepNode();
void onRemoveKeepNode();
void onSelectKeepNode();
void onKeepNodeSourceChanged(int);
void onAddGroup(); void onAddGroup();
void onRemoveGroup(); void onRemoveGroup();
void onSelectGroup(); void onSelectGroup();

View File

@ -5143,6 +5143,22 @@ Please select a group and try again</translation>
<source>SEPARATE_CORNERS_AND_MEDIUM</source> <source>SEPARATE_CORNERS_AND_MEDIUM</source>
<translation>No merge of corner and medium nodes</translation> <translation>No merge of corner and medium nodes</translation>
</message> </message>
<message>
<source>KEEP_NODES</source>
<translation>Nodes to keep</translation>
</message>
<message>
<source>GROUP_SUBMESH</source>
<translation>Groups and Sub-meshes</translation>
</message>
<message>
<source>SELECT</source>
<translation>Select: </translation>
</message>
<message>
<source></source>
<translation></translation>
</message>
</context> </context>
<context> <context>
<name>SMESHGUI_ExtrusionAlongPathDlg</name> <name>SMESHGUI_ExtrusionAlongPathDlg</name>

View File

@ -4113,7 +4113,8 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
//purpose : //purpose :
//======================================================================= //=======================================================================
void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes) void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
const SMESH::ListOfIDSources& NodesToKeep)
throw (SALOME::SALOME_Exception) throw (SALOME::SALOME_Exception)
{ {
SMESH_TRY; SMESH_TRY;
@ -4123,6 +4124,16 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
TPythonDump aTPythonDump; TPythonDump aTPythonDump;
aTPythonDump << this << ".MergeNodes(["; aTPythonDump << this << ".MergeNodes([";
TIDSortedNodeSet setOfNodesToKeep;
for ( int i = 0; i < NodesToKeep.length(); ++i )
{
prepareIdSource( NodesToKeep[i] );
SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE );
while ( nodeIt->more() )
setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() ));
}
::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
for (int i = 0; i < GroupsOfNodes.length(); i++) for (int i = 0; i < GroupsOfNodes.length(); i++)
{ {
@ -4132,9 +4143,13 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
for ( int j = 0; j < aNodeGroup.length(); j++ ) for ( int j = 0; j < aNodeGroup.length(); j++ )
{ {
CORBA::Long index = aNodeGroup[ j ]; CORBA::Long index = aNodeGroup[ j ];
const SMDS_MeshNode * node = aMesh->FindNode(index); if ( const SMDS_MeshNode * node = aMesh->FindNode( index ))
if ( node ) {
aListOfNodes.push_back( node ); if ( setOfNodesToKeep.count( node ))
aListOfNodes.push_front( node );
else
aListOfNodes.push_back( node );
}
} }
if ( aListOfNodes.size() < 2 ) if ( aListOfNodes.size() < 2 )
aListOfListOfNodes.pop_back(); aListOfListOfNodes.pop_back();
@ -4142,9 +4157,10 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
if ( i > 0 ) aTPythonDump << ", "; if ( i > 0 ) aTPythonDump << ", ";
aTPythonDump << aNodeGroup; aTPythonDump << aNodeGroup;
} }
getEditor().MergeNodes( aListOfListOfNodes ); getEditor().MergeNodes( aListOfListOfNodes );
aTPythonDump << "])"; aTPythonDump << "], " << NodesToKeep << ")";
declareMeshModified( /*isReComputeSafe=*/false ); declareMeshModified( /*isReComputeSafe=*/false );

View File

@ -488,7 +488,8 @@ public:
const SMESH::ListOfIDSources& ExceptSubMeshOrGroups, const SMESH::ListOfIDSources& ExceptSubMeshOrGroups,
CORBA::Boolean SeparateCornersAndMedium) CORBA::Boolean SeparateCornersAndMedium)
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes) void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
const SMESH::ListOfIDSources& NodesToKeep )
throw (SALOME::SALOME_Exception); throw (SALOME::SALOME_Exception);
void FindEqualElements(SMESH::SMESH_IDSource_ptr Object, void FindEqualElements(SMESH::SMESH_IDSource_ptr Object,
SMESH::array_of_long_array_out GroupsOfElementsID) SMESH::array_of_long_array_out GroupsOfElementsID)

View File

@ -1609,6 +1609,8 @@ class Mesh:
# @return SMESH.Hypothesis_Status # @return SMESH.Hypothesis_Status
# @ingroup l2_hypotheses # @ingroup l2_hypotheses
def AddHypothesis(self, hyp, geom=0): def AddHypothesis(self, hyp, geom=0):
if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
hyp, geom = geom, hyp
if isinstance( hyp, Mesh_Algorithm ): if isinstance( hyp, Mesh_Algorithm ):
hyp = hyp.GetAlgorithm() hyp = hyp.GetAlgorithm()
pass pass
@ -4428,9 +4430,18 @@ class Mesh:
# @param GroupsOfNodes a list of groups of nodes IDs for merging # @param GroupsOfNodes a list of groups of nodes IDs for merging
# (e.g. [[1,12,13],[25,4]], then nodes 12, 13 and 4 will be removed and replaced # (e.g. [[1,12,13],[25,4]], then nodes 12, 13 and 4 will be removed and replaced
# by nodes 1 and 25 correspondingly in all elements and groups # by nodes 1 and 25 correspondingly in all elements and groups
# @param NodesToKeep nodes to keep in the mesh: a list of groups, sub-meshes or node IDs.
# If @a NodesToKeep does not include a node to keep for some group to merge,
# then the first node in the group is kept.
# @ingroup l2_modif_trsf # @ingroup l2_modif_trsf
def MergeNodes (self, GroupsOfNodes): def MergeNodes (self, GroupsOfNodes, NodesToKeep=[]):
self.editor.MergeNodes(GroupsOfNodes) unRegister = genObjUnRegister()
if NodesToKeep:
if isinstance( NodesToKeep, list ) and isinstance( NodesToKeep[0], int ):
NodesToKeep = self.GetIDSource( NodesToKeep, SMESH.NODE )
if not isinstance( NodesToKeep, list ):
NodesToKeep = [ NodesToKeep ]
self.editor.MergeNodes(GroupsOfNodes,NodesToKeep)
## Finds the elements built on the same nodes. ## Finds the elements built on the same nodes.
# @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching # @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching