23081: [CEA 1496] Control merge nodes behaviour: set fixed nodes
@ -1,10 +1,14 @@
|
||||
# Merging Nodes
|
||||
|
||||
import SMESH_mechanic
|
||||
import SMESH_mechanic, SMESH
|
||||
mesh = SMESH_mechanic.mesh
|
||||
|
||||
# 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)
|
||||
mesh.MergeNodes(GroupsOfNodes)
|
||||
mesh.MergeNodes(GroupsOfNodes, NodesToKeep=allSegs)
|
||||
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 43 KiB |
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
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
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 7.0 KiB |
@ -26,7 +26,23 @@ merging.</li>
|
||||
nodes. This check-box is enabled provided that the selected mesh
|
||||
includes quadratic elements.</li>
|
||||
<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>
|
||||
|
||||
<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_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
|
||||
\ref tui_merging_nodes "Merge Nodes" operation.
|
||||
|
@ -10,7 +10,7 @@ So that
|
||||
- bi-quadratic quadrangle will be split into 4 linear quadrangles;
|
||||
- tri-quadratic hexahedron will be split into 8 linear hexahedra;
|
||||
- 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"
|
||||
|
||||
|
@ -658,7 +658,8 @@ module SMESH
|
||||
in boolean SeparateCornersAndMedium)
|
||||
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);
|
||||
|
||||
/*!
|
||||
|
@ -7334,16 +7334,17 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
|
||||
// Fill nodeNodeMap and elems
|
||||
|
||||
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*>::iterator nIt = nodes.begin();
|
||||
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;
|
||||
nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep ));
|
||||
if ( nToRemove != nToKeep ) {
|
||||
//MESSAGE(" node to remove " << nToRemove->GetID());
|
||||
nodeNodeMap.insert( make_pair( nToRemove, nToKeep ));
|
||||
if ( nToRemove != nToKeep )
|
||||
{
|
||||
rmNodeIds.push_back( nToRemove->GetID() );
|
||||
AddToSameGroups( nToKeep, nToRemove, aMesh );
|
||||
// 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() ))
|
||||
sm->SetIsAlwaysComputed( true );
|
||||
}
|
||||
|
||||
SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
|
||||
while ( invElemIt->more() ) {
|
||||
const SMDS_MeshElement* elem = invElemIt->next();
|
||||
|
@ -95,7 +95,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
enum ActionType { MERGE_NODES, MERGE_ELEMENTS };
|
||||
enum ActionType { MERGE_NODES, MERGE_ELEMENTS, TYPE_AUTO=0, TYPE_MANUAL };
|
||||
}
|
||||
namespace SMESH
|
||||
{
|
||||
@ -363,7 +363,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
||||
GroupMeshLayout->addWidget(LineEditMesh);
|
||||
|
||||
/***************************************************************/
|
||||
// Controls for switch dialog behaviour
|
||||
// Controls for switch dialog behaviour (myTypeId)
|
||||
|
||||
TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this );
|
||||
GroupType = new QButtonGroup( this );
|
||||
@ -378,7 +378,7 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
||||
aTypeBoxLayout->addWidget( rb1 );
|
||||
aTypeBoxLayout->addWidget( rb2 );
|
||||
|
||||
myTypeId = 0;
|
||||
myTypeId = TYPE_AUTO;
|
||||
|
||||
/***************************************************************/
|
||||
// Controls for coincident elements detecting
|
||||
@ -410,6 +410,32 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
||||
GroupExcludeLayout->setMargin(MARGIN);
|
||||
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 );
|
||||
fooLayout->setSpacing(SPACING);
|
||||
fooLayout->setMargin(0);
|
||||
@ -417,13 +443,27 @@ SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction)
|
||||
fooLayout->addWidget(SpinBoxTolerance, 0, 1 );
|
||||
fooLayout->addWidget(SeparateCornersAndMedium, 1, 0 );
|
||||
fooLayout->addWidget(GroupExclude, 2, 0, 1, 2 );
|
||||
fooLayout->addWidget(GroupKeep, 3, 0, 1, 2 );
|
||||
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 {
|
||||
TextLabelTolerance = 0;
|
||||
SpinBoxTolerance = 0;
|
||||
GroupExclude = 0;
|
||||
ListExclude = 0;
|
||||
KeepFromButGroup = 0;
|
||||
SelectKeepNodesButton = 0;
|
||||
AddKeepNodesButton = 0;
|
||||
RemoveKeepNodesButton = 0;
|
||||
KeepList = 0;
|
||||
mySubMeshOrGroupFilter = 0;
|
||||
}
|
||||
|
||||
GroupCoincidentWidget = new QWidget(GroupCoincident);
|
||||
@ -562,6 +602,14 @@ void SMESHGUI_MergeDlg::Init()
|
||||
connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
|
||||
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(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
|
||||
connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup()));
|
||||
@ -638,7 +686,7 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
|
||||
return false;
|
||||
|
||||
try {
|
||||
if (myTypeId == 0)
|
||||
if (myTypeId == TYPE_AUTO)
|
||||
onDetect();
|
||||
|
||||
SUIT_OverrideCursor aWaitCursor;
|
||||
@ -672,12 +720,51 @@ bool SMESHGUI_MergeDlg::ClickOnApply()
|
||||
aGroupsOfElements[anArrayNum++] = anIds.inout();
|
||||
}
|
||||
|
||||
SMESH::ListOfIDSources_var nodesToKeep;
|
||||
SMESH::IDSource_wrap tmpIdSource;
|
||||
if ( myAction == MERGE_NODES )
|
||||
aMeshEditor->MergeNodes (aGroupsOfElements.inout());
|
||||
{
|
||||
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 )
|
||||
aMeshEditor->MergeNodes (aGroupsOfElements.inout(), nodesToKeep);
|
||||
else
|
||||
aMeshEditor->MergeElements (aGroupsOfElements.inout());
|
||||
|
||||
if ( myTypeId == 0 ) {
|
||||
if ( myTypeId == TYPE_AUTO ) {
|
||||
if (myAction == MERGE_NODES )
|
||||
SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"),
|
||||
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"),
|
||||
tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data()));
|
||||
}
|
||||
nodesToKeep->length(0); // release before tmpIdSource calls UnRegister()
|
||||
|
||||
|
||||
} catch(...) {
|
||||
}
|
||||
catch(...) {
|
||||
}
|
||||
|
||||
ListCoincident->clear();
|
||||
@ -810,7 +898,7 @@ void SMESHGUI_MergeDlg::updateControls()
|
||||
{
|
||||
if (ListEdit->count() == 0)
|
||||
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);
|
||||
buttonApply->setEnabled(enable);
|
||||
DetectButton->setEnabled( !myMesh->_is_nil() );
|
||||
@ -823,6 +911,13 @@ void SMESHGUI_MergeDlg::updateControls()
|
||||
myMesh->NbVolumesOfOrder( SMESH::ORDER_QUADRATIC ) > 0 ));
|
||||
|
||||
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->clearFilters();
|
||||
|
||||
if (send == SelectMeshButton) {
|
||||
if (send == SelectMeshButton)
|
||||
{
|
||||
myEditCurrentArgument = (QWidget*)LineEditMesh;
|
||||
SMESH::SetPointRepresentation(false);
|
||||
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
|
||||
aViewWindow->SetSelectionMode(ActorSelection);
|
||||
if (myTypeId == 1)
|
||||
if (myTypeId == TYPE_MANUAL)
|
||||
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();
|
||||
connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
|
||||
@ -1165,11 +1278,12 @@ void SMESHGUI_MergeDlg::SetEditCurrentArgument()
|
||||
|
||||
//=================================================================================
|
||||
// function : SelectionIntoArgument()
|
||||
// purpose : Called when selection as changed or other case
|
||||
// purpose : Called when selection has changed or other case
|
||||
//=================================================================================
|
||||
void SMESHGUI_MergeDlg::SelectionIntoArgument()
|
||||
{
|
||||
if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
|
||||
if (myEditCurrentArgument == (QWidget*)LineEditMesh)
|
||||
{
|
||||
QString aString = "";
|
||||
LineEditMesh->setText(aString);
|
||||
|
||||
@ -1196,6 +1310,9 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
|
||||
myEntry = IO->getEntry();
|
||||
myMesh = SMESH::GetMeshByIO(IO);
|
||||
|
||||
if ( myEntry != aCurrentEntry && KeepList )
|
||||
KeepList->clear();
|
||||
|
||||
if (myMesh->_is_nil())
|
||||
return;
|
||||
|
||||
@ -1205,7 +1322,7 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
|
||||
if (!myActor)
|
||||
myActor = SMESH::FindActorByObject(myMesh);
|
||||
|
||||
if ( myActor && myTypeId == 1 && mySelector->IsSelectionEnabled() ) {
|
||||
if ( myActor && myTypeId == TYPE_MANUAL && mySelector->IsSelectionEnabled() ) {
|
||||
mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
|
||||
mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
|
||||
|
||||
@ -1246,6 +1363,59 @@ void SMESHGUI_MergeDlg::SelectionIntoArgument()
|
||||
|
||||
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;
|
||||
switch (id)
|
||||
{
|
||||
case 0: // automatic
|
||||
case TYPE_AUTO: // automatic
|
||||
|
||||
myIdPreview->SetPointsLabeled(false);
|
||||
SMESH::SetPointRepresentation(false);
|
||||
if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
|
||||
@ -1345,7 +1516,8 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id)
|
||||
GroupEdit->hide();
|
||||
break;
|
||||
|
||||
case 1: // manual
|
||||
case TYPE_MANUAL: // manual
|
||||
|
||||
SMESH::UpdateView();
|
||||
|
||||
// Costruction of the logical filter
|
||||
@ -1383,3 +1555,168 @@ void SMESHGUI_MergeDlg::onTypeChanged (int id)
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -81,6 +81,8 @@ private:
|
||||
void enterEvent( QEvent* ); /* mouse enter the QWidget */
|
||||
void keyPressEvent( QKeyEvent* );
|
||||
void onEditGroup();
|
||||
bool isKeepNodesIDsSelection();
|
||||
bool isNewKeepNodesGroup( const char* entry );
|
||||
|
||||
void FindGravityCenter( TColStd_MapOfInteger&,
|
||||
std::list<gp_XYZ>& );
|
||||
@ -99,12 +101,13 @@ private:
|
||||
SMESH::SMESH_IDSource_var mySubMeshOrGroup;
|
||||
SMESH_Actor* myActor;
|
||||
SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter;
|
||||
SUIT_SelectionFilter* mySubMeshOrGroupFilter;
|
||||
|
||||
SMESH::TIdPreview* myIdPreview;
|
||||
|
||||
int myAction;
|
||||
bool myIsBusy;
|
||||
int myTypeId;
|
||||
int myTypeId; // manual(1) or automatic(0)
|
||||
|
||||
// Widgets
|
||||
QGroupBox* GroupConstructors;
|
||||
@ -142,6 +145,12 @@ private:
|
||||
QGroupBox* GroupExclude;
|
||||
QListWidget* ListExclude;
|
||||
|
||||
QButtonGroup* KeepFromButGroup;
|
||||
QPushButton* SelectKeepNodesButton;
|
||||
QPushButton* AddKeepNodesButton;
|
||||
QPushButton* RemoveKeepNodesButton;
|
||||
QListWidget* KeepList;
|
||||
|
||||
QGroupBox* TypeBox;
|
||||
QButtonGroup* GroupType;
|
||||
|
||||
@ -159,6 +168,10 @@ protected slots:
|
||||
void ClickOnHelp();
|
||||
void updateControls();
|
||||
void onDetect();
|
||||
void onAddKeepNode();
|
||||
void onRemoveKeepNode();
|
||||
void onSelectKeepNode();
|
||||
void onKeepNodeSourceChanged(int);
|
||||
void onAddGroup();
|
||||
void onRemoveGroup();
|
||||
void onSelectGroup();
|
||||
|
@ -5143,6 +5143,22 @@ Please select a group and try again</translation>
|
||||
<source>SEPARATE_CORNERS_AND_MEDIUM</source>
|
||||
<translation>No merge of corner and medium nodes</translation>
|
||||
</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>
|
||||
<name>SMESHGUI_ExtrusionAlongPathDlg</name>
|
||||
|
@ -4113,7 +4113,8 @@ FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
|
||||
//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)
|
||||
{
|
||||
SMESH_TRY;
|
||||
@ -4123,6 +4124,16 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
|
||||
|
||||
TPythonDump aTPythonDump;
|
||||
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;
|
||||
for (int i = 0; i < GroupsOfNodes.length(); i++)
|
||||
{
|
||||
@ -4132,19 +4143,24 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
|
||||
for ( int j = 0; j < aNodeGroup.length(); j++ )
|
||||
{
|
||||
CORBA::Long index = aNodeGroup[ j ];
|
||||
const SMDS_MeshNode * node = aMesh->FindNode(index);
|
||||
if ( node )
|
||||
if ( const SMDS_MeshNode * node = aMesh->FindNode( index ))
|
||||
{
|
||||
if ( setOfNodesToKeep.count( node ))
|
||||
aListOfNodes.push_front( node );
|
||||
else
|
||||
aListOfNodes.push_back( node );
|
||||
}
|
||||
}
|
||||
if ( aListOfNodes.size() < 2 )
|
||||
aListOfListOfNodes.pop_back();
|
||||
|
||||
if ( i > 0 ) aTPythonDump << ", ";
|
||||
aTPythonDump << aNodeGroup;
|
||||
}
|
||||
|
||||
getEditor().MergeNodes( aListOfListOfNodes );
|
||||
|
||||
aTPythonDump << "])";
|
||||
aTPythonDump << "], " << NodesToKeep << ")";
|
||||
|
||||
declareMeshModified( /*isReComputeSafe=*/false );
|
||||
|
||||
|
@ -488,7 +488,8 @@ public:
|
||||
const SMESH::ListOfIDSources& ExceptSubMeshOrGroups,
|
||||
CORBA::Boolean SeparateCornersAndMedium)
|
||||
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);
|
||||
void FindEqualElements(SMESH::SMESH_IDSource_ptr Object,
|
||||
SMESH::array_of_long_array_out GroupsOfElementsID)
|
||||
|
@ -1609,6 +1609,8 @@ class Mesh:
|
||||
# @return SMESH.Hypothesis_Status
|
||||
# @ingroup l2_hypotheses
|
||||
def AddHypothesis(self, hyp, geom=0):
|
||||
if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ):
|
||||
hyp, geom = geom, hyp
|
||||
if isinstance( hyp, Mesh_Algorithm ):
|
||||
hyp = hyp.GetAlgorithm()
|
||||
pass
|
||||
@ -4428,9 +4430,18 @@ class Mesh:
|
||||
# @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
|
||||
# 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
|
||||
def MergeNodes (self, GroupsOfNodes):
|
||||
self.editor.MergeNodes(GroupsOfNodes)
|
||||
def MergeNodes (self, GroupsOfNodes, NodesToKeep=[]):
|
||||
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.
|
||||
# @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching
|
||||
|