[Gmsh] A few modifications to wrap Gmsh in Java

Benjamin Ruard ruard at artenum.com
Tue Jun 7 15:42:25 CEST 2011


Hi everybody!

I am working on wrapping some functions of Gmsh in Java with CMake, SWIG
and JNI that could be shared with the community when finalized.

The objective of my work is to be able to access the following
functionalities from a Java program:
        - Reading a file in geo format
        - Creating geometry elements (GVertex, GFace and GRegion) and
adding them in a GModel with the geoFactory.
        - Meshing in 1, 2 or 3 dimensions the geometry stored in the
GModel
        - Writing a file in msh format containing the resulting mesh

To achieve this goal, I had to perform a few modifications in Gmsh
source code that I would to suggest for future versions of Gmsh. 

1) First, SWIG failed to wrap the GEdge class because it does not
recognize the meshGenerationStatus type. So I added this precision in
GEdge.h file:

typedef enum {PENDING, DONE, FAILED} meshGenerationStatus;
  struct {
    // Here is the modification that indicates in what class
    // meshGenerationStatus is defined.
    mutable GEdge::meshGenerationStatus status;
  } meshStatistics;

2) The same issue is present in GFace.h file :

typedef enum {PENDING, DONE, FAILED} meshGenerationStatus;
  struct {
    // Here is the modification that indicates in what class
    // meshGenerationStatus is defined.
    mutable GFace::meshGenerationStatus status;
    double worst_element_shape, best_element_shape,
average_element_shape;
    double smallest_edge_length, longest_edge_length, efficiency_index;
    int nbEdge, nbTriangle;
    int nbGoodQuality, nbGoodLength;
  } meshStatistics;

3) Moreover, at the present time, when you create a GFace, you have to
pay a close attention to the orientation of the GEdges constituting the
GFace. Indeed, if the GEdges are not correctly oriented, the creation of
the GFace fails and Gmsh crashes. So I added 4 lines in the
GModelFactory.cpp file.
First, I included the menuWindow.h and the ListUtils.h at the beginning:

#include "menuWindow.h"
#include "ListUtils.h"

Then, I added 3 lines which automatically orient the GEdges when you ask
to create a planar face in the method GFace addPlanarFace(GModel *gm,
std::vector< std::vector<GEdge *> > edges):

GFace *GeoFactory::addPlanarFace(GModel *gm, std::vector<
std::vector<GEdge *> > edges)
{ 
  //create line loops
  std::vector<EdgeLoop *> vecLoops;
  int nLoops = edges.size();
  for (int i=0; i< nLoops; i++){
    int numl = gm->getMaxElementaryNumber(1) + i;
    while (FindEdgeLoop(numl)){
      numl++;
      if (!FindEdgeLoop(numl)) break;
    }
    int nl=(int)edges[i].size();
    List_T *iListl = List_Create(nl, nl, sizeof(int));
    for(int j = 0; j < nl; j++){
      int numEdge = edges[i][j]->tag();
      List_Add(iListl, &numEdge); 
    }

// Beginning of the modification
    int type=ENT_LINE;
    if(select_contour(type, edges[0][0]->tag(), iListl)){
// End of the modification
        sortEdgesInLoop(numl, iListl);
        EdgeLoop *l = Create_EdgeLoop(numl, iListl);
        vecLoops.push_back(l);
        Tree_Add(GModel::current()->getGEOInternals()->EdgeLoops, &l);
        l->Num = numl;
// Beginning of the modification
    }
// End of the modification
    
    List_Delete(iListl);
  }
 
  //create plane surfaces
  int numf = gm->getMaxElementaryNumber(2) + 1;
  Surface *s = Create_Surface(numf, MSH_SURF_PLAN);
  List_T *iList = List_Create(nLoops, nLoops, sizeof(int));
  for (unsigned int i=0; i< vecLoops.size(); i++){
    int numl = vecLoops[i]->Num;
    List_Add(iList, &numl);
  }
  setSurfaceGeneratrices(s, iList);
  End_Surface(s);
  Tree_Add(GModel::current()->getGEOInternals()->Surfaces, &s);
  s->Typ= MSH_SURF_PLAN;
  s->Num = numf;
  List_Delete(iList);
 
  //gmsh surface
  GFace *gf = new gmshFace(gm,s);
  gm->add(gf);

  return gf;
}

With this modification, addPlanarFace method orients automatically the
GEdges.

4) To make this work, the class must have access to select_contour
function.
This is why I deleted the static keyword in the menuWindow.cpp file
where the select_contour function is defined. Moreover I added the
declaration of the following function in the menuWindow.h:

int select_contour(int type, int num, List_T * List);

Do you think these modifications are pertinent and that they could be
integrated in Gmsh source code?

Thanks for your time
Kind regards

Benjamin JEANTY-RUARD