Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
335 jab 1
// ----------------------------------------
2
// A simple Range Scan Viewer
3
//
4
// Controls:
5
// - left mouse down + mouse motion : rotate
6
// - Scroll button and +- buttons   : zoom
7
// - right mouse click              : centre trackball
8
// - esc                            : exits
9
// - x,y,z buttons                  : switch trackball up axis
10
// ----------------------------------------
11
 
12
#if (_MSC_VER >= 1200)
13
#pragma warning (disable: 4786)
14
#endif
15
 
16
#include <list>
17
#include <vector>
18
 
19
#include <assert.h>
20
#include <stdio.h>
21
#ifdef WIN32
22
#include <windows.h>
23
#include <io.h>
24
#endif
25
#include <string.h>
26
#include <stdlib.h>
27
 
28
#include <iostream>
29
#include <CGLA/Vec2i.h>
30
#include <CGLA/Vec2f.h>
31
 
32
#include <CGLA/Vec3f.h>
33
#include <CGLA/Mat4x4f.h>
34
#include "GLGraphics/gel_glut.h"
35
#include "GLGraphics/QuatTrackBall.h"
36
#include "Geometry/KDTree.h"
37
 
38
 
39
#include "ply.h"
40
 
41
#include <CGLA/statistics.h>
42
#include <CGLA/eigensolution.h>
43
 
44
using namespace std;
45
using namespace CGLA;
46
using namespace Geometry;
47
using namespace GLGraphics;
48
 
49
namespace
50
{
51
	int win_size_x = 800;
52
	int win_size_y = 800;
53
 
54
	QuatTrackBall* ball;
55
	int spin_timer = 20;
56
	void spin(int x);
57
 
58
	int main_window;
59
 
60
	Vec3f cen;
61
	Vec3f pmin;
62
	Vec3f bbsize;
63
	std::vector<CGLA::Vec3f> verts;
64
	std::vector<CGLA::Vec3f> norms;
65
	float rad;
66
 
67
	void verts_from_conf(std::string filename, float dist=0.002)
68
	{
69
		verts.clear();
70
		norms.clear();
71
 
72
		CGLA::Quatf qrot;
73
		CGLA::Vec3f tr;
74
		CGLA::Mat4x4f transform;
75
		CGLA::Mat4x4f Ntransform;
76
 
77
		char plyfile[50];
78
		char elemtag[50];
79
		FILE * pFile;
80
		//filename = "data/" + filename;
81
		pFile = fopen (filename.c_str(),"r");
82
		if (pFile==NULL)
83
		{
84
			cout << "file error " << filename << endl;
85
			return;
86
		}
87
 
88
		bool end=false;
89
 
90
		cen=Vec3f(0,0,0);
91
		pmin=Vec3f(1000,10000,1000);
92
		bbsize=Vec3f(-100,-100,-100);
93
 
94
		cout << "using file " << filename << endl;
95
 
96
		while(!end)
97
		{
98
			//bmesh bun045.ply -0.0520211 -0.000383981 -0.0109223 0.00548449 -0.294635 -0.0038555 0.955586
99
 
100
			//int params = fscanf (pFile, "%s %s %f %f %f %f %f %f %f", &elemtag, &plyfile, &tr[0], &tr[1], &tr[2], &qrot.qw ,&qrot.qv[0], &qrot.qv[1], &qrot.qv[2]);
101
			int params = fscanf (pFile, "%s %s %f %f %f %f %f %f %f", &elemtag, &plyfile, &tr[0], &tr[1], &tr[2],&qrot.qv[0], &qrot.qv[1], &qrot.qv[2], &qrot.qw );
102
			//int params = fscanf (pFile, "%s ", &elemtag);
103
			if (params>0)
104
			{
105
				if ( strcmp(elemtag, "bmesh")==0 )
106
				{
107
					//  fscanf (pFile, "%s %f %f %f %f %f %f %f\n", &plyfile, &tr[0], &tr[1], &tr[2],&qrot.qv[0], &qrot.qv[1], &qrot.qv[2], &qrot.qw );
108
					string splyfile = string(plyfile);
109
					cout << "found plyfile " << splyfile << endl;
110
 
111
					qrot = qrot.inverse();
112
					transform = CGLA::translation_Mat4x4f(tr) * qrot.get_Mat4x4f();
113
					Ntransform = transform;
114
					Ntransform = invert(Ntransform);
115
					Ntransform = transpose(Ntransform);
116
 
117
					PlyFile *ply;
118
					int nelems;
119
					int nprops;
120
					char **elist;
121
					int file_type;
122
					float version;
123
					int num_elems;
124
					//PlyProperty **plist;
125
					char *elem_name;
126
 
127
 
128
					ply = ply_open_for_reading(splyfile.c_str(), &nelems, &elist, &file_type, &version);
129
 
130
					/* print what we found out about the file */
131
					printf ("version %f\n", version);
132
					printf ("type %d\n", file_type);
133
 
134
					/* go through each kind of element that we learned is in the file */
135
					/* and read them */
136
 
137
					for (int i = 0; i < nelems; i++) 
138
					{
139
 
140
						/* get the description of the first element */
141
						elem_name = elist[i];
142
						//plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);
143
						ply_get_element_description (ply, elem_name, &num_elems, &nprops);
144
 
145
						/* print the name of the element, for debugging */
146
						printf ("element %s %d\n", elem_name, num_elems);
147
 
148
						/* if we're on vertex elements, read them in */
149
						if (equal_strings ("vertex", elem_name)) 
150
						{
151
							typedef struct PlyVertex {
152
								float x,y,z;             /* the usual 3-space position of a vertex */
153
							} PlyVertex;
154
 
155
							PlyProperty vert_props[] = { /* list of property information for a vertex */
156
								{"x", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,x), 0, 0, 0, 0},
157
								{"y", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,y), 0, 0, 0, 0},
158
								{"z", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,z), 0, 0, 0, 0},
159
							};
160
 
161
							/* set up for getting vertex elements */
162
							ply_get_property (ply, elem_name, &vert_props[0]);
163
							ply_get_property (ply, elem_name, &vert_props[1]);
164
							ply_get_property (ply, elem_name, &vert_props[2]);
165
 
166
 
167
							/* grab all the vertex elements */
168
							for (int j = 0; j < num_elems; j++) 
169
							{
170
								PlyVertex * pv = (PlyVertex *) malloc (sizeof (PlyVertex));
171
 
172
								/* grab and element from the file */
173
								ply_get_element (ply, (void*)pv);
174
 
175
								Vec3f v = transform.mul_3D_point(Vec3f(pv->x, pv->y, pv->z));
176
								verts.push_back(v);
177
 
178
								Vec3f n = Ntransform.mul_3D_vector(Vec3f(0,0,1));
179
								norms.push_back(n);
180
 
181
								cen += v;
182
								pmin = v_min(pmin,v);
183
								bbsize = v_max(bbsize,v);
184
							}
185
						}
186
					}
187
				}
188
			}
189
			else
190
			{
191
				end=true;
192
				fclose(pFile);
193
			}
194
		}
195
 
196
		if (dist>0)
197
		{
198
			Geometry::KDTree<CGLA::Vec3f,int>* tree = new Geometry::KDTree<CGLA::Vec3f,int>();
199
			for (unsigned int i=0; i<verts.size(); ++i)
200
				tree->insert(verts[i], i);
201
			tree->build();
202
 
203
			int skip=0;
204
			for (unsigned int i=0; i<verts.size(); ++i)
205
			{
206
				if (i % 100000 == 0)
207
					cerr << ".";
208
 
209
				vector<CGLA::Vec3f> neigbours;
210
				vector<int> neigbour_ids;
211
				int num = tree->in_sphere(verts[i], dist, neigbours, neigbour_ids);
212
 
213
				if (num > 5)
214
				{
215
					Mat3x3f A;
216
					Vec3f m = covariance(neigbours, A);
217
					Mat3x3f Q,L;
218
					int n = power_eigensolution(A, Q, L);
219
 
220
					int min_id;
221
					if ( L[0][0] < L[1][1])
222
					{
223
						if ( L[0][0] < L[2][2])
224
							min_id = 0;
225
						else
226
							min_id = 2;
227
					}
228
					else
229
					{
230
						if ( L[1][1] < L[2][2])
231
							min_id = 1;
232
						else
233
							min_id = 2;
234
					}
235
 
236
					Vec3f temp_n(Q[min_id][0], Q[min_id][1], Q[min_id][2]);
237
					temp_n.normalize();
238
					float sgn = sign(dot(temp_n, norms[i]));
239
					norms[i] = sgn*temp_n;
240
				}
241
				else
242
				{
243
					norms[i] = Vec3f(0,0,0);
244
					skip++;
245
				}
246
			}
247
 
248
			cout << skip << " of " << verts.size() << " with zero normal" << endl;;
249
		}
250
		cen /= (float)verts.size();
251
		bbsize =  bbsize-pmin;
252
		rad = 0.7f*bbsize.length();
253
 
254
		//for(unsigned int i=0; i<verts.size(); ++i )
255
		//  scale( verts[i], rad);
256
		//
257
		//pmin= Vec3f(0,0,0);
258
		//  //bbsize = Vec3f(cur_dim);
259
		//  bbsize = Vec3f(1,1,1);
260
		//  cen = 0.5f*bbsize;
261
	}
262
 
263
	void write_obj(string fn)
264
	{
265
		FILE* pFile = fopen (fn.c_str(),"w+");
266
		if (pFile==NULL)
267
		{
268
			cout << "file error " << fn << endl;
269
			return;
270
		}
271
 
272
		fprintf( pFile, "# %d vertices with normal\n", verts.size());
273
		//fprintf( pFile, "# center : %d vertices with normal", verts.size());
274
 
275
		for(unsigned int i=0; i<verts.size(); ++i )
276
		  fprintf( pFile, "v %f %f %f\n", verts[i][0], verts[i][1], verts[i][2]);
277
		for(unsigned int i=0; i<norms.size(); ++i )
278
		  fprintf( pFile, "vn %f %f %f\n", norms[i][0], norms[i][1], norms[i][2]);
279
 
280
		fclose(pFile);
281
 
282
	}
283
 
284
 
285
	void mouse_motion(int x, int y)
286
	{
287
		ball->roll_ball(Vec2i(x,y));
288
	}
289
 
290
	void mouse(int btn, int state, int x, int y)
291
	{
292
		if(state == GLUT_DOWN) 
293
		{
294
			if(btn == GLUT_LEFT_BUTTON) 
295
				ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
296
			else if(btn == GLUT_MIDDLE_BUTTON) 
297
				ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
298
			else if(btn == GLUT_RIGHT_BUTTON) 
299
				ball->grab_ball(PAN_ACTION, Vec2i(x, y));
300
		}
301
		else if(state == GLUT_UP)
302
			ball->release_ball();	
303
	}
304
 
305
	void spin(int x)
306
	{
307
		ball->do_spin();
308
		glutTimerFunc(spin_timer, spin, 0);  
309
		glutPostRedisplay();
310
	}
311
 
312
 
313
	void draw()
314
	{
315
		glBegin(GL_POINTS);
316
		for(unsigned int i=0; i<verts.size(); ++i )
317
		{
318
			glVertex3fv( verts[i].get());
319
		}
320
		glEnd();
321
	}
322
 
323
	void draw_normals(float l=0.001)
324
	{
325
		glBegin(GL_LINES);
326
		for(unsigned int i=0; i<verts.size(); ++i )
327
		{
328
			Vec3f p1 = verts[i] + l*norms[i];
329
			glVertex3fv( verts[i].get());
330
			glVertex3fv( p1.get());
331
		}
332
		glEnd();
333
	}
334
 
335
	void display()
336
	{
337
		static bool washere = false;
338
		static unsigned int lp, ln;
339
		if(!washere)
340
		{
341
			cout << "Creating display list" << endl;
342
			lp = glGenLists(1);
343
			glNewList(lp, GL_COMPILE);
344
			draw();
345
			glEndList();
346
			cout << "Creating display list" << endl;
347
			ln = glGenLists(1);
348
			glNewList(ln, GL_COMPILE);
349
			draw_normals();
350
			glEndList();
351
 
352
			washere = true;
353
			glutTimerFunc(spin_timer, spin, 0);	
354
		}
355
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
356
		glLoadIdentity();
357
		ball->set_gl_modelview();
358
		glColor3f(0.9,0.1,0);
359
		glCallList(lp);
360
		glColor3f(0.0,0.9,0.5);
361
		glCallList(ln);
362
 
363
		glPushMatrix();
364
		glColor3f(0.7,0.9,0.3);
365
 
366
		glTranslatef(cen[0], cen[1], cen[2]);
367
		glScalef(bbsize[0], bbsize[1], bbsize[2]);
368
		glutWireCube(1.0);
369
		glPopMatrix();
370
		glutSwapBuffers();
371
	}
372
 
373
	void keyboard(unsigned char key, int x, int y)
374
	{
375
		switch(key)
376
		{
377
		case '\033': exit(0); break;
378
			//case '+': ball->closer(); break;
379
			//case '-': ball->farther(); break;
380
			//default:
381
			//    ball->up_axis(key);
382
		}
383
	}
384
}
385
 
386
int main(int argc, char** argv)
387
{
388
	// GLUT INIT
389
	glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
390
	glutInitWindowSize(win_size_x, win_size_y);
391
	glutInit(&argc, argv);
392
	main_window = glutCreateWindow("OBJ Viewer");
393
	glutDisplayFunc(display);
394
	glutKeyboardFunc(keyboard);
395
	glutMotionFunc(mouse_motion);
396
	glutMouseFunc(mouse);
397
	//glutIdleFunc(idle);
398
 
399
	// GL INIT
400
	glClearColor(.8f, 0.9f, 1.0f, 0.f);
401
	glEnable(GL_DEPTH_TEST);
402
 
403
	// LOAD OBJ
404
	string fn;
405
	if(argc>1)
406
		fn = argv[1];
407
	else
408
		fn = "bun.conf";
409
 
410
	verts_from_conf(fn, 0.002);
411
 
412
	cout << "Loading " << fn << endl;
413
	if(fn == "") exit(0);
414
 
415
	write_obj("bunny.obj");
416
	//return 0;
417
 
418
	// Initialize Trackball
419
 
420
	ball = new QuatTrackBall(cen,2*rad,800,800);
421
 
422
	// Setup projection
423
	glMatrixMode(GL_PROJECTION);
424
	glLoadIdentity();
425
	gluPerspective(53,1.0f,rad/100.0,rad*3.0);
426
	glMatrixMode(GL_MODELVIEW);
427
 
428
	// Pass control to GLUT
429
	glutMainLoop();
430
 
431
	return 0;
432
}