Hi everyone, i'm back with another problem that i cant seem to work out.

i'm trying to read in a .obj file which is basicaly a list of vertices and facets in this format

v 0.00 0.00 0.00
f 0 0 0

i dont know before hand how many vertices and facets the object has so i'm looping round once counting each occurance of v and f then looping around a second time and extracting the data.

once i know how many v's and f's there are i then malloc the correct amount of memory required to store them.

i close the file and reopen it to get back to the start of the file (not the best way i know)

i then read in the lines again and split them up using strtok to get each number and then i convert to float

this is the code i have so far

The problem is that my runs through fine the first time and prints out the ammount of v's and f's then crashes when doing the second loop and i cant seem to figure out why.

any help would be gratefully appreciated

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
	float **vertices;
	int **facets;
}object;

object cube;
int loadObject(object objectin);

int main(int argc, char *argv[])
{
	loadObject(cube);
	getchar();
}
int loadObject(object objectin)
{
	int i;
	unsigned int v = 0; //ammount of vertices
	unsigned int f = 0; //ammount of facets
	unsigned int vt = 0; //ammount of texture vertices
	unsigned int lncount = 0; //ammount of lines in the file
	unsigned int count = 0;
	float x = 0;
	float y = 0;
	float z = 0;
	char *pch; //character pointer
	float **vertices;
	int **facets;
	int n;
	int eof = 1;


	char line[100];


	FILE *infile;

	infile = fopen("object.obj", "r"); //open file for reading

	do
	{
		if (fgets(line, sizeof line,infile)== NULL)
		{
			eof = 0;
		}
		else
		{
            ++lncount;
			if(strncmp(line,"v",1)== 0)
			{
				++v;
			}
			else if (strncmp(line, "f",1) == 0)
			{
				++f;
			}
			else if (strncmp(line, "vt", 2) == 0)
			{
				++vt;
			}
		}

	}while (eof != 0);
	printf("f = %d v = %d",f,v);
	
	vertices = malloc(v*5*sizeof(float));
	
	v = 0;

	fclose(infile);
	infile = fopen("object.obj", "r"); //open file for reading

	for (i = 1; i <= lncount; ++i)
	{
		fgets(line, sizeof line,infile);
	    if (strncmp(line,"v",1) == 0)
		{
  			pch = strtok(line," v");
  			count = 0;
  			while (pch != NULL)
  			{
				++count;
    			printf("%s\n",pch);
    			switch (count)
    			{
					case 1:
    				        x = atof(pch);
					break;
					case 2:
					y = atof(pch);
					break;
					case 3:
					z = atof(pch);
					break;
			}
    			pch = strtok (NULL, " v");   			
  			}
    			vertices[v][0] = x;
    			vertices[v][1] = y;
    			vertices[v][2] = z;
                        ++v;
		}
	}

	for (i = 0; i < v; ++i)
	{
		printf("%f", vertices[i][0]);
		printf("%f", vertices[i][1]);
		printf("%f", vertices[i][2]);
	}
}

Recommended Answers

All 2 Replies

>>i close the file and reopen it to get back to the start of the file (not the best way i know)
Just call rewind() function or fseek()


>>if(strncmp(line,"v",1)== 0)
using strncmp() like that is too time consuming. Since the letter you want is at the beginning of the line just compare the first character if( line[0] == 'v' ) The loop starting on line 43 is incorrect because it will read the last line too many times. It should be coded like this:

while( fgets(line, sizeof(line), infile) )
{

}

>>vertices = malloc(v*5*sizeof(float));
You can't allocate vertices like that because vertices is a 2d array and you are only allocating the first dimension. There are a couple ways you can do this, but if you want to keep the 2d syntax as shown on lines 101-103 then you have to allocate each line separately

int i = 0;
// allocate v number of rows
vertices = malloc( v * sizeof(vertices *)); 
for(i = 0; i < v; i++)
{
   vertices[i] = malloc(5 * sizeof(float));
}

The other way to handle that is to make vertices a single dimension array, but the math on lines 101-103 becomes more complicated.

char *vertices;

vertices = malloc(v*5*sizeof(float));

...
vertices[v*4+0] = x;
vertices[v*4+1] = y;
vertices[v*4+2] = z;
commented: Great advice thank you very much :) +1

considering line 80 to 104,
You alredy have the data in line & you know exactly what format the data is. So, why dont you use sscanf().

And for the malloc problem

1) You may follow what dragon said & loop twice over the file
2) use a linked list. That would make you change a lot of code
3) or Use realloc, but be carefull though, cause you are using a pointer to a pointer to a float

The first looks better to me.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.