bos #32735 [CEA] Create 2D Mesh from 3D elements.

Adding test and icon to cmake. Adding the keyword MakeBoundaryOfEachElement to the 2smeshpy util class.

Add missing french translations of dialog box and operations results. Update copyright message of SMESHGUI_MakeFull2DFrom3DOp new class.
This commit is contained in:
cconopoima 2023-06-27 14:59:34 -03:00
parent dbda21f07d
commit 964c854356
27 changed files with 737 additions and 28 deletions

View File

@ -196,6 +196,7 @@ SET(GOOD_TESTS
transforming_meshes_ex11.py
transforming_meshes_ex12.py
transforming_meshes_ex13.py
transforming_meshes_ex14.py
use_existing_faces.py
viewing_meshes_ex02.py
quad_medial_axis_algo.py

View File

@ -0,0 +1,47 @@
# Create 2D mesh from 3D elements
import salome
salome.salome_init_without_session()
import SMESH
from salome.geom import geomBuilder
from salome.smesh import smeshBuilder
geom_builder = geomBuilder.New()
smesh_builder = smeshBuilder.New()
box = geom_builder.MakeBoxDXDYDZ(100, 100, 100)
gFaces = geom_builder.SubShapeAllSorted(box, geom_builder.ShapeType["FACE"])
f1,f2 = gFaces[0],gFaces[1]
geom_builder.addToStudy(box,"box")
geom_builder.addToStudyInFather(box,f1,"face1")
geom_builder.addToStudyInFather(box,f2,"face2")
twoFaces = geom_builder.MakeCompound([f1,f2])
## -----------
##
## Create 2D from 3D elements
##
## -----------
init_mesh = smesh_builder.Mesh(box, "box")
init_mesh.AutomaticHexahedralization() # it makes 3 x 3 x 3 hexahedrons
init_mesh.Compute()
mesh_1 = smesh_builder.CopyMesh(init_mesh, "Mesh_1")
#Return the number of created faces in the original mesh.
nb, new_mesh, new_group = mesh_1.MakeBoundaryOfEachElement()
if nb != 54: raise Exception("Error on MakeBoundaryOfEachElement call. The number of created elements does not match.")
if new_mesh.GetId() != mesh_1.GetId(): raise Exception("The mesh created from MakeBoundaryElements should be the same of the call")
if new_group: raise Exception("The group created from MakeBoundaryElements should be undefined")
mesh_2 = smesh_builder.CopyMesh(init_mesh, "Mesh_2")
#Return the number of created faces and a new_mesh and new_group
nb, new_mesh, new_group = mesh_2.MakeBoundaryOfEachElement("MyFacesElements", "Face_Mesh")
if nb != 54: raise Exception("Error on MakeBoundaryOfEachElement call. The number of created elements does not match.")
if new_mesh.GetId() == mesh_2.GetId(): raise Exception("The mesh created from MakeBoundaryElements should be the different of the call")
if not new_group: raise Exception("The group created from MakeBoundaryElements should be defined")

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,45 @@
.. _make_2dmesh_from_3d_elements_page:
**************************
Generate 2D mesh from 3D elements
**************************
This functionality allows to generate 2D mesh elements from the 3D elements in the mesh.
.. image:: ../images/2d_mesh_from_3d_elements.jpg
:align: center
.. centered::
2D mesh created from the 3D elements
*To generate 2D elements:*
.. |img| image:: ../images/2d_mesh_from_3d_elements_icon.png
#. Select a mesh or group in the Object Browser or in the 3D Viewer
#. From the **Modification** menu choose **Create 2D mesh from 3D** item, or click "Create 2D mesh from 3D" button |img| in the toolbar
The following dialog box will appear:
.. image:: ../images/2d_mesh_from_3d_elements_dlg.png
:align: center
.. centered::
Create 2D mesh from 3D elements dialog box
#. Click the **Apply** or **Apply and Close** button to perform the operation.
In this dialog:
* specify the **Target** mesh, where the boundary elements will be created.
* **This mesh** adds elements in the selected mesh.
* **New mesh** adds elements to a new mesh. The new mesh appears in the Object Browser with the name that you can change in the adjacent box.
* activate **Copy source mesh** checkbox to copy all elements of the selected mesh to the new mesh, else the new mesh will contain only 2D elements (old and created by this operation).
* activate **Create group** checkbox to create a group to which all the 2D elements (old and new) are added. The new group appears in the Object Browser with the name that you can change in the adjacent box.
**See Also** a sample TUI Script of a :ref:`tui_make_2dmesh_from_3d_elements` operation.

View File

@ -11,6 +11,7 @@ Salome provides a vast specter of mesh modification and transformation operation
* :ref:`Remove <removing_nodes_and_elements_page>` any existing mesh elements and nodes.
* :ref:`Convert linear mesh to quadratic <convert_to_from_quadratic_mesh_page>`, or vice versa.
* :ref:`Generate boundary elements <make_2dmesh_from_3d_page>`.
* :ref:`Generate 2D mesh from 3D elements <make_2dmesh_from_3d_elements_page>`.
* :ref:`Translate <translation_page>` in the indicated direction the mesh or some of its elements.
* :ref:`Rotate <rotation_page>` by the indicated axis and angle the mesh or some of its elements.
* :ref:`Scale <scale_page>` the mesh or some of its elements.
@ -80,6 +81,7 @@ Salome provides a vast specter of mesh modification and transformation operation
pattern_mapping.rst
convert_to_from_quadratic_mesh.rst
make_2dmesh_from_3d.rst
make_2dmesh_from_3d_elements.rst
generate_flat_elements.rst
cut_mesh_by_plane.rst

View File

@ -136,3 +136,13 @@ Reorient faces
:language: python
:download:`Download this script <../../examples/transforming_meshes_ex13.py>`
.. _tui_make_2dmesh_from_3d_elements:
Create 2D mesh from 3D elements
========================
.. literalinclude:: ../../examples/transforming_meshes_ex14.py
:language: python
:download:`Download this script <../../examples/transforming_meshes_ex14.py>`

View File

@ -1291,7 +1291,9 @@ module SMESH
* \param meshName - a name of a new mesh, which is a copy of the initial
* mesh + created boundary elements; "" means not to create the new mesh
* \param toCopyAll - if true, the whole initial mesh will be copied into
* the new mesh else only boundary elements will be copied into the new mesh
* the new mesh else only the new elements will be copied into the new mesh
* \param toCreateAllElements - if true, all the boundary elements of the mesh
* are computed.
* \param groups - optional groups of 2D elements to make boundary around
* \param mesh - returns the mesh where elements were added to
* \param group - returns the created group, if any
@ -1301,6 +1303,7 @@ module SMESH
in string groupName,
in string meshName,
in boolean toCopyAll,
in boolean toCreateAllElements,
in ListOfIDSources groups,
out SMESH_Mesh mesh,
out SMESH_Group group) raises (SALOME::SALOME_Exception);

View File

@ -34,6 +34,7 @@ SET(SMESH_RESOURCES_FILES
mesh_0D_elem.png
mesh_0D_on_all_nodes.png
mesh_2d_from_3d.png
mesh_2d_from_3d_elements.png
mesh_add.png
mesh_add_sub.png
mesh_algo_hexa.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 KiB

View File

@ -12809,7 +12809,8 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
bool toCopyElements/*=false*/,
bool toCopyExistingBoundary/*=false*/,
bool toAddExistingBondary/*= false*/,
bool aroundElements/*= false*/)
bool aroundElements/*= false*/,
bool toCreateAllElements/*= false*/)
{
SMDSAbs_ElementType missType = (dimension == BND_2DFROM3D) ? SMDSAbs_Face : SMDSAbs_Edge;
SMDSAbs_ElementType elemType = (dimension == BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume;
@ -12828,7 +12829,6 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
SMESH_MeshEditor* presentEditor;
SMESH_MeshEditor tgtEditor2( tgtEditor.GetMesh() );
presentEditor = toAddExistingBondary ? &tgtEditor : &tgtEditor2;
SMESH_MesherHelper helper( *myMesh );
const TopAbs_ShapeEnum missShapeType = ( missType==SMDSAbs_Face ? TopAbs_FACE : TopAbs_EDGE );
SMDS_VolumeTool vTool;
@ -12866,8 +12866,9 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
const SMDS_MeshElement* otherVol = 0;
for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
{
if ( !vTool.IsFreeFace(iface, &otherVol) &&
( !aroundElements || elements.count( otherVol )))
if ( !toCreateAllElements &&
!vTool.IsFreeFace(iface, &otherVol) &&
( !aroundElements || elements.count( otherVol )))
continue;
freeFacets.push_back( iface );
}

View File

@ -748,7 +748,8 @@ public:
bool toCopyElements = false,
bool toCopyExistingBondary = false,
bool toAddExistingBondary = false,
bool aroundElements = false);
bool aroundElements = false,
bool toCreateAllElements= false);
private:

View File

@ -136,6 +136,7 @@ SET(_moc_HEADERS
SMESHGUI_MakeNodeAtPointDlg.h
SMESHGUI_MeshInfosBox.h
SMESHGUI_Make2DFrom3DOp.h
SMESHGUI_MakeFull2DFrom3DOp.h
SMESHGUI_FindElemByPointDlg.h
SMESHGUI_MeshOrderDlg.h
SMESHGUI_CopyMeshDlg.h
@ -249,6 +250,7 @@ SET(_other_SOURCES
SMESHGUI_FileInfoDlg.cxx
SMESHGUI_MeshInfosBox.cxx
SMESHGUI_Make2DFrom3DOp.cxx
SMESHGUI_MakeFull2DFrom3DOp.cxx
SMESHGUI_FindElemByPointDlg.cxx
SMESHGUI_MeshOrderDlg.cxx
SMESHGUI_CopyMeshDlg.cxx

View File

@ -65,6 +65,7 @@
#include "SMESHGUI_MG_ADAPTDRIVER.h"
#include "SMESHGUI_HomardAdaptDlg.h"
#include "SMESHGUI_Make2DFrom3DOp.h"
#include "SMESHGUI_MakeFull2DFrom3DOp.h"
#include "SMESHGUI_MakeNodeAtPointDlg.h"
#include "SMESHGUI_Measurements.h"
#include "SMESHGUI_MergeDlg.h"
@ -3058,6 +3059,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
case SMESHOp::OpConvertMeshToQuadratic:
case SMESHOp::OpCreateDualMesh:
case SMESHOp::OpCreateBoundaryElements: // create 2D mesh from 3D
case SMESHOp::OpCreate2DElements: // create full 2D mesh from 3D
case SMESHOp::OpReorientFaces:
case SMESHOp::OpCreateGeometryGroup:
{
@ -4285,6 +4287,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( SMESHOp::OpConvertMeshToQuadratic, "CONV_TO_QUAD", "ICON_CONV_TO_QUAD" );
createSMESHAction( SMESHOp::OpCreateDualMesh, "CREATE_DUAL_MESH","ICON_CREATE_DUAL_MESH" );
createSMESHAction( SMESHOp::OpCreateBoundaryElements, "2D_FROM_3D", "ICON_2D_FROM_3D" );
createSMESHAction( SMESHOp::OpCreate2DElements, "2D_FROM_3D_ELEMENTS","ICON_2D_FROM_3D_ELEMENTS" );
createSMESHAction( SMESHOp::OpReset, "RESET" );
createSMESHAction( SMESHOp::OpScalarBarProperties, "SCALAR_BAR_PROP" );
@ -4535,6 +4538,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createMenu( SMESHOp::OpConvertMeshToQuadratic, modifyId, -1 );
createMenu( SMESHOp::OpCreateBoundaryElements, modifyId, -1 );
createMenu( SMESHOp::OpCreate2DElements, modifyId, -1 );
createMenu( SMESHOp::OpExtrusion, modifyId, -1 );
createMenu( SMESHOp::OpExtrusionAlongAPath, modifyId, -1 );
createMenu( SMESHOp::OpRevolution, modifyId, -1 );
@ -4688,6 +4692,7 @@ void SMESHGUI::initialize( CAM_Application* app )
int modifyTb = createTool( tr( "TB_MODIFY" ), QString( "SMESHModificationToolbar" ) ) ;
createTool( SMESHOp::OpConvertMeshToQuadratic, modifyTb );
createTool( SMESHOp::OpCreateBoundaryElements, modifyTb );
createTool( SMESHOp::OpCreate2DElements, modifyTb );
createTool( SMESHOp::OpExtrusion, modifyTb );
createTool( SMESHOp::OpExtrusionAlongAPath, modifyTb );
createTool( SMESHOp::OpRevolution, modifyTb );
@ -6044,6 +6049,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
case SMESHOp::OpCreateDualMesh:
op = new SMESHGUI_CreateDualMeshOp();
break;
case SMESHOp::OpCreate2DElements:
op = new SMESHGUI_MakeFull2DFrom3DOp();
break;
case SMESHOp::OpReorientFaces:
op = new SMESHGUI_ReorientFacesOp();
break;

View File

@ -73,17 +73,16 @@ SMESHGUI_Make2DFrom3DDlg::SMESHGUI_Make2DFrom3DDlg( QWidget* parent )
setWindowTitle( tr("CAPTION") );
// mode
QGroupBox* aModeGrp = new QGroupBox( tr( "MODE" ), mainFrame() );
QHBoxLayout* aModeGrpLayout = new QHBoxLayout( aModeGrp );
myModeGrp = new QGroupBox( tr( "MODE" ), mainFrame() );
QHBoxLayout* aModeGrpLayout = new QHBoxLayout( myModeGrp );
aModeGrpLayout->setMargin( MARGIN );
aModeGrpLayout->setSpacing( SPACING );
my2dFrom3dRB = new QRadioButton( tr( "2D_FROM_3D" ), aModeGrp );
my1dFrom2dRB = new QRadioButton( tr( "1D_FROM_2D" ), aModeGrp );
my2dFrom3dRB = new QRadioButton( tr( "2D_FROM_3D" ), myModeGrp );
my1dFrom2dRB = new QRadioButton( tr( "1D_FROM_2D" ), myModeGrp );
//my1dFrom3dRB = new QRadioButton( tr( "1D_FROM_3D" ), aModeGrp );
aModeGrpLayout->addWidget( my2dFrom3dRB );
aModeGrpLayout->addWidget( my1dFrom2dRB );
//aModeGrpLayout->addWidget( my1dFrom3dRB );
// // Groups of mesh faces
// setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) );
// createObject( tr( "Groups" ), mainFrame(), Groups );
@ -116,7 +115,7 @@ SMESHGUI_Make2DFrom3DDlg::SMESHGUI_Make2DFrom3DDlg( QWidget* parent )
QGridLayout* aDlgLay = new QGridLayout( mainFrame() );
aDlgLay->setMargin( 0 );
aDlgLay->setSpacing( SPACING );
aDlgLay->addWidget( aModeGrp, 0, 0, 1, 3 );
aDlgLay->addWidget( myModeGrp, 0, 0, 1, 3 );
aDlgLay->addWidget( objectWg( MeshOrGroups, Label ), 1, 0 );
aDlgLay->addWidget( objectWg( MeshOrGroups, Control ), 1, 1 );
aDlgLay->addWidget( aTargetGrp, 2, 0, 1, 3 );
@ -409,6 +408,7 @@ bool SMESHGUI_Make2DFrom3DOp::compute2DMesh( QStringList& theEntryList )
SUIT_OverrideCursor wc;
bool ok = false;
bool toCreateAllElements = false;
try {
SMESH::Bnd_Dimension mode = myDlg->mode();
QString meshName = myDlg->needNewMesh() ? myDlg->getNewMeshName() : QString();
@ -453,6 +453,7 @@ bool SMESHGUI_Make2DFrom3DOp::compute2DMesh( QStringList& theEntryList )
groupName.toUtf8().constData(),
meshName.toUtf8().constData(),
copyAll,
toCreateAllElements,
groups,
newMesh.out(),
newGrp.out() );

View File

@ -33,6 +33,7 @@
#include CORBA_SERVER_HEADER(SMESH_Mesh)
class QCheckBox;
class QGroupBox;
class QLineEdit;
class QRadioButton;
class SMESHGUI_Make2DFrom3DOp;
@ -65,6 +66,9 @@ public:
bool copySource() const;
protected:
QGroupBox* myModeGrp;
private slots:
void onTargetChanged();
void onGroupChecked();

View File

@ -0,0 +1,340 @@
// Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : SMESHGUI_MakeFull2DFrom3DOp.cxx
// Author : Cesar Conopoima, Open CASCADE S.A.S. (cesar.conopoima@opencascade.com)
#include "SMESHGUI_MakeFull2DFrom3DOp.h"
#include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_MeshUtils.h"
#include "SMESH_TypeFilter.hxx"
#include "SMESH_LogicalFilter.hxx"
#include "SMESHGUI_VTKUtils.h"
#include "SMESH_Actor.h"
// SALOME GUI includes
#include <LightApp_Application.h>
#include <LightApp_SelectionMgr.h>
#include <LightApp_UpdateFlags.h>
#include <SALOME_ListIO.hxx>
#include <SUIT_Desktop.h>
#include <SUIT_MessageBox.h>
#include <SUIT_OverrideCursor.h>
#include <SUIT_Session.h>
#include <SVTK_ViewModel.h>
//#include <SVTK_ViewWindow.h>
#include <SalomeApp_Study.h>
#include <SalomeApp_Tools.h>
// IDL includes
#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Group)
// Qt includes
#include <QGroupBox>
#include <Standard_ErrorHandler.hxx>
/*!
\class SMESHGUI_Make2DFrom3DDlg
\brief Copy Mesh dialog box
*/
SMESHGUI_MakeFull2DFrom3DDlg::SMESHGUI_MakeFull2DFrom3DDlg( QWidget* parent )
: SMESHGUI_Make2DFrom3DDlg( parent )
{
// title
setWindowTitle( tr("CAPTION") );
myModeGrp->setVisible(false);
}
SMESHGUI_MakeFull2DFrom3DDlg::~SMESHGUI_MakeFull2DFrom3DDlg()
{
}
/*!
\class SMESHGUI_MakeFull2DFrom3DOp
\brief Copy Mesh operation class
*/
SMESHGUI_MakeFull2DFrom3DOp::SMESHGUI_MakeFull2DFrom3DOp()
: SMESHGUI_SelectionOp(),
myMeshFilter(SMESH::MESH),
myGroupFilter(SMESH::GROUP)
{
}
SMESHGUI_MakeFull2DFrom3DOp::~SMESHGUI_MakeFull2DFrom3DOp()
{
}
LightApp_Dialog* SMESHGUI_MakeFull2DFrom3DOp::dlg() const
{
return myDlg;
}
void SMESHGUI_MakeFull2DFrom3DOp::startOperation()
{
if( !myDlg )
myDlg = new SMESHGUI_MakeFull2DFrom3DDlg( desktop() );
myHelpFileName = "make_2dmesh_from_3d_elements.html";
SMESHGUI_SelectionOp::startOperation();
myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
myDlg->show();
myDlg->activateObject( SMESHGUI_MakeFull2DFrom3DDlg::MeshOrGroups );
selectionDone();
}
void SMESHGUI_MakeFull2DFrom3DOp::selectionDone()
{
myDlg->clearSelection( SMESHGUI_MakeFull2DFrom3DDlg::MeshOrGroups );
mySrcMesh = SMESH::SMESH_Mesh::_nil();
if ( !dlg() ) return;
if ( dlg()->isVisible() ) {
try {
QStringList names, ids;
LightApp_Dialog::TypesList types;
selected( names, types, ids );
for ( int i = 0; i < names.count(); ++i )
names[i] = names[i].trimmed();
myDlg->selectObject( names, types, ids );
// enable/desable "new mesh" button
bool isMesh = true;
for ( int i = 0; i < ids.count() && isMesh; ++i )
{
_PTR(SObject) sobj = SMESH::getStudy()->FindObjectID( ids[i].toUtf8().constData() );
mySrcMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>( sobj );
}
myDlg->setNewMeshEnabled( isMesh );
}
catch ( const SALOME::SALOME_Exception& S_ex ) {
SalomeApp_Tools::QtCatchCorbaException( S_ex );
}
catch ( ... ) {
}
}
}
SUIT_SelectionFilter* SMESHGUI_MakeFull2DFrom3DOp::createFilter( const int /*theId*/ ) const
{
SMESHGUI_MakeFull2DFrom3DOp* me = (SMESHGUI_MakeFull2DFrom3DOp*) this;
QList<SUIT_SelectionFilter*> subFilters;
subFilters.append( & me->myMeshFilter );
subFilters.append( & me->myGroupFilter );
SUIT_SelectionFilter* f = new SMESH_LogicalFilter( subFilters, SMESH_LogicalFilter::LO_OR );
return f;
}
bool SMESHGUI_MakeFull2DFrom3DOp::isValid( QString& msg ) const
{
if ( !dlg() ) return false;
// check if a mesh is selected
if ( !myDlg->hasSelection( SMESHGUI_MakeFull2DFrom3DDlg::MeshOrGroups ))
{
msg = tr( "SMESH_ERR_NO_INPUT_MESH" );
return false;
}
QStringList entries;
dlg()->selectedObject( SMESHGUI_MakeFull2DFrom3DDlg::MeshOrGroups, entries );
const bool isMeshSelected = ( !mySrcMesh->_is_nil() );
if ( isMeshSelected )
{
// only one mesh is allowed
if ( entries.size() > 1 ) {
msg = tr( "SMESH_TOO_MANY_MESHES" );
return false;
}
}
else
{
// check if only groups are selected
for ( int i = 0; i < entries.count(); ++i )
{
SMESH::SMESH_GroupBase_var grp;
if ( _PTR(SObject) sobj = SMESH::getStudy()->FindObjectID( entries[i].toUtf8().constData() ))
grp = SMESH::SObjectToInterface<SMESH::SMESH_GroupBase>( sobj );
if ( grp->_is_nil() ) {
msg = tr( "SMESH_NOT_ONLY_GROUPS" );
return false;
}
}
}
// check if the selected objects contains elements of required type
bool hasVolumes = false;
for ( int i = 0; i < entries.count(); ++i )
{
SMESH::SMESH_IDSource_var idSource;
if ( _PTR(SObject) sobj = SMESH::getStudy()->FindObjectID( entries[i].toUtf8().constData() ))
idSource = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );
if ( !idSource->_is_nil() ) {
SMESH::array_of_ElementType_var types = idSource->GetTypes();
for ( int j = 0; j < (int) types->length(); ++j )
if ( types[j] == SMESH::VOLUME )
hasVolumes = true;
}
}
if ( !hasVolumes ) {
msg = tr( "SMESH_ERR_NO_3D_ELEMENTS" );
return false;
}
// check if new mesh name is specified
if ( myDlg->needNewMesh() && myDlg->getNewMeshName().isEmpty() ) {
msg = tr( "SMESH_ERR_MESH_NAME_NOT_SPECIFIED" );
return false;
}
// check if group name is specified
if ( myDlg->needGroup() && myDlg->getGroupName().isEmpty() ) {
msg = tr( "SMESH_ERR_GRP_NAME_NOT_SPECIFIED" );
return false;
}
return true;
}
bool SMESHGUI_MakeFull2DFrom3DOp::compute2DMesh( QStringList& theEntryList )
{
SUIT_OverrideCursor wc;
bool ok = false;
try {
QString meshName = myDlg->needNewMesh() ? myDlg->getNewMeshName() : QString();
QString groupName = myDlg->needGroup() ? myDlg->getGroupName() : QString();
bool copyAll = myDlg->copySource();
QStringList entries;
dlg()->selectedObject( SMESHGUI_MakeFull2DFrom3DDlg::MeshOrGroups, entries );
SMESH::ListOfIDSources_var groups = new SMESH::ListOfIDSources;
QString wrongGroups = "";
if ( mySrcMesh->_is_nil() ) // get selected groups, find groups of wrong type
{
int nbGroups = 0;
groups->length( entries.count() );
for ( int i = 0; i < entries.count(); ++i )
{
_PTR(SObject) sobj = SMESH::getStudy()->FindObjectID( entries[i].toUtf8().constData() );
SMESH::SMESH_IDSource_var grp = SMESH::SObjectToInterface<SMESH::SMESH_IDSource>( sobj );
SMESH::array_of_ElementType_var types = grp->GetTypes();
if ( types->length() < 1 || types[0] != SMESH::VOLUME )
{
if ( !wrongGroups.isEmpty() )
wrongGroups += ", ";
wrongGroups += sobj->GetName().c_str();
}
else
{
groups[ nbGroups++ ] = grp;
}
}
groups->length( nbGroups );
mySrcMesh = groups[0]->GetMesh();
}
if ( !CORBA::is_nil( mySrcMesh ) ) {
SMESH::SMESH_MeshEditor_var aMeshEditor = mySrcMesh->GetMeshEditor();
SMESH::SMESH_Group_var newGrp;
SMESH::SMESH_Mesh_var newMesh;
CORBA::Long nbAdded = aMeshEditor->MakeBoundaryElements( SMESH::BND_2DFROM3D,
groupName.toUtf8().constData(),
meshName.toUtf8().constData(),
copyAll,
true,
groups,
newMesh.out(),
newGrp.out() );
QString msg = tr("NB_ADDED").arg( nbAdded );
if ( !wrongGroups.isEmpty() )
msg += ".\n" + tr("WRONG_GROUPS").arg( wrongGroups );
SUIT_MessageBox::information( myDlg, tr("SMESH_INFORMATION"), msg);
if ( !newMesh->_is_nil() ) {
if( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) )
theEntryList.append( aSObject->GetID().c_str() );
}
ok = true;
for ( int i = 0; i < entries.count(); ++i )
if ( SMESH_Actor* actor = SMESH::FindActorByEntry( entries[i].toUtf8().constData() ))
{
actor->SetEntityMode( actor->GetEntityMode() | SMESH_Actor::eFaces );
SMESH::Update( actor->getIO(), actor->GetVisibility() );
}
SMESH::RepaintCurrentView();
}
}
catch ( ... ) {
}
return ok;
}
bool SMESHGUI_MakeFull2DFrom3DOp::onApply()
{
if ( SMESHGUI::isStudyLocked() )
return false;
QString msg;
if ( !isValid( msg ) ) {
dlg()->show();
if ( msg != "" )
SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), msg );
return false;
}
QStringList anEntryList;
bool res = false;
try {
res = compute2DMesh( anEntryList );
}
catch ( const SALOME::SALOME_Exception& S_ex ) {
SalomeApp_Tools::QtCatchCorbaException( S_ex );
}
catch ( ... ) {
}
if ( res ) {
SMESHGUI::Modified();
update( UF_ObjBrowser | UF_Model );
if( LightApp_Application* anApp =
dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() ) )
anApp->browseObjects( anEntryList, isApplyAndClose() );
myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) );
myDlg->setGroupName( SMESH::UniqueName( "Group" ) );
}
else {
SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), tr( "SMESH_OPERATION_FAILED" ) );
}
return res;
}

View File

@ -0,0 +1,77 @@
// Copyright (C) 2007-2023 CEA, EDF, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : SMESHGUI_MakeFull2DFrom3DOp.h
// Author : Cesar Conopoima, Open CASCADE S.A.S. (cesar.conopoima@opencascade.com)
#ifndef SMESHGUI_MakeFull2DFrom3DOp_H
#define SMESHGUI_MakeFull2DFrom3DOp_H
// SMESH includes
#include "SMESHGUI_Make2DFrom3DOp.h"
/*!
* \brief Dialog for options of generating 2D mesh from 3D.
*/
class SMESHGUI_EXPORT SMESHGUI_MakeFull2DFrom3DDlg : public SMESHGUI_Make2DFrom3DDlg
{
Q_OBJECT
public:
SMESHGUI_MakeFull2DFrom3DDlg( QWidget* );
virtual ~SMESHGUI_MakeFull2DFrom3DDlg();
friend class SMESHGUI_MakeFull2DFrom3DOp;
};
/*!
* \brief Operation to compute 2D mesh from 3D mesh
*/
class SMESHGUI_EXPORT SMESHGUI_MakeFull2DFrom3DOp : public SMESHGUI_SelectionOp
{
Q_OBJECT
public:
SMESHGUI_MakeFull2DFrom3DOp();
virtual ~SMESHGUI_MakeFull2DFrom3DOp();
virtual LightApp_Dialog* dlg() const;
protected:
virtual void startOperation();
virtual void selectionDone();
virtual SUIT_SelectionFilter* createFilter( const int ) const;
bool isValid( QString& ) const;
protected slots:
virtual bool onApply();
private:
bool compute2DMesh( QStringList& );
private:
SMESH::SMESH_Mesh_var mySrcMesh;
QPointer<SMESHGUI_MakeFull2DFrom3DDlg> myDlg;
SMESH_TypeFilter myMeshFilter;
SMESH_TypeFilter myGroupFilter;
};
#endif // SMESHGUI_MakeFull2DFrom3DOp_H

View File

@ -188,6 +188,8 @@ namespace SMESHOp {
OpSplitEdgeInteract = 4517, // MENU MODIFICATION - INTERACTIVE ADD NODE ON EDGE
OpSplitFaceInteract = 4518, // MENU MODIFICATION - INTERACTIVE ADD NODE ON FACE
OpCreateDualMesh = 4519, // MENU MODIFICATION - CREATE DUAL MESH
OpCreate2DElements = 4520, // MENU MODIFICATION - CREATE 2D MESH FROM 3D MESH
// Adaptation ---------------------//--------------------------------
OpMGAdapt = 8020, // MENU ADAPTATION - MG-ADAPT
OpHomardAdapt = 8021, // MENU ADAPTATION - HOMARD-ADAPT

View File

@ -675,6 +675,10 @@
<source>ICON_2D_FROM_3D</source>
<translation>mesh_2d_from_3d.png</translation>
</message>
<message>
<source>ICON_2D_FROM_3D_ELEMENTS</source>
<translation>mesh_2d_from_3d_elements.png</translation>
</message>
<message>
<source>ICON_SPLIT_TO_TETRA</source>
<translation>split_into_tetra.png</translation>

View File

@ -476,6 +476,10 @@
<source>MEN_2D_FROM_3D</source>
<translation>Create boundary elements</translation>
</message>
<message>
<source>MEN_2D_FROM_3D_ELEMENTS</source>
<translation>Create 2D mesh from 3D elements</translation>
</message>
<message>
<source>MEN_MESH_ORDER</source>
<translation>Change sub-mesh priority</translation>
@ -3380,6 +3384,10 @@ Use Display Entity menu command to show them.
<source>STB_2D_FROM_3D</source>
<translation>Create boundary elements</translation>
</message>
<message>
<source>STB_2D_FROM_3D_ELEMENTS</source>
<translation>Create 2D mesh from 3D elements</translation>
</message>
<message>
<source>STB_MESH_ORDER</source>
<translation>Change sub-mesh priority</translation>
@ -4108,6 +4116,10 @@ Use Display Entity menu command to show them.
<source>TOP_2D_FROM_3D</source>
<translation>Create boundary elements</translation>
</message>
<message>
<source>TOP_2D_FROM_3D_ELEMENTS</source>
<translation>Create 2D mesh from 3D elements</translation>
</message>
<message>
<source>TOP_MESH_ORDER</source>
<translation>Change sub-mesh priority</translation>
@ -7904,6 +7916,17 @@ It is impossible to read point coordinates from file</translation>
<translation>Generate</translation>
</message>
</context>
<context>
<name>SMESHGUI_MakeFull2DFrom3DDlg</name>
<message>
<source>CAPTION</source>
<translation>Create 2D mesh from 3D elements</translation>
</message>
<message>
<source>2D_FROM_3D_ELEMENTS</source>
<translation>2D from 3D</translation>
</message>
</context>
<context>
<name>SMESHGUI_Make2DFrom3DDlg</name>
<message>
@ -7955,6 +7978,43 @@ It is impossible to read point coordinates from file</translation>
<translation>Create group</translation>
</message>
</context>
<context>
<name>SMESHGUI_MakeFull2DFrom3DOp</name>
<message>
<source>NB_ADDED</source>
<translation>%1 boundary elements have been added</translation>
</message>
<message>
<source>WRONG_GROUPS</source>
<translation>The following groups have not been processed
as they are of improper type:
%1</translation>
</message>
<message>
<source>SMESH_ERR_NO_INPUT_MESH</source>
<translation>Source mesh is not specified</translation>
</message>
<message>
<source>SMESH_TOO_MANY_MESHES</source>
<translation>Only one mesh can be processed at once</translation>
</message>
<message>
<source>SMESH_NOT_ONLY_GROUPS</source>
<translation>Can&apos;t process meshes and groups at once</translation>
</message>
<message>
<source>SMESH_ERR_NO_3D_ELEMENTS</source>
<translation>The source objects do not contain 3D elements</translation>
</message>
<message>
<source>SMESH_ERR_MESH_NAME_NOT_SPECIFIED</source>
<translation>New mesh name is not specified</translation>
</message>
<message>
<source>SMESH_ERR_GRP_NAME_NOT_SPECIFIED</source>
<translation>Group name is not specified</translation>
</message>
</context>
<context>
<name>SMESHGUI_Make2DFrom3DOp</name>
<message>

View File

@ -476,6 +476,10 @@
<source>MEN_2D_FROM_3D</source>
<translation>Créer les éléments de frontière</translation>
</message>
<message>
<source>MEN_2D_FROM_3D_ELEMENTS</source>
<translation>Créer les faces des éléments volumiques</translation>
</message>
<message>
<source>MEN_MESH_ORDER</source>
<translation>Changer la priorité des sous-maillages</translation>
@ -3379,6 +3383,10 @@ Utilisez le menu &quot;Visualiser une entité&quot; pour les afficher.
<source>STB_2D_FROM_3D</source>
<translation>Créer les éléments de frontière</translation>
</message>
<message>
<source>STB_2D_FROM_3D_ELEMENTS</source>
<translation>Créer les faces des éléments volumiques</translation>
</message>
<message>
<source>STB_MESH_ORDER</source>
<translation>Changer la priorité des sous-maillages</translation>
@ -4107,6 +4115,10 @@ Utilisez le menu &quot;Visualiser une entité&quot; pour les afficher.
<source>TOP_2D_FROM_3D</source>
<translation>Créer les éléments de frontière</translation>
</message>
<message>
<source>TOP_2D_FROM_3D_ELEMENTS</source>
<translation>Créer les faces des éléments volumiques</translation>
</message>
<message>
<source>TOP_MESH_ORDER</source>
<translation>Changer la priorité des sous-maillages</translation>
@ -7930,6 +7942,17 @@ Il y a trop peu de points dans le fichier </translation>
<translation>Génerer</translation>
</message>
</context>
<context>
<name>SMESHGUI_MakeFull2DFrom3DDlg</name>
<message>
<source>CAPTION</source>
<translation>Créer les faces des éléments volumiques</translation>
</message>
<message>
<source>2D_FROM_3D_ELEMENTS</source>
<translation>Faces des éléments volumiques</translation>
</message>
</context>
<context>
<name>SMESHGUI_Make2DFrom3DDlg</name>
<message>
@ -7981,6 +8004,43 @@ Il y a trop peu de points dans le fichier </translation>
<translation>Créer un groupe</translation>
</message>
</context>
<context>
<name>SMESHGUI_MakeFull2DFrom3DOp</name>
<message>
<source>NB_ADDED</source>
<translation>%1 faces ont é ajoutés</translation>
</message>
<message>
<source>WRONG_GROUPS</source>
<translation>Les groupes suivants n'ont pas é traités
en raison de leurs types incompatibles:
%1</translation>
</message>
<message>
<source>SMESH_ERR_NO_INPUT_MESH</source>
<translation>Aucun maillage, sous-maillage ou groupe source n'est indiqué</translation>
</message>
<message>
<source>SMESH_TOO_MANY_MESHES</source>
<translation>Un seul maillage à la fois peut être traité</translation>
</message>
<message>
<source>SMESH_NOT_ONLY_GROUPS</source>
<translation>Impossible de traiter à la fois des maillages et des groupes</translation>
</message>
<message>
<source>SMESH_ERR_NO_3D_ELEMENTS</source>
<translation>L'objet source ne contient pas d'éléments 3D</translation>
</message>
<message>
<source>SMESH_ERR_MESH_NAME_NOT_SPECIFIED</source>
<translation>Le nom du nouveau maillage n'est pas indiqué</translation>
</message>
<message>
<source>SMESH_ERR_GRP_NAME_NOT_SPECIFIED</source>
<translation>Le nom du groupe n'est pas indiqué</translation>
</message>
</context>
<context>
<name>SMESHGUI_Make2DFrom3DOp</name>
<message>

View File

@ -765,7 +765,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
meshID = aCommand->GetResultValue();
else if ( method == "MakeBoundaryMesh")
meshID = aCommand->GetResultValue(1);
else if ( method == "MakeBoundaryElements")
else if ( method == "MakeBoundaryElements" || method == "MakeBoundaryOfEachElement" )
meshID = aCommand->GetResultValue(2);
if ( method.Search("MakeGroups") != -1 ||
@ -782,7 +782,7 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
groups = aCommand->GetResultValue();
else if ( method == "MakeBoundaryMesh" )
groups = aCommand->GetResultValue(2);
else if ( method == "MakeBoundaryElements")
else if ( method == "MakeBoundaryElements" || method == "MakeBoundaryOfEachElement" )
groups = aCommand->GetResultValue(3);
else if ( method == "Create0DElementsOnAllNodes" &&
aCommand->GetArg(2).Length() > 2 ) // group name != ''
@ -1828,7 +1828,8 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID& meshId):
}
else if ( theCreationCmd->GetMethod().Search("MakeMesh") != -1 ||
theCreationCmd->GetMethod() == "MakeBoundaryMesh" ||
theCreationCmd->GetMethod() == "MakeBoundaryElements" )
theCreationCmd->GetMethod() == "MakeBoundaryElements" ||
theCreationCmd->GetMethod() == "MakeBoundaryOfEachElement" )
{
// this mesh depends on a source mesh
// (theCreationCmd is already Process()ed by _pyMeshEditor)
@ -2521,7 +2522,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
"GetLastCreatedElems", "FaceGroupsSeparatedByEdges",
"MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh","TranslateObjectMakeMesh",
"Scale","ScaleMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh",
"MakeBoundaryElements", "SplitVolumesIntoTetra","SplitHexahedraIntoPrisms",
"MakeBoundaryElements", "MakeBoundaryOfEachElement", "SplitVolumesIntoTetra","SplitHexahedraIntoPrisms",
"DoubleElements","DoubleNodes","DoubleNode","DoubleNodeGroup","DoubleNodeGroups",
"DoubleNodeElem","DoubleNodeElemInRegion","DoubleNodeElemGroup","AffectedElemGroupsInRegion",
"DoubleNodeElemGroupInRegion","DoubleNodeElemGroups","DoubleNodeElemGroupsInRegion",

View File

@ -7306,6 +7306,7 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
* mesh + created boundary elements; "" means not to create the new mesh
* \param toCopyAll - if true, the whole initial mesh will be copied into
* the new mesh else only boundary elements will be copied into the new mesh
* \param toCreateAllElements - if true all the dim element are created from the mesh
* \param groups - optional groups of elements to make boundary around
* \param mesh - returns the mesh where elements were added to
* \param group - returns the created group, if any
@ -7317,6 +7318,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
const char* groupName,
const char* meshName,
CORBA::Boolean toCopyAll,
CORBA::Boolean toCreateAllElements,
const SMESH::ListOfIDSources& groups,
SMESH::SMESH_Mesh_out mesh,
SMESH::SMESH_Group_out group)
@ -7354,7 +7356,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
// process groups belonging to another mesh
SMESH::SMESH_Mesh_var otherMesh = groupsOfOtherMesh[0]->GetMesh();
SMESH::SMESH_MeshEditor_var editor = otherMesh->GetMeshEditor();
nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll,
nbAdded += editor->MakeBoundaryElements( dim, groupName, meshName, toCopyAll, toCreateAllElements,
groupsOfOtherMesh, mesh, group );
}
@ -7381,6 +7383,7 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
SMESH_Mesh* srcMesh = ( toCopyMesh && !toCopyAll ) ? myMesh : tgtMesh;
SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
// group of boundary elements
SMESH_Group* smesh_group = 0;
SMDSAbs_ElementType elemType = (dim == SMESH::BND_2DFROM3D) ? SMDSAbs_Volume : SMDSAbs_Face;
@ -7393,7 +7396,6 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
}
TIDSortedElemSet elements;
if ( groups.length() > 0 )
{
for ( int i = 0; i < nbGroups; ++i )
@ -7410,7 +7412,8 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
/*toCopyElements=*/false,
/*toCopyExistingBondary=*/srcMesh != tgtMesh,
/*toAddExistingBondary=*/true,
/*aroundElements=*/true);
/*aroundElements=*/true,
/*toCreateAllElements=*/toCreateAllElements);
}
}
}
@ -7422,7 +7425,8 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
tgtMesh,
/*toCopyElements=*/false,
/*toCopyExistingBondary=*/srcMesh != tgtMesh,
/*toAddExistingBondary=*/true);
/*toAddExistingBondary=*/true,
/*aroundElements=*/toCreateAllElements);
}
tgtMesh->GetMeshDS()->Modified();
@ -7437,13 +7441,21 @@ CORBA::Long SMESH_MeshEditor_i::MakeBoundaryElements(SMESH::Bnd_Dimension dim,
if ( group_var->_is_nil() )
pyDump << "_NoneGroup = "; // assignment to None is forbidden
else
pyDump << group_var << " = ";
pyDump << this << ".MakeBoundaryElements( "
<< "SMESH." << dimName[int(dim)] << ", "
<< "'" << groupName << "', "
<< "'" << meshName<< "', "
<< toCopyAll << ", "
<< groups << ")";
if ( toCreateAllElements )
pyDump << this << ".MakeBoundaryOfEachElement( ";
else
{
pyDump << this << ".MakeBoundaryElements( "
<< "SMESH." << dimName[int(dim)] << ", ";
}
pyDump<< "'" << groupName << "', "
<< "'" << meshName<< "', "
<< toCopyAll << ", "
<< groups << ")";
mesh = mesh_var._retn();
group = group_var._retn();

View File

@ -837,6 +837,7 @@ public:
const char* groupName,
const char* meshName,
CORBA::Boolean toCopyAll,
CORBA::Boolean toCreateAllElements,
const SMESH::ListOfIDSources& groups,
SMESH::SMESH_Mesh_out mesh,
SMESH::SMESH_Group_out group);

View File

@ -5465,6 +5465,32 @@ class Mesh(metaclass = MeshMeta):
if mesh: mesh = self.smeshpyD.Mesh(mesh)
return mesh, group
def MakeBoundaryOfEachElement(self, groupName="", meshName="", toCopyAll=False, groups=[] ):
"""
Create boundary elements around the whole mesh or groups of elements
Parameters:
groupName: a name of group to store all boundary elements in,
"" means not to create the group
meshName: a name of a new mesh, which is a copy of the initial
mesh + created boundary elements; "" means not to create the new mesh
toCopyAll: if True, the whole initial mesh will be copied into
the new mesh else only boundary elements will be copied into the new mesh
groups: list of :class:`sub-meshes, groups or filters <SMESH.SMESH_IDSource>` of elements to make boundary around
Returns:
tuple( long, mesh, group )
- long - number of added boundary elements
- mesh - the :class:`Mesh` where elements were added to
- group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
"""
dimension=SMESH.BND_2DFROM3D
toCreateAllElements = True # create all boundary elements in the mesh
nb, mesh, group = self.editor.MakeBoundaryElements( dimension,groupName,meshName,
toCopyAll,toCreateAllElements,groups)
if mesh: mesh = self.smeshpyD.Mesh(mesh)
return nb, mesh, group
def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="",
toCopyAll=False, groups=[]):
"""
@ -5488,9 +5514,9 @@ class Mesh(metaclass = MeshMeta):
- mesh - the :class:`Mesh` where elements were added to
- group - the :class:`group <SMESH.SMESH_Group>` of boundary elements or None
"""
toCreateAllElements = False # create only elements in the boundary of the solid
nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName,
toCopyAll,groups)
toCopyAll,toCreateAllElements,groups)
if mesh: mesh = self.smeshpyD.Mesh(mesh)
return nb, mesh, group