zeboidlund
zeboidlund

Reputation: 10137

Wavefront OBJ Parsing - why do I keep getting incorrect data as output?

I'm writing a Wavefront .OBJ mesh parser. While I've been working on this for about 3 weeks now, I decided to rewrite the majority of it, since I was parsing it character-by-character (which I felt was introducing too much complication, in the end, and wasn't working properly anyway). Now that I've been parsing it line-by-line, I feel like I'm getting worse results.

Here's an example of my output:

( STREAM ):# cube.obj


}

(LINE 2){

( STREAM ):#


}

(LINE 3){

( STREAM ): 


}

(LINE 4){

( STREAM ):g cube


}

(LINE 5){

( STREAM ): 


}

(LINE 6){

( VERTEX: 1 )'-597028128851671121920.000000 0.000000 -597118763794171953152.000000'

( STREAM ):v 0.0 0.0 0.0


}

(LINE 7){

( VERTEX: 2 )'-597028128851671121920.000000 0.000000 -597118763794171953152.000000'

( STREAM ):v 0.0 0.0 1.0


}

(LINE 8){

( VERTEX: 3 )'-597028128851671121920.000000 0.000000 -597118763794171953152.000000'

( STREAM ):v 0.0 1.0 0.0


}

(LINE 9){

( VERTEX: 4 )'-597028128851671121920.000000 0.000000 -597118763794171953152.000000'

( STREAM ):v 0.0 1.0 1.0


}

(LINE 10){

( VERTEX: 5 )'-597028128851671121920.000000 0.000000 -597118763794171953152.000000'

( STREAM ):v 1.0 0.0 0.0


}

(LINE 11){

( VERTEX: 6 )'-597028128851671121920.000000 0.000000 -597118763794171953152.000000'

( STREAM ):v 1.0 0.0 1.0


}

(LINE 12){

( VERTEX: 7 )'-597028128851671121920.000000 0.000000 -597118763794171953152.000000'

( STREAM ):v 1.0 1.0 0.0


}

(LINE 13){

( VERTEX: 8 )'-597028128851671121920.000000 0.000000 -597118763794171953152.000000'

( STREAM ):v 1.0 1.0 1.0


}

I'm not working on parsing the indices currently (which are the lines which begin with f), just for the sake of simplicity.

What I've tried so far (for vertex data)

Code

   //...declare lineCount and vertexCount above
   // NOTE: BUFF_LEN == 200

    while( !feof( filePtr ) )
    {
        printf( "(LINE %i){\n\n", lineCount );

        fgets( line, BUFF_LEN, filePtr );


        // append NULL term, since fgets does not
        // return one.

        line[ BUFF_LEN - 1 ] = '\0';

        // evaluate the first character
        switch( line[ 0 ] )
        {
            case 'v':
            {
                if ( line[ 1 ] == ' ' )
                {
                    // we have a vertex, not a normal

                    SIMD_VEC3 v;

                    fscanf( filePtr, " %f %f %f\n", &v[ 0 ], &v[ 1 ], &v[ 2 ] );

                    printf( "( %i )\'%f %f %f\'\n\n",
                            vertexCount, v[ 0 ], v[ 1 ], v[ 2 ] );

                    ++vertexCount;
                }
            }
                break;
        }
    //...printf out the current line parsed from fgets, increment line count
    }

I'm working in C++, but am looking for a standard C approach. I also am working with OpenGL and Linux, though I'm not sure that's relevant.

Upvotes: 2

Views: 171

Answers (1)

fen
fen

Reputation: 10105

As I understand:

  1. You take a line into a buffer - fgets( line, BUFF_LEN, filePtr );
  2. but then you use fscanf to read values for the vector... you use filepointer

I think you should use sscanf to read from the line buffer.

After the fist step file pointer is moved so when you use second step you are reading some different data from the file.

In general reading from a file involves:

  • read one line into some buffer
  • parse that buffer (that line)
  • read another line

some more info opengl totorial about OBJ, OBJ loader

Upvotes: 1

Related Questions