<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>
--- /dev/null
+/*!
+
+\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>
+*/
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
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 );
}
( 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 )
{
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);
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 );
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 );
createTool( 409, modifyTb );
createTool( 410, modifyTb );
createTool( 411, modifyTb );
+ createTool( 419, modifyTb );
createTool( 412, modifyTb );
createTool( 413, modifyTb );
createTool( 416, modifyTb );
#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>
bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/)
{
return (!myMesh->_is_nil() &&
- (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
+ (myListBox->count() > 0 || (myToAllChk->isChecked()/* && myActor*/)));
}
//=======================================================================
//=======================================================================
// 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) {
}
}
*/
- }
+ //}
}
anIds->length(myIds.Extent());
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;
}
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 );
}
/*!
}
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();
}
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()
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();
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;
+}
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:
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);
};
/*!
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;
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();
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
<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>
<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>
<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>