0020672: EDF 1243 SMESH : Be able to transform mixed mesh

* Add "Split into Tetrahedra" operation
This commit is contained in:
eap 2010-03-30 12:36:23 +00:00
parent 0e2bac7865
commit 01d2cde96d
11 changed files with 258 additions and 64 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 923 B

View File

@ -37,6 +37,7 @@ or created anew.</li>
<li>\subpage changing_orientation_of_elements_page "Change orientation"
of the selected elements.</li>
<li>\subpage cutting_quadrangles_page "Cut a quadrangle" into two triangles.</li>
<li>\subpage split_to_tetra_page "Split" volumic elements into tetrahedra.</li>
<li>\subpage smoothing_page "Smooth" elements, reducung distortions in
them by adjusting the locations of element corners.</li>
<li>Create an \subpage extrusion_page "extrusion" along a vector.</li>

View File

@ -0,0 +1,55 @@
/*!
\page split_to_tetra_page Splitting volumes into tetrahedra
\n This operation allows to split volumic elements into tetrahedra.
2D mesh is modified accordingly.
<em>To split volumes:</em>
<ol>
<li>Display a mesh or a submesh in the 3D viewer.</li>
<li>In the \b Modification menu select the <b>Split into Tetrahedra</b> item or
click <em>"Split into Tetrahedra"</em> button in the toolbar.
\image html split_into_tetra_icon.png
<center><em>"Split into Tetrahedra" button</em></center>
The following dialog box will appear:
\image html split_into_tetra.png
\par
<ul>
<li>The main list contains the list of volumes. You can click on
a volume in the 3D viewer and it will be highlighted (lock Shift
keyboard button to select several volumes). Click \b Add button and
the ID of this volume will be added to the list. To remove a
selected element or elements from the list click \b Remove button. <b>Sort
list</b> button allows to sort the list of IDs. \b Filter button allows to
apply a definite filter to the selection of volumes.
<br><b>Note:</b> If you split not all adjacent non-tetrahedral volumes, your mesh becomes
non-conform.</li>
<li><b>Apply to all</b> radio button allows to split all
volumes of the currently displayed mesh or submesh.</li>
</ul>
<ul>
<li>\b Split hexahedron
<ul>
<li><b>Into 5 tetrahedra</b> and <b>Into 6 tetrahedra</b> allows to
specify the number of tetrahedra a hexahedron will be split into. If the specified method does
not allow to get a conform mesh, a generic solution is applied: an additional node
is created at gravity center of a hexahedron, serving an apex of tetrahedra, all quadrangle sides of the hexahedron are split into two triangles each serving a base of a new tetrahedron.</li>
</ul>
</li>
<li><b>Select from</b> set of fields allows to choose a submesh or an
existing group whose elements will be automatically added to the
list.</li>
</ul>
<li>Click the \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
</ol>
*/

View File

@ -169,7 +169,8 @@ dist_salomeres_DATA = \
mesh_2d_from_3d.png \
mesh_free_faces.png \
scale.png \
scale_along_axes.png
scale_along_axes.png \
split_into_tetra.png
# VSR: little trick to avoid putting if SMESHCatalog.xml to the distribution archive
nodist_salomeres_SCRIPTS = SMESHCatalog.xml

Binary file not shown.

After

Width:  |  Height:  |  Size: 923 B

View File

@ -690,8 +690,8 @@
anActor->SetNodeColor( aColor.R, aColor.G, aColor.B );
else if( aGroupObject->GetType() == SMESH::EDGE )
anActor->SetEdgeColor( aColor.R, aColor.G, aColor.B );
else if( aGroupObject->GetType() == SMESH::ELEM0D )
anActor->Set0DColor( aColor.R, aColor.G, aColor.B );
else if( aGroupObject->GetType() == SMESH::ELEM0D )
anActor->Set0DColor( aColor.R, aColor.G, aColor.B );
else
anActor->SetSufaceColor( aColor.R, aColor.G, aColor.B );
}
@ -1853,9 +1853,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
( new SMESHGUI_UnionOfTwoTrianglesDlg( this ) )->show();
break;
}
case 409: // Change orientation
case 410: // Union of triangles
case 411: // Cutting of quadrangles
case 409: // Change orientation
case 410: // Union of triangles
case 411: // Cutting of quadrangles
case 419: // Splitting volumes into tetrahedra
{
if ( !vtkwnd )
{
@ -1873,6 +1874,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
aDlg = new SMESHGUI_ChangeOrientationDlg(this);
else if ( theCommandID == 410 )
aDlg = new SMESHGUI_UnionOfTrianglesDlg(this);
else if ( theCommandID == 419 )
aDlg = new SMESHGUI_CuttingIntoTetraDlg(this);
else
aDlg = new SMESHGUI_CuttingOfQuadsDlg(this);
@ -2981,6 +2984,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( 416, "EXTRUSION_ALONG", "ICON_EXTRUSION_ALONG" );
createSMESHAction( 417, "CONV_TO_QUAD", "ICON_CONV_TO_QUAD" );
createSMESHAction( 418, "2D_FROM_3D", "ICON_2D_FROM_3D" );
createSMESHAction( 419, "SPLIT_TO_TETRA", "ICON_SPLIT_TO_TETRA" );
createSMESHAction( 200, "RESET" );
createSMESHAction( 201, "SCALAR_BAR_PROP" );
createSMESHAction( 211, "WIRE", "ICON_WIRE", 0, true );
@ -3147,6 +3151,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( 409, modifyId, -1 );
createMenu( 410, modifyId, -1 );
createMenu( 411, modifyId, -1 );
createMenu( 419, modifyId, -1 );
createMenu( 412, modifyId, -1 );
createMenu( 413, modifyId, -1 );
createMenu( 416, modifyId, -1 );
@ -3247,6 +3252,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createTool( 409, modifyTb );
createTool( 410, modifyTb );
createTool( 411, modifyTb );
createTool( 419, modifyTb );
createTool( 412, modifyTb );
createTool( 413, modifyTb );
createTool( 416, modifyTb );

View File

@ -39,15 +39,17 @@
#include <SMDS_Mesh.hxx>
// SALOME GUI includes
#include <SUIT_ResourceMgr.h>
#include <SUIT_Desktop.h>
#include <SUIT_Session.h>
#include <SUIT_MessageBox.h>
#include <SUIT_OverrideCursor.h>
#include <SUIT_ResourceMgr.h>
#include <SUIT_Session.h>
#include <LightApp_SelectionMgr.h>
#include <LightApp_Application.h>
#include <SALOME_ListIO.hxx>
#include <SALOME_ListIteratorOfListIO.hxx>
#include <SalomeApp_Tools.h>
#include <SVTK_Selector.h>
#include <SVTK_ViewWindow.h>
@ -301,7 +303,7 @@ QWidget* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/)
{
return (!myMesh->_is_nil() &&
(myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
(myListBox->count() > 0 || (myToAllChk->isChecked()/* && myActor*/)));
}
//=======================================================================
@ -423,49 +425,51 @@ void SMESHGUI_MultiEditDlg::onOk()
//=======================================================================
// name : SMESHGUI_MultiEditDlg::getIds
// Purpose : Retrive identifiers from list box
// Purpose : Retrive identifiers from list box or the whole object
//=======================================================================
SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds(SMESH::SMESH_IDSource_var& obj)
{
SMESH::long_array_var anIds = new SMESH::long_array;
if (myToAllChk->isChecked())
{
myIds.Clear();
SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
if (!anActor)
anActor = myActor;
if (anActor != 0)
{
// skl 07.02.2006
SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
if( myFilterType == SMESH::TriaFilter ||
myFilterType == SMESH::QuadFilter ||
myFilterType == SMESH::FaceFilter ) {
SMDS_FaceIteratorPtr it = aMesh->facesIterator();
while(it->more()) {
const SMDS_MeshFace* f = it->next();
if(myFilterType == SMESH::FaceFilter) {
myIds.Add(f->GetID());
}
else if( myFilterType==SMESH::TriaFilter &&
( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
myIds.Add(f->GetID());
}
else if( myFilterType==SMESH::QuadFilter &&
( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
myIds.Add(f->GetID());
}
}
}
else if(myFilterType == SMESH::VolumeFilter) {
SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
while(it->more()) {
const SMDS_MeshVolume* f = it->next();
myIds.Add(f->GetID());
}
}
/* commented by skl 07.02.2006
obj = SMESH::SMESH_IDSource::_narrow( myMesh );
// SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
// if (!anActor)
// anActor = myActor;
// if (anActor != 0)
// {
// // skl 07.02.2006
// SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
// if( myFilterType == SMESH::TriaFilter ||
// myFilterType == SMESH::QuadFilter ||
// myFilterType == SMESH::FaceFilter ) {
// SMDS_FaceIteratorPtr it = aMesh->facesIterator();
// while(it->more()) {
// const SMDS_MeshFace* f = it->next();
// if(myFilterType == SMESH::FaceFilter) {
// myIds.Add(f->GetID());
// }
// else if( myFilterType==SMESH::TriaFilter &&
// ( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
// myIds.Add(f->GetID());
// }
// else if( myFilterType==SMESH::QuadFilter &&
// ( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
// myIds.Add(f->GetID());
// }
// }
// }
// else if(myFilterType == SMESH::VolumeFilter) {
// SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
// while(it->more()) {
// const SMDS_MeshVolume* f = it->next();
// myIds.Add(f->GetID());
// }
// }
/* commented by skl 07.02.2006 - to work with quadratic elements
TVisualObjPtr aVisualObj = anActor->GetObject();
vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
if (aGrid != 0) {
@ -490,7 +494,7 @@ SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
}
}
*/
}
//}
}
anIds->length(myIds.Extent());
@ -1034,9 +1038,12 @@ bool SMESHGUI_MultiEditDlg::onApply()
myBusy = true;
SMESH::long_array_var anIds = getIds();
SUIT_OverrideCursor aWaitCursor;
bool aResult = process(aMeshEditor, anIds.inout());
SMESH::SMESH_IDSource_var obj;
SMESH::long_array_var anIds = getIds(obj);
bool aResult = process(aMeshEditor, anIds.inout(), obj);
if (aResult) {
if (myActor) {
SALOME_ListIO sel;
@ -1124,9 +1131,13 @@ SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
}
bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
const SMESH::long_array& theIds)
const SMESH::long_array& theIds,
SMESH::SMESH_IDSource_ptr obj)
{
return theEditor->Reorient(theIds);
if ( CORBA::is_nil( obj ))
return theEditor->Reorient(theIds);
else
return theEditor->ReorientObject( obj );
}
/*!
@ -1190,11 +1201,16 @@ bool SMESHGUI_UnionOfTrianglesDlg::isValid (const bool theMess)
}
bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
const SMESH::long_array& theIds)
const SMESH::long_array& theIds,
SMESH::SMESH_IDSource_ptr obj)
{
SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0;
bool ok = theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
bool ok;
if ( CORBA::is_nil( obj ))
ok = theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
else
ok = theEditor->TriToQuadObject(obj, aCriterion, aMaxAngle);
if( ok ) {
QStringList aParameters;
aParameters << myMaxAngleSpin->text();
@ -1243,19 +1259,21 @@ void SMESHGUI_CuttingOfQuadsDlg::onClose()
}
bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
const SMESH::long_array& theIds)
const SMESH::long_array& theIds,
SMESH::SMESH_IDSource_ptr obj)
{
bool hasObj = (! CORBA::is_nil( obj ));
switch (myGroupChoice->checkedId()) {
case 0: // use diagonal 1-3
return theEditor->SplitQuad(theIds, true);
return hasObj ? theEditor->SplitQuadObject(obj, true) : theEditor->SplitQuad(theIds, true);
case 1: // use diagonal 2-4
return theEditor->SplitQuad(theIds, false);
return hasObj ? theEditor->SplitQuadObject(obj, false) : theEditor->SplitQuad(theIds, false);
default: // use numeric functor
break;
}
SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
return theEditor->QuadToTri(theIds, aCriterion);
SMESH::NumericalFunctor_var aCrit = getNumericalFunctor();
return hasObj ? theEditor->QuadToTriObject(obj, aCrit) : theEditor->QuadToTri(theIds, aCrit);
}
void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB()
@ -1295,8 +1313,9 @@ void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
erasePreview();
// get Ids of elements
SMESH::long_array_var anElemIds = getIds();
if (getIds()->length() == 0)
SMESH::SMESH_IDSource_var obj;
SMESH::long_array_var anElemIds = getIds(obj);
if (anElemIds->length() == 0 && obj->_is_nil() )
return;
SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
@ -1449,3 +1468,55 @@ void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
aCellTypesArray->Delete();
aCellLocationsArray->Delete();
}
/*!
* Class : SMESHGUI_CuttingIntoTetraDlg
* Description : Modification of orientation of faces
*/
SMESHGUI_CuttingIntoTetraDlg::SMESHGUI_CuttingIntoTetraDlg(SMESHGUI* theModule)
: SMESHGUI_MultiEditDlg(theModule, SMESH::VolumeFilter, false)
{
setWindowTitle(tr("CAPTION"));
myHelpFileName = "split_to_tetra_page.html";
myEntityType = SMESH::VolumeFilter;
myToAllChk->setChecked( true ); //aplly to the whole mesh by default
bool hasHexa = true;//myMesh->_is_nil() ? false : myMesh->NbHexas();
if ( hasHexa )
{
myGroupChoice->button(2)->hide();
myGroupChoice->button(0)->setText( tr("SPLIT_HEX_TO_5_TETRA"));
myGroupChoice->button(1)->setText( tr("SPLIT_HEX_TO_6_TETRA"));
myCriterionGrp->setTitle( tr("SPLIT_METHOD"));
myCriterionGrp->show();
myComboBoxFunctor->hide();
myChoiceWidget->show();
}
setSelectionMode();
updateButtons();
}
SMESHGUI_CuttingIntoTetraDlg::~SMESHGUI_CuttingIntoTetraDlg()
{
}
bool SMESHGUI_CuttingIntoTetraDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
const SMESH::long_array& theIds,
SMESH::SMESH_IDSource_ptr theObj)
{
SMESH::SMESH_IDSource_var obj = theObj;
if ( CORBA::is_nil( obj ))
obj = theEditor->MakeIDSource( theIds );
try {
theEditor->SplitVolumesIntoTetra( obj, myGroupChoice->checkedId()+1 );
}
catch ( const SALOME::SALOME_Exception& S_ex ) {
SalomeApp_Tools::QtCatchCorbaException( S_ex );
return false;
}
return true;
}

View File

@ -108,12 +108,13 @@ protected:
QWidget* createButtonFrame( QWidget* );
QWidget* createMainFrame( QWidget*, const bool );
virtual bool isValid( const bool );
SMESH::long_array_var getIds();
SMESH::long_array_var getIds(SMESH::SMESH_IDSource_var& obj);
void updateButtons();
void setSelectionMode();
virtual bool isIdValid( const int ) const;
virtual bool process( SMESH::SMESH_MeshEditor_ptr,
const SMESH::long_array& ) = 0;
const SMESH::long_array& ,
SMESH::SMESH_IDSource_ptr obj) = 0;
int entityType();
protected:
@ -174,7 +175,9 @@ public:
virtual ~SMESHGUI_ChangeOrientationDlg();
protected:
virtual bool process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& );
virtual bool process( SMESH::SMESH_MeshEditor_ptr,
const SMESH::long_array& ,
SMESH::SMESH_IDSource_ptr obj);
};
/*!
@ -191,7 +194,9 @@ public:
protected:
virtual bool isValid( const bool );
virtual bool process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& );
virtual bool process( SMESH::SMESH_MeshEditor_ptr,
const SMESH::long_array&,
SMESH::SMESH_IDSource_ptr obj );
private:
SMESHGUI_SpinBox* myMaxAngleSpin;
@ -210,7 +215,9 @@ public:
virtual ~SMESHGUI_CuttingOfQuadsDlg();
protected:
virtual bool process( SMESH::SMESH_MeshEditor_ptr, const SMESH::long_array& );
virtual bool process( SMESH::SMESH_MeshEditor_ptr,
const SMESH::long_array& ,
SMESH::SMESH_IDSource_ptr obj);
protected slots:
virtual void onClose();
@ -226,4 +233,22 @@ private:
QCheckBox* myPreviewChk;
};
/*!
* Class : SMESHGUI_CuttingIntoTetraDlg
* Description : Split all volumes into tetrahedrons
*/
class SMESHGUI_CuttingIntoTetraDlg : public SMESHGUI_MultiEditDlg
{
Q_OBJECT
public:
SMESHGUI_CuttingIntoTetraDlg( SMESHGUI* );
virtual ~SMESHGUI_CuttingIntoTetraDlg();
protected:
virtual bool process( SMESH::SMESH_MeshEditor_ptr,
const SMESH::long_array&,
SMESH::SMESH_IDSource_ptr obj );
};
#endif // SMESHGUI_MULTIEDITDLG_H

View File

@ -461,5 +461,9 @@
<source>ICON_2D_FROM_3D</source>
<translation>mesh_2d_from_3d.png</translation>
</message>
<message>
<source>ICON_SPLIT_TO_TETRA</source>
<translation>split_into_tetra.png</translation>
</message>
</context>
</TS>

View File

@ -710,6 +710,18 @@
<source>MEN_WIRE</source>
<translation>Wireframe</translation>
</message>
<message>
<source>MEN_SPLIT_TO_TETRA</source>
<translation>Split into Tetrahedra</translation>
</message>
<message>
<source>TOP_SPLIT_TO_TETRA</source>
<translation>Split into Tetrahedra</translation>
</message>
<message>
<source>STB_SPLIT_TO_TETRA</source>
<translation>Split into Tetrahedra</translation>
</message>
<message>
<source>MESHERS_FILE_CANT_OPEN</source>
<translation>Can not open resource file</translation>
@ -4763,6 +4775,25 @@ It is impossible to read point coordinates from file</translation>
<translation>Use numeric functor</translation>
</message>
</context>
<context>
<name>SMESHGUI_CuttingIntoTetraDlg</name>
<message>
<source>CAPTION</source>
<translation>Splitting volumes into tetrahedra</translation>
</message>
<message>
<source>SPLIT_METHOD</source>
<translation>Split hexahedron</translation>
</message>
<message>
<source>SPLIT_HEX_TO_5_TETRA</source>
<translation>Into 5 tetrahedra</translation>
</message>
<message>
<source>SPLIT_HEX_TO_6_TETRA</source>
<translation>Into 6 tetrahedra</translation>
</message>
</context>
<context>
<name>SMESHGUI_PrecisionDlg</name>
<message>