## Copyright (C) 2009 G. D. McBain

## -*- texinfo -*-
## @deftypefn {Function File} {} msh2mesh (@var{filenamestub})
## Translate the Gmsh .msh two-dimensional mesh file
## @var{filenamestub}.msh into MEDIT format, @var{filenamestub}.mesh.
## This is written for speed rather than generality and makes several
## assumptions about the form and content of the input; it does no
## error-checking.
## @end deftypefn

## Author: G. D. McBain <gdmcbain@freeshell.org>
## Created: 2009-08-21
## Keywords: finite element, meshing, Gmsh, MEDIT

function msh2mesh (filenamestub, fout)
  
  fin = fopen (strcat (filenamestub, ".msh"));
  
  ## Write boilerplate
  fout = fopen (strcat (filenamestub, ".mesh"), "w");
  fdisp (fout, "MeshVersionFormatted\n1");
  fdisp (fout, "Dimension\n2");

  ## Read boilerplate and nodes
  do
    txt = fgetl (fin);
    until (regexp (txt, "[$]Nodes"))
  nnodes = fscanf (fin, "%d", 1);
  nodes = fscanf (fin, "%g", [4, nnodes])';
  printf ("Read %d nodes.\n", rows (nodes));

  ## Write nodes
  fprintf (fout, "Vertices\n%d\n", nnodes);
  fprintf (fout, "%.16g %.16g %d\n",
	   vertcat (nodes(:,2:3)', zeros (1, nnodes)) );

  ## Read edges
  do
    txt = fgetl (fin);
  until (regexp (txt, "[$]Elements"))
  nelts = fscanf (fin, "%d", 1); # number of elements
  fgetl (fin);			# discard rest of line
  edges = zeros (nelts, 3);
  nedges = 0;
  while (true)
    eltline = fgetl (fin);
    eltdata = sscanf (eltline, "%d", 8);
    if (eltdata(2) != 1)
      printf ("Read %d edges.\n", nedges);
      break;			# done reading edges
    endif
    edges(++nedges,:) = eltdata([7:8,4]);
  endwhile

  ## Write edges
  fprintf (fout, "Edges\n%d\n", nedges);
  fprintf (fout, "%d %d %d\n", edges(1:nedges,:)');

  ## Read triangles
  ntriangles = nelts - nedges
  triangles = zeros (ntriangles, 4);
  eltdata = sscanf (eltline, "%d", 9); # reread first triangle
  triangles(1,:) = eltdata([7:9,4]);
  eltdata = fscanf (fin, "%d", [9, ntriangles-1]); # rest of triangles
  triangles(2:end,:) = eltdata([7:9,4], :)';
  
  fclose (fin);

  ## Write triangles
  fprintf (fout, "Triangles\n%d\n", ntriangles);
  fprintf (fout, "%d %d %d %d\n", triangles');

  fclose (fout);
endfunction
