//-----------------------------------------------------------------
//
//  Copyright (c) 2003
//
//           Department of Computer Science
//              University of Copenhagen
//                      (DIKU)
//
//                       and
//
//  School of Dentistry, Dept. of Pediatric Dentistry
//              University of Copenhagen
//                       (3DLab)
//
//  All Rights Reserved.
//
//  This software is provided as is WITHOUT ANY WARRANTY; Use it on
//  your own risk.
//
//  Please send remarks, questions and bug reports to simulation@diku.dk
//
//-------------------------------------------------------------------

/**
 * Maya to gmsh export MEL script.
 * How to use:
 *
 *    1) Add mel-script to your script path
 *    2) write for instance 
 *
 *         "gmsh pCube1 0.5 myfile.geo"
 *
 *       on the command line (in Maya)
 *
 *  This mel script uses the auxiliary script 
 *  edgeVertexOrder.mel. Most of the mel code
 *  was written based on the MEL How-to by Joey
 *  Ponthieux (Video Applications Group, NASA
 *  Langley Research Center
 *
 * @see
 *
 *    http://www.ewertb.com/maya/mel/mel_a55.html
 *
 * @param obj
 * @param length
 * @param fileName
 */
global proc gmsh(string $obj, float $length, string $fileName)
{
  if ($length <= 0)
  {
    error "length must be positive!";
  }

  if( !`objExists $obj` ) 
  {
    error "No object of that name!";
  }

  string $notPoly = "Nothing counted : no polygonal object is selected.";
  if(`polyEvaluate -fmt -v $obj` == $notPoly)
  {
    error "Only works on polygons!";
  }

  string $out = "";

  int $fileID = `fopen $fileName "w"`;

  $out = "\n//--- Characteristic Length ---------\n\n";
  fprint $fileID $out;
  $out = "\tlength =" + $length +";\n";
  fprint $fileID $out;

  int $region = 100;
 
    $out = "\n//--- vertices of mesh " + $obj + "--------------\n\n";
    fprint $fileID $out;

    //--- Get number of vertices in mesh
    int $vertexCount[] = `polyEvaluate -v $obj`;

    for ($i=0; $i < $vertexCount[0]; ++$i)
    {
      //--- get coordinates of the i'th vertex
      float $coords[] = eval("pointPosition " +$obj + ".vtx["+$i+"]");
      $out = "\tPoint(" +($i+1)+ ") = {" +$coords[0]+ "," +$coords[1]+ "," +$coords[2]+ ",length} ;\n";
      fprint $fileID $out;
    }

    $out = "\n//--- edges of mesh " + $obj + "--------------\n\n";
    fprint $fileID $out;



    //--- Get number of edges in mesh
    int $edgeCount[] = `polyEvaluate -e $obj`;

    for ($i=0; $i < $edgeCount[0]; ++$i)
    {
      //--- get indices of the end nodes 
      string $edge = $obj + ".e["+$i+"]";
      string $attr[] = `listAttr $edge`;

      int $idxA = match( "[0-9]+", $attr[0] );
      int $idxB = match( "[0-9]+", $attr[4] );

      $out = "\tLine(" +($i+1)+ ") = {" +($idxA+1)+ "," +($idxB+1)+ "} ;\n";
      fprint $fileID $out;
    }

    $out = "\n\tn = " + $edgeCount[0] + " ; // Last edge index \n" ;
    fprint $fileID $out;


    $out = "\n//--- faces of mesh " + $obj + "--------------\n\n";
    fprint $fileID $out;

    int $faceCount[] = `polyEvaluate -f $obj`;
    int $count = 0;

    for ($i=0; $i < $faceCount[0]; ++$i) 
    {
      string $facet = $obj + ".f["+$i+"]";

      string $vtxFace[] = `polyListComponentConversion -fromFace -toVertexFace $facet`;

      $vtxFace = `filterExpand -sm 70 -expand true $vtxFace`;

      // Array's to store our result
      string $edgeOrder[];
      int $edges[];
      int $numEdges = 0;

      for ( $vf in $vtxFace )
      {
        // Get edge for this vtxFace
        string $edge[] = `polyListComponentConversion -fromVertexFace -toEdge $vf`;
        $edge = `filterExpand -sm 32 -expand true $edge`;

        // And append to our result
        string $tmpStr = $edge[0];
        $edgeOrder[ $numEdges ] = $tmpStr;

        // Hack to get rid of object name, which includes a number as well
        $tmpStr =  match( "\[[0-9]+\]", $tmpStr );
        $edges[ $numEdges ] = match( "[0-9]+", $tmpStr );
	$edges[ $numEdges ] = $edges[ $numEdges ] +1; // converting to gmsh idx


	// Check order of vertices in edge for this face
	string $attr[] = `listAttr $edge[0]`;

        int $storedIdxA = match( "[0-9]+", $attr[0] );
        int $storedIdxB = match( "[0-9]+", $attr[4] );

	string $res[] = `edgeVertexOrder $edge[0] $facet`;
	if ( size($res) > 0)
	{
          string $tmpIdxA = match( "\[[0-9]+\]", $res[0] );
          string $tmpIdxB = match( "\[[0-9]+\]", $res[1] );
          int $idxA = match( "[0-9]+", $tmpIdxA );
          int $idxB = match( "[0-9]+", $tmpIdxB );
	
          if ( $idxA == $storedIdxB && $idxB == $storedIdxA )
	    $edges[ $numEdges ] = - $edges[ $numEdges ];
	}

        $numEdges++;
      }

      $out = "\tLine Loop(n+"+ ($count+1)  +") =  {"+($edges[0]);
      for( $k = 1; $k < $numEdges; ++$k)
      {
        $out = $out + "," + ($edges[$k]) ;
      }
      $out = $out + "};\n";
      fprint $fileID $out;

      $out = "\tPlane Surface(n+"+ ($count+2) +") = {n+"+ ($count+1)  +"} ;\n\n" ;
      fprint $fileID $out;

      $count = $count + 2 ;
    }

    $out = "\tm = n +" +$count+ " ; // Last face index \n";
    fprint $fileID $out;

    $out = "\n//--- Mesh " +$obj+ "---------------------------------------\n\n";
    fprint $fileID $out;


    string $faceIndices = "n+2";
    for ($i=1; $i < $faceCount[0]; ++$i) 
    {
      $faceIndices = $faceIndices + ",n+" + (($i+1)*2);
    }

    $out = "\tSurface Loop(m+1) = {" +$faceIndices+ "} ;\n";
    fprint $fileID $out;
    $out = "\tVolume(m+2) = {m+1} ;\n";
    fprint $fileID $out;

    $out = "\n//--- Set region number of mesh " +$obj+ "---------------------\n\n";
    fprint $fileID $out;

    $out = "\tMyRegionNumber  = " + $region + " ;\n";
    fprint $fileID $out;
    $out = "\tPhysical Volume (MyRegionNumber) = {m+2} ;\n";
    fprint $fileID $out;


  string $fullPath = `file -q -exn $fileName`;
  fclose $fileID;
  print ("Done writing gmsh geometry file: "+$fullPath+"\n");
}
