Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

file loading

Status
Not open for further replies.

gautamn

Programmer
Jun 24, 2003
1
IN
Hey

I am trying to read in an object file, it seems to parse fine, but then it doesn't read in some data at all. My major concern is with the "case 'f'." I am trying hard to debug it and find out what I am doing wrong but to no avail. This is my file loading code

Code:
header file 

#ifndef OBJ_H 
#define OBJ_H 

#include <stdio.h> 
#include <vector> 

typedef struct { 
   float x, y, z; 
} OBJ_VERTEX; 

typedef struct { 
  float s, t; 
} OBJ_TEXTURE; 

typedef struct { 
  float xn, yn, zn; 
} OBJ_NORMALS; 

typedef struct { 
  unsigned int *vertexIndex; 
  unsigned int *textureIndex; 
  unsigned int *normalIndex; 
} OBJ_FACES; 

typedef struct { 
   int countVertex; 
   int countTextures; 
   int countNormals; 
   int countFaces; 
   OBJ_VERTEX *vertex; 
   OBJ_TEXTURE *texture; 
   OBJ_NORMALS *normals; 
   OBJ_FACES faces; 
}  OBJ_FILE_INFO; 

void Read_File(OBJ_FILE_INFO *info, const char *filename); 
void Destroy_File(OBJ_FILE_INFO &info); 

#endif



Code:
Source file 

#include &quot;obj.h&quot; 

void Read_File(OBJ_FILE_INFO *info, const char *filename) 
{ 
    FILE *fp; 
    int ch;                    // character to read in one at a time 
    float x, y, z; 
    float s, t, u; 
    float xn, yn, zn; 
    int f1[3], f2[3], f3[3]; 
    char buffer[100]; // our temporary buffer to dump in unnecessary information 
    int countVertex = 0; 
    int countTextures = 0; 
    int countNormals = 0; 
    int countFaces = 0; 
    int i = 0, j = 0, k = 0, m = 0; 

    // open text file for reading 
    fp = fopen(filename, &quot;rt&quot;); 

    // check if file exists 
    if(!fp) { fprintf(stderr, &quot;ERROR:FILE NOT FOUND\n&quot;); return; } 

    // read till you reach end of file 
    while(fgets(buffer, 100, fp) != NULL) { 
         if(buffer[0] == 'v' && buffer[1] == ' ') 
              countVertex++; 

         if(buffer[0] == 'v' && buffer[1] == 't') 
              countTextures++; 

         if(buffer[0] == 'v' && buffer[1] == 'n') 
              countNormals++; 

         if(buffer[0] == 'f' && buffer[1] == ' ') 
              countFaces++; 
    } 

    rewind(fp); 

    info->countVertex = countVertex; 
    info->countTextures = countTextures; 
    info->countNormals = countNormals; 
    info->countFaces = countFaces * 3; 

    printf(&quot;DUMP : %d  %d&quot;, info->countFaces, info->countFaces / 3); 

    info->vertex = new OBJ_VERTEX [ countVertex]; 
    info->texture = new OBJ_TEXTURE [countTextures]; 
    info->normals = new OBJ_NORMALS [countNormals]; 
    info->faces.vertexIndex = new unsigned int [countFaces * 3]; 


    while(!feof(fp)) { 
        ch = fgetc(fp); 

        switch(ch) { 
           case '#' : 
                // read in tell next line 
                fgets(buffer, 100, fp); 
                printf(&quot;DUMP : %s&quot;, buffer); 
                break; 

           case 'v' : 
                // read in vertex information 
                ch = fgetc(fp); 
                // this is a vertex 
                if(ch == ' ') { 
                    fscanf(fp, &quot;%f %f %f&quot;, &x, &y, &z); 

                    info->vertex[i].x = x; 
                    info->vertex[i].y = y; 
                    info->vertex[i].z = z; 
                    i++; 
                } 

               // this is texture information 
               if(ch == 't') { 
                  fscanf(fp, &quot;%f %f %f&quot;, &s, &t, &u); 
                  info->texture[j].s = s; 
                  info->texture[j].t = t; 
                  j++; 
               } 

               // this is normal information 
               if(ch == 'n') { 
                  fscanf(fp, &quot;%f %f %f&quot;, &xn, &yn, &zn); 
                  //printf(&quot;Normals : %f %f %f\n&quot;, xn, yn, zn); 
                  info->normals[k].xn = xn; 
                  info->normals[k].yn = yn; 
                  info->normals[k].zn = zn; 
                  k++; 
               } 
               break; 

         case 'f' : 
              ch = fgetc(fp); 
              if(ch == ' ') { 
                   fscanf(fp, &quot;%d/%d/%d %d/%d/%d %d/%d/%d&quot;, 
                          &f1[0], &f1[1], &f1[2], &f2[0], &f2[1], 
                          &f[2], 
                          &f3[0], &f3[1], &f3[2]); 

                   info->faces.vertexIndex[m] = f1[0]; 
                   info->faces.vertexIndex[m + 1] = f2[0]; 
                   info->faces.vertexIndex[m + 2] = f3[0]; 
                   m += 3; 
               } 
               break; 

         default : 
              // read in all other unnecessary data and dumps it 
              fgets(buffer, 100, fp); 
              break; 
        } 

    } 

    fclose(fp); 
    printf(&quot;DUMP m : %d\n&quot;, m); 

}

Code:
This is the model text file 

# 
mtllib cube.mtl 

# Object Object4 
# Vertices 8 
v -5.000000 -5.000000 5.000000 
v 5.000000 -5.000000 5.000000 
v -5.000000 -5.000000 -5.000000 
v 5.000000 -5.000000 -5.000000 
v -5.000000 5.000000 5.000000 
v 5.000000 5.000000 5.000000 
v -5.000000 5.000000 -5.000000 
v 5.000000 5.000000 -5.000000 

# Normals 8 
vn -0.577350 -0.577350 -0.577350 
vn 0.333333 -0.666667 -0.666667 
vn -0.666667 0.333333 -0.666667 
vn 0.666667 0.666667 -0.333333 
vn -0.666667 -0.666667 0.333333 
vn 0.666667 -0.333333 0.666667 
vn -0.333333 0.666667 0.666667 
vn 0.577350 0.577350 0.577350 

# UV 1 
vt 0.000000 0.000000 0.000000 

o Object4 


# Face indices 12 
usemtl 

f 3/1/3 2/1/2 1/1/1 
f 3/1/3 4/1/4 2/1/2 
f 2/1/2 5/1/5 1/1/1 
f 2/1/2 6/1/6 5/1/5 
f 5/1/5 3/1/3 1/1/1 
f 5/1/5 7/1/7 3/1/3 
f 7/1/7 6/1/6 8/1/8 
f 7/1/7 5/1/5 6/1/6 
f 4/1/4 7/1/7 8/1/8 
f 4/1/4 3/1/3 7/1/7 
f 6/1/6 4/1/4 8/1/8 
f 6/1/6 2/1/2 4/1/4


The problem I am facing is instead of it reading at f 3/1/3 2/1/2 1/1/1 it starts to read from the second face index. Anybody have any idea what I might be doing wrong ?

Thank you
 
The main problem as I see it is the piece-meal reading of the file one character at a time, followed by calls to fscanf
The problem with this is, you're never sure where fscanf() stops reading data - one misplaced character in your file, and following fgetc() calls are out of step.

I always use fgets() to read a line into a buffer, then use sscanf (or whatever is appropriate) to extract information from that buffer.
Code:
#include <stdio.h>

int main()
{
    float   x, y, z;
    int     f1[3], f2[3], f3[3];
    int     nconv;
    char buff[BUFSIZ];
    FILE *fp = fopen(&quot;toto&quot;, &quot;r&quot;);

    while (fgets(buff, BUFSIZ, fp) != NULL) {
        switch (buff[0]) {
        case 'v':
            switch ( buff[1] ) {
                case ' ':
                    nconv = sscanf( buff, &quot;%*c %f %f %f&quot;, &x, &y, &z);
                    printf( &quot;Status=%d, vertex = %f %f %f\n&quot;, nconv, x, y, z );
                    break;
                case 't':
                    nconv = sscanf( buff, &quot;%*c%*c %f %f %f&quot;, &x, &y, &z);
                    printf( &quot;Status=%d, texture = %f %f %f\n&quot;, nconv, x, y, z );
                    break;
                case 'n':
                    nconv = sscanf( buff, &quot;%*c%*c %f %f %f&quot;, &x, &y, &z);
                    printf( &quot;Status=%d, normal = %f %f %f\n&quot;, nconv, x, y, z );
                    break;
                default:
                    fprintf( stderr, &quot;Bad vector information - %s&quot;, buff );
            }
            break;

        case 'f':
            nconv = sscanf( buff, &quot;%*c %d/%d/%d %d/%d/%d %d/%d/%d&quot;,
                &f1[0], &f1[1], &f1[2],
                &f2[0], &f2[1], &f2[2],
                &f3[0], &f3[1], &f3[2]);
            printf( &quot;Status=%d, face = %d,%d,%d %d,%d,%d %d,%d,%d\n&quot;, nconv,
                f1[0], f1[1], f1[2],
                f2[0], f2[1], f2[2],
                f3[0], f3[1], f3[2]);
            break;

        case '#':
        case '\n':
            break;  // ignore comments and blank lines

        default:
            fprintf( stderr, &quot;Unrecognised line type - %s&quot;, buff );
            break;
        }
    }
    fclose( fp );
    return 0;
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top