Sign in to follow this  
dreamslayerx

Reading in a file.

Recommended Posts

dreamslayerx    114
Hi guys. I trying to do something very simple,but for some reason. When using inFile.ignore('\n'). I am not getting want I want to display. The goal here is to read in the v, vertex, vt, vertex texture, and f, faces so that I can apply some texturing later. I would like if if whenever I come across v, vt, or f, I would like to read in the values and ignoring all the other information. Does anyone have any idea? Keep it simple I am new.

You can read the .obj file using wordPad or someother text editor. I understand how to read in code, but maybe you guys know a more efficient way to extract this data.

[/file]
# Blender3D v249 OBJ File: cube.blend

# www.blender3d.org

mtllib cube.mtl

v 1.000000 -1.000000 -1.000000

v 1.000000 -1.000000 1.000000

v -1.000000 -1.000000 1.000000

v -1.000000 -1.000000 -1.000000

v 1.000000 1.000000 -1.000000

v 0.999999 1.000000 1.000001

v -1.000000 1.000000 1.000000

v -1.000000 1.000000 -1.000000

vt 0.666667 0.000000

vt 0.666667 0.333333

vt 0.333334 0.333333

vt 0.333333 0.000000

vt 0.333333 1.000000

vt 0.333334 0.666667

vt 0.666667 0.666667

vt 0.666667 1.000000

vt 0.333333 0.333333

vt 0.333333 0.666667

vt 0.000000 0.666667

vt 0.000000 1.000000

vt 0.000000 0.333333

vt 0.000000 0.000000

usemtl Material_cube_Cube.bmp

s off

f 5/1 1/2 4/3

f 5/1 4/3 8/4

f 3/5 7/6 8/7

f 3/5 8/7 4/8

f 2/2 6/7 3/9

f 6/7 7/6 3/9

f 1/10 5/5 2/11

f 5/5 6/12 2/11

f 5/9 8/13 6/4

f 8/13 7/14 6/4

f 1/10 2/11 3/13

f 1/10 3/13 4/9
[/file]

Share this post


Link to post
Share on other sites
dreamslayerx    114
[quote name='SiCrane' timestamp='1315092594' post='4857295']
Show your code.
[/quote]


Oh sure it is your basic code,but I have been playing around with it a little, but it looks like this. I'm really asking for tips. Many things are commented out because I have been trying different things. I would like to know if someone has an effiecient method for reading this.

[size="2"][color="#0000ff"][size="2"][color="#0000ff"]void[/color][/size][/color][/size][size="2"] readFile() [/size][size="2"][color="#008000"][size="2"][color="#008000"]//Working section Used to count the number of floats in a file. This section can make program slower.

[/color][/size][/color][/size][size="2"]{

ifstream inFile;

inFile.open([/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"cube.obj"[/color][/size][/color][/size][size="2"]);

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"] (!inFile.is_open())

{

cout << [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"Unable to open file"[/color][/size][/color][/size][size="2"]; [/size][size="2"][color="#008000"][size="2"][color="#008000"]///C:\Users\Alanzo Granville\Documents\Visual Studio 2008\Projects\Opening_A_File_Program\Opening_A_File_Program

[/color][/size][/color][/size][size="2"]exit(1); [/size][size="2"][color="#008000"][size="2"][color="#008000"]/// terminate with error

[/color][/size][/color][/size][size="2"]}

[/size][size="2"][color="#008000"][size="2"][color="#008000"]// inFile.peek() This will be the section where I peek into the file to see what is going to be read next;

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]int[/color][/size][/color][/size][size="2"] i =0;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]char[/color][/size][/color][/size][size="2"] ch;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]int[/color][/size][/color][/size][size="2"] num;

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//Reading the first character of the file

//inFile>>ch;

//cout<<ch<<' ';

//ch = inFile.peek();

[/color][/size][/color][/size][size="2"]inFile>>ch;

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//inFile.ignore(25,'\n');

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]while[/color][/size][/color][/size][size="2"](!inFile.eof())

{

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//ch = inFile.peek();

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//inFile>>ch;

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//cout<<ch<<endl;

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//char ch;

//ch = inFile.peek();

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//if(ch == '#')

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]// {

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//if (i<3)

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//{

//inFile.ignore(50,'\n');

// }

// if(i==3)

// ch=inFile.peek();

//cout<<" You are inside the first if statment"<<endl;

[/color][/size][/color][/size][size="2"]

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](ch == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'v'[/color][/size][/color][/size][size="2"] || [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'t'[/color][/size][/color][/size][size="2"]||[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'f'[/color][/size][/color][/size][size="2"]||[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'/'[/color][/size][/color][/size][size="2"])

{

inFile>>ch;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](ch == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'0'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'1'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'2'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'3'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'4'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'5'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'6'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'7'[/color][/size][/color][/size][size="2"]||

ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'8'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'9'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'.'[/color][/size][/color][/size][size="2"]||ch ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'-'[/color][/size][/color][/size][size="2"])

{

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//cout<<"Did you get in"<<endl;

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//inFile >> ch;// num;

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//inFile>>ch;

[/color][/size][/color][/size][size="2"]

cout<<ch<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]' '[/color][/size][/color][/size][size="2"];

i++;

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//inFile>>ch;

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//cout << ch<<' '<<endl;

[/color][/size][/color][/size][size="2"]}

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//else

[/color][/size][/color][/size][size="2"]}



[/size][size="2"][color="#008000"][size="2"][color="#008000"]//inFile.get();

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//}

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//inFile.get();

//floatC=i;

[/color][/size][/color][/size][size="2"]}[/size][size="2"][color="#008000"][size="2"][color="#008000"]//end of while loop

[/color][/size][/color][/size][size="2"]}

[/size]

Share this post


Link to post
Share on other sites
pulpfist    528
No need to extract every byte like that unless you are writing a compiler or something.

You should be able to read and parse this file in less than 10 lines using idiomatic C++

I suggest you look into the global [url="http://www.cplusplus.com/reference/string/getline/"]getline[/url] function. This function can be used to read the file line by line.

Each line (that isn't empty) can be fed to a [url="http://www.dreamincode.net/forums/topic/95826-stringstream-tutorial/"][url="http://www.cplusplus.com/reference/iostream/stringstream/"]stringstream[/url][/url] object. This object will let you split a line into items, and convert them at the same time.
Just what you need.

Basically you extract the first item from the stringstream as a string, if that string is a 'v', you extract the next three items into some suitable variables, like floats. Conversion is implicit.

[url="http://www.cplusplus.com/doc/tutorial/basic_io/"]example[/url]

Share this post


Link to post
Share on other sites
dreamslayerx    114
[quote name='pulpfist' timestamp='1315145204' post='4857482']
No need to extract every byte like that unless you are writing a compiler or something.

You should be able to read and parse this file in less than 10 lines using idiomatic C++

I suggest you look into the global [url="http://www.cplusplus.com/reference/string/getline/"]getline[/url] function. This function can be used to read the file line by line.

Each line (that isn't empty) can be fed to a [url="http://www.cplusplus.com/reference/iostream/stringstream/"]stringstream[/url] object. This object will let you split a line into items, and convert them at the same time.
Just what you need.

Basically you extract the first item from the stringstream as a string, if that string is a 'v', you extract the next three items into some suitable variables, like floats. Conversion is implicit.

[url="http://www.cplusplus.com/doc/tutorial/basic_io/"]example[/url]
[/quote]


Ok I follow what you said thanks, but I am having an issue with it reading in spaces into the arrays. Any Idea on how to stop that or ignore spaces. Below is how the code looks. I have commented out alot of things, so those things can be ignored.

[/code]

[size="2"][color="#0000ff"][size="2"][color="#0000ff"]void[/color][/size][/color][/size][size="2"] readFile() [/size][size="2"][color="#008000"][size="2"][color="#008000"]//Working section Used to count the number of floats in a file. This section can make program slower.

[/color][/size][/color][/size][size="2"]{

ifstream inFile;

inFile.open([/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"cube.obj"[/color][/size][/color][/size][size="2"]);

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"] (!inFile.is_open())

{

cout << [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"Unable to open file"[/color][/size][/color][/size][size="2"]; [/size][size="2"][color="#008000"][size="2"][color="#008000"]///C:\Users\Alanzo Granville\Documents\Visual Studio 2008\Projects\Opening_A_File_Program\Opening_A_File_Program

[/color][/size][/color][/size][size="2"]exit(1); [/size][size="2"][color="#008000"][size="2"][color="#008000"]/// terminate with error

[/color][/size][/color][/size][size="2"]}

[/size][size="2"][color="#008000"][size="2"][color="#008000"]// inFile.peek() This will be the section where I peek into the file to see what is going to be read next;

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]int[/color][/size][/color][/size][size="2"] i =0;

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//here we want to read in 3 different types of values,

/* 1) Declare our stringstream as stringstream ss;

2) Use a getline command to to read the entire line

ex: inFile.getline(how many items to read, string object that extracted content is stored, stops when this char is read )

inFile.get(buff, bufferSize); //(We are using this one) This implies if buff is 6, 6 items will be read, and bufferSize will store those 6 items

into some char array

or

inFile.get(buff, bufferSize, ','); //Here is similar but the last char ',' tells the comman to stop reading when it reaches a ',' comma

4)Now we need to store what is read from getline into our string stream ss.

ex:

ss << buff;

//now a for loop or while loop can be written to make sure that we read all the data from ss



ss.getline(date read into ss, number of inputs, character to discard); //This states that

ex:

ss.getline(buff, 6, ','); //Here the data read in is buff and reads 6 times, and the delimitor or stop read point is the comma which

will be discarded. Reads 6 lines

5)Now convert input value that was read in from ss into the object that we want such as int, float, char, etc using atoi function from stdlib library

ex.

suppose the variable that we want to store it in is and array called store[rows][colums] wher rows is the number of rows and colums the number of columns

store[row][column] = atoi(buff); if buff is an int, now the string data will be changed into an int object, same goes for float or char

//atof(buff) changes the data into a float

6) Then before outter loop ends or while loop ends to start again input any character into ss to do the need formating if neccessary. Then clear ss.

ex.

ss<<" "; //puts space between each character read

// now to clear. Clearing ss allows for us to read the new data that is written

ex.

ss.clear();

and results can be read out by using store[row][column]

//We are going to manipulate

1) check to see if string is v, vt, or f;

2) create conditional statemes for each one for example:

example:



//Here we may have to make stringstream ss read until it reaches a space or getline read until it reaches a space

ex:

inFile.getline(float data type, ' '); //I may have to play around with this to get it working properly. Reads till it reachs a space

if (string == 'v')

{





}*/

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]char[/color][/size][/color][/size][size="2"] ch; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//buffer size

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//I need to find out why my arrays cann't take other variables

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]int[/color][/size][/color][/size][size="2"] gather=1000; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//buffer size

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]char[/color][/size][/color][/size][size="2"] buff[1000]; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//stating that the size of the buff array is equal to gather

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]float[/color][/size][/color][/size][size="2"] vertPoint[1000][5]; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//for verteices until I pass data to structs has to be global

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]float[/color][/size][/color][/size][size="2"] texPoint[1000][3];

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]int[/color][/size][/color][/size][size="2"] j=0;

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//Reading the first character of the file

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]while[/color][/size][/color][/size][size="2"](!inFile.eof())

{

inFile>>ch;

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//cout<<ch<<endl;

[/color][/size][/color][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](ch == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'v'[/color][/size][/color][/size][size="2"])

{

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//cout<<"You made it into the first if statment"<<endl;

[/color][/size][/color][/size][size="2"]inFile.getline(buff,[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]' '[/color][/size][/color][/size][size="2"]); [/size][size="2"][color="#008000"][size="2"][color="#008000"]//right now this sets our buff array variabler

[/color][/size][/color][/size][size="2"]cout<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"This is the buff array "[/color][/size][/color][/size][size="2"]<<buff<<endl;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"]( buff[0] == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]' '[/color][/size][/color][/size][size="2"]) [/size][size="2"][color="#008000"][size="2"][color="#008000"]//checks the first character read in by buff to see if we have a vertex, vertex texture, or triangle face

[/color][/size][/color][/size][size="2"]{

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//cout<<"You made it into the second if statement"<<endl;

[/color][/size][/color][/size][size="2"]ss<<buff; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//This reads the data into the stringstream ss

[/color][/size][/color][/size][size="2"]

vertPoint[j][i] = atof(buff); [/size][size="2"][color="#008000"][size="2"][color="#008000"]//stringstream data that is stored in ss is given to variable point as a floating point value

[/color][/size][/color][/size][size="2"]cout<<vertPoint[j][i]<<endl; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//line used to makes sure that I have proper output; It can be commented out

[/color][/size][/color][/size][size="2"]j++;

i=(i+1)%5; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//This will keep the i value between 0 to 2, while j increases with the number of vertices since it is

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//storing spaces into the array

[/color][/size][/color][/size][size="2"]

}

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//I'll fix this part after I finish with the above section with storing properly in an array

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"]( buff[0] == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'t'[/color][/size][/color][/size][size="2"]) [/size][size="2"][color="#008000"][size="2"][color="#008000"]//checks the first character read in by buff to see if we have a vertex, vertex texture, or triangle face

[/color][/size][/color][/size][size="2"]{

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](buff[0] = [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]' '[/color][/size][/color][/size][size="2"]);

{

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//I need to ignore the spaces readin by buff

[/color][/size][/color][/size][size="2"]

ss<<buff; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//This reads the data into the stringstream ss

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//Its not that it is reading spaces arrays are incremented like so i=1, j=1, then i=2, j=2

[/color][/size][/color][/size][size="2"]

texPoint[j][i]= atof(buff); [/size][size="2"][color="#008000"][size="2"][color="#008000"]//stringstream data that is stored in ss is given to variable point as a floating point value

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//cout<<texPoint[j][i]<<endl; //line used to makes sure that I have proper output; It can be commented out

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//j++;

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//i=(i+1)%3;

[/color][/size][/color][/size][size="2"]

}

}

}





}

[/size][size="2"][color="#008000"][size="2"][color="#008000"]/*for(i =0; i<2;i++)

{

for(j=0; j<14;j++)

{

cout<<texPoint[j][i]<<endl;

}

}*/

[/color][/size][/color][/size][size="2"]ss.getline(buff,[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]'\n'[/color][/size][/color][/size][size="2"]);

cout<<ss.str()<<endl;; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//allows me to see the entire string thats read in ouput to the screen

[/color][/size][/color][/size][size="2"]cout<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"Test Number "[/color][/size][/color][/size][size="2"]<<vertPoint[0][0]<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]' '[/color][/size][/color][/size][size="2"]<<vertPoint[2][2]<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]' '[/color][/size][/color][/size][size="2"]<< vertPoint[3][3]<<endl; [/size][size="2"][color="#008000"][size="2"][color="#008000"]//This is how my output is set up reads first line correctly

[/color][/size][/color][/size][size="2"]ss.clear(); [/size][size="2"][color="#008000"][size="2"][color="#008000"]//clears the stringstream ss

//inFile.getline(buff,2); //This read the entire line up to 1000 characters; it stops at the end of the line

[/color][/size][/color][/size][size="2"][/size][size="2"][color="#008000"][size="2"][color="#008000"]//unless the line contains more than 1000 characters.

//while(!inFile.eof())//for (int i =0; i<3; i++)

//{

/*if(buff == " #")

{

ss << buff; //This stores

ss.getline(buff,1,' ');

ss<<' ';

cout<< ss.str();//<<endl; //This prints out the data read into ss from buff.

ss.clear();

}*/

//}//end of while loop

//while(!inFile.eof())

// {

[/color][/size][/color][/size][size="2"]

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//}//end of while loop

[/color][/size][/color][/size][size="2"]}

[/size]

[/code]

[/output]
//output without all the wording
//just comment out the line of code where it says [size="2"]cout<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"This is the buff array "[/color][/size][/color][/size][size="2"]<<buff<<endl;


[/size]

1
1
-1
-1
1
0.999999
-1
-1
1.000000 -1.000000 -1.000000 1.000000 -1.000000 1.000000 -1.000000 -1.000000 1.
000000 -1.000000 -1.000000 -1.000000 1.000000 1.000000 -1.000000 0.999999 1.0000
00 1.000001 -1.000000 1.000000 1.000000 -1.000000 1.000000 -1.000000 0.666667 0
.000000 0.666667 0.333333 0.333334 0.333333 0.333333 0.000000 0.333333 1.000
000 0.333334 0.666667 0.666667 0.666667 0.666667 1.000000 0.333333 0.333333
0.333333 0.666667 0.000000 0.666667 0.000000 1.000000 0.000000 0.333333 0.0
00000 0.000000
Test Number 1 -1 -1

Press any key to continue . . .

[/output]

Share this post


Link to post
Share on other sites
latent    139
[quote name='dreamslayerx' timestamp='1315284485' post='4858061']
Ok I follow what you said thanks, but I am having an issue with it reading in spaces into the arrays. Any Idea on how to stop that or ignore spaces. Below is how the code looks. I have commented out alot of things, so those things can be ignored.
[/quote]

If you're just getting stuck on parsing a delimited string, a quick google search turns up lots of results, such as
* [url="http://www.cplusplus.com/forum/general/17771/"]http://www.cplusplus.com/forum/general/17771/[/url]
and if you want to use stringstream there's a few examples out there...

* [url="http://www.dreamincode.net/forums/topic/95826-stringstream-tutorial/"]http://www.dreamincode.net/forums/topic/95826-stringstream-tutorial/[/url]

Also, maybe it's just the formatting of your post, but a big function like that might only serve to confuse the matter more, especially when you come back to it later. Once you have a parsing function the process of reading the file should be very trivial and as pulpfist suggests, only take a few lines of code.




Share this post


Link to post
Share on other sites
pulpfist    528
Here is a small example of how you could get started parsing the file.
I have to admit, its going to be more than 10 lines lol.
Note that this example is far from finished.
[source lang="cpp"]
void readFile()
{
ifstream inFile("cube.obj"); // Create and open file
if (!inFile.is_open())
{
cout << "Unable to open file" << endl;
exit(1);
}

string line, item, lib;
float x, y, z;

while(getline(inFile, line)) // Continue to read the next line until the end of file
{
stringstream ss(line); // Create a new stringstream and fill it with the line
if(!(ss >> item)) // Extract the first item. If there is no items left, this expression will be false and we continue to read the next line.
continue;

if(item == "#")
continue; // We found a comment. Continue to read the next line.
else if(item == "v")
{
ss >> x >> y >> z; // Extract and convert the next three items from the stream
cout << "We found a v: " << x << " " << y << " " << z << endl;
}
else if(item == "vt")
{
ss >> x >> y; // Extract and convert the next two items from the stream
cout << "We found a vt: " << x << " " << y << endl;
}
else if(item == "mtllib")
{
ss >> lib; // Extract the next item from the stream
cout << "We found a mtllib: " << lib << endl;
}
// And so on...
}
}[/source]

Since an expression like this [i]ss >> x >> y >> z;[/i] returns false if there is less that three items left in the stream, we can take advantage of this to make the function a bit more robust:
[i]if(!(ss >> x >> y >> z)) // report error...[/i]

Also note that the expression [i]else if(item == "vt")[/i] is case sensitive, so it won't match a VT or a Vt.

Share this post


Link to post
Share on other sites
rip-off    10976
Don't keep a bunch of outdated comments in your file. Instead, use version control. This way you'll feel free to add or remove code as you like, you can always get it back the way you had it later.

The sheer number of comments is hiding things from you. For example, this line:
[code]
if(buff[0] = ' ');
{
// code...
}
[/code]
Note the semicolon after the if statement. This is treated as the following:
[code]
if(buff[0] = ' ')
{
// Nothing to do here!
}

// code...
[/code]
That is, your code is unconditionally executed.

Using fixed size buffers like you are doing is a recipe for failure - someone is either going to have a data file with lines longer than you expect, or more vertices than you catered for.

Using atof() makes it hard for you to test for failure - on failure it returns 0, which is a perfectly valid float!

Instead, use std::string and std::vector:
[code]

struct Vertex
{
float x;
float y;
float z;
};

struct TexPoint
{
float u;
float v;
};

// TODO: more sophisticated error reporting (e.g. build a vector of struct Error { int line, SomeErrorEnumeration errorType; })
bool parseLine(const std::string &line, std::vector<Vertex> &vertices, std::vector<TexPoint> &texturePoints)
{
if(line.empty())
{
return true;
}

std::stringstream stream(line);

char c;
if(!stream >> c)
{
return false;
}

if(c == '#')
{
return true;
}
else if(c == 'v')
{
if(stream.peek() == 't')
{
TexPoint texture;
if((stream >> texture.u >> texture.v) && (stream >> std::ws) && stream.eof())
{
texturePoints.push_back(texture);
return true;
}
// Failed to parse floats, or unexpected garbage at end of line
return false;
}
else
{
Vertex vertex;
if((stream >> vertex.x >> vertex.y >> vertex.z) && (stream >> std::ws) && stream.eof())
{
vertices.push_back(vertex);
return true;
}
// Failed to parse floats, or unexpected garbage at end of line
return false;
}
}
// Unhandled character
return false;
}

bool readFile(std::vector<Vertex> &vertices, std::vector<TexPoint> &texturePoints)
{
std::ifstream stream("cube.obj");

if(!stream.is_open())
{
// TODO: better error notification
cout << "Unable to open file";
return false;
}

std::string line;
while(std::getline(stream, line))
{
bool b = parseLine(line, vertices, texturePoints);
// TODO: test b...
}
return true;
}
[/code]
Something like that (it isn't tested).

Share this post


Link to post
Share on other sites
Aardvajk    13207
Just for future reference, from your first code, this doesn't work the way you think:

[code]
if(ch == 'v' || 't'||'f'||'/')
[/code]

In english, it means: if ch equals v or if t isn't zero or if f isn't zero or if / isn't zero. Since none of the latter three are zero, the condition will always be true.

[code]
if(ch == 'v' || ch == 't' || ch == 'f' || ch == '/')
[/code]

would be correct.

[code]
else if(c == 'v')
{
if(stream.peek() == 't')
{
TexPoint texture;
if((stream >> texture.u >> texture.v) && (stream >> std::ws) && stream.eof())
[/code]

Sorry if having a senior moment, ripoff, but would you not need to consume that 't' after the peek before reading the first number?

Share this post


Link to post
Share on other sites
dreamslayerx    114
[attachment=5280:Cube OBJ JPEG.jpg][quote name='pulpfist' timestamp='1315298445' post='4858098']
Here is a small example of how you could get started parsing the file.
I have to admit, its going to be more than 10 lines lol.
Note that this example is far from finished.
[source lang="cpp"]
void readFile()
{
ifstream inFile("cube.obj"); // Create and open file
if (!inFile.is_open())
{
cout << "Unable to open file" << endl;
exit(1);
}

string line, item, lib;
float x, y, z;

while(getline(inFile, line)) // Continue to read the next line until the end of file
{
stringstream ss(line); // Create a new stringstream and fill it with the line
if(!(ss >> item)) // Extract the first item. If there is no items left, this expression will be false and we continue to read the next line.
continue;

if(item == "#")
continue; // We found a comment. Continue to read the next line.
else if(item == "v")
{
ss >> x >> y >> z; // Extract and convert the next three items from the stream
cout << "We found a v: " << x << " " << y << " " << z << endl;
}
else if(item == "vt")
{
ss >> x >> y; // Extract and convert the next two items from the stream
cout << "We found a vt: " << x << " " << y << endl;
}
else if(item == "mtllib")
{
ss >> lib; // Extract the next item from the stream
cout << "We found a mtllib: " << lib << endl;
}
// And so on...
}
}[/source]

Since an expression like this [i]ss >> x >> y >> z;[/i] returns false if there is less that three items left in the stream, we can take advantage of this to make the function a bit more robust:
[i]if(!(ss >> x >> y >> z)) // report error...[/i]

Also note that the expression [i]else if(item == "vt")[/i] is case sensitive, so it won't match a VT or a Vt.
[/quote]

Nice and clear code. I was looking for a way to read things in clearly. I used your code and here is the output for the v and vt portion below. But the question is how do I handle reading in the face porition of the file. All I want is the integers values and not the / or the spaces. Here is the face porition:

usemtl Material_cube_Cube.bmp

s off

f 5/1 1/2 4/3

f 5/1 4/3 8/4

f 3/5 7/6 8/7

f 3/5 8/7 4/8

f 2/2 6/7 3/9

f 6/7 7/6 3/9

f 1/10 5/5 2/11

f 5/5 6/12 2/11

f 5/9 8/13 6/4

f 8/13 7/14 6/4

f 1/10 2/11 3/13

f 1/10 3/13 4/9


Sometimes faces can also be discrible as f 1/2/3 where 1 is the vertex number, 2 is the vertex texture number, and 3 is the vertex normal.


[/code]
[size="2"][color="#0000ff"][size="2"][color="#0000ff"]void[/color][/size][/color][/size][size="2"] readFile() [/size][size="2"][color="#008000"][size="2"][color="#008000"]//Working section Used to count the number of floats in a file. This section can make program slower.

[/color][/size][/color][/size][size="2"]{

ifstream inFile;

inFile.open([/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"cube.obj"[/color][/size][/color][/size][size="2"]);

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"] (!inFile.is_open())

{

cout << [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"Unable to open file"[/color][/size][/color][/size][size="2"]; [/size][size="2"][color="#008000"][size="2"][color="#008000"]///C:\Users\Alanzo Granville\Documents\Visual Studio 2008\Projects\Opening_A_File_Program\Opening_A_File_Program

[/color][/size][/color][/size][size="2"]exit(1); [/size][size="2"][color="#008000"][size="2"][color="#008000"]/// terminate with error

[/color][/size][/color][/size]}
[size="2"]string line, item, lib;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]float[/color][/size][/color][/size][size="2"] x,y,z;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]int[/color][/size][/color][/size][size="2"] v_Num, vt_Num, vn_Num;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]while[/color][/size][/color][/size][size="2"](getline(inFile, line))

{

stringstream ss(line);

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](!(ss>>item))

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]continue[/color][/size][/color][/size][size="2"];

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](item == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"#"[/color][/size][/color][/size][size="2"])

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]continue[/color][/size][/color][/size][size="2"];

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]else[/color][/size][/color][/size][size="2"] [/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](item == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"v"[/color][/size][/color][/size][size="2"])

{

ss>> x>> y >>z;

cout<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"We found a v: "[/color][/size][/color][/size][size="2"]<<x <<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]" "[/color][/size][/color][/size][size="2"]<<y<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]" "[/color][/size][/color][/size][size="2"]<<z<<endl;

}

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]else[/color][/size][/color][/size][size="2"] [/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](item == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"vt"[/color][/size][/color][/size][size="2"])

{

ss >> x >> y;

cout<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"We found a vt "[/color][/size][/color][/size][size="2"] <<x <<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]" "[/color][/size][/color][/size][size="2"]<<y<<endl;

}

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]else[/color][/size][/color][/size][size="2"] [/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](item == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"f"[/color][/size][/color][/size][size="2"]) [/size][size="2"][color="#008000"][size="2"][color="#008000"]//faces, Here we have to read character by character from file

[/color][/size][/color][/size][size="2"]{

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//Assuming I need a loop in the statment to finish reading the entire file



[/color][/size][/color][/size][size="2"]}

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]else[/color][/size][/color][/size][size="2"] [/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](item ==[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"mtllib"[/color][/size][/color][/size][size="2"])

{

ss>>lib;

cout<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"We found a mtllib :"[/color][/size][/color][/size][size="2"] <<lib<<endl;

}

}

}

[/size]
[/code]

[/output]

We found a mtllib :cube.mtl
We found a v: 1 -1 -1
We found a v: 1 -1 1
We found a v: -1 -1 1
We found a v: -1 -1 -1
We found a v: 1 1 -1
We found a v: 0.999999 1 1
We found a v: -1 1 1
We found a v: -1 1 -1
We found a vt 0.666667 0
We found a vt 0.666667 0.333333
We found a vt 0.333334 0.333333
We found a vt 0.333333 0
We found a vt 0.333333 1
We found a vt 0.333334 0.666667
We found a vt 0.666667 0.666667
We found a vt 0.666667 1
We found a vt 0.333333 0.333333
We found a vt 0.333333 0.666667
We found a vt 0 0.666667
We found a vt 0 1
We found a vt 0 0.333333
We found a vt 0 0

Press any key to continue . . .

[/output]

Share this post


Link to post
Share on other sites
dreamslayerx    114
Sorry for double posting, but here is something that I have got. Below is the code I wrote,but it doesn't satisfy the condition for normals since it will have two /'s instead of just one.

[/code]
[size="2"]

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]else[/color][/size][/color][/size][size="2"] [/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]if[/color][/size][/color][/size][size="2"](item == [/size][size="2"][color="#a31515"][size="2"][color="#a31515"]"f"[/color][/size][/color][/size][size="2"]) [/size][size="2"][color="#008000"][size="2"][color="#008000"]//faces, Here we have to read character by character from file

[/color][/size][/color][/size][size="2"]{

[/size][size="2"][color="#008000"][size="2"][color="#008000"]//Assuming I need a loop in the statment to finish reading the entire file

[/color][/size][/color][/size][size="2"]cout<<ss.str()<<endl;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]char[/color][/size][/color][/size][size="2"] ch;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]int[/color][/size][/color][/size][size="2"] v, vt;

[/size][size="2"][color="#0000ff"][size="2"][color="#0000ff"]for[/color][/size][/color][/size][size="2"](i=0;i<3;i++) [/size][size="2"][color="#008000"][size="2"][color="#008000"]//reads 3 faces

[/color][/size][/color][/size][size="2"]{

ss>> v>>ch>>vt;

cout<<v<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]" "[/color][/size][/color][/size][size="2"]<<ch<<[/size][size="2"][color="#a31515"][size="2"][color="#a31515"]" "[/color][/size][/color][/size][size="2"]<<vt<<endl;

}

[/size]
[/code]

[/output]

[size="2"]f 5/1 1/2 4/3 //This section of output is from the ss.str() function so that I can read the entire string to ensure the proper output
5 / 1 //These are the outputs which is int v =5, char ch = '/', int vt = 1 and the for loop makes it read 3 times
1 / 2
4 / 3
f 5/1 4/3 8/4
5 / 1
4 / 3
8 / 4
f 3/5 7/6 8/7
3 / 5
7 / 6
8 / 7
f 3/5 8/7 4/8
3 / 5
8 / 7
4 / 8
f 2/2 6/7 3/9
2 / 2
6 / 7
3 / 9
f 6/7 7/6 3/9
6 / 7
7 / 6
3 / 9
f 1/10 5/5 2/11
1 / 10
5 / 5
2 / 11
f 5/5 6/12 2/11
5 / 5
6 / 12
2 / 11
f 5/9 8/13 6/4
5 / 9
8 / 13
6 / 4
f 8/13 7/14 6/4
8 / 13
7 / 14
6 / 4
f 1/10 2/11 3/13
1 / 10
2 / 11
3 / 13
f 1/10 3/13 4/9
1 / 10
3 / 13
4 / 9[/size]

[size="2"]Press any key to continue . . .

[/size][/output]

Share this post


Link to post
Share on other sites
pulpfist    528
Well done [img]http://public.gamedev.net/public/style_emoticons/default/cool.gif[/img]

Here is a little twist I made that uses peek to find out if the vertex has a normal

[code]

char ch;
int v, vt, n;
for(int i = 0; i < 3; i++)
{
ss >> v >> ch >> vt;
cout << v << " " << ch << " " << vt;
if(ss.peek() == '/')
{
ss >> ch >> n;
cout << " " << ch << " " << n;
}
cout << endl;
}[/code]


I would also advice that you store the data in structs, and use the vector as arrays. You can see a good example of that in rip-off's post

Share this post


Link to post
Share on other sites
dreamslayerx    114
[quote name='Aardvajk' timestamp='1315331703' post='4858258']
Just for future reference, from your first code, this doesn't work the way you think:

[code]
if(ch == 'v' || 't'||'f'||'/')
[/code]

In english, it means: if ch equals v or if t isn't zero or if f isn't zero or if / isn't zero. Since none of the latter three are zero, the condition will always be true.

[code]
if(ch == 'v' || ch == 't' || ch == 'f' || ch == '/')
[/code]

would be correct.

[code]
else if(c == 'v')
{
if(stream.peek() == 't')
{
TexPoint texture;
if((stream >> texture.u >> texture.v) && (stream >> std::ws) && stream.eof())
[/code]

Sorry if having a senior moment, ripoff, but would you not need to consume that 't' after the peek before reading the first number?
[/quote]


Yeah I agree. I am planning on string the data into structs one being struct for vertices, vertex textures, and vertex normals. then the faces will be in a struct called triangles. Thanks guys. I'll show you the results when I display the image usng OpenGL.

Share this post


Link to post
Share on other sites
dreamslayerx    114
OK guys here is the final result. The program works great. I actually built a house model and textured it. The image may be a little off since I had it rotating to check each side. Thanks so much for the help.

[attachment=5386:HouseTextureWithUVs.jpg]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this