By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,670 Members | 1,462 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,670 IT Pros & Developers. It's quick & easy.

Reading a file in OFF format

P: n/a
Hi,

I am not very familiar with C++ programming, so before I do a dirty hack I
ask for a more elegant solution (but only the usage of STL is allowed, no
special libs).
So I need to read a file in OFF format and store the values read in some
file format, I suppose in arrays of floats or ints would be meaningful:

My general idea:

- Open the file
- Read line 1 and check if OFF file
- Read line 2 and store values for Nv and Nf (how to tokenize that ?
searching for spaces ? is there sth. like a StringTokenizer in C++ ?)
- Read the vertex table (again: I would tokenize through searching for
strings -is there a more elegant approach ?)
- Read the faces (same question as above)

Thanks for your help !

---

The OFF format can be described as:

We use a very simple ASCII format for representing polygonal meshes. It
consists of a short header, a table of vertex coordinates, and a table of
polygons (all triangles) stored as indices into the vertex table.
a.. header
The header includes the number of vertices Nv, the number of faces
(triangles) Nf, and the number of edges which is assumed to be always 0,
i.e., there is only a vertex and a face table.
OFF
Nv Nf 0

b.. vertex table
The vertex table stored the geometry information. It contains Nv lines
with x y z coordinates for every vertex, i.e.
x[0] y[0] z[0]
...
x[Nv-1] y[Nv-1] z[Nv-1]

c.. table of faces/triangles
This table contains the connectivity information stored in Nf lines. Every
line describes a face/polygon, the first number denotes the number of
vertices, it is assumed to be always 3, i.e. the the meshes consist of
triangles only! Then the following 3 numbers are indices into the vertex
table (starting with index 0), i.e.
3 i0[0] i1[0] i2[0]
...
3 i0[Nf-1] i1[Nf-1] i2[Nf-1]


Jul 22 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a

"Alexander Schmidt" <no****@web.de> wrote in message
news:2l************@uni-berlin.de...
Hi,

I am not very familiar with C++ programming, so before I do a dirty hack I
ask for a more elegant solution (but only the usage of STL is allowed, no
special libs).
So I need to read a file in OFF format and store the values read in some
file format, I suppose in arrays of floats or ints would be meaningful:

My general idea:

- Open the file
- Read line 1 and check if OFF file
- Read line 2 and store values for Nv and Nf (how to tokenize that ?
searching for spaces ? is there sth. like a StringTokenizer in C++ ?)
- Read the vertex table (again: I would tokenize through searching for
strings -is there a more elegant approach ?)
- Read the faces (same question as above)

Thanks for your help !

---

The OFF format can be described as:

We use a very simple ASCII format for representing polygonal meshes. It
consists of a short header, a table of vertex coordinates, and a table of
polygons (all triangles) stored as indices into the vertex table.
a.. header
The header includes the number of vertices Nv, the number of faces
(triangles) Nf, and the number of edges which is assumed to be always 0,
i.e., there is only a vertex and a face table.
OFF
Nv Nf 0

b.. vertex table
The vertex table stored the geometry information. It contains Nv lines
with x y z coordinates for every vertex, i.e.
x[0] y[0] z[0]
...
x[Nv-1] y[Nv-1] z[Nv-1]

c.. table of faces/triangles
This table contains the connectivity information stored in Nf lines. Every line describes a face/polygon, the first number denotes the number of
vertices, it is assumed to be always 3, i.e. the the meshes consist of
triangles only! Then the following 3 numbers are indices into the vertex
table (starting with index 0), i.e.
3 i0[0] i1[0] i2[0]
...
3 i0[Nf-1] i1[Nf-1] i2[Nf-1]


This is my solution, if someone has comments how to improve, they're
welcome:

#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

// Global declarations
int RETURN_OK = 0;
int RETURN_ERROR = 1;

int nv, nf;

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

struct facade
{
int v1;
int v2;
int v3;
};

vertex *vertices;
facade *facades;

// Parser
void parse(string filename)
{
// Container holding last line read
string readLine;
// Containers for delimiter positions
int delimiterPos_1, delimiterPos_2, delimiterPos_3, delimiterPos_4;

// Open file for reading
ifstream in(filename.c_str());

// Check if file is in OFF format
getline(in,readLine);
if (readLine != "OFF")
{
cout << "The file to read is not in OFF format." << endl;
return;
}

// Read values for Nv and Nf
getline(in,readLine);
delimiterPos_1 = readLine.find(" ", 0);
nv = atoi(readLine.substr(0,delimiterPos_1+1).c_str());
delimiterPos_2 = readLine.find(" ", delimiterPos_1);
nf = atoi(readLine.substr(delimiterPos_1,delimiterPos_2 +1).c_str());

// Read the vertices
vertices = new vertex[nv];

for (int n=0; n<nv; n++)
{
getline(in,readLine);
delimiterPos_1 = readLine.find(" ", 0);
vertices[n].x = atof(readLine.substr(0,delimiterPos_1).c_str());
delimiterPos_2 = readLine.find(" ", delimiterPos_1+1);
vertices[n].y =
atof(readLine.substr(delimiterPos_1,delimiterPos_2 ).c_str());
delimiterPos_3 = readLine.find(" ", delimiterPos_2+1);
vertices[n].z =
atof(readLine.substr(delimiterPos_2,delimiterPos_3 ).c_str());

cout << vertices[n].x << "\t" << vertices[n].y << "\t" <<
vertices[n].z << "\t" << endl;
}

// Read the facades
facades = new facade[nf];

for (int n=0; n<nf; n++)
{
getline(in,readLine);
delimiterPos_1 = readLine.find(" ", 0);
delimiterPos_2 = readLine.find(" ", delimiterPos_1+1);
facades[n].v1 =
atoi(readLine.substr(delimiterPos_1,delimiterPos_2 ).c_str());
delimiterPos_3 = readLine.find(" ", delimiterPos_2+1);
facades[n].v2 =
atoi(readLine.substr(delimiterPos_2,delimiterPos_3 ).c_str());
delimiterPos_4 = readLine.find(" ", delimiterPos_3+1);
facades[n].v3 =
atoi(readLine.substr(delimiterPos_3,delimiterPos_4 ).c_str());

cout << facades[n].v1 << "\t" << facades[n].v2 << "\t" <<
facades[n].v3 << "\t" << endl;
}
}
// Main
int main(int argc, char *argv[])
{
// Check input
if (argc != 2)
{
cout << "You have entered an incorrect number of command line
parameters. See README and try again." << endl;
return RETURN_ERROR;
}

// Read the filename
string filename = argv[1];

// Parse the file
parse(filename);

return RETURN_OK;
}
Jul 22 '05 #2

P: n/a
* Alexander Schmidt wrote:

"Alexander Schmidt" <no****@web.de> wrote in message
news:2l************@uni-berlin.de...
Hi,

I am not very familiar with C++ programming, so before I do a dirty hack I
ask for a more elegant solution (but only the usage of STL is allowed, no
special libs).
I guess this is some kind of homework?
So I need to read a file in OFF format and store the values read in some
file format, I suppose in arrays of floats or ints would be meaningful:

My general idea:

- Open the file
- Read line 1 and check if OFF file
- Read line 2 and store values for Nv and Nf (how to tokenize that ?
searching for spaces ? is there sth. like a StringTokenizer in C++ ?)

The iostreams support formatted input. There is also an istringstream
which should do what you want, but you can just read in the tokens one
by one:
in >> lineRead >> nv >> nf ...

Some advice:
- Use C++ as C++ and not a better C. In particular: learn to use
classes.
- Try to avoid using new wherever possible. In your example you really
don't need more than one instance of vertex and facade. In a more
complex situation, you would, but then you could use the
vector template class from the stl.
- Don't write using namespace std;. The std namespace will probably
include new names in future revisions of C++.
- Always check input from sources you don't control.
- Don't create objects before you need them. This usually makes the
variable type apparent to a reader.
- Read books.
This is my solution, if someone has comments how to improve, they're
welcome:

#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;

// Global declarations
int RETURN_OK = 0;
int RETURN_ERROR = 1;
You should use EXIT_SUCCESS and EXIT_FAILURE instead of these.

int nv, nf;

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

struct facade
{
int v1;
int v2;
int v3;
};

vertex *vertices;
facade *facades;

// Parser
void parse(string filename)
{
// Container holding last line read
string readLine;
// Containers for delimiter positions
int delimiterPos_1, delimiterPos_2, delimiterPos_3, delimiterPos_4;

// Open file for reading
ifstream in(filename.c_str());

// Check if file is in OFF format
getline(in,readLine);
if (readLine != "OFF")
{
cout << "The file to read is not in OFF format." << endl;
return;
}

// Read values for Nv and Nf
getline(in,readLine); /* delimiterPos_1 = readLine.find(" ", 0);
nv = atoi(readLine.substr(0,delimiterPos_1+1).c_str());
delimiterPos_2 = readLine.find(" ", delimiterPos_1);
nf = atoi(readLine.substr(delimiterPos_1,delimiterPos_2 +1).c_str()); */
istringstream tokenizer(readLine);
tokenizer >> nv >> nf;
// Read the vertices
vertices = new vertex[nv];

for (int n=0; n<nv; n++)
{
getline(in,readLine);
tokenizer.str(readLine);
tokenizer >> ...
delimiterPos_1 = readLine.find(" ", 0);
vertices[n].x = atof(readLine.substr(0,delimiterPos_1).c_str());
delimiterPos_2 = readLine.find(" ", delimiterPos_1+1);
vertices[n].y =
atof(readLine.substr(delimiterPos_1,delimiterPos_2 ).c_str());
delimiterPos_3 = readLine.find(" ", delimiterPos_2+1);
vertices[n].z =
atof(readLine.substr(delimiterPos_2,delimiterPos_3 ).c_str());

cout << vertices[n].x << "\t" << vertices[n].y << "\t" <<
vertices[n].z << "\t" << endl;
}

// Read the facades
facades = new facade[nf];

for (int n=0; n<nf; n++)
{
getline(in,readLine);
delimiterPos_1 = readLine.find(" ", 0);
delimiterPos_2 = readLine.find(" ", delimiterPos_1+1);
facades[n].v1 =
atoi(readLine.substr(delimiterPos_1,delimiterPos_2 ).c_str());
delimiterPos_3 = readLine.find(" ", delimiterPos_2+1);
facades[n].v2 =
atoi(readLine.substr(delimiterPos_2,delimiterPos_3 ).c_str());
delimiterPos_4 = readLine.find(" ", delimiterPos_3+1);
facades[n].v3 =
atoi(readLine.substr(delimiterPos_3,delimiterPos_4 ).c_str());

cout << facades[n].v1 << "\t" << facades[n].v2 << "\t" <<
facades[n].v3 << "\t" << endl;
}
delete [] vertices;
delete [] facades;
}


--
Robert Bauck Hamar
Jul 22 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.