Archived

This topic is now archived and is closed to further replies.

cowsarenotevil

File loader

Recommended Posts

cowsarenotevil    3006
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[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 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 -~-The Cow of Darkness-~-

Share this post


Link to post
Share on other sites
cowsarenotevil    3006
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-~-

Share this post


Link to post
Share on other sites
SirHando    122
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]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
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;
}

Share this post


Link to post
Share on other sites
thasmin    122
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...

Share this post


Link to post
Share on other sites