How Can I Import Values from OBJ file to My C++ Program?

Hello Professionals,

I have been working with a file that generates the polygons of a certain OBJ file. (in this case, a dodecahedron). I successfully did this by "manually" transferring the values from the dodecahedron.obj file which can be seen as well from this site:

https://people.sc.fsu.edu/~jburkardt/data/obj/dodecahedron.obj

As you can see here there are vertices and faces which are abbreviated as "v" and "f".

Moreover, here's my program that generates dodecahedron 3D shape via OpenGL.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#include <GL/glut.h>

void mouseCB(int button, int stat, int x, int y);
void mouseMotionCB(int x, int y);

bool mouseLeftDown;
bool mouseRightDown;
float mouseX, mouseY;
float cameraAngleX = 0;
float cameraAngleY = 0;
float cameraDistance;
bool dlUsed;


GLdouble vertex[][3] = { //Manually copied from Dodecahedron.obj file
	{-0.57735,-0.57735, 0.57735},
	{0.934172,  0.356822,  0},
	{0.934172, -0.356822,  0},
	{-0.934172,  0.356822,  0},
	{-0.934172, -0.356822,  0},
	{0, 0.934172,  0.356822},
	{0,0.934172, -0.356822},
	{0.356822,  0, -0.934172},
	{-0.356822,  0, -0.934172},
	{0,-0.934172, -0.356822},
	{0,-0.934172,  0.356822},
	{0.356822,  0,  0.934172},
	{-0.356822,  0, 0.934172},
	{0.57735,  0.57735, -0.57735},
	{0.57735,  0.57735,  0.57735},
	{-0.57735,  0.57735, -0.57735},
	{-0.57735,  0.57735,  0.57735},
	{0.57735, -0.57735, -0.57735},
	{0.57735, -0.57735,  0.57735},
	{-0.57735, -0.57735, -0.57735}
};

int face[][4] = { //Manually copied from Dodecahedron.obj file but subtracted 1 to each
	{18,  2,  1}, //values because of index concerns...
	{11,  18,1},
	{14,11,  1},
	{ 7,  13,  1 },
	{17,  7,  1 },
	{2, 17,  1 },
	{  19,  4,  3},
	{  8,  19,  3},
	{  15,  8,  3},
	{  12,  16,  3},
	{  0,  12,  3},
	{  4,  0,  3},
	{  6,  15,  3},
	{  5,  6,  3},
	{  16,  5,  3},
	{  5,  14,  1},
	{  6,  5,  1},
	{  13,  6,  1},
	{  9,  17,  2},
	{  10,  9,  2},
	{  18,  10,  2},
	{  10,  0,  4},
	{  9,  10,  4},
	{  19,  9,  4},
	{  19,  8,  7},
	{  9,  19,  7},
	{  17,  9,  7},
	{  8,  15,  6},
	{  7,  8,  6},
	{  13,  7,  6},
	{  11,  14,  5},
	{  12,  11,  5},
	{  16,  12,  5},
	{  12,  0,  10},
	{  11,  12, 10},
	{  18,  11,  10}

};

void idle()
{
	glutPostRedisplay();
}






void display(void)
{
	int i;
	int j;
	//static int r = 0; /*rotation angle */

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	glLoadIdentity();

	/*Viewpoint position and line of sight direction */
	gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

	/*Rotation of figure */
	//glRotated((double)r, 0.0, 1.0, 0.0);

	//insert from teapot
	// tramsform camera ; this helps to activate the the mouseCB and mouseMotionCB :) 
	glTranslatef(0, 0, cameraDistance);
	glRotatef(cameraAngleX, 1, 0, 0);   // pitch
	glRotatef(cameraAngleY, 0, 1, 0);   // heading
	//

	/*Drawing figures */
	glColor3d(0.0, 1.0, 0.0);
	glBegin(GL_TRIANGLES); //originial GL_QUADS
	for (j = 0; j <36; ++j) { //original j<6
		for (i = 0; i <3; ++i) { //original i<4
			glVertex3dv(vertex[face[j][i]]);
		}
	}
	glEnd();
	glColor3f(1.0, 0.0, 0.0);
	glBegin(GL_LINE_LOOP);
	for (j = 0; j <36; ++j) { //original j<6
		for (i = 0; i <3; ++i) { //original i<4
			glVertex3dv(vertex[face[j][i]]);
		}
	}
	glEnd();
	


	glutSwapBuffers();

	/*Return the rotation angle to 0 when turning around */
	//if (++r >= 360) r = 0;
}

void resize(int w, int h)
{
	glViewport(0, 0, w, h);

	/*Setting perspective transformation matrix */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);

	/*Model view transformation matrix setting */
	glMatrixMode(GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
	switch (key) {
	case 'q':
	case 'Q':
	case '\033': /*'\ 033' is the ASCII code of ESC */
		exit(0);
	default:
		break;
	}
}
void init(void)
{
	glClearColor(1.0, 1.0, 1.0, 1.0);
}
void mouseCB(int button, int state, int x, int y)
{
	mouseX = x;
	mouseY = y;

	if (button == GLUT_LEFT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
			mouseLeftDown = true;
		}
		else if (state == GLUT_UP)
			mouseLeftDown = false;
	}

	else if (button == GLUT_RIGHT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
			mouseRightDown = true;
		}
		else if (state == GLUT_UP)
			mouseRightDown = false;
	}
}


void mouseMotionCB(int x, int y)
{
	if (mouseLeftDown)
	{
		cameraAngleY += (x - mouseX);
		cameraAngleX += (y - mouseY);
		mouseX = x;
		mouseY = y;
	}
	if (mouseRightDown)
	{
		cameraDistance += (y - mouseY) * 0.2f;
		mouseY = y;
	}

	glutPostRedisplay();
}

///////////////////////////////////////////////////////////////////////////////
// initialize global variables
///////////////////////////////////////////////////////////////////////////////
bool initSharedMem()
{
	mouseLeftDown = mouseRightDown = false;
	dlUsed = true;

	return true;
}


int main(int argc, char * argv[])
{
	initSharedMem();
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE|GLUT_DEPTH);
	glutInitWindowSize(1000, 1000);
	glutInitWindowPosition(100, 100);
	glutCreateWindow(argv[0]);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);
	glEnable(GL_DEPTH_TEST);
	glutDisplayFunc(display);
	glutReshapeFunc(resize);
	glutKeyboardFunc(keyboard);
	glutMouseFunc(mouseCB);
	glutMotionFunc(mouseMotionCB);
	init();
	glutMainLoop();
	return 0;
}


I am wondering how can I effectively use the "fstream" library in order to transfer the values from dodecahedron.obj to C++ so my program can read the values without manually typing them in my program one by one? I just realized typing manually the values as shown from lines 16-35 (for vertex) and lines 39-74 (for faces) is really prone to error.. :(

P.S. I also manually typed the commas, spaces, brackets into my program in order to be fed to my for loops. :(
Last edited on
can I effectively use the "fstream" library
Yes, for instance:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::string line;
while(getline(fin, line))
{
  std::stringstream ss{line};
  char ch;
  ss >> ch;
  switch(ch)
  {
    case 'v':
      ... // further reading with ss
    break;
    case 'f':
      ... // further reading with ss
    break;
  }
}
You can also generate the vertices and face-vertex lists in-situ.

I don't know whether OpenGl can use pentagons as well as triangles, but the following will supply both.

There are quicker ways of getting the dodecahedron vertices (see Wikipedia), but it is quite hard to assemble the faces that way.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;


const double PI = 3.141592653589793;
const int NVERT = 20, NFACE = 12;   // For a dodecahedron


//================================================


struct Pt{ double x, y, z; };

Pt operator +( Pt p, Pt q ) { return { p.x + q.x, p.y + q.y, p.z + q.z }; }
Pt operator -( Pt p, Pt q ) { return { p.x - q.x, p.y - q.y, p.z - q.z }; }
Pt operator *( double r, Pt p ) { return { r * p.x, r * p.y, r * p.z }; }
double dot( Pt p, Pt q ) { return p.x * q.x + p.y * q.y + p.z * q.z; }
double abs( Pt p ) { return sqrt( dot( p, p ) ); }
Pt cross( Pt p, Pt q ) { return { p.y * q.z - p.z * q.y, p.z * q.x - p.x * q.z, p.x * q.y - p.y * q.x }; }


//================================================


Pt rotX( Pt p, double angle )       // Rotate about x axis
{
   double c = cos( angle ), s = sin( angle );
   return { p.x, p.y * c - p.z * s, p.y * s + p.z * c };
}


//================================================


Pt rotZ( Pt p, double angle )       // Rotate about z axis
{
   double c = cos( angle ), s = sin( angle );
   return { p.x * c - p.y * s, p.x * s + p.y * c, p.z };
}


//================================================


Pt reflectInPlane( Pt p, Pt norm, Pt ref )    // Reflect in plane defined by normal vector and reference point
{
   norm = ( 1.0 / abs( norm ) ) * norm;       // Make unit normal
   return { p - 2.0 * dot( p - ref, norm ) * norm };
}


//================================================


void dodecahedron( Pt vertex[], int pentagon[][5], int triangle[][3] )
{
   double L = 4.0 / ( sqrt( 3.0 ) * ( 1.0 + sqrt( 5.0 ) ) );     // Length of side
   double d = 0.5 * L / sin( 0.2 * PI );                         // Circumradius of pentagonal face
   double ztop = sqrt( 1.0 - d * d );                            // z coordinate of flat top

   // Initially, dodecahedron with horizontal top, two rows of side pentagons, horizontal bottom
   // VERTICES: find a reference vertex in each of 4 tiers (z levels), then rotate in increments of 2 pi / 5
   vertex[0] = { 0, -d, ztop };
   for ( int i = 1; i <= 4; i++ ) vertex[i] = rotZ( vertex[0], 0.4 * PI * i );
   vertex[5] = rotX( vertex[0], 2.0 * asin( 0.5 * L ) );
   vertex[10] = reflectInPlane( vertex[1], vertex[0] - vertex[5], 0.5 * ( vertex[0] + vertex[5] ) );
   vertex[15] = { vertex[2].x, -vertex[2].y, -vertex[2].z };
   for ( int t = 1; t < 4; t++ )
   {
      for ( int i = 1; i <= 4; i++ ) vertex[5*t+i] = rotZ( vertex[5*t], 0.4 * PI * i );
   }

   // If required (purely optional) rotate to the same vertices as the original
   double angle = atan( d * cos( 0.2 * PI ) / ztop );
   for ( int v = 0; v < NVERT; v++ ) vertex[v] = rotX( vertex[v], angle );


   // PENTAGONS (list of vertices; ANTICLOCKWISE when seen from OUTSIDE)
   int p = 0;
   for ( int i = 0; i < 5; i++ ) pentagon[p][i] = i;
   for ( p = 1; p <= 5; p++ )
   {
      int off1 = (p-1)%5;
      int off2 =  p   %5;
      pentagon[p][0] =      off1;
      pentagon[p][1] =  5 + off1;
      pentagon[p][2] = 10 + off1;
      pentagon[p][3] =  5 + off2;
      pentagon[p][4] =      off2;
   }
   for ( p = 6; p <= 10; p++ )
   {
      int off1 = (p-6)%5;
      int off2 = (p-2)%5;
      pentagon[p][0] =  5 + off1;
      pentagon[p][1] = 10 + off2;
      pentagon[p][2] = 15 + off2;
      pentagon[p][3] = 15 + off1;
      pentagon[p][4] = 10 + off1;
   }
   p = 11;
   for ( int i = 0; i < 5; i++ ) pentagon[p][i] = 19 - i;


   // TRIANGLES (split each pentagon into 3 triangles; bit arbitary!
   int vert[3][3] = { { 4, 0, 3 }, { 0, 1, 3 }, { 1, 2, 3 } };       // How the pentagon is split into triangles
   for ( p = 0; p < NFACE; p++ )
   {
      for ( int t = 0; t < 3; t++ )                                                     // Triangle loop
      {
         for ( int v = 0; v < 3; v++ ) triangle[3*p+t][v] = pentagon[p][vert[t][v]];    // Vertex-of-triangle loop
      }
   }
}


//================================================


void output( Pt vertex[], int pentagon[][5], int triangle[][3] )
{
   #define SF << fixed << setprecision( 6 ) << setw( 10 ) <<
   #define SI << setw( 2 ) <<

   cout << "VERTICES:\n";
   for ( int v = 0; v < NVERT; v++ ) cout SF vertex[v].x << ", " SF vertex[v].y << ", " SF vertex[v].z << '\n';

   cout << "\nPENTAGONS:\n";
   for ( int p = 0; p < NFACE; p++ ) 
   {
      for ( int i = 0; i < 5; i++ ) cout SI pentagon[p][i] << " ";
      cout << '\n';
   }

   cout << "\nTRIANGLES:\n";
   for ( int t = 0; t < 3 * NFACE; t++ )
   {
      for ( int i = 0; i < 3; i++ ) cout SI triangle[t][i] << " ";
      cout << '\n';
   }
}


//================================================


int main()
{
   Pt vertex[NVERT];
   int pentagon[NFACE][5], triangle[3*NFACE][3];

   dodecahedron( vertex, pentagon, triangle );
   output( vertex, pentagon, triangle );
}

//================================================ 

VERTICES:
  0.000000,  -0.934172,   0.356822
  0.577350,  -0.577350,   0.577350
  0.356822,  -0.000000,   0.934172
 -0.356822,   0.000000,   0.934172
 -0.577350,  -0.577350,   0.577350
  0.000000,  -0.934172,  -0.356822
  0.934172,  -0.356822,  -0.000000
  0.577350,   0.577350,   0.577350
 -0.577350,   0.577350,   0.577350
 -0.934172,  -0.356822,   0.000000
  0.577350,  -0.577350,  -0.577350
  0.934172,   0.356822,  -0.000000
  0.000000,   0.934172,   0.356822
 -0.934172,   0.356822,   0.000000
 -0.577350,  -0.577350,  -0.577350
  0.356822,   0.000000,  -0.934172
  0.577350,   0.577350,  -0.577350
 -0.000000,   0.934172,  -0.356822
 -0.577350,   0.577350,  -0.577350
 -0.356822,   0.000000,  -0.934172

PENTAGONS:
 0  1  2  3  4 
 0  5 10  6  1 
 1  6 11  7  2 
 2  7 12  8  3 
 3  8 13  9  4 
 4  9 14  5  0 
 5 14 19 15 10 
 6 10 15 16 11 
 7 11 16 17 12 
 8 12 17 18 13 
 9 13 18 19 14 
19 18 17 16 15 

TRIANGLES:
 4  0  3 
 0  1  3 
 1  2  3 
 1  0  6 
 0  5  6 
 5 10  6 
 2  1  7 
 1  6  7 
 6 11  7 
 3  2  8 
 2  7  8 
 7 12  8 
 4  3  9 
 3  8  9 
 8 13  9 
 0  4  5 
 4  9  5 
 9 14  5 
10  5 15 
 5 14 15 
14 19 15 
11  6 16 
 6 10 16 
10 15 16 
12  7 17 
 7 11 17 
11 16 17 
13  8 18 
 8 12 18 
12 17 18 
14  9 19 
 9 13 19 
13 18 19 
15 19 16 
19 18 16 
18 17 16 

Last edited on
Thank you for your insights @coder777 and @lastchance.
I wonder what if the values of OBJ files are like this?

"f 932//932 931//931 930//930
f 933//933 932//932 930//930
f 934//934 932//932 933//933
f 935//935 934//934 933//933
f 936//936 934//934 935//935
......"

How will this program interpret the "//" between the numbers?
Regarding your program @lastchance, are the values in this line code manually input from user?

const int NVERT = 20, NFACE = 12;
Last edited on
NVERT and NFACE are global constants - the number of vertices and faces of a dodecahedron. They are used to size my arrays, so if I were to input them at run time then I would have to use dynamic arrays or vectors. Since all dodecahedra have that number of vertices and faces, and because I need them in several functions, I have made them global constants.

I'm not sure that I follow your previous question. If confronted with something like that I would just cut and paste into an editor and globally change all / to blanks. If you absolutely needed to do it in code then you could read each line into a string, change any / to a blank space, then stringstream the resulting line into the char and ints that you wanted. It seems a bit of an inefficient file format with every integer repeated.
Last edited on
I am having problems with these "Faces" values of OBJ files. Because sometimes, the values are only single integers like the ones in dodecahedron.obj

"f 19 3 2
f 12 19 2
f 15 12 2
f 8 14 2
..."

However, there are OBJ files that have the format like this:

"f 5/1/1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2
f 3/5/2 8/7/2 4/8/2
..."

Sometimes they have "/" or "//" per value. According to this website:
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-7-model-loading/

For example, if we are going to understand the "5/1/1", 5 means the vertex array, the next 1 is texture coordinate, and the next 1 is for normals. I find it difficult for me because, in this example, I actually don't wanna use the texture and normal values. I only want to use the vertex array (like the ones we were talking before). Is it possible to just import these values? In the recent example, is it possible to take only "5 1 4", "5 4 8", "3 7 8", "3 8 4", ...etc.?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

struct Point{ double x, y, z; };       // Spatial coordinates

struct Triangle{ int i, j, k; };       // Vertex numbers for a triangle

//======================================================================


void getFacesAndVertices( string filename, vector<Point> &vertices, vector<Triangle> &faces )
{
   faces.clear();   vertices.clear();                      // comment out to add to an existing collection

   string line;
   char c;
   int i, j, k;
   double x, y, z;
   string si, sj, sk;

   ifstream in( filename );
   while ( getline( in, line ) )                           // read whole line
   {
      if ( line.find_first_of( "vVfF" ) == string::npos ) continue;     // skip pointless lines

      istringstream ss( line );                            // put line into a stream for input
      ss >> c;                                             // get first character
      switch ( c )
      {
         case 'v':                                         // VERTICES
         case 'V':                                         //    (either case)
            ss >> x >> y >> z;                             // read from internal stream
            vertices.push_back( { x, y, z } );             // add to vector
            break;

         case 'f':                                         // FACES
         case 'F':                                         //    (either case)
            ss >> si >> sj >> sk;                          // FIRST, read into individual strings
            i = stoi(si);  j = stoi(sj);  k = stoi( sk );  // Get the FIRST integer from each string
            faces.push_back( { i, j, k } );                // add to vector
            break;
      }
   }
   in.close();
}


//======================================================================

int main()
{
   vector<Point> vertices;
   vector<Triangle> faces;
   string filename = "file.OBJ";

   getFacesAndVertices( filename, vertices, faces );

   cout << "Vertices:\n";
   for ( Point p : vertices ) cout << p.x << "  " << p.y << "  " << p.z << '\n';

   cout << "\n\n";

   cout << "Triangles\n";
   for ( Triangle t : faces ) cout << t.i << "  " << t.j << "  " << t.k << '\n';
}


file.OBJ: (see the variants at the end of this file)
# OBJ file created by ply_to_obj.c
#
g Object001

v  -0.57735  -0.57735  0.57735
v  0.934172  0.356822  0
v  0.934172  -0.356822  0
v  -0.934172  0.356822  0
v  -0.934172  -0.356822  0
v  0  0.934172  0.356822
v  0  0.934172  -0.356822
v  0.356822  0  -0.934172
v  -0.356822  0  -0.934172
v  0  -0.934172  -0.356822
v  0  -0.934172  0.356822
v  0.356822  0  0.934172
v  -0.356822  0  0.934172
v  0.57735  0.57735  -0.57735
v  0.57735  0.57735  0.57735
v  -0.57735  0.57735  -0.57735
v  -0.57735  0.57735  0.57735
v  0.57735  -0.57735  -0.57735
v  0.57735  -0.57735  0.57735
v  -0.57735  -0.57735  -0.57735

f  19  3  2
f  12  19  2
f  15  12  2
f  8  14  2
f  18  8  2
f  3  18  2
f  20  5  4
f  9  20  4
f  16  9  4
f  13  17  4
f  1  13  4
f  5  1  4
f  7  16  4
f  6  7  4
f  17  6  4
f  6  15  2
f  7  6  2
f  14  7  2
f  10  18  3
f  11  10  3
f  19  11  3
f  11  1  5
f  10  11  5
f  20  10  5
f  20  9  8
f  10  20  8
f  18  10  8
f  9  16  7
f  8  9  7
f  14  8  7
f  12/1/2  15/3/4  6/5/6
f  13/1/2  12/3/4  6/5/6
f  17/1/2  13/3/4  6/5/6
f  13//2  1//3  11//4
f  12//5  13//6  11//7
f  19//8  12//9  11//10


Output:
Vertices:
-0.57735  -0.57735  0.57735
0.934172  0.356822  0
0.934172  -0.356822  0
-0.934172  0.356822  0
-0.934172  -0.356822  0
0  0.934172  0.356822
0  0.934172  -0.356822
0.356822  0  -0.934172
-0.356822  0  -0.934172
0  -0.934172  -0.356822
0  -0.934172  0.356822
0.356822  0  0.934172
-0.356822  0  0.934172
0.57735  0.57735  -0.57735
0.57735  0.57735  0.57735
-0.57735  0.57735  -0.57735
-0.57735  0.57735  0.57735
0.57735  -0.57735  -0.57735
0.57735  -0.57735  0.57735
-0.57735  -0.57735  -0.57735


Triangles
19  3  2
12  19  2
15  12  2
8  14  2
18  8  2
3  18  2
20  5  4
9  20  4
16  9  4
13  17  4
1  13  4
5  1  4
7  16  4
6  7  4
17  6  4
6  15  2
7  6  2
14  7  2
10  18  3
11  10  3
19  11  3
11  1  5
10  11  5
20  10  5
20  9  8
10  20  8
18  10  8
9  16  7
8  9  7
14  8  7
12  15  6
13  12  6
17  13  6
13  1  11
12  13  11
19  12  11
Last edited on
Thank you for this excellent program @lastchance. If I will include this code to my program, can I include is as library instead? For example, if I will name this code as "importOBJ.h" as its filename, is it possible to include this file to my glut program? Like:

#include <iostream>
#include <GL/glut.h>
#include "importOBJ.h" //Like this format???
Oh, is it also possible to add a counter in this code portion like:

1
2
3
4
5
6
7
8
9
  
int counter=0; 
case 'f':                                         // FACES
case 'F':                                         //    (either case)
            ss >> si >> sj >> sk;                          // FIRST, read into individual strings
            i = stoi(si);  j = stoi(sj);  k = stoi( sk );  // Get the FIRST integer from each string
            faces.push_back( { i, j, k } );                // add to vector
            counter++;     //to count the number of lines in faces...   
            break;


I am thinking if this is possible and will I be able to take this value?
I am trying this code to read my Armadillo.obj, but it seems like it kept on printing these values.. (continuously)

Link: https://i.imgur.com/cNb8iPA.png

I tried to search this value manually from the Armadillo's OBJ file itself, and it shows only one result... I am wondering why it prints continuously? :(

Link: https://i.imgur.com/kvjoZqx.png

Link to Armadillo.obj file: http://www.prinmath.com/csci5229/OBJ/armadillo.zip



You can put the declarations of the structures and getFacesAndVertices() in a header file, and the declaration (i.e. code) of the function in a separate cpp file which is linked - or you could simply cut and paste it with your code.

You don't need a separate counter: vectors have a size() function, which will do the job perfectly well.

Sorry, but I don't download code from unknown sites.
It's okay my friend. I understand. :)
The first two links were pictures of my program. The last link was a repository of OBJ file.
I tried to rename the "vn" to "n" and at some point it was working, but I don't know why. :/
Thanks a bunch for your help @lastchance. You're an angel. :D
Topic archived. No new replies allowed.