#!/usr/bin/perl
# bulk2gibi.pl         SOURCE    LC    01/10/24
#
# [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
# CHAMPANEY Laurent  Universite de Versailles St Quentin le 27 / 11 / 02
#
# Transfert de maillages "Bulk Data" (sortie CATIA) vers GIBIANE
#
#  Usage :
#    bulk2gibi.pl [-d densite] [-h] [-v] mail
#  
#  lit mail.dat et le converti en mail.sauv
#
#  Utilisation dans CAST3M (Gibiane)
#    OPTI REST FORMAT 'mail.sauv'; REST FORMAT;
#
# ======================================================================
#
# ======================================================================
# Analyse des arguments
# ======================================================================
use Getopt::Long;
#
@knownoptions = (
#                 "mode|m=s",
                 "help|h",
                 "densite|d=f",
#                 "physical|p",
                 "verbose|v");
GetOptions (@knownoptions) || exit ;
$ndime1 = 2;
$ifour1 = 2;
$ifomod1 = 2;
if ($opt_mode){
	$ifour1 = -1; $ndime1 = 2;
	if ($opt_mode eq 'DP') {$ifour1 = -1; $ifomod1 = -1; $ndime1 = 2};
	if ($opt_mode eq 'CP') {$ifour1 = -2; $ifomod1 = -1; $ndime1 = 2};
	if ($opt_mode eq 'AX') {$ifour1 =  0; $ifomod1 =  0; $ndime1 = 2};
	if ($opt_mode eq '3D') {$ifour1 =  2; $ifomod1 = 2; $ndime1 = 3};
}else {
	$ifour1 = 2; $ndime1 = 3; $ifomod1 = 2;
};
if ($opt_dimension){$ndime1=$opt_dimension};
$densi1 = 1.;
if ($opt_densite){$densi1=$opt_densite};
$verb1 = 0;
if ($opt_verbose){$verb1=1};
$phys1 = 0;
if ($opt_physical){$phys1=1};
#
if ($opt_help){sortie_usage(); exit();};
#
if($#ARGV==-1) { sortie_usage(); exit();}
else {
        ($generic , $generic_ext) = ( $ARGV[0] =~ /([-_\/\w]*)\.?(\w*)/ ) ;
}
#
# ======================================================================
# Fichier d'ecriture vers Castem
# ======================================================================
$bulk_file = "$generic.dat";
$gibi_file ="$generic.sauv";
# $phys_file = "$generic.phy";
# if ($phys1 && (-e $phys_file)) {
# 	print "Entitees Physiques :\n";
# 	open (PHYSFIC, $phys_file) or die "Le fichier $phys_file n'extiste pas";
# 	while ($line = <PHYSFIC>) {
# 		$line =~ /^\s*(\S+)\s*=\s*([0-9]*)\s*;/ ;
# 		$nom=$1;
# 		$nom=~ tr/a-z/A-Z/;
# 		$Phys[$2] = $nom;
# 		print "$1=$nom\n";
# 	}
# }
#
# ======================================================================
# En premier on balaie fichier pour compter les noeuds et les elements
# ======================================================================
open (INFIC, $bulk_file) || die "Le fichier $bulk_file n existe pas\n";
my $nbnode1 = 0;
my $nbtetr1 = 0;
my $nbtria1 = 0;
my $nbquad1 = 0;
my $nbhexa1 = 0;
my $nbpenta1 = 0;
my $nbmesh1 = 0;
while ($line = <INFIC>) {
	if ($line =~ /GRID.*/) {
		$nbnode1++;
		@tab = split ( /\s+/ , $line ) ;
		$corres[@tab[1]]=$nbnode1;

		}
	if ($line =~ /CTETRA.*/) {$nbtetr1++}
	if ($line =~ /CHEXA.*/)  {$nbhexa1++}
	if ($line =~ /CPENTA.*/) {$nbpent1++}
	if ($line =~ /CTRIA3.*/) {$nbtria1++}
	if ($line =~ /CTRIA6.*/) {$nbtria1++}
	if ($line =~ /CQUAD4.*/) {$nbquad1++}
	if ($line =~ /.*MESH.*/) {$nbmesh1++}
};
if ($verb1) {print "Nbre de noeuds      : $nbnode1\n"};
if ($verb1) {print "Nbre de maillages   : $nbmesh1\n"};
if ($verb1) {print "Nbre de triangles   : $nbtria1\n"};
if ($verb1) {print "Nbre de quadrangles : $nbquad1\n"};
if ($verb1) {print "Nbre de tétraèdres  : $nbtetr1\n"};
if ($verb1) {print "Nbre d'hexaèdres    : $nbhexa1\n"};
if ($verb1) {print "Nbre de pentaèdres  : $nbpent1\n"};
close(INFIC);
$nb_elem1 = $nbtetr1 + $nbhexa1 + $nbpent1 + $nbtria1 + $nbquad1;
if ($nbnode1 == 0) {die "Pas de noeuds !\n"};
if ($nb_elem1 == 0) {die "Pas d'elements !\n"};
#
# ======================================================================
# On s'occupe du fichier des noeuds
# ======================================================================
open (INFIC, $bulk_file);
until ($line =~ /GRID.*/) {$line = <INFIC>};
#
open (NODEFIC, ">gms2gibi.temp.node");
#
print NODEFIC " ENREGISTREMENT DE TYPE   2\n";
printf NODEFIC (" PILE NUMERO  32NBRE OBJETS NOMMES       0NBRE OBJETS%8d\n", $nbnode1);
printf NODEFIC ("%8d\n", $nbnode1);
$nli1 = int($nbnode1 / 10);
$nre1 = $nbnode1 - (10 * $nli1);
#
if ($nli1 > 0)
	{
	for ($i = 0; $i < $nli1; $i++)
		{
		for ($k = 1; $k <= 10; $k++)
			{
			printf NODEFIC ("%8d",(($i * 10) + $k));
			}
		print NODEFIC "\n";
		}
	}
if ($nre1 > 0)
        {
        for ($k = 1; $k <= $nre1; $k++)
	        {
	        printf NODEFIC ("%8d",(($nli1 * 10) + $k));
	        }
        print NODEFIC "\n";
        }
#
print  NODEFIC " ENREGISTREMENT DE TYPE   2\n";
print  NODEFIC " PILE NUMERO  33NBRE OBJETS NOMMES       0NBRE OBJETS       1\n";
printf NODEFIC ("  %6d\n", (($ndime1 + 1) * $nbnode1));
$ind1 = 0;
for ($i = 0 ; $i < $nbnode1 ; $i++)
	{
	$line=~ s/,/./g;
	@ta0 = split ( /\s+/ , $line ) ;
	$line = <INFIC>;
	@tab[1] = @ta0[2];
	@tab[2] = @ta0[3];
	$line=~ s/,/./g;
	@ta0 = split ( /\s+/ , $line ) ;
	$line = <INFIC>;
	@tab[3] = @ta0[2];
#       Les coordonnees
        for ($k = 1; $k <= $ndime1; $k++)
	 	{
#		if (@tab[$k] >= 0.)
#		{
         	printf NODEFIC ("%+22.14E", @tab[$k]);
#		}
	        $ind1++;
		if ($ind1 >= 3)
			{
			$ind1 = 0;
         	        print NODEFIC "\n";
			}
		}
#       La densite
       	printf NODEFIC ("%+22.14E", $densi1);
        $ind1++;
	if ($ind1 >= 3)
		{
		$ind1 = 0;
       	        print NODEFIC "\n";
		}

	}	
if ($ind1 != 0) {print NODEFIC "\n"};
#
print NODEFIC " ENREGISTREMENT DE TYPE   5\n";
printf NODEFIC ("LABEL AUTOMATIQUE :   %-50s","1");
#
close (NODEFIC);
#
# ======================================================================
# On s'occupe du fichier des maillages
# ======================================================================
do {$line = <INFIC>} until (not ($line =~ /\$.*/));
#
open (ELEMFIC1, ">gms2gibi.temp.elem");
#
# Petits tableaux de travail
# corresp en type elemens
my %bulk_types = ();
# Conversion bulk 
$bulk_elem{CTRIA3}=2;
$bulk_elem{CTRIA6}=9;
$bulk_elem{CQUAD4}=3;
$bulk_elem{CTETRA}=4;
$bulk_elem{CHEXA}=5;
$bulk_elem{CPENTA}=6;
$bulk_elem{CTET10}=11;
$bulk_elem{CHEX20}=12;
# Conversion castem
$type_elem[1] = 2;
$type_elem[2] = 4;
$type_elem[3] = 8;
$type_elem[4] = 23;
$type_elem[5] = 14;
$type_elem[6] = 16;
$type_elem[7] = 25;
$type_elem[9] = 6;
$type_elem[11] = 24;
$type_elem[12] = 15;
$type_elem[15] = 1;
# corresp en nombre de noeuds
$nnod_elem[1] = 2;
$nnod_elem[2] = 3;
$nnod_elem[3] = 4;
$nnod_elem[4] = 4;
$nnod_elem[5] = 8;
$nnod_elem[6] = 6;
$nnod_elem[7] = 5;
$nnod_elem[9] = 6;
$nnod_elem[11] = 10;
$nnod_elem[12] = 20;
$nnod_elem[15] = 1;
# corresp en type d'entite
$enti_elem[1] = 'L';
$enti_elem[2] = 'S';
$enti_elem[3] = 'S';
$enti_elem[4] = 'V';
$enti_elem[5] = 'V';
$enti_elem[6] = 'V';
$enti_elem[7] = 'V';
$enti_elem[9] = 'S';
$enti_elem[11] = 'V';
$enti_elem[15] = 'P';
#
$nb_maillage = 0;
$nb_maillag2 = 0;
#
$i_coul = 0;
#
$iobj1 = 0;
$index1[1] = 0;
$index1[2] = 0;
$index1[3] = 0;
$index1[4] = 0;
$nb_elem2[1] = 0;
$nb_elem2[2] = 0;
$nb_elem2[3] = 0;
$nb_elem2[4] = 0;
$nb_type1 = 0;
#
for ($i = 0 ; $i < $nb_elem1 ; $i++)
	{
	@tab = split ( /\s+/ , $line ) ;
#       Pour les element stockés sur plusieurs lignes
	if (@tab[0] eq "CTETRA") {
		if (@tab[7]) {
			$line2 = <INFIC>;
			@tab2 = split ( /\s+/ , $line2 ) ;
			@tab[0] = "CTET10";
			@tab[8] =~ /(.*)\+.*/;
			@tab[8] = $1;
#			$line = "@tab[0] @tab[1] @tab[2] @tab[3] @tab[4] @tab[5] @tab[6]  @tab[7] @tab[8] @tab2[1] @tab2[2] @tab2[3] @tab2[4]";
			$line = "@tab[0] @tab[1] @tab[2] @tab[3] @tab[7] @tab[4] @tab[8]  @tab[5] @tab2[1] @tab2[2] @tab2[3] @tab2[4] @tab[6]";

		}
	}
#       L'objet
        $jobj1 = @tab[2];
	if ($iobj1 == 0) {$iobj1 = $jobj1};
# On teste si on change d'objet
	if ($jobj1 != $iobj1)
		{
#               Nouveau maillage : on ecrit 
		ecrit_maillage();
#
        	$iobj1 = $jobj1;
                $index1[1] = 0;
                $index1[2] = 0;
                $index1[3] = 0;
                $index1[4] = 0;
                $nb_elem2[1] = 0;
                $nb_elem2[2] = 0;
                $nb_elem2[3] = 0;
                $nb_elem2[4] = 0;
                $nb_type1 = 0;
		}
#
        if ($nb_type1 == 0)
                {
                $nb_type1++;
#               Les tetraèdres pour l'instant
	        $type_elem1[1]=$bulk_elem{@tab[0]};
                $nb_elem2[1]++;
                $index1[1]++;
                $list_ligne[1][$index1[1]] = $line;
                }
         else
                {
                $test1 = 0;
                for ($j = 1 ; $j <= $nb_type1 ; $j++)
                        {
                        if ($bulk_elem{@tab[0]} == $type_elem1[$j]) 
                                {
                                $nb_elem2[$j]++;
                                $index1[$j]++;
                                $list_ligne[$j][$index1[$j]] = $line;
                                $test1 = 1; 
                                }
                        }
                if ($test1 == 0)
                        {
                        $nb_type1++;
                        $type_elem1[$nb_type1]=$bulk_elem{@tab[0]};
                        $nb_elem2[$nb_type1]++;
                        $index1[$nb_type1]++;
                        $list_ligne[$nb_type1][$index1[$nb_type1]] = $line;
                        }
                }
	do {$line = <INFIC>} until (not ($line =~ /\$.*/));
#
#       Les numeros de noeud

	}	
# Dernier maillage : on ecrit 
ecrit_maillage();
close(ELEMFIC1);
#
if ($verb1) {print "$nb_maillag2 maillages dont $nb_maillage nommes\n";}
#
#  On ecrit tout
open (OUFIC, ">$gibi_file");
# Options renerales
print OUFIC " ENREGISTREMENT DE TYPE   4\n";
printf OUFIC (" NIVEAU  12 NIVEAU ERREUR   0 DIMENSION%4d\n",$ndime1);
print OUFIC " DENSITE 0.10000E+01\n";
print OUFIC " ENREGISTREMENT DE TYPE   7\n";
print OUFIC " NOMBRE INFO CASTEM2000   8\n";
printf OUFIC (" IFOUR%4d NIFOUR   0 IFOMOD%4d IECHO   1 IIMPI   0 IOSPI   0 ISOTYP   1\n", $ifour1, $ifomod1);
print OUFIC " NSDPGE     0\n";
print OUFIC " ENREGISTREMENT DE TYPE   2\n";
# Elements
printf OUFIC (" PILE NUMERO   1NBRE OBJETS NOMMES%8dNBRE OBJETS%8d\n",$nb_maillage,$nb_maillag2);
$npoin1 = 0;
$nline1 = 0;
$nsurf1 = 0;
$nvolu1 = 0;
$ind1 = 0;
for ($i = 1 ; $i <= $nb_maillage ; $i++)
	{
	if ($type_mail[$i] eq 'P')
		{
                $npoin1++;
		$nom = "$type_mail[$i]$npoin1";
		}
	if ($type_mail[$i] eq 'L')
		{
                $nline1++;
		$nom = "$type_mail[$i]$nline1";
		}
	if ($type_mail[$i] eq 'S')
		{
                $nsurf1++;
		$nom = "$type_mail[$i]$nsurf1";
		}
	if ($type_mail[$i] eq 'V')
		{
                $nvolu1++;
		$nom = "$type_mail[$i]$nvolu1";
		}
	if ($Phys[$num_entit[$i]]) {$nom = $Phys[$num_entit[$i]]};
	printf OUFIC (" %-8s",$nom);
        $ind1++;
	if ($ind1 >= 8)
		{
		$ind1 = 0;
       	        print OUFIC "\n";
		}
	}
if ($ind1 != 0) {print OUFIC "\n"};
$ind1 = 0;
for ($i = 1 ; $i <= $nb_maillage ; $i++)
	{
	printf OUFIC ("%8d",$num_mail[$i]);
        $ind1++;
	if ($ind1 >= 10)
		{
		$ind1 = 0;
       	        print OUFIC "\n";
		}
	}
if ($ind1 != 0) {print OUFIC "\n"};
#
# On concatene
open (INFIC, "gms2gibi.temp.elem");
while ($line=<INFIC>) {
	print OUFIC "$line";
};
close (INFIC);
open (INFIC, "gms2gibi.temp.node");
while ($line=<INFIC>) {
	print OUFIC "$line";
};
close (INFIC);
#
close (OUFIC);
#
#
# On fait le menage
unlink <gms2gibi.temp.elem>;
unlink <gms2gibi.temp.node>;
#
# ======================================================================
# On sort
# ======================================================================
print "\n";
print "Conversion $msh_file vers $gibi_file effectuee\n";
print "   (Densité $densi1 - Dimension : $ndime1)\n";
print "Restitution :    OPTI REST FORMAT '$gibi_file'; REST FORMAT; \n";
print "\n";
#
# Fini
exit;
#
# ===========================================================> End <===
sub ecrit_maillage {
        if ($nb_type1 > 1)
                {
#               Nouvel objet : on enregistre
                if ($verb1) {print "Objet complexe : $nb_type1 types d elements\n";}
#               Entete
                printf ELEMFIC1 ("%8d",0);
                printf ELEMFIC1 ("%8d",$nb_type1);
                printf ELEMFIC1 ("%8d",0);
                printf ELEMFIC1 ("%8d",0);
                printf ELEMFIC1 ("%8d\n",0);
#
                $nb_maillage++;
		$i_coul++;
		if ($icoul == 7) {$icoul = 0};
                $type_mail[$nb_maillage] = $enti_elem[$type_elem1[1]];
		$num_entit[$nb_maillage] = $iobj1;
                $num_mail[$nb_maillage] = $nb_maillag2 + 1;
#
                for ($k = 1; $k <= $nb_type1; $k++)
                        {
                        printf ELEMFIC1 ("%8d",($nb_maillag2 + $k + 1));
                        }
                print ELEMFIC1 "\n";
                $nb_maillag2 = $nb_maillag2 + $nb_type1 + 1; 
                }
        else                
                {
                $nb_maillage++;
		$i_coul++;
		if ($icoul == 7) {$icoul = 0};
                $nb_maillag2++;
                $type_mail[$nb_maillage] = $enti_elem[$type_elem1[1]];
		$num_entit[$nb_maillage] = $iobj1;
                $num_mail[$nb_maillage] = $nb_maillag2;
                }
#
        for ($h = 1; $h <= $nb_type1; $h++)
                {
#               Nouvel objet : on enregistre
                $inum1 = $nb_maillag2 - $nb_type1 + $h;
                if ($verb1) {print "Maillage $inum1 : $nb_elem2[$h] elements\n";}
#               Entete
                printf ELEMFIC1 ("%8d",$type_elem[$type_elem1[$h]]);
                printf ELEMFIC1 ("%8d",0);
                printf ELEMFIC1 ("%8d",0);
                printf ELEMFIC1 ("%8d",$nnod_elem[$type_elem1[$h]]);
                printf ELEMFIC1 ("%8d\n",$nb_elem2[$h]);
#               Couleurs
                $ind2 = 0;
                for ($k = 1; $k <= $nb_elem2[$h]; $k++)
                        {
                        printf ELEMFIC1 ("%8d",$i_coul);
                        $ind2++;
                        if ($ind2 >= 10)
                                {
                                $ind2 = 0;
                                print ELEMFIC1 "\n";
                                }
                        }

                if ($ind2 != 0) {print ELEMFIC1 "\n"};
#               Noeuds                    
                $ind1 = 0;
                for ($j = 1; $j <= $nb_elem2[$h]; $j++)
                        {
                        $line2 = $list_ligne[$h][$j];
                        @tab2 = split ( /\s+/ , $line2 ) ;
                        $nno1 = $nnod_elem[$type_elem1[$h]];
                        for ($k = 3; $k <= (2 + $nno1); $k++)
                                {
                                printf ELEMFIC1 ("%8d", $corres[@tab2[$k]]);
                                $ind1++;
                                if ($ind1 >= 10)
                                        {
                                        $ind1 = 0;
                                        print ELEMFIC1 "\n";
                                        }
                                }
                        }
                if ($ind1 != 0) {print ELEMFIC1 "\n"};
                }
#
	return;
};

sub sortie_usage {
        print "  \n";
        print "========================================================  \n";
        print "bulk2gibi.pl : convertion BULKDATA (sortie CATIA) \n";
        print "                 vers CAST3M (Gibiane)\n";
        print "Laurent CHAMPANEY                      Octobre 2002\n";
        print "========================================================  \n";
        print "  \n";
        print "Usage :\n";
        print "  bulk2gibi.pl [-d densite] [-v] [-h]  mail\n";
        print "  \n";
        print "  lit mail.dat et le converti en mail.sauv\n";
        print "  \n";
        print "  Restitution dans CAST3M\n";
        print "    OPTI REST FORMAT 'mail.sauv'; REST FORMAT;\n";
        print "  \n";
        print "  L'option -h donne ces infos\n";
        print "  L'option -v affiche des infos pendant l'execution\n";
        print "  \n";
        print "  Dans Cast3m les noms des maillages sont :\n";
        print "    P1, P2, ... Pn : pour les points\n";
        print "    L1, L2, ... Ln : pour les lignes\n";
        print "    S1, S2, ... Sn : pour les surfaces\n";
        print "    V1, V2, ... Vn : pour les volumes\n";
        print "  \n";
        print "========================================================  \n";
        print "bulk2gibi.pl : convertion BULKDATA vers CAST3M (Gibiane)\n";
        print "Laurent CHAMPANEY                      Octobre 2002\n";
        print "========================================================  \n";
        print "  \n";
	return;
        };

# ======================================================================
#  Avancee dans le fichier 
# ======================================================================
#
sub avance {
	while ($line ne "@_") {$line =<INFIC>}
};

