22487: EDF 2778 SMESH: Add a GUI for the flat elements generation

This commit is contained in:
eap 2014-03-19 18:29:49 +04:00
parent cd3fc5209f
commit 9ab3722c1b
17 changed files with 218 additions and 79 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -4,7 +4,7 @@
\n This operation allows duplicating mesh nodes or/and elements, which can be useful to emulate a crack in the model.
Duplication consists in creation of mesh element "equal" to existing ones.
Duplication consists in creation of mesh elements "equal" to existing ones.
<em>To duplicate nodes or/and elements:</em>
<ol>
@ -14,7 +14,7 @@ Duplication consists in creation of mesh element "equal" to existing ones.
<br>
\image html duplicate_nodes.png "Duplicate Nodes or/and Elements button"
</li>
<li>Check in the dialog box one of three radio buttons corresponding to
<li>Check in the dialog box one of four radio buttons corresponding to
the type of duplication operation you would like to perform.</li>
<li>Fill the other fields available in the dialog box (depending on
the chosen operation mode).</li>
@ -22,11 +22,12 @@ Duplication consists in creation of mesh element "equal" to existing ones.
operation of duplication.</li>
</ol>
\n "Duplicate Nodes or/and Elements" dialog has three working modes:
\n "Duplicate Nodes or/and Elements" dialog has four working modes:
<ul>
<li>\ref mode_without_elem_anchor "Duplicate nodes only"</li>
<li>\ref mode_with_elem_anchor "Duplicate nodes and border elements"</li>
<li>\ref mode_elem_only_anchor "Duplicate elements only"</li>
<li>\ref mode_group_boundary_anchor "Duplicate nodes on group boundaries"</li>
</ul>
<br>
@ -103,12 +104,11 @@ located at the "crack" (if any) are cloned automatically.
<h2>Duplicate elements only</h2>
This mode duplicates the given elements, i.e. creates new elements with the same nodes as the given elements.
<br>
\image html duplicate03.png
Parameters to be defined in this mode:
<ul>
<li><b>Group of elements to duplicate</b> (<em>mandatory</em>): these
elements will be duplicated.</li>
@ -118,6 +118,38 @@ This mode duplicates the given elements, i.e. creates new elements with the same
"DoubleElements".</li>
</ul>
<br>
\anchor mode_group_boundary_anchor
<h2>Duplicate nodes on group boundaries</h2>
This mode duplicates nodes located on boundaries between given groups of
volumes. If required, flat elements are created on the duplicated
nodes: a triangular facet shared by two volumes of two groups generates
a flat prism, a quadrangular facet generates a flat hexahedron.
<br>
The created flat volumes are stored in groups. These groups are named
according to the position of the group in the list of groups: group
"j_n_p" is a group of flat elements that are built between the group \#n
and the group \#p in the group list. All the flat elements are gathered
into the group named "joints3D". The flat element of the multiple
junctions between the simple junction are stored in a group named
"jointsMultiples".
<br>
\image html duplicate04.png
Parameters to be defined in this mode:
<ul>
<li><b>Groups of volumes</b> (<em>mandatory</em>): list of volume
groups. These groups should be disjoint, i.e. should not share volumes.</li>
<li><b>Create joint elements</b> : if checked - the flat elements are created.</li>
<li><b>On all boundaries</b> : if checked - then the volumes not
included into the <b>Groups of volumes</b> are considered as another given
group. And thus nodes on boundary between <b>Groups of volumes</b> and the
rest mesh are also duplicated.</li>
</ul>
<br><b>See Also</b> a sample TUI Script of a
\ref tui_duplicate_nodes "Duplicate nodes or/and elements" operation.

View File

@ -1275,10 +1275,13 @@ module SMESH
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
* \param theDomains - list of groups of volumes
* \param createJointElems - if TRUE, create the elements
* \param onAllBoundaries - if TRUE, the nodes and elements are also created on
* the boundary between \a theDomains and the rest mesh
* \return TRUE if operation has been completed successfully, FALSE otherwise
*/
boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains,
in boolean createJointElems )
in boolean createJointElems,
in boolean onAllBoundaries)
raises (SALOME::SALOME_Exception);
/*!

View File

@ -197,6 +197,7 @@ SET(SMESH_RESOURCES_FILES
mesh_duplicate_nodes.png
mesh_duplicate_nodes_with_elem.png
mesh_duplicate_elem_only.png
mesh_duplicate_group_boundary.png
mesh_bounding_box.png
mesh_hypo_viscous_layers.png
mesh_tree_hypo_viscous_layers.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

View File

@ -10563,8 +10563,13 @@ double SMESH_MeshEditor::OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const
gp_Vec v2(p0, g2);
gp_Vec n1 = vref.Crossed(v1);
gp_Vec n2 = vref.Crossed(v2);
try {
return n2.AngleWithRef(n1, vref);
}
catch ( Standard_Failure ) {
}
return Max( v1.Magnitude(), v2.Magnitude() );
}
/*!
* \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
@ -10576,13 +10581,16 @@ double SMESH_MeshEditor::OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const
* If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
* All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
* The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
* @param theElems - list of groups of volumes, where a group of volume is a set of
* \param theElems - list of groups of volumes, where a group of volume is a set of
* SMDS_MeshElements sorted by Id.
* @param createJointElems - if TRUE, create the elements
* @return TRUE if operation has been completed successfully, FALSE otherwise
* \param createJointElems - if TRUE, create the elements
* \param onAllBoundaries - if TRUE, the nodes and elements are also created on
* the boundary between \a theDomains and the rest mesh
* \return TRUE if operation has been completed successfully, FALSE otherwise
*/
bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
bool createJointElems)
bool createJointElems,
bool onAllBoundaries)
{
MESSAGE("----------------------------------------------");
MESSAGE("SMESH_MeshEditor::doubleNodesOnGroupBoundaries");
@ -10611,15 +10619,20 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
MESSAGE(".. Number of domains :"<<theElems.size());
TIDSortedElemSet theRestDomElems;
const int iRestDom = -1;
const int idom0 = onAllBoundaries ? iRestDom : 0;
const int nbDomains = theElems.size();
// Check if the domains do not share an element
for (int idom = 0; idom < theElems.size()-1; idom++)
for (int idom = 0; idom < nbDomains-1; idom++)
{
// MESSAGE("... Check of domain #" << idom);
const TIDSortedElemSet& domain = theElems[idom];
TIDSortedElemSet::const_iterator elemItr = domain.begin();
for (; elemItr != domain.end(); ++elemItr)
{
SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
const SMDS_MeshElement* anElem = *elemItr;
int idombisdeb = idom + 1 ;
for (int idombis = idombisdeb; idombis < theElems.size(); idombis++) // check if the element belongs to a domain further in the list
{
@ -10635,7 +10648,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
}
}
for (int idom = 0; idom < theElems.size(); idom++)
for (int idom = 0; idom < nbDomains; idom++)
{
// --- build a map (face to duplicate --> volume to modify)
@ -10648,7 +10661,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
TIDSortedElemSet::const_iterator elemItr = domain.begin();
for (; elemItr != domain.end(); ++elemItr)
{
SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
const SMDS_MeshElement* anElem = *elemItr;
if (!anElem)
continue;
int vtkId = anElem->getVtkId();
@ -10661,26 +10674,30 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
{
int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
if (! domain.count(elem)) // neighbor is in another domain : face is shared
if (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared
{
bool ok = false ;
for (int idombis = 0; idombis < theElems.size(); idombis++) // check if the neighbor belongs to another domain of the list
for (int idombis = 0; idombis < theElems.size() && !ok; idombis++) // check if the neighbor belongs to another domain of the list
{
// MESSAGE("Domain " << idombis);
const TIDSortedElemSet& domainbis = theElems[idombis];
if ( domainbis.count(elem)) ok = true ; // neighbor is in a correct domain : face is kept
}
if ( ok ) // the characteristics of the face is stored
if ( ok || onAllBoundaries ) // the characteristics of the face is stored
{
DownIdType face(downIds[n], downTypes[n]);
if (!faceDomains.count(face))
faceDomains[face] = emptyMap; // create an empty entry for face
if (!faceDomains[face].count(idom))
{
faceDomains[face][idom] = vtkId; // volume associated to face in this domain
celldom[vtkId] = idom;
//MESSAGE(" cell with a border " << vtkId << " domain " << idom);
}
if ( !ok )
{
theRestDomElems.insert( elem );
faceDomains[face][iRestDom] = neighborsVtkIds[n];
celldom[neighborsVtkIds[n]] = iRestDom;
}
}
}
}
@ -10694,14 +10711,14 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
// explore the nodes of the face and see if they belong to a cell in the domain,
// which has only a node or an edge on the border (not a shared face)
for (int idomain = 0; idomain < theElems.size(); idomain++)
for (int idomain = idom0; idomain < nbDomains; idomain++)
{
//MESSAGE("Domain " << idomain);
const TIDSortedElemSet& domain = theElems[idomain];
const TIDSortedElemSet& domain = (idomain == iRestDom) ? theRestDomElems : theElems[idomain];
itface = faceDomains.begin();
for (; itface != faceDomains.end(); ++itface)
{
std::map<int, int> domvol = itface->second;
const std::map<int, int>& domvol = itface->second;
if (!domvol.count(idomain))
continue;
DownIdType face = itface->first;
@ -10730,8 +10747,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
//no cells created after BuildDownWardConnectivity
}
DownIdType aCell(downId, vtkType);
if (!cellDomains.count(aCell))
cellDomains[aCell] = emptyMap; // create an empty entry for cell
cellDomains[aCell][idomain] = vtkId;
celldom[vtkId] = idomain;
//MESSAGE(" cell " << vtkId << " domain " << idomain);
@ -10753,12 +10768,12 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
std::map<int, std::vector<int> > mutipleNodesToFace; // nodes multi domains with domain order to transform in Face (junction between 3 or more 2D domains)
MESSAGE(".. Duplication of the nodes");
for (int idomain = 0; idomain < theElems.size(); idomain++)
for (int idomain = idom0; idomain < nbDomains; idomain++)
{
itface = faceDomains.begin();
for (; itface != faceDomains.end(); ++itface)
{
std::map<int, int> domvol = itface->second;
const std::map<int, int>& domvol = itface->second;
if (!domvol.count(idomain))
continue;
DownIdType face = itface->first;
@ -10770,15 +10785,12 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
for (; itn != oldNodes.end(); ++itn)
{
int oldId = *itn;
//MESSAGE("-+-+-a node " << oldId);
if (!nodeDomains.count(oldId))
nodeDomains[oldId] = emptyMap; // create an empty entry for node
if (nodeDomains[oldId].empty())
{
nodeDomains[oldId][idomain] = oldId; // keep the old node in the first domain
//MESSAGE("-+-+-b oldNode " << oldId << " domain " << idomain);
}
std::map<int, int>::iterator itdom = domvol.begin();
std::map<int, int>::const_iterator itdom = domvol.begin();
for (; itdom != domvol.end(); ++itdom)
{
int idom = itdom->first;
@ -10816,7 +10828,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
}
MESSAGE(".. Creation of elements");
for (int idomain = 0; idomain < theElems.size(); idomain++)
for (int idomain = idom0; idomain < nbDomains; idomain++)
{
itface = faceDomains.begin();
for (; itface != faceDomains.end(); ++itface)
@ -10885,11 +10897,12 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
for (int id=0; id < doms.size(); id++)
{
int idom = doms[id];
const TIDSortedElemSet& domain = (idom == iRestDom) ? theRestDomElems : theElems[idom];
for (int ivol=0; ivol<nbvol; ivol++)
{
int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]);
SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId);
if (theElems[idom].count(elem))
if (domain.count(elem))
{
SMDS_VtkVolume* svol = dynamic_cast<SMDS_VtkVolume*>(elem);
domvol[idom] = svol;
@ -11070,7 +11083,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
feDom.clear();
MESSAGE(".. Modification of elements");
for (int idomain = 0; idomain < theElems.size(); idomain++)
for (int idomain = idom0; idomain < nbDomains; idomain++)
{
std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
for (; itnod != nodeDomains.end(); ++itnod)

View File

@ -553,7 +553,8 @@ public:
double OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const gp_Pnt& g1, const gp_Pnt& g2);
bool DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
bool createJointElems);
bool createJointElems,
bool onAllBoundaries);
bool CreateFlatElementsOnFacesGroups( const std::vector<TIDSortedElemSet>& theElems );

View File

@ -110,6 +110,7 @@ SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
QPixmap iconWithoutElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES")));
QPixmap iconWithElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES_WITH_ELEM")));
QPixmap iconElemOnly (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_ELEM_ONLY")));
QPixmap iconGrpBoundary (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_GROUP_BOUNDARY")));
QPixmap iconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
// Main layout
@ -130,13 +131,17 @@ SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
aRadioButton2->setIcon(iconWithElem);
QRadioButton* aRadioButton3 = new QRadioButton(aConstructorsBox);
aRadioButton3->setIcon(iconElemOnly);
QRadioButton* aRadioButton4 = new QRadioButton(aConstructorsBox);
aRadioButton4->setIcon(iconGrpBoundary);
aConstructorsBoxLayout->addWidget(aRadioButton1);
aConstructorsBoxLayout->addWidget(aRadioButton2);
aConstructorsBoxLayout->addWidget(aRadioButton3);
aConstructorsBoxLayout->addWidget(aRadioButton4);
myGroupConstructors->addButton(aRadioButton1, 0);
myGroupConstructors->addButton(aRadioButton2, 1);
myGroupConstructors->addButton(aRadioButton3, 2);
myGroupConstructors->addButton(aRadioButton4, 3);
// Arguments
myGroupArguments = new QGroupBox(this);
@ -162,8 +167,8 @@ SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
myLineEdit3 = new QLineEdit(myGroupArguments);
myLineEdit3->setReadOnly(true);
myCheckBoxNewElemGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_ELEMENTS"), myGroupArguments);
myCheckBoxNewNodeGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments);
myCheckBox1 = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_ELEMENTS"), myGroupArguments);
myCheckBox2 = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments);
aGroupArgumentsLayout->addWidget(myTextLabel1, 0, 0);
aGroupArgumentsLayout->addWidget(mySelectButton1, 0, 1);
@ -174,8 +179,8 @@ SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
aGroupArgumentsLayout->addWidget(myTextLabel3, 2, 0);
aGroupArgumentsLayout->addWidget(mySelectButton3, 2, 1);
aGroupArgumentsLayout->addWidget(myLineEdit3, 2, 2);
aGroupArgumentsLayout->addWidget(myCheckBoxNewElemGroup, 3, 0);
aGroupArgumentsLayout->addWidget(myCheckBoxNewNodeGroup, 4, 0);
aGroupArgumentsLayout->addWidget(myCheckBox1, 3, 0);
aGroupArgumentsLayout->addWidget(myCheckBox2, 4, 0);
aGroupArgumentsLayout->setRowStretch(5, 1);
// Buttons
@ -207,8 +212,8 @@ SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
aMainLayout->addWidget(myGroupArguments);
aMainLayout->addWidget(aGroupButtons);
myCheckBoxNewElemGroup->setChecked(true);
myCheckBoxNewNodeGroup->setChecked(true);
myCheckBox1->setChecked(true);
myCheckBox2->setChecked(true);
// Initialize the dialog
Init();
@ -223,6 +228,8 @@ SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule )
connect(mySelectButton2, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument()));
connect(mySelectButton3, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument()));
connect(myCheckBox2, SIGNAL(stateChanged(int)), SLOT(updateButtons()));
connect(myButtonOk, SIGNAL(clicked()), this, SLOT(onOk()));
connect(myButtonClose, SIGNAL(clicked()), this, SLOT(reject()));
connect(myButtonApply, SIGNAL(clicked()), this, SLOT(onApply()));
@ -298,8 +305,9 @@ void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
myTextLabel1->setText(tr("GROUP_NODES_TO_DUPLICATE"));
myTextLabel2->setText(tr("GROUP_NODES_TO_REPLACE"));
myCheckBoxNewElemGroup->hide();
myCheckBoxNewNodeGroup->show();
myCheckBox1->hide();
myCheckBox2->show();
myCheckBox2->setText( tr("CONSTRUCT_NEW_GROUP_NODES"));
// Hide the third field
myTextLabel2->show();
@ -319,8 +327,10 @@ void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
myTextLabel2->setText(tr("GROUP_NODES_NOT_DUPLICATE"));
myTextLabel3->setText(tr("GROUP_ELEMS_TO_REPLACE"));
myCheckBoxNewElemGroup->show();
myCheckBoxNewNodeGroup->show();
myCheckBox1->show();
myCheckBox2->show();
myCheckBox1->setText( tr("CONSTRUCT_NEW_GROUP_ELEMENTS"));
myCheckBox2->setText( tr("CONSTRUCT_NEW_GROUP_NODES"));
// Show the third field
myTextLabel2->show();
@ -338,8 +348,30 @@ void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId)
myGroupArguments->setTitle(tr("DUPLICATION_ONLY_ELEMS"));
myTextLabel1->setText(tr("GROUP_ELEMS_TO_DUPLICATE"));
myCheckBoxNewElemGroup->show();
myCheckBoxNewNodeGroup->hide();
myCheckBox1->show();
myCheckBox1->setText( tr("CONSTRUCT_NEW_GROUP_ELEMENTS"));
myCheckBox2->hide();
// Hide the second and the third field
myTextLabel2->hide();
mySelectButton2->hide();
myLineEdit2->hide();
myTextLabel3->hide();
mySelectButton3->hide();
myLineEdit3->hide();
break;
}
case 3:
{
// Set text to the group of arguments and to all the labels
myGroupArguments->setTitle(tr("DUPLICATION_GROUP_BOUNDARY"));
myTextLabel1->setText(tr("GROUP_VOLUME_GROUPS"));
myCheckBox1->show();
myCheckBox2->show();
myCheckBox1->setText( tr("CREATE_JOINT_ELEMENTS"));
myCheckBox2->setText( tr("ON_ALL_BOUNDARIES"));
// Hide the second and the third field
myTextLabel2->hide();
@ -367,8 +399,8 @@ bool SMESHGUI_DuplicateNodesDlg::onApply()
BusyLocker lock( myBusy );
bool toCreateElemGroup = myCheckBoxNewElemGroup->isChecked();
bool toCreateNodeGroup = myCheckBoxNewNodeGroup->isChecked();
bool toCreateElemGroup = myCheckBox1->isChecked();
bool toCreateNodeGroup = myCheckBox2->isChecked();
int operationMode = myGroupConstructors->checkedId();
// Apply changes
@ -451,7 +483,21 @@ bool SMESHGUI_DuplicateNodesDlg::onApply()
}
break;
}
case 3:
{
bool createJointElems = myCheckBox1->isChecked();
bool onAllBoundaries = myCheckBox2->isChecked();
SMESH::ListOfGroups_var g1 = new SMESH::ListOfGroups();
g1->length( myGroups1.count() );
for ( int i = 0; i < myGroups1.count(); i++ )
g1[i] = myGroups1[i];
result = aMeshEditor->DoubleNodesOnGroupBoundaries( g1.in(), createJointElems, onAllBoundaries );
break;
}
} // switch( operationMode )
}
catch (const SALOME::SALOME_Exception& S_ex) {
SalomeApp_Tools::QtCatchCorbaException(S_ex);
@ -553,6 +599,9 @@ void SMESHGUI_DuplicateNodesDlg::onSelectionChanged()
case 2:
ok = ( aGroupType != SMESH::NODE );
break;
case 3:
ok = ( aGroupType == SMESH::VOLUME );
break;
}
}
if ( ok ) aGroups << aGroup;
@ -575,8 +624,15 @@ void SMESHGUI_DuplicateNodesDlg::onSelectionChanged()
else if ( myCurrentLineEdit == myLineEdit3 ) myGroups3.clear();
myCurrentLineEdit->clear();
}
// Enable/disable "Apply and Close" and "Apply" buttons
updateButtons();
}
/*!
* \brief Enable/disable "Apply and Close" and "Apply" buttons
*/
void SMESHGUI_DuplicateNodesDlg::updateButtons()
{
bool isDataValid = isValid();
myButtonOk->setEnabled( isDataValid );
myButtonApply->setEnabled( isDataValid );
@ -610,11 +666,14 @@ void SMESHGUI_DuplicateNodesDlg::onEditCurrentArgument()
*/
bool SMESHGUI_DuplicateNodesDlg::isValid()
{
return myGroupConstructors->checkedId() == 1 ?
( !myGroups1.isEmpty() && !myGroups3.isEmpty() ) :
( !myGroups1.isEmpty() );
switch( myGroupConstructors->checkedId() )
{
case 1: return ( !myGroups1.isEmpty() && !myGroups3.isEmpty() );
case 3: return ( myGroups1.count() > ( myCheckBox2->isChecked() ? 0 : 1 ));
default: return !myGroups1.isEmpty();
}
return false;
}
/*!
\brief SLOT called when dialog shoud be deativated.

View File

@ -83,6 +83,8 @@ private slots:
void onDeactivate();
void updateButtons();
private:
QLineEdit* myCurrentLineEdit;
@ -98,8 +100,8 @@ private:
QLineEdit* myLineEdit1;
QLineEdit* myLineEdit2;
QLineEdit* myLineEdit3;
QCheckBox* myCheckBoxNewElemGroup;
QCheckBox* myCheckBoxNewNodeGroup;
QCheckBox* myCheckBox1;
QCheckBox* myCheckBox2;
QPushButton* myButtonOk;
QPushButton* myButtonApply;

View File

@ -439,6 +439,10 @@
<source>ICON_SMESH_DUPLICATE_ELEM_ONLY</source>
<translation>mesh_duplicate_elem_only.png</translation>
</message>
<message>
<source>ICON_SMESH_DUPLICATE_GROUP_BOUNDARY</source>
<translation>mesh_duplicate_group_boundary.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_ALGO</source>
<translation>mesh_tree_algo.png</translation>

View File

@ -6752,6 +6752,10 @@ It is impossible to read point coordinates from file</translation>
<source>DUPLICATION_ONLY_ELEMS</source>
<translation>Duplicate elements only</translation>
</message>
<message>
<source>DUPLICATION_GROUP_BOUNDARY</source>
<translation>Duplicate nodes on group boundaries</translation>
</message>
<message>
<source>GROUP_ELEMS_TO_DUPLICATE</source>
<translation>Group of elements to duplicate</translation>
@ -6764,6 +6768,10 @@ It is impossible to read point coordinates from file</translation>
<source>GROUP_ELEMS_TO_REPLACE</source>
<translation>Group of elements to replace nodes with new ones</translation>
</message>
<message>
<source>GROUP_VOLUME_GROUPS</source>
<translation>Groups of volumes</translation>
</message>
<message>
<source>CONSTRUCT_NEW_GROUP_NODES</source>
<translation>Construct group with newly created nodes</translation>
@ -6772,6 +6780,14 @@ It is impossible to read point coordinates from file</translation>
<source>CONSTRUCT_NEW_GROUP_ELEMENTS</source>
<translation>Construct group with newly created elements</translation>
</message>
<message>
<source>CREATE_JOINT_ELEMENTS</source>
<translation>Create joint elements</translation>
</message>
<message>
<source>ON_ALL_BOUNDARIES</source>
<translation>On all boundaries</translation>
</message>
</context>
<context>
<name>SMESHGUI_Make2DFrom3DDlg</name>

View File

@ -6875,18 +6875,21 @@ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
* If there is no shared faces between the group #n and the group #p in the list, the group j_n_p is not created.
* All the flat elements are gathered into the group named "joints3D" (or "joints2D" in 2D situation).
* The flat element of the multiple junctions between the simple junction are stored in a group named "jointsMultiples".
* @param theDomains - list of groups of volumes
* @param createJointElems - if TRUE, create the elements
* @return TRUE if operation has been completed successfully, FALSE otherwise
* \param theDomains - list of groups of volumes
* \param createJointElems - if TRUE, create the elements
* \param onAllBoundaries - if TRUE, the nodes and elements are also created on
* the boundary between \a theDomains and the rest mesh
* \return TRUE if operation has been completed successfully, FALSE otherwise
*/
//================================================================================
CORBA::Boolean
SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
CORBA::Boolean createJointElems )
CORBA::Boolean createJointElems,
CORBA::Boolean onAllBoundaries )
throw (SALOME::SALOME_Exception)
{
bool aResult = false;
bool isOK = false;
SMESH_TRY;
initData();
@ -6894,10 +6897,11 @@ SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& the
SMESHDS_Mesh* aMeshDS = getMeshDS();
// MESSAGE("theDomains.length = "<<theDomains.length());
if ( theDomains.length() <= 1 )
if ( theDomains.length() <= 1 && !onAllBoundaries )
THROW_SALOME_CORBA_EXCEPTION("At least 2 groups are required.", SALOME::BAD_PARAM);
vector<TIDSortedElemSet> domains;
domains.clear();
domains.resize( theDomains.length() );
for ( int i = 0, n = theDomains.length(); i < n; i++ )
{
@ -6906,26 +6910,25 @@ SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& the
{
// if ( aGrp->GetType() != SMESH::VOLUME )
// THROW_SALOME_CORBA_EXCEPTION("Not a volume group", SALOME::BAD_PARAM);
TIDSortedElemSet domain;
domain.clear();
domains.push_back(domain);
SMESH::long_array_var anIDs = aGrp->GetIDs();
arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
}
}
aResult = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems );
isOK = getEditor().DoubleNodesOnGroupBoundaries( domains, createJointElems, onAllBoundaries );
// TODO publish the groups of flat elements in study
declareMeshModified( /*isReComputeSafe=*/ !aResult );
declareMeshModified( /*isReComputeSafe=*/ !isOK );
// Update Python script
TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
<< ", " << createJointElems << " )";
<< ", " << createJointElems << ", " << onAllBoundaries << " )";
SMESH_CATCH( SMESH::throwCorbaException );
return aResult;
myMesh_i->CreateGroupServants(); // publish created groups if any
return isOK;
}
//================================================================================

View File

@ -923,12 +923,15 @@ public:
* The nodes of the internal faces at the boundaries of the groups are doubled.
* In option, the internal faces are replaced by flat elements.
* Triangles are transformed in prisms, and quadrangles in hexahedrons.
* @param theDomains - list of groups of volumes
* @param createJointElems - if TRUE, create the elements
* @return TRUE if operation has been completed successfully, FALSE otherwise
* \param theDomains - list of groups of volumes
* \param createJointElems - if TRUE, create the elements
* \param onAllBoundaries - if TRUE, the nodes and elements are also create on
* the boundary between \a theDomains and the rest mesh
* \return TRUE if operation has been completed successfully, FALSE otherwise
*/
CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
CORBA::Boolean createJointElems )
CORBA::Boolean createJointElems,
CORBA::Boolean onAllBoundaries )
throw (SALOME::SALOME_Exception);
/*!
* \brief Double nodes on some external faces and create flat elements.

View File

@ -4503,9 +4503,11 @@ class Mesh:
# Triangles are transformed in prisms, and quadrangles in hexahedrons.
# @param theDomains - list of groups of volumes
# @param createJointElems - if TRUE, create the elements
# @param onAllBoundaries - if TRUE, the nodes and elements are also created on
# the boundary between \a theDomains and the rest mesh
# @return TRUE if operation has been completed successfully, FALSE otherwise
def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ):
return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems )
def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ):
return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries )
## Double nodes on some external faces and create flat elements.
# Flat elements are mainly used by some types of mechanic calculations.