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 Rhinorhino 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
Joined
Jun 24, 2003
Messages
1
Location
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