From 246a01ab716909058ec8255c089999a6e2a5d99f Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Fri, 23 Sep 2022 10:40:31 +0200 Subject: [PATCH] First working version Missing update of object browser + parameters + generic adaptation to shape --- idl/SMESH_Gen.idl | 34 ++- src/SMESHGUI/CMakeLists.txt | 4 + src/SMESHGUI/SMESHGUI.cxx | 12 +- src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx | 86 ++++++ src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h | 59 ++++ src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx | 284 ++++++++++++++++++++ src/SMESHGUI/SMESHGUI_CreateDualMeshOp.h | 64 +++++ src/SMESHGUI/SMESHGUI_Operations.h | 1 + src/SMESH_I/SMESH_2smeshpy.cxx | 21 +- src/SMESH_I/SMESH_Gen_i.cxx | 114 +++++++- src/SMESH_I/SMESH_Gen_i.hxx | 4 + src/SMESH_SWIG/smeshBuilder.py | 164 ++++++----- 12 files changed, 750 insertions(+), 97 deletions(-) create mode 100644 src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx create mode 100644 src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h create mode 100644 src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx create mode 100644 src/SMESHGUI/SMESHGUI_CreateDualMeshOp.h diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index 1f25c739f..e9b678031 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -159,12 +159,12 @@ module SMESH Update the study */ void UpdateStudy(); - + /*! Set enable publishing in the study */ void SetEnablePublish( in boolean theIsEnablePublish ); - + /*! Get enable publishing in the study */ @@ -284,6 +284,14 @@ module SMESH in boolean theMakeRequiredGroups, out SMESH::ComputeError theError) raises ( SALOME::SALOME_Exception ); + /*! + * Create a dual mesh of a Tetrahedron mesh + * \param meshPart - TetraHedron mesh to create dual from + * \param meshName - a name of the new mesh + */ + SMESH_Mesh CreateDualMesh(in SMESH_IDSource mesh, + in string meshName) + raises ( SALOME::SALOME_Exception ); /*! * Create a mesh by copying a part of another mesh @@ -305,7 +313,7 @@ module SMESH * \param newGeometry - a new geometry * \param meshName - a name of the new mesh * \param toCopyGroups - to create groups in the new mesh - * \param toReuseHypotheses - if True, existing hypothesis will be used by the new mesh, + * \param toReuseHypotheses - if True, existing hypothesis will be used by the new mesh, * otherwise new hypotheses with the same parameters will be created for the new mesh. * \param toCopyElements - to copy mesh elements of same sub-shapes of the two geometries * \param newMesh - return a new mesh @@ -526,10 +534,10 @@ module SMESH */ long_array GetInsideSphere( in SMESH_IDSource theSource, in ElementType theElemType, - in double theX, - in double theY, + in double theX, + in double theY, in double theZ, - in double theR ); + in double theR ); /*! * Return indices of elements, which are located inside the box @@ -544,12 +552,12 @@ module SMESH */ long_array GetInsideBox( in SMESH_IDSource theSource, in ElementType theElemType, - in double theX1, - in double theY1, + in double theX1, + in double theY1, in double theZ1, in double theX2, in double theY2, - in double theZ2); + in double theZ2); /*! * Return indices of elements, which are located inside the box * \param theSource - mesh, sub-mesh or group @@ -565,14 +573,14 @@ module SMESH */ long_array GetInsideCylinder( in SMESH_IDSource theSource, in ElementType theElemType, - in double theX, - in double theY, + in double theX, + in double theY, in double theZ, in double theDX, in double theDY, in double theDZ, in double theH, - in double theR ); + in double theR ); /*! * Return indices of elements, which are located inside the geometry * \param theSource - mesh, sub-mesh or group @@ -583,7 +591,7 @@ module SMESH long_array GetInside( in SMESH_IDSource theSource, in ElementType theElemType, in GEOM::GEOM_Object theGeom, - in double theTolerance ); + in double theTolerance ); MG_ADAPT CreateMG_ADAPT(); SMESHHOMARD::HOMARD_Gen CreateHOMARD_ADAPT() raises ( SALOME::SALOME_Exception ); diff --git a/src/SMESHGUI/CMakeLists.txt b/src/SMESHGUI/CMakeLists.txt index ff26f0dc0..2ab720fc6 100644 --- a/src/SMESHGUI/CMakeLists.txt +++ b/src/SMESHGUI/CMakeLists.txt @@ -157,6 +157,8 @@ SET(_moc_HEADERS SMESHGUI_AddNodeOnSegmentDlg.h SMESHGUI_AddNodeOnFaceDlg.h SMESHGUI_InteractiveOp.h + SMESHGUI_CreateDualMeshDlg.h + SMESHGUI_CreateDualMeshOp.h ) # header files / no moc processing @@ -283,6 +285,8 @@ SET(_other_SOURCES SMESHGUI_AddNodeOnSegmentDlg.cxx SMESHGUI_AddNodeOnFaceDlg.cxx SMESHGUI_InteractiveOp.cxx + SMESHGUI_CreateDualMeshDlg.cxx + SMESHGUI_CreateDualMeshOp.cxx ) # sources / to compile diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index c326027ed..e57f7ea4d 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -97,6 +97,8 @@ #include "SMESHGUI_SymmetryDlg.h" #include "SMESHGUI_TranslationDlg.h" #include "SMESHGUI_TransparencyDlg.h" +#include "SMESHGUI_CreateDualMeshDlg.h" +#include "SMESHGUI_CreateDualMeshOp.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_VTKUtils.h" @@ -2142,7 +2144,7 @@ SMESHGUI::SMESHGUI() : SalomeApp_Module( "SMESH" ) { CORBA::Boolean anIsEmbeddedMode; myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode); - + //MESSAGE("-------------------------------> anIsEmbeddedMode=" << anIsEmbeddedMode); // 0019923: EDF 765 SMESH : default values of hypothesis @@ -3051,6 +3053,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) // Adaptation - end case SMESHOp::OpSplitBiQuadratic: case SMESHOp::OpConvertMeshToQuadratic: + case SMESHOp::OpCreateDualMesh: case SMESHOp::OpCreateBoundaryElements: // create 2D mesh from 3D case SMESHOp::OpReorientFaces: case SMESHOp::OpCreateGeometryGroup: @@ -4275,6 +4278,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( SMESHOp::OpRevolution, "REVOLUTION", "ICON_REVOLUTION" ); createSMESHAction( SMESHOp::OpPatternMapping, "MAP", "ICON_MAP" ); 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::OpReset, "RESET" ); @@ -4524,6 +4528,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( SMESHOp::OpConvertMeshToQuadratic, modifyId, -1 ); createMenu( SMESHOp::OpCreateBoundaryElements, modifyId, -1 ); + createMenu( SMESHOp::OpCreateDualMesh, modifyId, -1 ); createMenu( SMESHOp::OpExtrusion, modifyId, -1 ); createMenu( SMESHOp::OpExtrusionAlongAPath, modifyId, -1 ); createMenu( SMESHOp::OpRevolution, modifyId, -1 ); @@ -4675,6 +4680,7 @@ void SMESHGUI::initialize( CAM_Application* app ) int modifyTb = createTool( tr( "TB_MODIFY" ), QString( "SMESHModificationToolbar" ) ) ; createTool( SMESHOp::OpConvertMeshToQuadratic, modifyTb ); + createTool( SMESHOp::OpCreateDualMesh, modifyTb ); createTool( SMESHOp::OpCreateBoundaryElements, modifyTb ); createTool( SMESHOp::OpExtrusion, modifyTb ); createTool( SMESHOp::OpExtrusionAlongAPath, modifyTb ); @@ -4788,6 +4794,7 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( separator(), -1, 0 ); createPopupItem( SMESHOp::OpConvertMeshToQuadratic, OB, mesh_submesh, "&& " + hasElems ); createPopupItem( SMESHOp::OpCreateBoundaryElements, OB, mesh_group, "&& selcount=1 && dim>=2"); + createPopupItem( SMESHOp::OpCreateDualMesh, OB, mesh_submesh, "&& selcount=1 && dim>=2"); // Adaptation - begin popupMgr()->insert( separator(), -1, 0 ); @@ -6025,6 +6032,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const case SMESHOp::OpCreateBoundaryElements: // create 2D mesh as boundary on 3D op = new SMESHGUI_Make2DFrom3DOp(); break; + case SMESHOp::OpCreateDualMesh: + op = new SMESHGUI_CreateDualMeshOp(); + break; case SMESHOp::OpReorientFaces: op = new SMESHGUI_ReorientFacesOp(); break; diff --git a/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx new file mode 100644 index 000000000..614220058 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx @@ -0,0 +1,86 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_CreateDualMeshDlg.cxx +// Author : Yoann AUDOUIN (EDF) +// SMESH includes +// +#include "SMESHGUI_CreateDualMeshDlg.h" + +#include "SMESHGUI_CreateDualMeshOp.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPACING 6 +#define MARGIN 11 + +SMESHGUI_CreateDualMeshDlg::SMESHGUI_CreateDualMeshDlg() + : SMESHGUI_Dialog( 0, false, true ) +{ + setWindowTitle( tr( "CAPTION" ) ); + + // Create top controls + + // mesh + setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) ); + createObject( tr( "MESH" ), mainFrame(), 0 ); + + myWarning = new QLabel(QString("%1").arg(tr("NON_TETRA_MESH_WARNING")), mainFrame()); + + // Fill layout + QGridLayout* aLay = new QGridLayout( mainFrame() ); + aLay->setMargin( 5 ); + aLay->setSpacing( 5 ); + + aLay->addWidget( objectWg( 0, Label ), 0, 0 ); + aLay->addWidget( objectWg( 0, Btn ), 0, 1 ); + aLay->addWidget( objectWg( 0, Control ), 0, 2 ); + aLay->addWidget( myWarning, 3, 0, 1, 3 ); + +} + +SMESHGUI_CreateDualMeshDlg::~SMESHGUI_CreateDualMeshDlg() +{ +} + +void SMESHGUI_CreateDualMeshDlg::ShowWarning(bool toShow) +{ + if ( toShow ) + myWarning->show(); + else + myWarning->hide(); +} + +bool SMESHGUI_CreateDualMeshDlg::isWarningShown() +{ + return myWarning->isVisible(); +} \ No newline at end of file diff --git a/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h b/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h new file mode 100644 index 000000000..e5096b237 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_CreateDualMeshDlg.h +// Author : Yoann Audouin (EDF) +// +#ifndef SMESHGUI_CREATEDUALMESHDLG_H +#define SMESHGUI_CREATEDUALMESHDLG_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +#include "SMESHGUI_Dialog.h" + +class QCheckBox; +class QRadioButton; +class QButtonGroup; +class QGroupBox; +class QLabel; + +class SMESHGUI_EXPORT SMESHGUI_CreateDualMeshDlg : public SMESHGUI_Dialog +{ + Q_OBJECT + +public: + SMESHGUI_CreateDualMeshDlg(); + virtual ~SMESHGUI_CreateDualMeshDlg(); + + void ShowWarning(bool); + bool isWarningShown(); + +signals: + void onClicked( int ); + +private: + QLabel* myWarning; +}; + +#endif // SMESHGUI_CREATEDUALMESHDLG_H diff --git a/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx b/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx new file mode 100644 index 000000000..25f811700 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx @@ -0,0 +1,284 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_CreateDualMeshOp.cxx +// Author : Yoann AUDOUIN (EDF) +// SMESH includes +// +#include "SMESHGUI_CreateDualMeshOp.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_CreateDualMeshDlg.h" +#include "SMESHGUI_MeshEditPreview.h" +#include "SMESHGUI_Utils.h" +#include "SMESH_ActorUtils.h" +#include "SMESH_TypeFilter.hxx" +#include "SMDSAbs_ElementType.hxx" + +// SALOME GUI includes +#include +#include +#include +#include +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +// VTK includes +#include + +//================================================================================ +/*! + * \brief Constructor + * + * Initialize operation +*/ +//================================================================================ +SMESHGUI_CreateDualMeshOp::SMESHGUI_CreateDualMeshOp() + : SMESHGUI_SelectionOp(), + myDlg( 0 ) +{ +} + +//================================================================================ +/*! + * \brief Destructor +*/ +//================================================================================ +SMESHGUI_CreateDualMeshOp::~SMESHGUI_CreateDualMeshOp() +{ + if ( myDlg ) delete myDlg; +} + +//================================================================================ +/*! + * \brief Gets dialog of this operation + * \retval LightApp_Dialog* - pointer to dialog of this operation +*/ +//================================================================================ +LightApp_Dialog* SMESHGUI_CreateDualMeshOp::dlg() const +{ + return myDlg; +} + +//================================================================================ +/*! + * \brief Creates dialog if necessary and shows it + * + * Virtual method redefined from base class called when operation is started creates + * dialog if necessary and shows it, activates selection + */ +//================================================================================ +void SMESHGUI_CreateDualMeshOp::startOperation() +{ + if( !myDlg ) + { + myDlg = new SMESHGUI_CreateDualMeshDlg( ); + } + connect( myDlg, SIGNAL( onClicked( int ) ), SLOT( ConnectRadioButtons( int ) ) ); + + myHelpFileName = "create_dual_mesh.html"; + + SMESHGUI_SelectionOp::startOperation(); + + myDlg->activateObject( 0 ); + myDlg->ShowWarning( false ); + myDlg->show(); + + selectionDone(); +} + +//================================================================================ +/*! + * \brief Updates dialog's look and feel + * + * Virtual method redefined from the base class updates dialog's look and feel + */ +//================================================================================ +void SMESHGUI_CreateDualMeshOp::selectionDone() +{ + if ( !dlg()->isVisible() ) + return; + + SMESHGUI_SelectionOp::selectionDone(); + try + { + QString anObjEntry = myDlg->selectedObject( 0 ); + _PTR(SObject) pObj = SMESH::getStudy()->FindObjectID( anObjEntry.toUtf8().data() ); + if ( !pObj ) return; + + SMESH::SMESH_IDSource_var idSource = + SMESH::SObjectToInterface( pObj ); + + myDlg->setButtonEnabled( true, QtxDialog::OK | QtxDialog::Apply ); + if( idSource->_is_nil() ) + { + myDlg->setButtonEnabled( false, QtxDialog::OK | QtxDialog::Apply ); + return; + } + SMESH::SMESH_Mesh_var mesh = idSource->GetMesh(); + + // show warning on non-conformal result mesh + if ( ! idSource->_is_nil() ) + { + SMESH::SMESH_subMesh_var subMesh = + SMESH::SObjectToInterface( pObj ); + // TODO: Check that mesh is only tetra + if (!checkMesh(idSource)){ + myDlg->ShowWarning( true ); + } + } + } + catch ( const SALOME::SALOME_Exception& S_ex ) + { + SalomeApp_Tools::QtCatchCorbaException( S_ex ); + } + catch ( ... ) + { + } +} + +//================================================================================ +/*! + * \brief Creates selection filter + * \param theId - identifier of current selection widget + * \retval SUIT_SelectionFilter* - pointer to the created filter or null + * + * Creates selection filter in accordance with identifier of current selection widget + */ +//================================================================================ +SUIT_SelectionFilter* SMESHGUI_CreateDualMeshOp::createFilter( const int theId ) const +{ + if ( theId == 0 ) + return new SMESH_TypeFilter( SMESH::MESHorSUBMESH ); + else + return 0; +} + +//================================================================================ +/*! + * \brief Edits mesh + * + * Virtual slot redefined from the base class called when "Apply" button is clicked + */ +//================================================================================ +bool SMESHGUI_CreateDualMeshOp::onApply() +{ + SUIT_OverrideCursor aWaitCursor; + + QString aMess; + QStringList anEntryList; + + QString anObjEntry = myDlg->selectedObject( 0 ); + _PTR(SObject) pObj = SMESH::getStudy()->FindObjectID( anObjEntry.toUtf8().data() ); + if ( !pObj ) + { + dlg()->show(); + SUIT_MessageBox::warning( myDlg, + tr( "SMESH_WRN_WARNING" ), tr("MESH_IS_NOT_SELECTED") ); + return false; + } + + SMESH::SMESH_Mesh_var mesh; + SMESH::SMESH_IDSource_var idSource = + SMESH::SObjectToInterface( pObj ); + if( !CORBA::is_nil(idSource) ) + mesh = idSource->GetMesh(); + + if( CORBA::is_nil(mesh) ) + { + SUIT_MessageBox::warning( myDlg, + tr( "SMESH_WRN_WARNING" ), tr("REF_IS_NULL") ); + return false; + } + + bool aResult = false; + SMESH::SMESH_Gen_var gen = SMESHGUI::GetSMESHGen(); + SMESH::SMESH_Mesh_var newMesh; + QByteArray newMeshName="MESH_DUAL"; + try + { + // TODO: Call the python script using medcoupling + // String to run medcoupling dual + // TODO: change name as previous name + "_dual" + newMesh = gen->CreateDualMesh(mesh, newMeshName.constData()); + + if ( !newMesh->_is_nil() ) + if ( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) ) + { + anEntryList.append( aSObject->GetID().c_str() ); + + SMESH::SetName( aSObject, newMeshName ); + } + aResult = true; + } + catch ( const SALOME::SALOME_Exception& S_ex ) + { + SalomeApp_Tools::QtCatchCorbaException( S_ex ); + aResult = false; + } + catch ( ... ) + { + aResult = false; + } + if( aResult ) + { + SMESHGUI::Modified(); + update( UF_ObjBrowser | UF_Model | UF_Viewer ); + selectionDone(); + } + + + // updateObjBrowser(true); + // SMESHGUI::Modified(); + + // if( LightApp_Application* anApp = + // dynamic_cast( SUIT_Session::session()->activeApplication() ) ) + // anApp->browseObjects( anEntryList, true ); + + return true; + +} + +//================================================================================ +/*! checkMesh + * Verify that mesh as only tetraheadrons as 3D elements + */ +//================================================================================ + +bool +SMESHGUI_CreateDualMeshOp::checkMesh( const SMESH::SMESH_IDSource_var& idSource) +{ + SMESH::smIdType_array_var nbElemOfType = idSource->GetMeshInfo(); + // Checking that the mesh only has Tetrahedron + bool hasOnlyTetra = ( + nbElemOfType[SMDSEntity_Tetra ] && + !nbElemOfType[SMDSEntity_Hexa ] && + !nbElemOfType[SMDSEntity_Pyramid ] && + !nbElemOfType[SMDSEntity_Polygon ] && + !nbElemOfType[SMDSEntity_Penta ] ); + + return hasOnlyTetra; +} diff --git a/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.h b/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.h new file mode 100644 index 000000000..cc928e6a3 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.h @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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 +// + +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_CreateDualMeshOp.h +// Author : Yoann AUDOUIN (EDF) +// +#ifndef SMESHGUI_CREATEDUALMESHOP_H +#define SMESHGUI_CREATEDUALMESHOP_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +#include "SMESHGUI_SelectionOp.h" + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class SMESHGUI_CreateDualMeshDlg; + +class SMESHGUI_EXPORT SMESHGUI_CreateDualMeshOp : public SMESHGUI_SelectionOp +{ + Q_OBJECT + +public: + SMESHGUI_CreateDualMeshOp(); + virtual ~SMESHGUI_CreateDualMeshOp(); + + virtual LightApp_Dialog* dlg() const; + + static bool checkMesh( const SMESH::SMESH_IDSource_var& ); +protected: + virtual void startOperation(); + virtual void selectionDone(); + virtual SUIT_SelectionFilter* createFilter( const int ) const; + +protected slots: + virtual bool onApply(); + +private: + SMESHGUI_CreateDualMeshDlg* myDlg; +}; + +#endif // SMESHGUI_CREATEDUALMESHOP_H diff --git a/src/SMESHGUI/SMESHGUI_Operations.h b/src/SMESHGUI/SMESHGUI_Operations.h index bb1596ec8..4fe19ff50 100644 --- a/src/SMESHGUI/SMESHGUI_Operations.h +++ b/src/SMESHGUI/SMESHGUI_Operations.h @@ -186,6 +186,7 @@ namespace SMESHOp { OpMoveNodeInteractive = 4516, // MENU MODIFICATION - MOVE NODE INTERACTIVE 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 // Adaptation ---------------------//-------------------------------- OpMGAdapt = 8020, // MENU ADAPTATION - MG-ADAPT OpHomardAdapt = 8021, // MENU ADAPTATION - HOMARD-ADAPT diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 22e47dc9c..03a600094 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -458,7 +458,7 @@ namespace { initialized = true; filteredArgs.push_back( "SMESH.MED_V2_1" ); filteredArgs.push_back( "SMESH.MED_V2_2" ); - } + } return std::find( filteredArgs.begin(), filteredArgs.end(), theArg ) != filteredArgs.end(); } } @@ -1022,6 +1022,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) } if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL" || + method == "CreateDualMesh" || method == "CopyMesh" ) // command result is a mesh { Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() ); @@ -1827,7 +1828,7 @@ _pyMesh::_pyMesh(const Handle(_pyCommand) theCreationCmd, const _pyID& meshId): const _pyID& meshID = theCreationCmd->GetObject(); addFatherMesh( meshID ); } - + // convert my creation command Handle(_pyCommand) creationCmd = GetCreationCmd(); creationCmd->SetObject( SMESH_2smeshpy::SmeshpyName() ); @@ -2419,7 +2420,7 @@ void _pyMesh::ClearCommands() list< Handle(_pySubMesh) >::iterator sm = mySubmeshes.begin(); for ( ; sm != mySubmeshes.end(); ++sm ) (*sm)->ClearCommands(); - + list< Handle(_pyGroup) >::iterator gr = myGroups.begin(); for ( ; gr != myGroups.end(); ++gr ) (*gr)->ClearCommands(); @@ -2579,7 +2580,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) // 1. Remove "MakeGroups" from the Command TCollection_AsciiString aMethod = theCommand->GetMethod(); int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1; - + if(is0DmethObj) pos = pos-2; //Remove "0D" from the Command too aMethod.Trunc(pos-1); @@ -3410,7 +3411,7 @@ void _pyLayerDistributionHypo::Flush() list< Handle(_pyCommand) >::iterator cmd = myArgCommands.begin(); _pyID prevNewName; for ( cmd = myArgCommands.begin(); cmd != myArgCommands.end(); ++cmd ) - { + { const _pyID& hyp1dID = (*cmd)->GetArg( 1 ); if ( hyp1dID.IsEmpty() ) continue; @@ -3434,7 +3435,7 @@ void _pyLayerDistributionHypo::Flush() } newName += "_Distribution"; prevNewName = newName; - + hyp1d->GetCreationCmd()->SetResultValue( newName ); } list< Handle(_pyCommand) >& cmds = theGen->GetCommands(); @@ -4631,7 +4632,7 @@ _pyGroup::_pyGroup(const Handle(_pyCommand)& theCreationCmd, const _pyID & id) //================================================================================ /*! - * \brief Check if "[ group1, group2 ] = mesh.GetGroups()" creation command + * \brief Check if "[ group1, group2 ] = mesh.GetGroups()" creation command * can be cleared */ //================================================================================ @@ -4802,7 +4803,7 @@ void _pyFilter::Process( const Handle(_pyCommand)& theCommand) if ( !myNewID.IsEmpty() ) theCommand->SetObject( myNewID ); - + // Convert the following set of commands into smesh.GetFilterFromCriteria(criteria) // aFilter0x2aaab0487080 = aFilterManager.CreateFilter() // aFilter0x2aaab0487080.SetCriteria(aCriteria) @@ -4845,7 +4846,7 @@ void _pyFilter::Process( const Handle(_pyCommand)& theCommand) void _pyFilter::Flush() { if ( myNewID.IsEmpty() ) return; - + list< Handle(_pyCommand) >::iterator cmd = myArgCmds.begin(); for ( ; cmd != myArgCmds.end(); ++cmd ) if ( !(*cmd)->IsEmpty() ) @@ -4982,7 +4983,7 @@ _pyHypothesisReader::_pyHypothesisReader() // ... // dim="2"> // - // + // // SetEnforcedVertex, // SetEnforcedVertexNamed // diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index cfc7c95b5..79d031823 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -49,6 +49,10 @@ #include #include +// Have to be included before std headers +#include +#include + #ifdef WIN32 #include #include @@ -2802,6 +2806,114 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, return newMesh._retn(); } + +//================================================================================ +/*! + * \brief Create a mesh by copying a part of another mesh + * \param mesh - TetraHedron mesh + * \param meshName Name of the created mesh + * \retval SMESH::SMESH_Mesh_ptr - the new mesh + */ +//================================================================================ + +SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateDualMesh(SMESH::SMESH_IDSource_ptr mesh, + const char* meshName) +{ + Unexpect aCatch(SALOME_SalomeException); + + TPythonDump* pyDump = new TPythonDump(this); // prevent dump from CreateMesh() + std::unique_ptr pyDumpDeleter( pyDump ); + + // 1. Get source mesh + + if ( CORBA::is_nil( mesh )) + THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM ); + + std::cout << mesh << std::endl; + SMESH::SMESH_Mesh_var srcMesh = mesh->GetMesh(); + SMESH_Mesh_i* srcMesh_i = SMESH::DownCast( srcMesh ); + if ( !srcMesh_i ) + THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM ); + + SMESH_Mesh& srcMesh2 = srcMesh_i->GetImpl(); + + // TODO: Get it + CORBA::String_var mesh_ior=GetORB()->object_to_string(mesh); + std::string mesh_id = mesh_ior.in(); + std::string dual_mesh_file="/tmp/test_dual.med"; + std::string mesh_name = "MESH"; + + std::string python_code; + python_code += "import sys\n"; + python_code += "import salome\n"; + python_code += "import medcoupling as mc\n"; + python_code += "from math import pi\n"; + python_code += "salome.salome_init()\n"; + python_code += "import GEOM\n"; + python_code += "from salome.geom import geomBuilder\n"; + python_code += "geompy = geomBuilder.New()\n"; + python_code += "import SMESH, SALOMEDS\n"; + python_code += "from salome.smesh import smeshBuilder\n"; + python_code += "smesh = smeshBuilder.New()\n"; + python_code += "def create_dual_mesh(mesh_ior, output_file):\n"; + python_code += " mesh = salome.orb.string_to_object(mesh_ior)\n"; + python_code += " shape = mesh.GetShapeToMesh()\n"; + python_code += " if not mesh:\n"; + python_code += " raise Exception(\"Could not find mesh using id: \", mesh_id)\n"; + python_code += " int_ptr = mesh.ExportMEDCoupling(True, True)\n"; + python_code += " dab = mc.FromPyIntPtrToDataArrayByte(int_ptr)\n"; + python_code += " tetras = mc.MEDFileMesh.New(dab)[0]\n"; + python_code += " tetras = mc.MEDCoupling1SGTUMesh(tetras)\n"; + python_code += " polyh = tetras.computeDualMesh()\n"; + python_code += " skin = tetras.buildUnstructured().computeSkin()\n"; + python_code += " skin_polyh = polyh.buildUnstructured().computeSkin()\n"; + python_code += " allNodesOnSkinPolyh = skin_polyh.computeFetchedNodeIds()\n"; + python_code += " allNodesOnSkin = skin.computeFetchedNodeIds()\n"; + python_code += " ptsAdded = allNodesOnSkinPolyh.buildSubstraction(allNodesOnSkin)\n"; + python_code += " ptsAddedMesh = mc.MEDCouplingUMesh.Build0DMeshFromCoords( skin_polyh.getCoords()[ptsAdded] )\n"; + python_code += " ptsAddedCoo = ptsAddedMesh.getCoords()\n"; + python_code += " ptsAddedCooModified = ptsAddedCoo[:]\n"; + python_code += " polyh.setName(\"MESH\")\n"; + python_code += " polyh.write(output_file)\n"; + + // Running Python script + assert(Py_IsInitialized()); + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + PyRun_SimpleString(python_code.c_str()); + std::string cmd=""; + cmd += "create_dual_mesh(\"" + mesh_id + "\", \"" + dual_mesh_file + "\")"; + PyRun_SimpleString(cmd.c_str()); + + PyGILState_Release(gstate); + + // Import created MED + SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil()); + SMESH_Mesh_i* newMesh_i = SMESH::DownCast( newMesh ); + if ( !newMesh_i ) + THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR ); + SALOMEDS::SObject_wrap meshSO = ObjectToSObject( newMesh ); + if ( !meshSO->_is_nil() ) + { + SetName( meshSO, meshName, "Mesh" ); + SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED"); + } + + SMESH_Mesh& newMesh2 = newMesh_i->GetImpl(); + + newMesh2.MEDToMesh(dual_mesh_file.c_str(), "MESH"); + + SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS(); + + newMeshDS->Modified(); + + *pyDump << newMesh << " = " << this + << ".CreateDualMesh( " << mesh << ", " + << "'" << meshName << "') "; + + return newMesh._retn(); +} + //================================================================================ /*! * \brief Create a mesh by copying a part of another mesh @@ -6182,7 +6294,7 @@ CORBA::Long SMESH_Gen_i::GetObjectId(CORBA::Object_ptr theObject) { if ( myStudyContext && !CORBA::is_nil( theObject )) { CORBA::String_var iorString = GetORB()->object_to_string( theObject ); - string iorStringCpp(iorString.in()); + string iorStringCpp(iorString.in()); return myStudyContext->findId( iorStringCpp ); } return 0; diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index ad86102ef..bd8872038 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -253,6 +253,10 @@ public: CORBA::Boolean theMakeRequiredGroups, SMESH::ComputeError_out theError); + // Create dual mesh of a tetrahedron mesh + SMESH::SMESH_Mesh_ptr CreateDualMesh(SMESH::SMESH_IDSource_ptr meshPart, + const char* meshName); + // Copy a part of mesh SMESH::SMESH_Mesh_ptr CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, const char* meshName, diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index d0fa9a291..c46a97751 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -216,7 +216,7 @@ NO_NAME = "NoName" def GetName(obj): """ Return a name of an object - + Returns: object name """ @@ -429,26 +429,26 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): def init_smesh(self,geompyD = None): """ Set Geometry component - """ + """ #print("init_smesh") self.UpdateStudy(geompyD) notebook.myStudy = salome.myStudy def Mesh(self, obj=0, name=0): """ - Create a mesh. This mesh can be either + Create a mesh. This mesh can be either * an empty mesh not bound to geometry, if *obj* == 0 * an empty mesh bound to geometry, if *obj* is GEOM.GEOM_Object * a mesh wrapping a :class:`CORBA mesh ` given as *obj* parameter. Parameters: - obj: either + obj: either 1. a :class:`CORBA mesh ` got by calling e.g. :: - salome.myStudy.FindObjectID("0:1:2:3").GetObject() + salome.myStudy.FindObjectID("0:1:2:3").GetObject() 2. a geometrical object for meshing 3. none. @@ -648,7 +648,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): if sc: sb.LoadWith(sc, self) pass - + def SetEnablePublish( self, theIsEnablePublish ): """ Set enable publishing in the study. Calling SetEnablePublish( False ) allows to @@ -677,7 +677,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Create a Mesh object(s) importing data from the given MED file Returns: - a tuple ( list of class :class:`Mesh` instances, + a tuple ( list of class :class:`Mesh` instances, :class:`SMESH.DriverMED_ReadStatus` ) """ @@ -744,7 +744,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Returns: an instance of class :class:`Mesh` - See also: + See also: :meth:`Mesh.Append` """ @@ -773,12 +773,32 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name ) return aMesh + def CreateDualMesh( self, mesh, meshName): + """ + Create a dual of a mesh. + + Parameters: + mesh: Tetrahedron mesh + :class:`mesh, `. + + meshName: a name of the new mesh + + Returns: + an instance of class :class:`Mesh` + """ + + if isinstance( mesh, Mesh ): + meshPart = mesh.GetMesh() + mesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName) + return Mesh(self, self.geompyD, mesh) + + def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False): """ Create a mesh by copying a part of another mesh. Parameters: - meshPart: a part of mesh to copy, either + meshPart: a part of mesh to copy, either :class:`mesh, sub-mesh, group or filter `. To copy nodes or elements not forming any mesh object, pass result of :meth:`Mesh.GetIDSource` as *meshPart* @@ -810,7 +830,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): meshName: an optional name of the new mesh. If omitted, the mesh name is kept. toCopyGroups: to create groups in the new mesh. toReuseHypotheses: to reuse hypotheses of the *sourceMesh*. - toCopyElements: to copy mesh elements present on non-modified sub-shapes of + toCopyElements: to copy mesh elements present on non-modified sub-shapes of *sourceMesh*. Returns: tuple ( ok, newMesh, newGroups, newSubMeshes, newHypotheses, invalidEntries ) @@ -1285,7 +1305,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Returns: minimum distance value - See also: + See also: :meth:`GetMinDistance` """ @@ -1313,7 +1333,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Returns: :class:`SMESH.Measure` structure or None if input data is invalid - See also: + See also: :meth:`MinDistance` """ @@ -1360,7 +1380,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Returns: tuple of six values (minX, minY, minZ, maxX, maxY, maxZ) - See also: + See also: :meth:`GetBoundingBox` """ @@ -1381,7 +1401,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): Returns: :class:`SMESH.Measure` structure - See also: + See also: :meth:`BoundingBox` """ @@ -1460,14 +1480,14 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): def GetGravityCenter(self, obj): """ Get gravity center of all nodes of a mesh object. - - Parameters: + + Parameters: obj: :class:`mesh, sub-mesh, group or filter ` - Returns: + Returns: Three components of the gravity center (x,y,z) - See also: + See also: :meth:`Mesh.BaryCenter` """ if isinstance(obj, Mesh): obj = obj.mesh @@ -1481,11 +1501,11 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): """ Computes a radian measure of an angle defined by 3 points: <(p1,p2,p3) - Parameters: - p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct + Parameters: + p1,p2,p3: coordinates of 3 points defined by either SMESH.PointStruct or list [x,y,z] - Returns: + Returns: Angle in radians """ if isinstance( p1, list ): p1 = PointStruct(*p1) @@ -1551,7 +1571,7 @@ class Mesh(metaclass = MeshMeta): It also has methods to define groups of mesh elements, to modify a mesh (by addition of new nodes and elements and by changing the existing entities), to get information about a mesh and to export a mesh in different formats. - """ + """ geom = 0 mesh = 0 @@ -2081,12 +2101,12 @@ class Mesh(metaclass = MeshMeta): def SetMeshOrder(self, submeshes): """ Set priority of sub-meshes. It works in two ways: - + * For sub-meshes with assigned algorithms of same dimension generating mesh of *several dimensions*, it sets the order in which the sub-meshes are computed. * For the rest sub-meshes, it sets the order in which the sub-meshes are checked - when looking for meshing parameters to apply to a sub-shape. To impose the - order in which sub-meshes with uni-dimensional algorithms are computed, + when looking for meshing parameters to apply to a sub-shape. To impose the + order in which sub-meshes with uni-dimensional algorithms are computed, call **submesh.Compute()** in a desired order. Parameters: @@ -2300,23 +2320,23 @@ class Mesh(metaclass = MeshMeta): meshPart: a part of mesh (:class:`sub-mesh, group or filter `) to export instead of the mesh autoDimension: if *True* (default), a space dimension of a MED mesh can be either - + - 1D if all mesh nodes lie on OX coordinate axis, or - 2D if all mesh nodes lie on XOY coordinate plane, or - 3D in the rest cases. - + If *autoDimension* is *False*, the space dimension is always 3. fields: list of GEOM fields defined on the shape to mesh. - geomAssocFields: each character of this string means a need to export a - corresponding field; correspondence between fields and characters + geomAssocFields: each character of this string means a need to export a + corresponding field; correspondence between fields and characters is following: - + - 'v' stands for "_vertices_" field; - 'e' stands for "_edges_" field; - 'f' stands for "_faces_" field; - 's' stands for "_solids_" field. - - zTolerance (float): tolerance in Z direction. If Z coordinate of a node is + + zTolerance (float): tolerance in Z direction. If Z coordinate of a node is close to zero within a given tolerance, the coordinate is set to zero. If *ZTolerance* is negative (default), the node coordinates are kept as is. saveNumbers(boolean) : enable saving numbers of nodes and cells. @@ -2371,8 +2391,8 @@ class Mesh(metaclass = MeshMeta): the typical use is auto_groups=False. version (int): define the version (xy, where version is x.y.z) of MED file format. For instance med 3.2.1 is coded 3*10+2 = 32, med 4.0.0 is coded 4*10+0 = 40. - The rules of compatibility to write a mesh in an older version than - the current version depend on the current version. For instance, + The rules of compatibility to write a mesh in an older version than + the current version depend on the current version. For instance, with med 4.0 it is possible to write/append med files in 4.0.0 (default) or 3.2.1 or 3.3.1 formats. If the version is equal to -1, the version is not changed (default). @@ -2387,8 +2407,8 @@ class Mesh(metaclass = MeshMeta): If *autoDimension* is *False*, the space dimension is always 3. fields: list of GEOM fields defined on the shape to mesh. - geomAssocFields: each character of this string means a need to export a - corresponding field; correspondence between fields and characters + geomAssocFields: each character of this string means a need to export a + corresponding field; correspondence between fields and characters is following: - 'v' stands for "_vertices_" field; @@ -2396,7 +2416,7 @@ class Mesh(metaclass = MeshMeta): - 'f' stands for "_faces_" field; - 's' stands for "_solids_" field. - zTolerance (float): tolerance in Z direction. If Z coordinate of a node is + zTolerance (float): tolerance in Z direction. If Z coordinate of a node is close to zero within a given tolerance, the coordinate is set to zero. If *ZTolerance* is negative (default), the node coordinates are kept as is. saveNumbers (boolean) : enable saving numbers of nodes and cells. @@ -2564,7 +2584,7 @@ class Mesh(metaclass = MeshMeta): If **autoDimension** is *False*, the space dimension is always 3. """ - + print("WARNING: ExportToMED() is deprecated, use ExportMED() instead") # process positional arguments #args = [i for i in args if i not in [SMESH.MED_V2_1, SMESH.MED_V2_2]] # backward compatibility @@ -2641,7 +2661,7 @@ class Mesh(metaclass = MeshMeta): Create an empty standalone mesh group Parameters: - elementType: the :class:`type ` of elements in the group; + elementType: the :class:`type ` of elements in the group; either of (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME) name: the name of the mesh group @@ -2881,7 +2901,7 @@ class Mesh(metaclass = MeshMeta): def GetGroups(self, elemType = SMESH.ALL): """ - Get the list of groups existing in the mesh in the order of creation + Get the list of groups existing in the mesh in the order of creation (starting from the oldest one) Parameters: @@ -3592,7 +3612,7 @@ class Mesh(metaclass = MeshMeta): Return the type of mesh element or node Returns: - the value from :class:`SMESH.ElementType` enumeration. + the value from :class:`SMESH.ElementType` enumeration. Return SMESH.ALL if element or node with the given ID does not exist """ @@ -3886,7 +3906,7 @@ class Mesh(metaclass = MeshMeta): Returns: a list of three double values - See also: + See also: :meth:`smeshBuilder.GetGravityCenter` """ @@ -4004,7 +4024,7 @@ class Mesh(metaclass = MeshMeta): Returns: tuple of six values (minX, minY, minZ, maxX, maxY, maxZ) - See Also: + See Also: :meth:`GetBoundingBox()` """ @@ -4027,7 +4047,7 @@ class Mesh(metaclass = MeshMeta): Returns: :class:`SMESH.Measure` structure - See Also: + See Also: :meth:`BoundingBox()` """ @@ -4163,7 +4183,7 @@ class Mesh(metaclass = MeshMeta): Returns: an object (a new group or a temporary :class:`SMESH.SMESH_IDSource`) holding IDs of new and/or found 0D elements. IDs of 0D elements - can be retrieved from the returned object by + can be retrieved from the returned object by calling :meth:`GetIDs() ` """ @@ -4537,7 +4557,7 @@ class Mesh(metaclass = MeshMeta): edges = self.GetIDSource( edges, SMESH.EDGE ) unRegister.set( edges ) return self.editor.Get1DBranches( edges, startNode ) - + def FindSharpEdges( self, angle, addExisting=False ): """ Return sharp edges of faces and non-manifold ones. @@ -4604,7 +4624,7 @@ class Mesh(metaclass = MeshMeta): def AddNodeOnSegment(self, Node1, Node2, position = 0.5): """ Replace each triangle bound by Node1-Node2 segment with - two triangles by connecting a node made on the link with a node + two triangles by connecting a node made on the link with a node opposite to the link. Parameters: @@ -4874,7 +4894,7 @@ class Mesh(metaclass = MeshMeta): a quadrangle. Parameters: - theElements: the faces to be splitted. This can be either + theElements: the faces to be splitted. This can be either :class:`mesh, sub-mesh, group, filter ` or a list of face IDs. By default all quadrangles are split @@ -4943,8 +4963,8 @@ class Mesh(metaclass = MeshMeta): to numerical functors. Returns: - * 1 if 1-3 diagonal is better, - * 2 if 2-4 diagonal is better, + * 1 if 1-3 diagonal is better, + * 2 if 2-4 diagonal is better, * 0 if error occurs. Note: @@ -5096,7 +5116,7 @@ class Mesh(metaclass = MeshMeta): This operation uses :doc:`pattern_mapping` functionality for splitting. Parameters: - theObject: the object from which the list of hexahedrons is taken; + theObject: the object from which the list of hexahedrons is taken; this is :class:`mesh, sub-mesh, group or filter ` theNode000,theNode001: within the range [0,7]; gives the orientation of the pattern relatively each hexahedron: the (0,0,0) key-point of the pattern @@ -5588,7 +5608,7 @@ class Mesh(metaclass = MeshMeta): of all steps, else - size of each step Returns: - the list of created :class:`groups ` if *MakeGroups* == True, + the list of created :class:`groups ` if *MakeGroups* == True, empty list otherwise """ @@ -5644,7 +5664,7 @@ class Mesh(metaclass = MeshMeta): - a list of tree components of the point or - a node ID or - a GEOM point - angles: list of angles in radians. Nodes at each extrusion step are rotated + angles: list of angles in radians. Nodes at each extrusion step are rotated around *basePoint*, additionally to previous steps. anglesVariation: forces the computation of rotation angles as linear variation of the given *angles* along path steps @@ -5862,13 +5882,13 @@ class Mesh(metaclass = MeshMeta): PathShape: optional shape (edge or wire) which defines the sub-mesh of the mesh defined by *PathObject* if the mesh contains not only path segments, else it can be None NodeStart: the first or the last node on the path. Defines the direction of extrusion HasAngles: not used obsolete - Angles: list of angles in radians. Nodes at each extrusion step are rotated + Angles: list of angles in radians. Nodes at each extrusion step are rotated around *basePoint*, additionally to previous steps. LinearVariation: forces the computation of rotation angles as linear variation of the given Angles along path steps HasRefPoint: allows using the reference point RefPoint: optional scaling and rotation center (mass center of the extruded - elements by default). The User can specify any point as the Reference Point. + elements by default). The User can specify any point as the Reference Point. *RefPoint* can be either GEOM Vertex, [x,y,z] or :class:`SMESH.PointStruct` MakeGroups: forces the generation of new groups from existing ones ScaleFactors: optional scale factors to apply during extrusion @@ -5876,7 +5896,7 @@ class Mesh(metaclass = MeshMeta): else *scaleFactors* [i] is applied to nodes at the i-th extrusion step Returns: - list of created :class:`groups ` and + list of created :class:`groups ` and :class:`error code ` Example: :ref:`tui_extrusion_along_path` """ @@ -5896,7 +5916,7 @@ class Mesh(metaclass = MeshMeta): Angles,AnglesParameters,hasVars = ParseAngles(Angles) ScaleFactors,ScalesParameters,hasVars = ParseParameters(ScaleFactors) Parameters = AnglesParameters + var_separator + \ - RefPoint.parameters + var_separator + ScalesParameters + RefPoint.parameters + var_separator + ScalesParameters self.mesh.SetParameters(Parameters) return self.editor.ExtrusionAlongPathObjects(Nodes, Edges, Faces, PathObject, PathShape, NodeStart, @@ -5917,7 +5937,7 @@ class Mesh(metaclass = MeshMeta): Path: 1D mesh or 1D sub-mesh, along which proceeds the extrusion NodeStart: the start node from Path. Defines the direction of extrusion HasAngles: not used obsolete - Angles: list of angles in radians. Nodes at each extrusion step are rotated + Angles: list of angles in radians. Nodes at each extrusion step are rotated around *basePoint*, additionally to previous steps. LinearVariation: forces the computation of rotation angles as linear variation of the given Angles along path steps @@ -5960,7 +5980,7 @@ class Mesh(metaclass = MeshMeta): PathShape: shape (edge) defines the sub-mesh for the path NodeStart: the first or the last node on the edge. Defines the direction of extrusion HasAngles: not used obsolete - Angles: list of angles in radians. Nodes at each extrusion step are rotated + Angles: list of angles in radians. Nodes at each extrusion step are rotated around *basePoint*, additionally to previous steps. HasRefPoint: allows using the reference point RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default). @@ -6001,7 +6021,7 @@ class Mesh(metaclass = MeshMeta): PathShape: shape (edge) defines the sub-mesh for the path NodeStart: the first or the last node on the edge. Defines the direction of extrusion HasAngles: not used obsolete - Angles: list of angles in radians. Nodes at each extrusion step are rotated + Angles: list of angles in radians. Nodes at each extrusion step are rotated around *basePoint*, additionally to previous steps. HasRefPoint: allows using the reference point RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default). @@ -6012,7 +6032,7 @@ class Mesh(metaclass = MeshMeta): variation of the given Angles along path steps Returns: - list of created :class:`groups ` and + list of created :class:`groups ` and :class:`error code ` if *MakeGroups* == True, only :class:`error code ` otherwise Example: :ref:`tui_extrusion_along_path` @@ -6039,7 +6059,7 @@ class Mesh(metaclass = MeshMeta): PathShape: shape (edge) defines the sub-mesh for the path NodeStart: the first or the last node on the edge. Defines the direction of extrusion HasAngles: not used obsolete - Angles: list of angles in radians. Nodes at each extrusion step are rotated + Angles: list of angles in radians. Nodes at each extrusion step are rotated around *basePoint*, additionally to previous steps. HasRefPoint: allows using the reference point RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default). @@ -6050,7 +6070,7 @@ class Mesh(metaclass = MeshMeta): variation of the given Angles along path steps Returns: - list of created :class:`groups ` and + list of created :class:`groups ` and :class:`error code ` if *MakeGroups* == True, only :class:`error code ` otherwise Example: :ref:`tui_extrusion_along_path` @@ -6077,7 +6097,7 @@ class Mesh(metaclass = MeshMeta): PathShape: shape (edge) defines the sub-mesh for the path NodeStart: the first or the last node on the edge. Defines the direction of extrusion HasAngles: not used obsolete - Angles: list of angles in radians. Nodes at each extrusion step are rotated + Angles: list of angles in radians. Nodes at each extrusion step are rotated around *basePoint*, additionally to previous steps. HasRefPoint: allows using the reference point RefPoint: the reference point around which the shape is rotated (the mass center of the shape by default). @@ -6088,7 +6108,7 @@ class Mesh(metaclass = MeshMeta): variation of the given Angles along path steps Returns: - list of created :class:`groups ` and + list of created :class:`groups ` and :class:`error code ` if *MakeGroups* == True, only :class:`error code ` otherwise Example: :ref:`tui_extrusion_along_path` @@ -6498,7 +6518,7 @@ class Mesh(metaclass = MeshMeta): theObject (SMESH.SMESH_IDSource): the source object (mesh, sub-mesh, group or filter) theValue (float): signed offset size MakeGroups (boolean): forces the generation of new groups from existing ones - CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements, + CopyElements (boolean): if *NewMeshName* is empty, True means to keep original elements, False means to remove original elements. NewMeshName (string): the name of a mesh to create. If empty, offset elements are added to this mesh @@ -6879,7 +6899,7 @@ class Mesh(metaclass = MeshMeta): Parameters: theElements: container of elements to duplicate. It can be a - :class:`mesh, sub-mesh, group, filter ` + :class:`mesh, sub-mesh, group, filter ` or a list of element IDs. If *theElements* is a :class:`Mesh`, elements of highest dimension are duplicated theGroupName: a name of group to contain the generated elements. @@ -6889,7 +6909,7 @@ class Mesh(metaclass = MeshMeta): in any group. Returns: - a :class:`group ` where the new elements are added. + a :class:`group ` where the new elements are added. None if *theGroupName* == "". """ @@ -7158,7 +7178,7 @@ class Mesh(metaclass = MeshMeta): return self.editor.CreateHoleSkin( radius, theShape, groupName, theNodesCoords ) def MakePolyLine(self, segments, groupName='', isPreview=False ): - """ + """ Create a polyline consisting of 1D mesh elements each lying on a 2D element of the initial triangle mesh. Positions of new nodes are found by cutting the mesh by the plane passing through pairs of points specified by each :class:`SMESH.PolySegment` structure. @@ -7176,7 +7196,7 @@ class Mesh(metaclass = MeshMeta): segments: list of :class:`SMESH.PolySegment` defining positions of cutting planes. groupName: optional name of a group where created mesh segments will be added. - """ + """ editor = self.editor if isPreview: editor = self.mesh.GetMeshEditPreviewer() @@ -7331,10 +7351,10 @@ class Mesh(metaclass = MeshMeta): """ Computes a radian measure of an angle defined by 3 nodes: <(node1,node2,node3) - Parameters: + Parameters: node1,node2,node3: IDs of the three nodes - Returns: + Returns: Angle in radians [0,PI]. -1 if failure case. """ p1 = self.GetNodeXYZ( node1 ) -- 2.30.2