\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>
<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>
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>
<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>
"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.
* 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);
/*!
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
gp_Vec v2(p0, g2);
gp_Vec n1 = vref.Crossed(v1);
gp_Vec n2 = vref.Crossed(v2);
- return n2.AngleWithRef(n1, vref);
+ try {
+ return n2.AngleWithRef(n1, vref);
+ }
+ catch ( Standard_Failure ) {
+ }
+ return Max( v1.Magnitude(), v2.Magnitude() );
}
/*!
* 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
- * SMDS_MeshElements sorted by Id.
- * @param createJointElems - if TRUE, create the elements
- * @return TRUE if operation has been completed successfully, FALSE otherwise
+ * \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
+ * \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");
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
{
}
}
- for (int idom = 0; idom < theElems.size(); idom++)
+ for (int idom = 0; idom < nbDomains; idom++)
{
// --- build a map (face to duplicate --> volume to modify)
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();
{
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;
+ }
}
}
}
// 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;
//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);
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;
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;
}
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)
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;
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)
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 );
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
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);
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);
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
aMainLayout->addWidget(myGroupArguments);
aMainLayout->addWidget(aGroupButtons);
- myCheckBoxNewElemGroup->setChecked(true);
- myCheckBoxNewNodeGroup->setChecked(true);
+ myCheckBox1->setChecked(true);
+ myCheckBox2->setChecked(true);
// Initialize the dialog
Init();
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()));
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();
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();
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();
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
}
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);
}
catch ( const std::exception& exc ) {
INFOS( "Follow exception was cought:\n\t" << exc.what() );
- }
+ }
catch (...) {
INFOS( "Unknown exception was cought !!!" );
}
case 2:
ok = ( aGroupType != SMESH::NODE );
break;
+ case 3:
+ ok = ( aGroupType == SMESH::VOLUME );
+ break;
}
}
if ( ok ) aGroups << aGroup;
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 );
*/
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.
*/
void onDeactivate();
+ void updateButtons();
+
private:
QLineEdit* myCurrentLineEdit;
QLineEdit* myLineEdit1;
QLineEdit* myLineEdit2;
QLineEdit* myLineEdit3;
- QCheckBox* myCheckBoxNewElemGroup;
- QCheckBox* myCheckBoxNewNodeGroup;
+ QCheckBox* myCheckBox1;
+ QCheckBox* myCheckBox2;
QPushButton* myButtonOk;
QPushButton* myButtonApply;
<source>ICON_SMESH_DUPLICATE_NODES_WITH_ELEM</source>
<translation>mesh_duplicate_nodes_with_elem.png</translation>
</message>
- <message>
+ <message>
<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>
<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>
<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>
<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>
* 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();
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++ )
{
{
// 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;
}
//================================================================================
* 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.
# 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.