2017-02-01 1 views
-1

kann nicht verwendet werden Ich versuche, meine .obj-Datei in eine Headerdatei .h zu konvertieren, aber ich bekomme "Kann nicht verwenden" Definiert (@array) '(Vielleicht solltest du einfach die definierte()?) "Warnung weglassen und keine .h Dateien haben erstellt."Definierte (@array)" Warnung bei der Konvertierung von .obj zu .h

Ich habe versucht, @center zu $center oder omintting defined() ersetzen, aber es erstellt .exe-Datei!
Ich habe irgendwo gelesen, dass es ein Perl-Versionsproblem sein könnte, meins ist 5.22 und ich konnte keine höheren Versionen finden, um es zu versuchen.

Update1:
ich die "obj2opengl.pl" und "myobject.obj" im gleichen Ordner abgelegt haben. und versuchen, es mit diesem Code in der Konsole zu konvertieren (win10): c:\obj2openglfolder>obj2opengl.pl myobject.obj

Update2:
Dies ist der line154 Code, der das Problem verursachen:

if(defined(@center)) { 
    $xcen = $center[0]; 
    $ycen = $center[1]; 
    $zcen = $center[2]; 
} 

Update3:
dieses ist der ganze Code:

# ----------------------------------------------------------------- 

# Main Program 

# ----------------------------------------------------------------- 

handleArguments(); 
# derive center coords and scale factor if neither provided nor disabled 

unless(defined($scalefac) && defined($xcen)) { 
calcSizeAndCenter(); 

} 


if($verbose) { 
printInputAndOptions(); 

} 


# TODO check integrity: Does every referenced vertex, normal and coord 
exist? 

loadData(); 

normalizeNormals(); 


if($verbose) { 
printStatistics(); 

} 


writeOutput(); 


# ----------------------------------------------------------------- 

# Sub Routines 

# ----------------------------------------------------------------- 


sub handleArguments() { 
my $help = 0; 
my $man = 0; 
my $noscale = 0; 
my $nomove = 0; 
$verbose = 1; 
$errorInOptions = !GetOptions (
    "help" => \$help, 
    "man" => \$man, 
    "noScale" => \$noscale, 
    "scale=f" => \$scalefac, 
    "noMove" => \$nomove, 
    "center=f{3}" => \@center, 
    "outputFilename=s" => \$outFilename, 
    "nameOfObject=s" => \$object, 
    "verbose!" => \$verbose, 
    ); 

if($noscale) { 
    $scalefac = 1; 
} 

if($nomove) { 
    @center = (0, 0, 0); 
} 

if(@center) { 
    $xcen = $center[0]; 
    $ycen = $center[1]; 
    $zcen = $center[2]; 
} 

if($#ARGV == 0) { 
    my ($file, $dir, $ext) = fileparse($ARGV[0], qr/\.[^.]*/); 
    $inFilename = $dir . $file . $ext; 
} else { 
    $errorInOptions = true; 
} 

# (optional) derive output filename from input filename 
unless($errorInOptions || defined($outFilename)) { 
    my ($file, $dir, $ext) = fileparse($inFilename, qr/\.[^.]*/); 
    $outFilename = $dir . $file . ".h"; 
} 

# (optional) define object name from output filename 
unless($errorInOptions || defined($object)) { 
    my ($file, $dir, $ext) = fileparse($outFilename, qr/\.[^.]*/); 
    $object = $file; 
} 

($inFilename ne $outFilename) or 
    die ("Input filename must not be the same as output filename") 
    unless($errorInOptions); 

if($errorInOptions || $man || $help) { 
    pod2usage(-verbose => 2) if $man; 
    pod2usage(-verbose => 1) if $help; 
    pod2usage(); 
} 

# check wheter file exists 
open (INFILE, "<$inFilename") 
    || die "Can't find file '$inFilename' ...exiting \n"; 
close(INFILE); 

} 


# Stores center of object in $xcen, $ycen, $zcen 

# and calculates scaling factor $scalefac to limit max 

# side of object to 1.0 units 

sub calcSizeAndCenter() { 
open (INFILE, "<$inFilename") 
    || die "Can't find file $inFilename...exiting \n"; 

$numVerts = 0; 

my (
    $xsum, $ysum, $zsum, 
    $xmin, $ymin, $zmin, 
    $xmax, $ymax, $zmax, 
    ); 

while ($line = <INFILE>) 
{ 
    chop $line; 

    if ($line =~ /v\s+.*/) 
    { 

    $numVerts++; 
    @tokens = split(' ', $line); 

    $xsum += $tokens[1]; 
    $ysum += $tokens[2]; 
    $zsum += $tokens[3]; 

    if ($numVerts == 1) 
    { 
     $xmin = $tokens[1]; 
     $xmax = $tokens[1]; 
     $ymin = $tokens[2]; 
     $ymax = $tokens[2]; 
     $zmin = $tokens[3]; 
     $zmax = $tokens[3]; 
    } 
    else 
    { 
     if ($tokens[1] < $xmin) 
     { 
     $xmin = $tokens[1]; 
     } 
     elsif ($tokens[1] > $xmax) 
     { 
     $xmax = $tokens[1]; 
     } 

     if ($tokens[2] < $ymin) 
     { 
     $ymin = $tokens[2]; 
     } 
     elsif ($tokens[2] > $ymax) 
     { 
     $ymax = $tokens[2]; 
     } 

     if ($tokens[3] < $zmin) 
     { 
     $zmin = $tokens[3]; 
     } 
     elsif ($tokens[3] > $zmax) 
     { 
     $zmax = $tokens[3]; 
     } 

    } 

    } 

} 
close INFILE; 

# Calculate the center 
unless(defined($xcen)) { 
    $xcen = $xsum/$numVerts; 
    $ycen = $ysum/$numVerts; 
    $zcen = $zsum/$numVerts; 
} 

# Calculate the scale factor 
unless(defined($scalefac)) { 
    my $xdiff = ($xmax - $xmin); 
    my $ydiff = ($ymax - $ymin); 
    my $zdiff = ($zmax - $zmin); 

    if (($xdiff >= $ydiff) && ($xdiff >= $zdiff)) 
    { 
     $scalefac = $xdiff; 
    } 
    elsif (($ydiff >= $xdiff) && ($ydiff >= $zdiff)) 
    { 
     $scalefac = $ydiff; 
    } 
    else 
    { 
     $scalefac = $zdiff; 
    } 
    $scalefac = 1.0/$scalefac; 
} 

} 


sub printInputAndOptions() { 
print "Input file  : $inFilename\n"; 
print "Output file : $outFilename\n"; 
print "Object name : $object\n"; 
print "Center   : <$xcen, $ycen, $zcen>\n"; 
print "Scale by  : $scalefac\n"; 

} 


sub printStatistics() { 
print "----------------\n"; 
print "Vertices  : $numVerts\n"; 
print "Faces   : $numFaces\n"; 
print "Texture Coords : $numTexture\n"; 
print "Normals  : $numNormals\n"; 

} 


# reads vertices into $xcoords[], $ycoords[], $zcoords[] 

# where coordinates are moved and scaled according to 

# $xcen, $ycen, $zcen and $scalefac 

# reads texture coords into $tx[], $ty[] 

# where y coordinate is mirrowed 

# reads normals into $nx[], $ny[], $nz[] 

# but does not normalize, see normalizeNormals() 

# reads faces and establishes lookup data where 

# va_idx[], vb_idx[], vc_idx[] for vertices 

# ta_idx[], tb_idx[], tc_idx[] for texture coords 

# na_idx[], nb_idx[], nc_idx[] for normals 

# store indizes for the former arrays respectively 

# also, $face_line[] store actual face string 

sub loadData { 
$numVerts = 0; 
$numFaces = 0; 
$numTexture = 0; 
$numNormals = 0; 

open (INFILE, "<$inFilename") 
    || die "Can't find file $inFilename...exiting \n"; 

while ($line = <INFILE>) 
{ 
    chop $line; 

    # vertices 
    if ($line =~ /v\s+.*/) 
    { 
    @tokens= split(' ', $line); 
    $x = ($tokens[1] - $xcen) * $scalefac; 
    $y = ($tokens[2] - $ycen) * $scalefac; 
    $z = ($tokens[3] - $zcen) * $scalefac;  
    $xcoords[$numVerts] = $x; 
    $ycoords[$numVerts] = $y; 
    $zcoords[$numVerts] = $z; 

    $numVerts++; 
    } 

    # texture coords 
    if ($line =~ /vt\s+.*/) 
    { 
    @tokens= split(' ', $line); 
    $x = $tokens[1]; 
    $y = 1 - $tokens[2]; 
    $tx[$numTexture] = $x; 
    $ty[$numTexture] = $y; 

    $numTexture++; 
    } 

    #normals 
    if ($line =~ /vn\s+.*/) 
    { 
    @tokens= split(' ', $line); 
    $x = $tokens[1]; 
    $y = $tokens[2]; 
    $z = $tokens[3]; 
    $nx[$numNormals] = $x; 
    $ny[$numNormals] = $y; 
    $nz[$numNormals] = $z; 

    $numNormals++; 
    } 

    # faces 
    if ($line =~ /f\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)(\s+([^ ]+))?/) 
    { 
    @a = split('/', $1); 
    @b = split('/', $2); 
    @c = split('/', $3); 
    $va_idx[$numFaces] = $a[0]-1; 
    $ta_idx[$numFaces] = $a[1]-1; 
    $na_idx[$numFaces] = $a[2]-1; 

    $vb_idx[$numFaces] = $b[0]-1; 
    $tb_idx[$numFaces] = $b[1]-1; 
    $nb_idx[$numFaces] = $b[2]-1; 

    $vc_idx[$numFaces] = $c[0]-1; 
    $tc_idx[$numFaces] = $c[1]-1; 
    $nc_idx[$numFaces] = $c[2]-1; 

    $face_line[$numFaces] = $line; 

    $numFaces++; 

    # ractangle => second triangle 
    if($5 != "") 
    { 
     @d = split('/', $5); 
     $va_idx[$numFaces] = $a[0]-1; 
     $ta_idx[$numFaces] = $a[1]-1; 
     $na_idx[$numFaces] = $a[2]-1; 

     $vb_idx[$numFaces] = $d[0]-1; 
     $tb_idx[$numFaces] = $d[1]-1; 
     $nb_idx[$numFaces] = $d[2]-1; 

     $vc_idx[$numFaces] = $c[0]-1; 
     $tc_idx[$numFaces] = $c[1]-1; 
     $nc_idx[$numFaces] = $c[2]-1; 

     $face_line[$numFaces] = $line; 

     $numFaces++; 
    } 

    } 
} 

close INFILE; 

} 


sub normalizeNormals { 
for ($j = 0; $j < $numNormals; ++$j) 
{ 
$d = sqrt ($nx[$j]*$nx[$j] + $ny[$j]*$ny[$j] + $nz[$j]*$nz[$j]); 

    if ($d == 0) 
    { 
    $nx[$j] = 1; 
    $ny[$j] = 0; 
    $nz[$j] = 0; 
    } 
    else 
    { 
    $nx[$j] = $nx[$j]/$d; 
    $ny[$j] = $ny[$j]/$d; 
    $nz[$j] = $nz[$j]/$d; 
    } 

} 

} 


sub fixedIndex { 
local $idx = $_[0]; 
local $num = $_[1]; 
if($idx >= 0) 
{ 
    $idx; 
} else { 
    $num + $idx + 1; 
} 

} 


sub writeOutput { 
open (OUTFILE, ">$outFilename") 
    || die "Can't create file $outFilename ... exiting\n"; 

print OUTFILE "/*\n"; 
print OUTFILE "created with obj2opengl.pl\n\n"; 

# some statistics 
print OUTFILE "source file : $inFilename\n"; 
print OUTFILE "vertices  : $numVerts\n"; 
print OUTFILE "faces   : $numFaces\n"; 
print OUTFILE "normals  : $numNormals\n"; 
print OUTFILE "texture coords : $numTexture\n"; 
print OUTFILE "\n\n"; 

# example usage 
print OUTFILE "// include generated arrays\n"; 
print OUTFILE "#import \"".$outFilename."\"\n"; 
print OUTFILE "\n"; 
print OUTFILE "// set input data to arrays\n"; 
print OUTFILE "glVertexPointer(3, GL_FLOAT, 0, ".$object."Verts);\n"; 
print OUTFILE "glNormalPointer(GL_FLOAT, 0, ".$object."Normals);\n" 
    if $numNormals > 0; 
print OUTFILE "glTexCoordPointer(2, GL_FLOAT, 0, ".$object."TexCoords);\n" 
    if $numTexture > 0; 
print OUTFILE "\n"; 
print OUTFILE "// draw data\n"; 
print OUTFILE "glDrawArrays(GL_TRIANGLES, 0, ".$object."NumVerts);\n"; 
print OUTFILE "*/\n\n"; 

# needed constant for glDrawArrays 
print OUTFILE "unsigned int ".$object."NumVerts = ".($numFaces * 3).";\n\n"; 

# write verts 
print OUTFILE "float ".$object."Verts \[\] = {\n"; 
for($j = 0; $j < $numFaces; $j++) 
{ 
    $ia = fixedIndex($va_idx[$j], $numVerts); 
    $ib = fixedIndex($vb_idx[$j], $numVerts); 
    $ic = fixedIndex($vc_idx[$j], $numVerts); 
    print OUTFILE " // $face_line[$j]\n"; 
    print OUTFILE " $xcoords[$ia], $ycoords[$ia], $zcoords[$ia],\n"; 
    print OUTFILE " $xcoords[$ib], $ycoords[$ib], $zcoords[$ib],\n"; 
    print OUTFILE " $xcoords[$ic], $ycoords[$ic], $zcoords[$ic],\n"; 
} 
print OUTFILE "};\n\n"; 

# write normals 
if($numNormals > 0) { 
    print OUTFILE "float ".$object."Normals \[\] = {\n"; 
    for($j = 0; $j < $numFaces; $j++) { 
     $ia = fixedIndex($na_idx[$j], $numNormals); 
     $ib = fixedIndex($nb_idx[$j], $numNormals); 
     $ic = fixedIndex($nc_idx[$j], $numNormals); 
     print OUTFILE " // $face_line[$j]\n"; 
     print OUTFILE " $nx[$ia], $ny[$ia], $nz[$ia],\n"; 
     print OUTFILE " $nx[$ib], $ny[$ib], $nz[$ib],\n"; 
     print OUTFILE " $nx[$ic], $ny[$ic], $nz[$ic],\n"; 
    } 

    print OUTFILE "};\n\n"; 
} 

# write texture coords 
if($numTexture) { 
    print OUTFILE "float ".$object."TexCoords \[\] = {\n"; 
    for($j = 0; $j < $numFaces; $j++) { 
     $ia = fixedIndex($ta_idx[$j], $numTexture); 
     $ib = fixedIndex($tb_idx[$j], $numTexture); 
     $ic = fixedIndex($tc_idx[$j], $numTexture); 
     print OUTFILE " // $face_line[$j]\n"; 
     print OUTFILE " $tx[$ia], $ty[$ia],\n"; 
     print OUTFILE " $tx[$ib], $ty[$ib],\n"; 
     print OUTFILE " $tx[$ic], $ty[$ic],\n"; 
    } 

    print OUTFILE "};\n\n"; 
} 

close OUTFILE; 

} 
+1

Wo Ihr Code? – Toto

+0

im Ordner "obj2openglfolder" im C-Verzeichnis – tbp

+3

Bitte lesen und stellen Sie [mcve] bereit. – AdrianHHH

Antwort

1

Von perldoc:

Die Verwendung von definierten on-Aggregaten (Hashes und Arrays) ist veraltet. Früher wurde gemeldet, ob Speicher für dieses Aggregat jemals zugewiesen wurde. Dieses Verhalten verschwindet möglicherweise in zukünftigen Versionen von Perl. Sie sollten stattdessen einen einfachen Test für die Größe verwenden:

if (@an_array) { print "has array elements\n" } 
    if (%a_hash) { print "has hash members\n" } 
+0

Das ist richtig. Ich wundere mich jedoch über den Zweck des "definierten" Tests im obigen Code. Ich meine, testet es, ob das Array _existiert_ oder ob es Werte hat? Definiert bedeutet Ersteres, aber der Code würde letzteres tun. – Sobrique

+0

Ich habe es versucht, dieser Fall geht die Warnung über, aber immer noch keine .h-Dateien erstellt. es erstellt nur eine .exe-Datei und ich brauche es nicht. Danke trotzdem – tbp

4

Das ist, weil ein Array kein ‚undefined‘ hat Zustand. Es hat nur einen "leeren" Zustand.

Wenn Sie das tun:

#!/usr/bin/env perl 
use strict; 
use warnings; 

use Data::Dumper; 

my @array = undef; 
print Dumper \@array ; 

Dann, was man bekommt, ist:

$VAR1 = [ 
      undef 
     ]; 

die ein Array mit einem einzigen (undefined) Element ist.

Aber Sie können testen, ob ein Array leer ist, trivialerweise - denn in einem skalaren Kontext @array gibt eine Reihe von Elementen:

print scalar @list; 

Solange Sie einen skalaren Kontext erzwingen, dann werden Sie bekommen ein numerischer Wert aus.

Nützlich für ein 'leeres' Array, das ist Null, und funktioniert daher gut in einem 'Wenn' zu testen, ob es Werte im Array gibt.

if (@array) { 
    print "Array has ", scalar @array, " entries\n"; 
} 
else { 
    print "Array is empty.\n"; 
} 
+0

Danke. Also was soll ich genau machen? Ich bin nicht vertraut mit Perl – tbp

+1

Vielleicht einen Perl-Programmierer mieten? Ich meine, Sie haben uns 4 Perlzeilen gegeben, und wir können Ihnen sagen, was damit nicht stimmt - aber wir können Ihnen nicht sagen, wie wir es beheben sollen, weil wir nicht sagen können, was der Rest Ihres Codes ist macht. – Sobrique

3

defined(@array) verwendet, um zurückzugeben, ob das Array leer war oder nicht. Das war ein Fehler.

defined(@array) sollte immer true zurückgeben (da die Anzahl der Elemente in einem Array immer definiert ist).

Statt den Fehler zu beheben (Code stumm zu schalten), kann der Benutzer durch diese spezielle (und nutzlose) Verwendung von defined nun wissen, dass er etwas falsch macht und wie er es beheben kann.

Wie die Fehlermeldung suggeriert, einfach if (@array) verwenden, um zu überprüfen, ob das Array leer ist.

0

Ersetzen Sie einfach

`if(defined(@center)) { 
     $xcen = $center[0]; 
     $ycen = $center[1]; 
     $zcen = $center[2]; 
    }` 

zu

if (@center) { 
    print "Array has ", scalar @array, " entries\n"; 
    $xcen = $center[0]; 
    $ycen = $center[1]; 
    $zcen = $center[2]; 
} 
Verwandte Themen