From: YOANN AUDOUIN Date: Wed, 20 Dec 2023 07:26:11 +0000 (+0100) Subject: Adding option to simplify polyhedrons X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=cea2aeff1058b70dd7e54e91753cc286df143cb1;p=modules%2Fsmesh.git Adding option to simplify polyhedrons --- diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index 5f751319a..7ae48c49c 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -299,10 +299,14 @@ module SMESH * \param mesh - TetraHedron mesh to create dual from * \param meshName - a name of the new mesh * \param adaptToShape - if True project boundary point on shape + * \param simplify - if True merge coplanar faces of a polyhedra + * \param eps - epislon tp define coplanar faces */ SMESH_Mesh CreateDualMesh(in SMESH_IDSource mesh, in string meshName, - in boolean adaptToShape) + in boolean adaptToShape, + in boolean simplify, + in double eps) raises ( SALOME::SALOME_Exception ); /*! diff --git a/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx index 86b34392d..f357deafa 100644 --- a/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,16 @@ SMESHGUI_CreateDualMeshDlg::SMESHGUI_CreateDualMeshDlg() myProjShape = new QCheckBox(QString(tr("PROJ_SHAPE")), mainFrame()); myProjShape->toggle(); + mySimplify = new QCheckBox(QString(tr("SIMPLIFY")), mainFrame()); + mySimplify->toggle(); + + mySimpEps = new QLineEdit(mainFrame()); + + QDoubleValidator *validator = new QDoubleValidator(1e-16, 100, 1000, mySimpEps); + + mySimpEps->setValidator(validator); + mySimpEps->setText("1e-4"); + myWarning = new QLabel(QString("%1").arg(tr("NON_TETRA_MESH_WARNING")), mainFrame()); // Fill layout @@ -71,10 +82,12 @@ SMESHGUI_CreateDualMeshDlg::SMESHGUI_CreateDualMeshDlg() 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 ); aLay->addWidget( myMeshNameLabel, 1, 0 ); aLay->addWidget( myMeshName, 1, 2 ); - aLay->addWidget( myProjShape, 2, 0 ); + aLay->addWidget( myProjShape, 2, 0 ); + aLay->addWidget( mySimplify, 3, 0 ); + aLay->addWidget( mySimpEps, 3, 1 ); + aLay->addWidget( myWarning, 4, 0, 1, 3 ); } @@ -93,4 +106,13 @@ void SMESHGUI_CreateDualMeshDlg::ShowWarning(bool toShow) bool SMESHGUI_CreateDualMeshDlg::isWarningShown() { return myWarning->isVisible(); -} \ No newline at end of file +} + +void SMESHGUI_CreateDualMeshDlg::DisplayEps(bool on) +{ + std::cout << "DisplayEps" << on << std::endl; + if ( on ) + mySimpEps->setEnabled(true); + else + mySimpEps->setDisabled(true); +} diff --git a/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h b/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h index e6e6a5958..83a143768 100644 --- a/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h +++ b/src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h @@ -48,10 +48,13 @@ public: virtual ~SMESHGUI_CreateDualMeshDlg(); void ShowWarning(bool); + void DisplayEps(bool); bool isWarningShown(); QLineEdit* myMeshName; QCheckBox* myProjShape; + QCheckBox* mySimplify; + QLineEdit* mySimpEps; signals: void onClicked( int ); diff --git a/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx b/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx index b945692c3..b0ac24fb1 100644 --- a/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx @@ -103,6 +103,7 @@ void SMESHGUI_CreateDualMeshOp::startOperation() myDlg = new SMESHGUI_CreateDualMeshDlg( ); } connect( myDlg, SIGNAL( onClicked( int ) ), SLOT( ConnectRadioButtons( int ) ) ); + connect( myDlg->mySimplify, SIGNAL( toggled( bool ) ), SLOT( DisplayEps( bool ) ) ); myHelpFileName = "create_dual_mesh.html"; @@ -229,9 +230,12 @@ bool SMESHGUI_CreateDualMeshOp::onApply() SMESH::SMESH_Mesh_var newMesh; QByteArray newMeshName=myDlg->myMeshName->text().toUtf8(); bool adapt_to_shape=myDlg->myProjShape->isChecked(); + bool simplify=myDlg->mySimplify->isChecked(); + double eps=myDlg->mySimpEps->text().toDouble(); + std::cout << "eps" << eps << std::endl; try { - newMesh = gen->CreateDualMesh(mesh, newMeshName.constData(), adapt_to_shape); + newMesh = gen->CreateDualMesh(mesh, newMeshName.constData(), adapt_to_shape, simplify, eps); if ( !newMesh->_is_nil() ) if ( _PTR(SObject) aSObject = SMESH::ObjectToSObject( newMesh ) ) diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 48c73b054..f9baddba9 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -5745,6 +5745,10 @@ Please specify it and try again PROJ_SHAPE Project boundary elements on shape + + SIMPLIFY + Simplify polyhedrons + SMESHGUI_ConvToQuadOp @@ -7926,7 +7930,7 @@ It is impossible to read point coordinates from file 2D_FROM_3D_ELEMENTS 2D from 3D - + SMESHGUI_Make2DFrom3DDlg diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts index 96818910a..6e5178da4 100644 --- a/src/SMESHGUI/SMESH_msg_fr.ts +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -5751,6 +5751,10 @@ Sélectionner des éléments et essayer encore PROJ_SHAPE Projection des élements de bord sur la géométrie + + SIMPLIFY + Simplification des polyèdres + SMESHGUI_ConvToQuadOp @@ -7952,7 +7956,7 @@ Il y a trop peu de points dans le fichier 2D_FROM_3D_ELEMENTS Faces des éléments volumiques - + SMESHGUI_Make2DFrom3DDlg diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 81dcf5a37..bd2c19eeb 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -2897,7 +2897,10 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::ListOfIDSources& theMeshesArray, SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateDualMesh(SMESH::SMESH_IDSource_ptr mesh, const char* meshName, - CORBA::Boolean adapt_to_shape) + CORBA::Boolean adapt_to_shape, + CORBA::Boolean simplify, + CORBA::Double eps_poly + ) { Unexpect aCatch(SALOME_SalomeException); @@ -2930,17 +2933,28 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateDualMesh(SMESH::SMESH_IDSource_ptr mesh gstate = PyGILState_Ensure(); - std::string ats; + // Converting arugments in string + std::string ats = "False"; if(adapt_to_shape) ats = "True"; - else - ats = "False"; - std::string cmd="import salome.smesh.smesh_tools as smt\n"; - cmd +="smt.smesh_create_dual_mesh(\"" + mesh_ior + "\", r\"" + - dual_mesh_file.string() + "\", mesh_name=\"" + mesh_name + "\", adapt_to_shape=" + ats + ")"; - MESSAGE(cmd); + std::string sp="False"; + if(simplify) + sp = "True"; + std::ostringstream ss; + ss << eps_poly; + + std::string cmd="import salome.smesh.smesh_tools as smt\n"; + cmd +="smt.smesh_create_dual_mesh(\"" + mesh_ior + "\"" + + ", r\"" + dual_mesh_file.string() + "\"" + + ", mesh_name=\"" + mesh_name + "\"" + + ", adapt_to_shape=" + ats + + ", simplify_poly=" + sp + + ", eps_poly=" + ss.str() + ")"; + MESSAGE("Dual mesh python command" + cmd); + + // Calling code in Python Interperter PyObject *py_main = PyImport_AddModule("__main__"); PyObject *py_dict = PyModule_GetDict(py_main); PyObject *local_dict = PyDict_New(); diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index 26a4227e9..3255871bc 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -259,7 +259,9 @@ public: // Create dual mesh of a tetrahedron mesh SMESH::SMESH_Mesh_ptr CreateDualMesh(SMESH::SMESH_IDSource_ptr meshPart, const char* meshName, - CORBA::Boolean adapt_to_shape); + CORBA::Boolean adapt_to_shape, + CORBA::Boolean simplify, + CORBA::Double eps); // Copy a part of mesh SMESH::SMESH_Mesh_ptr CopyMesh(SMESH::SMESH_IDSource_ptr meshPart, diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 781137a69..15347e082 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -789,7 +789,7 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): aMesh = Mesh( self, self.geompyD, aSmeshMesh, name=name ) return aMesh - def CreateDualMesh( self, mesh, meshName, adaptToShape): + def CreateDualMesh( self, mesh, meshName="", adaptToShape=True, simplify=False, eps=1e-4): """ Create a dual of a mesh. @@ -798,14 +798,17 @@ class smeshBuilder( SMESH._objref_SMESH_Gen, object ): :class:`mesh, `. meshName: a name of the new mesh - adpatToShape: if true project boundary points on shape + adaptToShape: if true project boundary points on shape + simplify: if true will merge coplanar face of polyhedrons + eps: threshold to define if two face are coplanar Returns: an instance of class :class:`Mesh` """ if isinstance( mesh, Mesh ): mesh = mesh.GetMesh() - dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, adaptToShape) + dualMesh = SMESH._objref_SMESH_Gen.CreateDualMesh(self, mesh, meshName, + adaptToShape, simplify, eps) return Mesh(self, self.geompyD, dualMesh) diff --git a/src/SMESH_SWIG/smesh_tools.py b/src/SMESH_SWIG/smesh_tools.py index b964f55ea..f06c24986 100644 --- a/src/SMESH_SWIG/smesh_tools.py +++ b/src/SMESH_SWIG/smesh_tools.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +from os import environ import salome import medcoupling as mc @@ -15,7 +16,10 @@ smesh = smeshBuilder.New() from salome.kernel.logger import Logger logger = Logger("salome.smesh.smesh_tools") -logger.setLevel("WARNING") +if environ.get("SALOME_VERBOSE", "0") > "1": + logger.setLevel("DEBUG") +else: + logger.setLevel("WARNING") # prefix for groups with internal usage # i.e. used to transfer the faces and edges sub-shapes ids to the mesh @@ -114,7 +118,7 @@ def __deleteObj(theObj): pass def smesh_create_dual_mesh(mesh_ior, output_file, adapt_to_shape=True, - mesh_name="MESH"): + mesh_name="MESH", simplify_poly=False, eps_poly=1e-4): """ Create a dual of the mesh in input_file into output_file Args: @@ -131,6 +135,7 @@ def smesh_create_dual_mesh(mesh_ior, output_file, adapt_to_shape=True, shape = mesh.GetShapeToMesh() if adapt_to_shape: + logger.debug("Projecting on shape") faces = geompy.SubShapeAll(shape, geompy.ShapeType["FACE"]) faces_ids = geompy.GetSubShapesIDs(shape, faces) @@ -173,17 +178,36 @@ def smesh_create_dual_mesh(mesh_ior, output_file, adapt_to_shape=True, tetras = mc.MEDCoupling1SGTUMesh(tetras) # Create the polyhedra from the tetrahedra (main goal of this function) + logger.debug("Computing dual mesh") polyh = tetras.computeDualMesh() + umesh = polyh.buildUnstructured() + + if (simplify_poly): + logger.debug("Simplifying polyhedrons") + umesh.simplifyPolyhedra(eps_poly) + logger.debug("Colinearize edges") + #umesh.colinearizeEdges(eps_poly) + + bad_cells = umesh.arePolyhedronsNotCorrectlyOriented() + if not bad_cells.empty(): + logger.debug("Reorienting polyhedrons") + try: + umesh.orientCorrectlyPolyhedrons() + except Exception as exp: + print("Could not reorient Polyhedron") + print(exp) ## Adding skin + transfering groups on faces from tetras mesh - mesh2d = polyh.buildUnstructured().computeSkin() + logger.debug("Computing Skin") + mesh2d = umesh.computeSkin() mesh2d.setName(mesh_name) - polyh_coords = polyh.getCoords() + polyh_coords = umesh.getCoords() treated_edges = [] mc_groups = [] + logger.debug("Transferring groups") for grp_name in mc_mesh_file.getGroupsOnSpecifiedLev(-1): # This group is created by the export if grp_name == "Group_Of_All_Faces": @@ -238,8 +262,8 @@ def smesh_create_dual_mesh(mesh_ior, output_file, adapt_to_shape=True, logger.debug("Creating file with mesh: "+mesh_name) myfile = mc.MEDFileUMesh() myfile.setName(mesh_name) - polyh.setName(mesh_name) - myfile.setMeshAtLevel(0, polyh) + umesh.setName(mesh_name) + myfile.setMeshAtLevel(0, umesh) myfile.setMeshAtLevel(-1, mesh2d) for group in mc_groups: