]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
Adding option to simplify polyhedrons yan/dual_simplify_poly
authorYOANN AUDOUIN <B61570@dsp1062659>
Wed, 20 Dec 2023 07:26:11 +0000 (08:26 +0100)
committerYOANN AUDOUIN <B61570@dsp1062659>
Wed, 20 Dec 2023 07:26:11 +0000 (08:26 +0100)
idl/SMESH_Gen.idl
src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.cxx
src/SMESHGUI/SMESHGUI_CreateDualMeshDlg.h
src/SMESHGUI/SMESHGUI_CreateDualMeshOp.cxx
src/SMESHGUI/SMESH_msg_en.ts
src/SMESHGUI/SMESH_msg_fr.ts
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Gen_i.hxx
src/SMESH_SWIG/smeshBuilder.py
src/SMESH_SWIG/smesh_tools.py

index 5f751319a7e0c5459a5252893357800cca6b335d..7ae48c49c7dd622331f8d547918bbbeb6d058516 100644 (file)
@@ -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 );
 
     /*!
index 86b34392d9aeb027a3205b3326d6cc1ab4e62e3b..f357deafabe65bf837ccfa76ef3366d7d426051d 100644 (file)
@@ -35,6 +35,7 @@
 #include <QRadioButton>
 #include <QButtonGroup>
 #include <QGroupBox>
+#include <QDoubleValidator>
 #include <QFrame>
 #include <QHBoxLayout>
 #include <QGridLayout>
@@ -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("<b>%1</b>").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);
+}
index e6e6a59581d6bb161771eb347ee0b889bc126ef6..83a14376804f859750959f0f25193a7424ebfc7d 100644 (file)
@@ -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 );
index b945692c334b2227bf9426656b95fb31a6f0b05b..b0ac24fb12c7825ca78e71947cbeef3ef2ed0867 100644 (file)
@@ -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 ) )
index 48c73b054a70788b004922d6bb29d646e00d703e..f9baddba906f8d916cc694baad98a53ca7a039d1 100644 (file)
@@ -5745,6 +5745,10 @@ Please specify it and try again</translation>
         <source>PROJ_SHAPE</source>
         <translation>Project boundary elements on shape</translation>
     </message>
+    <message>
+        <source>SIMPLIFY</source>
+        <translation>Simplify polyhedrons</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_ConvToQuadOp</name>
@@ -7926,7 +7930,7 @@ It is impossible to read point coordinates from file</translation>
         <source>2D_FROM_3D_ELEMENTS</source>
         <translation>2D from 3D</translation>
     </message>
-</context>    
+</context>
 <context>
     <name>SMESHGUI_Make2DFrom3DDlg</name>
     <message>
index 96818910a04de0586074711d967aa35f206645db..6e5178da4661864f5e7006f276e348812c50321d 100644 (file)
@@ -5751,6 +5751,10 @@ Sélectionner des éléments et essayer encore</translation>
         <source>PROJ_SHAPE</source>
         <translation>Projection des élements de bord sur la géométrie</translation>
     </message>
+    <message>
+        <source>SIMPLIFY</source>
+        <translation>Simplification des polyèdres</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_ConvToQuadOp</name>
@@ -7952,7 +7956,7 @@ Il y a trop peu de points dans le fichier </translation>
         <source>2D_FROM_3D_ELEMENTS</source>
         <translation>Faces des éléments volumiques</translation>
     </message>
-</context> 
+</context>
 <context>
     <name>SMESHGUI_Make2DFrom3DDlg</name>
     <message>
index 81dcf5a3754c1bd1a6b2b93cde24c5316bee3d4f..bd2c19eebb41e8a939ff0bf8569a0d0d9e345e9e 100644 (file)
@@ -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();
index 26a4227e95c703c24ecae325b5bf413aeaea169d..3255871bc098bae7a6ac0f26bde092f4245c27ea 100644 (file)
@@ -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,
index 781137a69ee78affe699ec55ec91639da1a4ed45..15347e0825f4cb1e7f79a0669b99588b8416f062 100644 (file)
@@ -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, <SMESH.SMESH_IDSource>`.
 
                 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)
 
 
index b964f55eabbac9e79592727ae2ea2fb3c13fc1cd..f06c24986467763ece5a718e47a752fb885ecae5 100644 (file)
@@ -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: