#!/usr/bin/perl

################################################################
#Copyright (C) 2000,2001,2002 Shinobu Yoshimura, University of Tokyo,
#the Japan Society for the Promotion of Science (JSPS)
#All Rights Reserved
################################################################


#----------------------------------------------------#
#                      patch2vrml                    #
#                                 upDate 1999.07.13  #
#                                   write T.ookubo   #
#----------------------------------------------------#

#------- define sub  -----------#
sub help;
draw_vrml;        #only use --normal
draw_group_vrml;  #only use --group 
draw_face_group;  #only use --group 
get_color;



#  ----  main  ------


$opt = $ARGV[0];

$nelm = @ARGV;


if($nelm < 2){
    &help;
}

if($opt eq "--help" || $opt eq "-h"){
  help;
}

if($opt eq "--normal"){
  $pchFileName = $ARGV[1]; 
  draw_vrml($pchFileName); 
  exit(1);
}

if($opt eq "--group"){
  $pchFileName = $ARGV[1]; 
  $pcgFileName = $ARGV[2]; 
  draw_group_vrml($pchFileName,$pcgFileName); 
  exit(1);
}

&help;


#  ----  main end ------

######################################################
#   module help                                      #
#      --> help                                      #
######################################################
sub help{
print  STDERR  <<EOD
Usage:$0  [--normal || --group]   FileName1 [FileName2]
  --normal : nomal output.
     (exsample)  shell2vrml --normal xxxx.pch > xxxx.wrl
  --group : cad group
     (exsample)  shell2vrml --group  xxxx.pch yyyy.pcg > xxxx.wrl
EOD
;
exit(1);
}



######################################################
#   module name                                      #
#      --> draw_vrml                                 #
#   description                                      #
#      --> write vrml format (ver1.0) from patch     #
######################################################

sub draw_vrml{
  my($pchFileName) = @_;

  open(INFILE,"$pchFileName") || die  "Not Found $ARGV[1]\n";
  chop($nNode =  <INFILE>);

  $count = 0;

  for($count = 0; $count < $nNode; $count++){
    chop($_ =  <INFILE>);
    ($xCood[$count], $yCood[$count], $zCood[$count]) = split();
  }


  chop($nPatch =  <INFILE>);

  for($count = 0; $count < $nPatch; $count++){
    chop($_ =  <INFILE>);
    ($v0[$count], $v1[$count], $v2[$count]) = split();
  }


  print  STDERR  "nNode = $nNode      nPatch = $nPatch\n";

  print "#VRML V1.0 ascii\n";
  print "DEF  BackgroundColor Info {\n";
  print "    string  \"0 0 0\"\n";
  print "}\n";
  print "Material {\n";
  print "  diffuseColor 1 1 1\n";
  print "}\n";
  print "Coordinate3 {\n";
  print "  point [\n";


  for($count = 0; $count < $nNode; $count++){
    printf("  %e  %e  %e,\n",$xCood[$count], $yCood[$count],$zCood[$count]);
  }
  print "  ]\n";
  print "}\n";

  print "Material {\n";
  print "  diffuseColor 0  1  1\n";
  print "}\n";

  print "IndexedFaceSet {\n";
  print "  coordIndex [\n";
  for($count = 0; $count < $nPatch; $count++){
    printf("  %7d,  %7d,  %7d,  -1,\n",$v0[$count], $v1[$count], $v2[$count]);
  }

  print "  ]\n";
  print "}\n";

}

##########################################################
#   module name                                          #
#      --> draw_group_vrml                               #
#   description                                          #
#      --> write vrml format (ver1.0) from patch group   #
##########################################################
sub draw_group_vrml{
  my($pchFileName,$pcgFileName) = @_;


  open(INFILE01,"$pchFileName") || die  "Not Found $pchFileNam\n";
  chop($nNode =  <INFILE01>);

  $count = 0;

  for($count = 0; $count < $nNode; $count++){
    chop($_ =  <INFILE01>);
    ($xCood[$count], $yCood[$count], $zCood[$count]) = split();
  }


  chop($nPatch =  <INFILE01>);

  for($count = 0; $count < $nPatch; $count++){
    chop($_ =  <INFILE01>);
    ($v0[$count], $v1[$count], $v2[$count]) = split();
  }


  print  STDERR  "all node = $nNode      all patch = $nPatch\n";

  open(INFILE02,"$pcgFileName") || die  "Not Found $pcgFileName\n";

  #-- vertex --#
  chop($_ =  <INFILE02>);
  @splited       = split /,/, $_;
  $mainVertexInfoLable = $splited[0];


  if($mainVertexInfoLable ne "#mainVertexInfo"){
    print  STDERR  "lable of #mainVertexInfo not found\n";
    exit(0);
  }

  chop($_ =  <INFILE02>);
  ($mainVertexNLabel, $nVertex) = split();

  
  if($mainVertexNLabel ne "mainVertexN"){
    print  STDERR  "lable of mainVertexN not found\n";
    exit(0);
  }

  for($count = 0; $count < $nVertex; $count++){
    chop($mainV[$count] =  <INFILE02>);
  }



  #-- edge --#
  #  read only (not stack)#

  chop($_ =  <INFILE02>);
  @splited       = split / /, $_;
  $edgeGroupInfoLable = $splited[0];

  if($edgeGroupInfoLable ne "#edgeGroupInfo"){
    print  STDERR  "lable of #edgeGroupInfo not found\n";
    exit(0);
  }

  chop($_ =  <INFILE02>);
  ($edgeGroupN, $nEdge) = split();
  
  if($edgeGroupN ne "edgeGroupN"){
    print  STDERR  "lable of edgeGroupN not found\n";
  }

  
  for($count = 0; $count < $nEdge; $count++){
    chop($_ =  <INFILE02>);
    ($edgeGroup,$nOnEdge) = split();

    if($edgeGroup ne "edgeGroup"){
      print  STDERR  "lable of edgeGroup not found\n";
      exit(0);
    }
    for($count0 = 0; $count0 < $nOnEdge; $count0++){
      chop($_ =  <INFILE02>);
      $onEdge = $_;
    }

  }

  print "#VRML V1.0 ascii\n";
  print "DEF  BackgroundColor Info {\n";
  print "    string  \"0 0 0\"\n";
  print "}\n";
  print "Material {\n";
  print "  diffuseColor 1 1 1\n";
  print "}\n";
  print "Coordinate3 {\n";
  print "  point [\n";


  for($count = 0; $count < $nNode; $count++){
    printf("  %e  %e  %e,\n",$xCood[$count], $yCood[$count],$zCood[$count]);
  }
  print "  ]\n";
  print "}\n";




  #-- face group --#

  chop($_ =  <INFILE02>);
  @splited       = split / /, $_;
  $faceGroupInfoLable = $splited[0];

  if($faceGroupInfoLable ne "#faceGroupInfo"){
    print  STDERR  "lable of #faceGroupInfo not found\n";
    exit(0);
  }

  chop($_ =  <INFILE02>);
  ($faceGroupN, $nFace) = split();

  
  if($faceGroupN ne "faceGroupN"){
    print  STDERR  "lable of faceGroupN not found\n";
  }


  for($count = 0; $count < $nFace; $count++){
    chop($_ =  <INFILE02>);
    ($faceGroup,$nOnFace) = split();

    if($faceGroup ne "faceGroup"){
      print  STDERR  "lable of faceGroup not found\n";
      exit(0);
    }

    @onFace = ();
    for($count0 = 0; $count0 < $nOnFace; $count0++){
      chop($_ =  <INFILE02>);
      
      $onFace[$count0] = $_;
    }

    $data = $count / $nFace; 

    draw_face_group(\@v0,\@v1,\@v2,\@onFace,$data);
  }

  print  STDERR  "cad vertex  = $nVertex\n";
  print  STDERR  "cad edge    = $nEdge\n";
  print  STDERR  "cad face    = $nFace\n";





}

##########################################################
#   module name                                          #
#      --> get_color                                     #
#   description                                          #
#      --> return r g b from data                        #
##########################################################
sub get_color{
  my($data) = @_;
  my($red,$green,$blue);

  
  if($data < 0.0  ||  $data > 1.0){ 
    $red = 0.0;
    $green = 0.0;
    $blue = 0.0;
  }

  if ($data >= 0.0   &&  $data < 0.25) {
    $red    = 0.0;
    $green  = 4.0 * $data;
    $blue   = 1.0;
  }

  if ($data >= 0.25  &&  $data < 0.50) {
    $red    = 0.0;
    $green  = 1.0;
    $blue   = -4.0 * $data + 2.0;
  }

 if ($data >= 0.50  &&  $data < 0.75) {
   $red     = 4.0 * $data - 2.0;
   $green   = 1.0;
   $blue    = 0.0;
  }

 if ($data >= 0.75  &&  $data <= 1.00) {
   $red     = 1.0;
   $green   =  -4.0 * $data + 4.0;
   $blue    = 0.0;

 }

 return($red,$green,$blue);

}



##########################################################
#   module name                                          #
#      --> draw_face_group                               #
#   description                                          #
#      --> write vrml format (ver1.0) from patch group   #
##########################################################
sub draw_face_group{
  my($v0,$v1,$v2,$onFace,$data) = @_;

  my($red,$green,$bule,$count);


  $data=rand(1);

  ($red,$green,$bule) = &get_color($data);

  print "Material {\n";
  printf(" diffuseColor  %e  %e  %e\n",$red, $green,$bule);
  print "}\n";
  print "IndexedFaceSet {\n";
  print "  coordIndex [\n";
  
  for($count = 0; $count < $#onFace + 1; $count++){
    printf("  %7d,  %7d,  %7d,  -1,\n",$v0[$onFace[$count]],
                                       $v1[$onFace[$count]],
                                       $v2[$onFace[$count]]);
  }
    print "  ]\n";
  print "}\n";
}

















