File loader

Started by
4 comments, last by cowsarenotevil 21 years, 1 month ago
I don''t get errors when I compile this...but it doesn''t work the way I want(in fact it doesn''t work at all...). Here''s the general file format any help is greatly appreciated. It is a wavefront obj exported from milkshape... there are so many different types of this format, I wanted to load this myself. //////////////////////// words that are unimportant v float1 float2 float3 vt float1 float2 vn float1 float2 float3 f float1/float2/float3 float1/float2/float3 float1/float2/float3 //////////////////////// #include <iostream.h> #include <fstream> #include <string.h> #include <vector> using namespace std; #define FILENAME "bessie.obj" struct data { float x, y, z; }; int main() { ifstream infile; infile.open(FILENAME, ios::in); char *character = ""; char *temp = ""; vector data(0); for (int i=0; !infile.eof(); i++) { infile.get(character,255,'' ''); if (strcmp(character,"v") == 0) { // load in whatever "v" is data.resize(i+1); infile >> data.x >> data.y >> data.z; } else if (strcmp(character,"vt") == 0) { // load in whatever "vt" is data.resize(i+1); infile >> data.x >> data.y; } else if (strcmp(character,"vn") == 0) { // load in whatever "vn" is data.resize(i+1); infile >> data.x >> data.y >> data.z; } else if (strcmp(character,"f") == 0) { // load in whatever "f" is data.resize(i+3); for (int a=1; a<=3; a++) { infile.get(temp,''/''); data[a+i].x = atof(temp); infile.get(temp,''/''); data[a+i].y = atof(temp); infile.get(temp,'' '' ''\n''); data[a+i].z = atof(temp); } } } infile.close(); for (int j=0; j<data.capacity(); j++) { cout << data[j].x << "," << data[j].y << "," << data[j].z << endl; } return 0; } </i> -~-The Cow of Darkness-~-
-~-The Cow of Darkness-~-
Advertisement
I can''t respond to this... keeps losing the server...agian:


  #include <iostream.h>#include <fstream>#include <string.h>#include <vector>using namespace std;#define FILENAME "bessie.obj"struct data{	float x, y, z;};int main(){	ifstream infile;	infile.open(FILENAME, ios::in);	char *character;	char *temp;	vector<data> data(0);	for (int i=0; !infile.eof(); i++)	{		infile.get(character, '' '');		if (strcmp(character,"v") == 0)		{	// load in whatever "v" is			data.resize(i+1);			infile >> data[i].x >> data[i].y >> data[i].z;		} else if (strcmp(character,"vt") == 0)		{	// load in whatever "vt" is			data.resize(i+1);			infile >> data[i].x >> data[i].y;		} else if (strcmp(character,"vn") == 0)		{	// load in whatever "vn" is			data.resize(i+1);			infile >> data[i].x >> data[i].y >> data[i].z;		} else if (strcmp(character,"f") == 0)		{	// load in whatever "f" is			for (int a=1; a<=3; a++)			{				infile.get(temp,''/'');				data[a+i].x = atof(temp);				infile.get(temp,''/'');				data[a+i].y = atof(temp);				infile.get(temp,''/'');				data[a+i].z = atof(temp);			}		}	}	infile.close();	for (int j=0; j<data.capacity(); j++)	{		cout << data[j].x << "," << data[j].y << "," << data[j].z << endl;	}	return 0;}  


-~-The Cow of Darkness-~-
-~-The Cow of Darkness-~-
I don't know what compiler you are trying to use here, but I can't see how you expect this to work.

Calls to stream get methods require you to supply a buffer for it to put the data into. You are passing it an unitialised char pointer. I assume that this either seg faults or raises an exception os something similar.

I do not know the file format, so I can not really comment on the validity of the parser you have here.

You should at least so something like....

const int BUFFER_SIZE = 255;
char character[BUFFER_SIZE];
char temp[BUFFER_SIZE];

infile.get(&character, BUFFER_SIZE, ' '); // Make sure not to overflow the buffer.

Ciao

[edited by - SirHando on March 6, 2003 8:14:04 AM]
Learn STL better before trying to use it. Calling capacity() is wrong - should be size(). And you should use push_back() instead of resize() all the time. Here''s a rewritten version. Try to read each line and take note of the changes I''ve made


  #include <iostream>#include <fstream>#include <string>#include <sstream>#include <vector>using namespace std;struct Data {	float x, y, z;};int main() {	//no need to use ios::in	ifstream fin("bessie.obj");	//test if stream opened correctly	if (!fin)		return 1;	//use a stringbuf to read data. It can''t overflow.	stringbuf input;	vector<Data> datas;	while (!fin.eof()) {		fin.get(input, '' '');		//this is the C++ way to compare strings. Doesn''t		//work for char*		if (input.str() == "v") {			// load in whatever "v" is			Data n;			fin >> n.x >> n.y >> n.z;			datas.push_back(n);		} else if (input.str() == "vt") {			// load in whatever "vt" is			Data n;			fin >> n.x >> n.y;			datas.push_back(n);		} else if (input.str() == "vn") {			// load in whatever "vn" is			Data n;			fin >> n.x >> n.y >> n.z;			datas.push_back(n);		} else if (input.str() == "f") {			// load in whatever "f" is			Data n;			stringstream s;			for (int a=0; a<3; a++) {				fin.get(input, ''/'');				//c++ way to convert to float:				s << input.str();				s >> n.x;				fin.get(input, ''/'');				s << input.str();				s >> n.y;				fin.get(input, ''/'');				s << input.str();				s >> n.z;				datas.push_back(n);			}		}	}	//note datas.size(), not datas.capacity()	for (size_t j=0; j<datas.size(); j++)		cout << datas[j].x << "," << datas[j].y << "," << datas[j].z << endl;}  
You have the format wrong. For the faces, it''s integers not floats:

f int/int/int int/int/int int/int/int

Since you''re exporting from Milkshape this isn''t a problem, but there''s 3 ints per face is only when you''re specifying vertex/texcoord/normal. One or two ints is also valid. More than three vertices is also valid and it''s rendered like a triangle fan (I believe). Faces includes vertex 1,2,3, then 1,3,4, then 1,4,5...
I''m extremely bad at file loading, and it really shows... I tried anonymous poster''s code, and it just hung and I got a white box saying I had no resources...

-~-The Cow of Darkness-~-
-~-The Cow of Darkness-~-

This topic is closed to new replies.

Advertisement