Subversion Repositories gelsvn

Rev

Rev 388 | Rev 394 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 388 Rev 391
Line 50... Line 50...
50
#include <GLConsole/GLConsole.h>
50
#include <GLConsole/GLConsole.h>
51
 
51
 
52
#include "harmonics.h"
52
#include "harmonics.h"
53
#include "wireframe.h"
53
#include "wireframe.h"
54
 
54
 
-
 
55
using namespace std;
-
 
56
using namespace HMesh;
-
 
57
using namespace Geometry;
-
 
58
using namespace GLGraphics;
-
 
59
using namespace CGLA;
-
 
60
using namespace Util;
-
 
61
using namespace LinAlg;
-
 
62
 
-
 
63
int WINX=800, WINY=800;
-
 
64
 
-
 
65
class VisObj
-
 
66
{
-
 
67
	string file;
-
 
68
	GLViewController view_ctrl;
-
 
69
	GLuint display_list;
-
 
70
	bool create_display_list;
-
 
71
	Manifold mani;
-
 
72
	Harmonics* harmonics;
-
 
73
	
-
 
74
public:
-
 
75
	
-
 
76
	Manifold& mesh() {return mani;}
-
 
77
	GLViewController& view_control() {return view_ctrl;}
-
 
78
	
-
 
79
	bool reload(string _file)
-
 
80
	{
-
 
81
		if(_file != "") file = _file;
-
 
82
		mani.clear();
-
 
83
		if(!load(file, mani))
-
 
84
			return false;
-
 
85
		Vec3f c(0,0,0);
-
 
86
		float r = 5;
-
 
87
		mani.get_bsphere(c,r);
-
 
88
		view_ctrl.set_centre(c);
-
 
89
		view_ctrl.set_eye_dist(2*r);
-
 
90
		return true;
-
 
91
	}
-
 
92
	
-
 
93
	VisObj():
-
 
94
	file(""), view_ctrl(WINX,WINY, Vec3f(0), 1.0), display_list(glGenLists(1)), create_display_list(true), harmonics(0) 
-
 
95
	{
-
 
96
	}
-
 
97
	
-
 
98
	void display(bool wire, bool harm, bool flat)
-
 
99
	{
-
 
100
		if(create_display_list)
-
 
101
		{
-
 
102
			create_display_list = false;
-
 
103
			
-
 
104
			glNewList(display_list,GL_COMPILE);
-
 
105
			if(wire)
-
 
106
			{
-
 
107
				enable_wireframe();
-
 
108
				draw(mani);
-
 
109
				glUseProgram(0);	
-
 
110
			}
-
 
111
			else if(harm)
-
 
112
				harmonics->draw();
-
 
113
			else 
-
 
114
				draw(mani,!flat);
-
 
115
			glEndList();
-
 
116
		}
-
 
117
		view_ctrl.reset_projection();
-
 
118
		view_ctrl.set_gl_modelview();
-
 
119
		glCallList(display_list);
-
 
120
	}
-
 
121
	
-
 
122
	
-
 
123
	void post_create_display_list()
-
 
124
	{
-
 
125
		create_display_list = true;
-
 
126
	}
-
 
127
	
-
 
128
	void harmonics_analyze_mesh()
-
 
129
	{
-
 
130
		delete harmonics;
-
 
131
		harmonics = new Harmonics(mani);
-
 
132
	}
-
 
133
	
-
 
134
	void harmonics_reset_shape()
-
 
135
	{
-
 
136
		if(harmonics)
-
 
137
			harmonics->reset_shape();
-
 
138
	}
-
 
139
	
-
 
140
	void harmonics_parse_key(unsigned char key)
-
 
141
	{
-
 
142
		harmonics->parse_key(key);
-
 
143
	}
-
 
144
	
-
 
145
	void harmonics_partial_reconstruct(int eig0, int eig1, float scale)
-
 
146
	{
-
 
147
		if(harmonics)
-
 
148
			harmonics->partial_reconstruct(eig0, eig1, scale);
-
 
149
	}
-
 
150
	
-
 
151
};
-
 
152
 
-
 
153
inline VisObj& get_vis_obj(int i)
-
 
154
{
-
 
155
	static VisObj vo[9];
-
 
156
	return vo[i];
-
 
157
}
-
 
158
 
-
 
159
inline VisObj& avo()
-
 
160
{
-
 
161
	static CVar<int> active("active_mesh",0);
-
 
162
	return get_vis_obj(active);
-
 
163
}
-
 
164
 
-
 
165
inline Manifold& active_mesh()
-
 
166
{
-
 
167
	return avo().mesh();
-
 
168
}
-
 
169
 
-
 
170
inline GLViewController& active_view_control()
-
 
171
{
-
 
172
	return avo().view_control();
-
 
173
}
55
 
174
 
56
// Single global instance so glut can get access
175
// Single global instance so glut can get access
57
GLConsole theConsole;
176
GLConsole theConsole;
58
 
177
 
59
////////////////////////////////////////////////////////////////////////////////
178
////////////////////////////////////////////////////////////////////////////////
60
char* ConsoleHelp(std::vector<std::string> &args)
179
char* ConsoleHelp(std::vector<std::string> &args)
61
{
180
{
62
    theConsole.Printf("");
181
    theConsole.Printf("");
63
    theConsole.Printf("----------------- HELP -----------------");
182
    theConsole.Printf("----------------- HELP -----------------");
64
    theConsole.Printf("Press ~ key to open and close console");
183
    theConsole.Printf("Press ESC key to open and close console");
65
    theConsole.Printf("Press TAB to see the available commands and functions");
184
    theConsole.Printf("Press TAB to see the available commands and functions");
66
    theConsole.Printf("Functions are shown in green and variables in yellow");
185
    theConsole.Printf("Functions are shown in green and variables in yellow");
67
    theConsole.Printf("Setting a value: [command] = value");
186
    theConsole.Printf("Setting a value: [command] = value");
68
    theConsole.Printf("Getting a value: [command]");
187
    theConsole.Printf("Getting a value: [command]");
69
    theConsole.Printf("Functions: [function] [arg1] [arg2] ...");
188
    theConsole.Printf("Functions: [function] [arg1] [arg2] ...");
70
    theConsole.Printf("Entering just the function name will give a description.");
189
    theConsole.Printf("Entering arg1=? or arg1=help will give a description.");
71
    theConsole.Printf("History: Up and Down arrow keys move through history.");
190
    theConsole.Printf("History: Up and Down arrow keys move through history.");
72
    theConsole.Printf("Tab Completion: TAB does tab completion and makes suggestions.");
191
    theConsole.Printf("Tab Completion: TAB does tab completion and makes suggestions.");
-
 
192
    theConsole.Printf("");
-
 
193
    theConsole.Printf("Keyboard commands (when console is not active):");
-
 
194
    theConsole.Printf("w   : toggle wireframe");
-
 
195
    theConsole.Printf("f   : toggle flatshading");
-
 
196
    theConsole.Printf("1-9 : switch between active meshes.");
-
 
197
    theConsole.Printf("d   : (display.harmonics = 1) diffuse light on and off");
-
 
198
    theConsole.Printf("h   : (display.harmonics = 1) highlight on and off ");
-
 
199
    theConsole.Printf("+/- : (display.harmonics = 1) which eigenvector to show");
-
 
200
    theConsole.Printf("q   : quit program");
-
 
201
    theConsole.Printf("ESC : open console");
-
 
202
    theConsole.Printf("");
-
 
203
    theConsole.Printf("Mouse: Left button rotates, middle zooms, right pans");
73
    theConsole.Printf("----------------- HELP -----------------");
204
    theConsole.Printf("----------------- HELP -----------------");
74
    theConsole.Printf("");
205
    theConsole.Printf("");
75
    return "";
206
    return "";
76
}
207
}
77
 
208
 
78
using namespace std;
-
 
79
using namespace HMesh;
-
 
80
using namespace Geometry;
209
bool wantshelp(std::vector<std::string> &args)
-
 
210
{
81
using namespace GLGraphics;
211
	if(args.size()==0) return false;
82
using namespace CGLA;
212
	string str = args[0];
83
using namespace Util;
213
	if(str=="help" || str=="HELP" || str=="Help" || str=="?") return true;
84
using namespace LinAlg;
214
	return false;
85
 
-
 
86
 
215
}
87
 
216
 
88
namespace 
217
/// Function that aligns two meshes.
-
 
218
char* console_align(std::vector<std::string> &args)
89
{
219
{
-
 
220
	if(wantshelp(args)) 
-
 
221
		{
-
 
222
			theConsole.Printf("usage: align <dest> <src>");
-
 
223
			theConsole.Printf("This function aligns dest mesh with src");
-
 
224
			theConsole.Printf("In practice the GLViewController of src is copied to dst.");
-
 
225
			theConsole.Printf("both arguments are mandatory and must be numbers between 1 and 9.");
-
 
226
			theConsole.Printf("Note that results might be unexpexted if the meshes are not on the same scale");
-
 
227
			return "";
-
 
228
		}
-
 
229
 
-
 
230
	int dest = 0;
-
 
231
	if(args.size()>0)
-
 
232
	{
90
	GLViewController* view_ctrl;
233
		istringstream a0(args[0]);
-
 
234
		a0 >> dest;
-
 
235
		--dest;
-
 
236
		if(dest <0 || dest>8) return "dest mesh out of range (1-9)";
-
 
237
	}
-
 
238
	else return "neither source nor destination mesh?!";
91
	int WINX=800, WINY=800;
239
	int src = 0;
-
 
240
	if(args.size()>1)
-
 
241
	{
-
 
242
		istringstream a1(args[1]);
92
	string file;
243
		a1 >> src;
-
 
244
		--src;
-
 
245
		if(src <0 || src>8) return "src mesh out of range (1-9)";
-
 
246
	}	
-
 
247
	else return "no src mesh?";
93
	
248
	
-
 
249
	get_vis_obj(dest).view_control() = get_vis_obj(src).view_control();
-
 
250
	
94
	Manifold mani;	
251
	return "";
95
	bool create_display_list = true;
-
 
96
}
252
}
97
 
253
 
-
 
254
 
98
char* console_save(std::vector<std::string> &args)
255
char* console_save(std::vector<std::string> &args)
99
{
256
{
-
 
257
	if(wantshelp(args)) 
-
 
258
		{
-
 
259
			theConsole.Printf("usage: save <name.x3d|name.obj> ");
-
 
260
			return "";
-
 
261
		}
100
	string& file_name = args[0];
262
	string& file_name = args[0];
101
	if(args.size() == 1)
263
	if(args.size() == 1)
102
	{
264
	{
103
		if(file_name.substr(file_name.length()-4,file_name.length())==".obj")
265
		if(file_name.substr(file_name.length()-4,file_name.length())==".obj")
104
		{
266
		{
105
			obj_save(file_name, mani);
267
			obj_save(file_name, active_mesh());
106
			return "";
268
			return "";
107
		}
269
		}
108
		else if(file_name.substr(file_name.length()-4,file_name.length())==".x3d")
270
		else if(file_name.substr(file_name.length()-4,file_name.length())==".x3d")
109
		{
271
		{
110
			x3d_save(file_name, mani);
272
			x3d_save(file_name, active_mesh());
111
			return "";
273
			return "";
112
		}
274
		}
113
		return "unknown format";
275
		return "unknown format";
114
	}
276
	}
115
	return "usage: save <name.x3d|name.obj> ";
277
	return "usage: save <name.x3d|name.obj> ";
116
}
278
}
117
 
279
 
118
char* console_refine_edges(std::vector<std::string> &args)
280
char* console_refine_edges(std::vector<std::string> &args)
119
{
281
{
-
 
282
	if(wantshelp(args)) 
-
 
283
		{
-
 
284
			theConsole.Printf("usage: refine.split_edges <length>");
-
 
285
			theConsole.Printf("splits edges longer than <length>; default is 0.5 times average length");
-
 
286
			return "";
-
 
287
		}
-
 
288
 
120
	float thresh = 0.5;
289
	float thresh = 0.5;
121
	if(args.size()>0)
290
	if(args.size()>0)
122
	{
291
	{
123
		istringstream a0(args[0]);
292
		istringstream a0(args[0]);
124
		a0 >> thresh;
293
		a0 >> thresh;
125
	}
294
	}
126
	float avg_length = average_edge_length(mani);
295
	float avg_length = average_edge_length(active_mesh());
127
	refine_edges(mani, thresh * avg_length);
296
	refine_edges(active_mesh(), thresh * avg_length);
128
	return "";
297
	return "";
129
 
298
	
130
}
299
}
131
 
300
 
132
char* console_refine_faces(std::vector<std::string> &args)
301
char* console_refine_faces(std::vector<std::string> &args)
133
{
302
{
134
	safe_triangulate(mani);
303
	if(wantshelp(args)) 
-
 
304
		{
-
 
305
			theConsole.Printf("usage: refine.split_faces ");
-
 
306
			theConsole.Printf("usage:  Takes no arguments. Inserts a vertex at the centre of each face.");
135
	return "";
307
			return "";
-
 
308
		}
136
 
309
 
-
 
310
	safe_triangulate(active_mesh());
-
 
311
	return "";
-
 
312
	
137
}
313
}
138
 
314
 
139
char* console_cc_subdivide(std::vector<std::string> &args)
315
char* console_cc_subdivide(std::vector<std::string> &args)
140
{
316
{
-
 
317
	if(wantshelp(args)) 
-
 
318
		{
-
 
319
			theConsole.Printf("usage: refine.catmull_clark ");
-
 
320
			theConsole.Printf("Splits each polygon into four (Catmull Clark style)");
-
 
321
			return "";
-
 
322
		}
141
	cc_split(mani,mani);
323
	cc_split(active_mesh(),active_mesh());
142
	return "";
324
	return "";
143
}
325
}
144
 
326
 
145
 
327
 
146
 
328
 
147
char* console_minimize_curvature(std::vector<std::string> &args)
329
char* console_minimize_curvature(std::vector<std::string> &args)
148
{
330
{
-
 
331
	if(wantshelp(args)) 
-
 
332
		{
-
 
333
			theConsole.Printf("usage: optimize.minimize_curvature <anneal>");
-
 
334
			theConsole.Printf("Flip edges to minimize mean curvature.");
-
 
335
			theConsole.Printf("If anneal is true, simulated annealing (slow) is used rather than a greedy scheme");
-
 
336
			return "";
-
 
337
		}
149
	bool anneal=false;
338
	bool anneal=false;
150
	if(args.size()>0)
339
	if(args.size()>0)
151
	{
340
	{
152
		istringstream a0(args[0]);
341
		istringstream a0(args[0]);
153
		a0 >> anneal;
342
		a0 >> anneal;
154
	}
343
	}
155
 
344
	
156
	minimize_curvature(mani, anneal);
345
	minimize_curvature(active_mesh(), anneal);
157
	create_display_list = true;
346
	avo().post_create_display_list();
158
	return "";
347
	return "";
159
}
348
}
160
 
349
 
161
char* console_minimize_dihedral(std::vector<std::string> &args)
350
char* console_minimize_dihedral(std::vector<std::string> &args)
162
{
351
{
-
 
352
	if(wantshelp(args)) 
-
 
353
		{
-
 
354
			theConsole.Printf("usage: optimize.minimize_dihedral <iter> <anneal> <use_alpha> <gamma> ");
-
 
355
			theConsole.Printf("Flip edges to minimize dihedral angles.");
-
 
356
			theConsole.Printf("Iter is the max number of iterations. anneal tells us whether to use ");
-
 
357
			theConsole.Printf("simulated annealing and not greedy optimization. use_alpha (default=true) ");
-
 
358
			theConsole.Printf("means to use angle and not cosine of anglegamma (default=4) is the power ");
-
 
359
			theConsole.Printf("to which we raise the dihedral angle");
-
 
360
			return "";
-
 
361
		}
163
	int iter = 1000;
362
	int iter = 1000;
164
	if(args.size()>0)
363
	if(args.size()>0)
165
	{
364
	{
166
		istringstream a0(args[0]);
365
		istringstream a0(args[0]);
167
		a0 >> iter;
366
		a0 >> iter;
168
	}
367
	}
169
 
368
	
170
	bool anneal = false;
369
	bool anneal = false;
171
	if(args.size()>1)
370
	if(args.size()>1)
172
	{
371
	{
173
		istringstream a0(args[0]);
372
		istringstream a0(args[0]);
174
		a0 >> anneal;
373
		a0 >> anneal;
175
	}
374
	}
176
 
375
	
177
	bool use_alpha = true;
376
	bool use_alpha = true;
178
	if(args.size()>2)
377
	if(args.size()>2)
179
	{
378
	{
180
		istringstream a0(args[0]);
379
		istringstream a0(args[0]);
181
		a0 >> use_alpha;
380
		a0 >> use_alpha;
182
	}
381
	}
183
 
382
	
184
	float gamma = 4.0;
383
	float gamma = 4.0;
185
	if(args.size()>3)
384
	if(args.size()>3)
186
	{
385
	{
187
		istringstream a0(args[0]);
386
		istringstream a0(args[0]);
188
		a0 >> gamma;
387
		a0 >> gamma;
189
	}
388
	}
190
	
389
	
191
	
390
	
192
	minimize_dihedral_angle(mani, iter, anneal, use_alpha, gamma);
391
	minimize_dihedral_angle(active_mesh(), iter, anneal, use_alpha, gamma);
193
	return "";
392
	return "";
194
}
393
}
195
 
394
 
196
char* console_maximize_min_angle(std::vector<std::string> &args)
395
char* console_maximize_min_angle(std::vector<std::string> &args)
197
{
396
{
-
 
397
	if(wantshelp(args)) 
-
 
398
		{
-
 
399
			theConsole.Printf("usage: optimize.maximize_min_angle <thresh> <anneal>");
-
 
400
			theConsole.Printf("Flip edges to maximize min angle - to make mesh more Delaunay.");
-
 
401
			theConsole.Printf("If the dot product of the normals between adjacent faces < thresh");
-
 
402
			theConsole.Printf("no flip will be made. anneal selects simulated annealing rather ");
-
 
403
			theConsole.Printf("nthan greedy optimization.");
-
 
404
			return "";
-
 
405
		}
198
	float thresh=0.0;
406
	float thresh=0.0;
199
	if(args.size()>0)
407
	if(args.size()>0)
200
	{
408
	{
201
		istringstream a0(args[0]);
409
		istringstream a0(args[0]);
202
		a0 >> thresh;
410
		a0 >> thresh;
Line 205... Line 413...
205
	if(args.size()>1)
413
	if(args.size()>1)
206
	{
414
	{
207
		istringstream a0(args[0]);
415
		istringstream a0(args[0]);
208
		a0 >> anneal;
416
		a0 >> anneal;
209
	}
417
	}
210
	maximize_min_angle(mani,thresh,anneal);
418
	maximize_min_angle(active_mesh(),thresh,anneal);
211
	return "";
419
	return "";
212
}
420
}
213
 
421
 
214
 
422
 
215
char* console_optimize_valency(std::vector<std::string> &args)
423
char* console_optimize_valency(std::vector<std::string> &args)
216
{
424
{
-
 
425
	if(wantshelp(args)) 
-
 
426
		{
-
 
427
			theConsole.Printf("usage: optimize.valency <anneal> ");
-
 
428
			theConsole.Printf("Optimizes valency for triangle meshes. Anneal selects simulated annealing rather than greedy optim.");
-
 
429
			return "";
-
 
430
		}
217
	bool anneal=false;
431
	bool anneal=false;
218
	if(args.size()>0)
432
	if(args.size()>0)
219
	{
433
	{
220
		istringstream a0(args[0]);
434
		istringstream a0(args[0]);
221
		a0 >> anneal;
435
		a0 >> anneal;
222
	}
436
	}
223
	optimize_valency(mani, anneal);
437
	optimize_valency(active_mesh(), anneal);
224
	return "";
438
	return "";
225
}
439
}
226
 
440
 
227
char* console_analyze(std::vector<std::string> &args)
441
char* console_analyze(std::vector<std::string> &args)
228
{
442
{
-
 
443
	if(wantshelp(args)) 
-
 
444
		{
-
 
445
			theConsole.Printf("usage:  harmonics.analyze");
-
 
446
			theConsole.Printf("Creates the Laplace Beltrami operator for the mesh and finds all eigensolutions.");
-
 
447
			theConsole.Printf("It also projects the vertices onto the eigenvectors - thus transforming the mesh");
-
 
448
			theConsole.Printf("to this basis.");
-
 
449
			theConsole.Printf("Note that this will stall the computer for a large mesh - as long as we use Lapack.");
-
 
450
			return "";
-
 
451
		}
229
	analyze_mesh(mani);
452
	avo().harmonics_analyze_mesh();
230
	return "";
453
	return "";
231
}
454
}
232
 
455
 
233
 
456
 
234
char* console_partial_reconstruct(std::vector<std::string> &args)
457
char* console_partial_reconstruct(std::vector<std::string> &args)
235
{
458
{
-
 
459
	if(wantshelp(args)) 
-
 
460
		{
-
 
461
			theConsole.Printf("usage: haramonics.partial_reconstruct <e0> <e1> <s>");
-
 
462
			theConsole.Printf("Reconstruct from projections onto eigenvectors. The two first arguments indicate");
-
 
463
			theConsole.Printf("the eigenvector interval that we reconstruct from. The last argument is the ");
-
 
464
			theConsole.Printf("scaling factor. Thus, for a vertex, v, the formula for computing the position, p, is:");
-
 
465
			theConsole.Printf("for (i=e0; i<=e1;++i) p += proj[i] * Q[i][v] * s;");
-
 
466
			theConsole.Printf("where proj[i] is the 3D vector containing the x, y, and z projections of the mesh onto");
-
 
467
			theConsole.Printf("eigenvector i. Q[i][v] is the v'th coordinate of the i'th eigenvector.");
-
 
468
			theConsole.Printf("Note that if vertex coordinates are not first reset, the result is probably unexpected.");
-
 
469
			return "";
-
 
470
		}
236
	int E0,E1;
471
	int E0,E1;
237
	float scale;
472
	float scale;
238
	istringstream a0(args[0]);
473
	istringstream a0(args[0]);
239
	a0 >> E0;
474
	a0 >> E0;
240
	istringstream a1(args[1]);
475
	istringstream a1(args[1]);
241
	a1 >> E1;
476
	a1 >> E1;
242
	istringstream a2(args[2]);
477
	istringstream a2(args[2]);
243
	a2 >> scale;
478
	a2 >> scale;
244
	partial_reconstruct(mani, E0,E1,scale);
479
	avo().harmonics_partial_reconstruct(E0,E1,scale);
245
	return "";
480
	return "";
246
}
481
}
247
 
482
 
248
char* console_reset_shape(std::vector<std::string> &args)
483
char* console_reset_shape(std::vector<std::string> &args)
249
{
484
{
250
	reset_shape(mani);
485
	if(wantshelp(args)) 
-
 
486
		{
-
 
487
			theConsole.Printf("usage: harmonics.reset_shape ");
-
 
488
			theConsole.Printf("Simply sets all vertices to 0,0,0. Call this before doing partial_reconstruct");
-
 
489
			theConsole.Printf("unless you know what you are doing.");
-
 
490
			return "";
-
 
491
		}
-
 
492
	avo().harmonics_reset_shape();
251
	return "";
493
	return "";
252
}
494
}
253
 
495
 
254
void reshape(int W, int H)
-
 
255
{
-
 
256
	view_ctrl->reshape(W,H);
-
 
257
}
-
 
258
 
496
 
259
char* console_close_holes(std::vector<std::string> &args)
497
char* console_close_holes(std::vector<std::string> &args)
260
{
498
{
-
 
499
	if(wantshelp(args)) 
-
 
500
		{
-
 
501
			theConsole.Printf("usage: cleanup.close_holes");
-
 
502
			theConsole.Printf("This function closes holes. It simply follows the loop of halfvectors which");
-
 
503
			theConsole.Printf("enclose the hole and add a face to which they all point.");
-
 
504
			return "";
-
 
505
		}
261
	close_holes(mani);
506
	close_holes(active_mesh());
262
	return "";
507
	return "";
263
}
508
}
264
 
509
 
265
char* console_reload(std::vector<std::string> &args)
510
char* console_reload(std::vector<std::string> &args)
266
{
511
{
267
	if(args.size()>0)
512
	if(wantshelp(args)) 
268
		file = args[0];
513
		{
269
	mani.clear();
514
			theConsole.Printf("usage:  reload <file>");
270
	load(file, mani); 
515
			theConsole.Printf("Reloads the current file if no argument is given, but");
-
 
516
			theConsole.Printf("if an argument is given, then that becomes the current file");
271
	Vec3f c(0,0,0);
517
			return "";
272
	float r = 5;
518
		}
273
	mani.get_bsphere(c,r);
519
	if(!avo().reload(args.size()>0 ? args[0]:""))
274
	delete view_ctrl;
520
		return "failed to load";
275
	view_ctrl = new GLViewController(WINX,WINY, c,r*2);
-
 
276
	return "";
521
	return "";
277
}
522
}
278
 
523
 
279
 
524
 
280
char* console_simplify(std::vector<std::string> &args)
525
char* console_simplify(std::vector<std::string> &args)
281
{
526
{
-
 
527
	if(wantshelp(args)) 
-
 
528
		{
-
 
529
			theConsole.Printf("usage: simplify <fraction> ");
-
 
530
			theConsole.Printf("Performs Garland Heckbert (quadric based) mesh simplification.");
-
 
531
			theConsole.Printf("The only argument is the fraction of vertices to keep.");
-
 
532
			return "";
-
 
533
		}
282
	float keep_fraction;
534
	float keep_fraction;
283
	if(args.size()==0) return "you must specify fraction of vertices to keep";
535
	if(args.size()==0) return "you must specify fraction of vertices to keep";
284
	istringstream a0(args[0]);
536
	istringstream a0(args[0]);
285
	a0 >> keep_fraction;
537
	a0 >> keep_fraction;
286
 
538
	
287
	Vec3f p0, p7;
539
	Vec3f p0, p7;
288
	mani.get_bbox(p0, p7);
540
	active_mesh().get_bbox(p0, p7);
289
	Vec3f d = p7-p0;
541
	Vec3f d = p7-p0;
290
	float s = 1.0/d.max_coord();
542
	float s = 1.0/d.max_coord();
291
	Vec3f pcentre = (p7+p0)/2.0;
543
	Vec3f pcentre = (p7+p0)/2.0;
292
	for(VertexIter vi = mani.vertices_begin(); vi != mani.vertices_end(); ++vi)
544
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
293
		vi->pos = (vi->pos - pcentre) * s;
545
		vi->pos = (vi->pos - pcentre) * s;
294
	quadric_simplify(mani,keep_fraction,0.0001f,true);
546
	quadric_simplify(active_mesh(),keep_fraction,0.0001f,true);
295
	for(VertexIter vi = mani.vertices_begin(); vi != mani.vertices_end(); ++vi)
547
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
296
		vi->pos = vi->pos*d.max_coord() + pcentre;
548
		vi->pos = vi->pos*d.max_coord() + pcentre;
297
	return "";
549
	return "";
298
}
550
}
299
 
551
 
-
 
552
char* console_vertex_noise(std::vector<std::string> &args)
-
 
553
{
-
 
554
	if(wantshelp(args)) 
-
 
555
		{
-
 
556
			theConsole.Printf("usage: noise.perturb_vertices <amplitude>");
-
 
557
			theConsole.Printf("adds a random vector to each vertex. To ensure uniformness, the vector must lie in the");
-
 
558
			theConsole.Printf("unit sphere. The length of the vector is multiplied by the average edge length and then amplitude");
-
 
559
			return "";
-
 
560
		}
-
 
561
	float avg_length = average_edge_length(active_mesh());
-
 
562
	
-
 
563
	float noise_amplitude = 0.5;
-
 
564
	if(args.size()>0) 
-
 
565
	{
-
 
566
		istringstream a0(args[0]);
-
 
567
		a0 >> noise_amplitude;
-
 
568
	}
-
 
569
	
-
 
570
	srand(0);
-
 
571
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
-
 
572
	{
-
 
573
		Vec3f v;
-
 
574
		do {
-
 
575
			v = Vec3f(rand(),rand(),rand());
-
 
576
			v /= RAND_MAX;
-
 
577
		} while(sqr_length(v) > 1.0);
-
 
578
		v -= Vec3f(0.5);
-
 
579
		v *= 2.0;
-
 
580
		v *= noise_amplitude;
-
 
581
		v *= avg_length;
-
 
582
		vi->pos += v;
-
 
583
	}		
-
 
584
	return "";
-
 
585
}
-
 
586
 
-
 
587
char* console_noisy_flips(std::vector<std::string> &args)
-
 
588
{
-
 
589
	if(wantshelp(args)) 
-
 
590
		{
-
 
591
			theConsole.Printf("usage:  noise.perturb_topology <iter>");
-
 
592
			theConsole.Printf("Perform random flips. iter (default=1) is the number of iterations.");
-
 
593
			theConsole.Printf("mostly for making nasty synthetic test cases.");
-
 
594
			return "";
-
 
595
		}
-
 
596
	int iter=1;
-
 
597
	if(args.size()>0)
-
 
598
	{
-
 
599
		istringstream a0(args[0]);
-
 
600
		a0 >> iter;
-
 
601
	}
-
 
602
	
-
 
603
	randomize_mesh(active_mesh(),  iter);
-
 
604
	return "";
-
 
605
}
-
 
606
 
300
char* console_laplacian_smooth(std::vector<std::string> &args)
607
char* console_laplacian_smooth(std::vector<std::string> &args)
301
{
608
{
-
 
609
	if(wantshelp(args)) 
-
 
610
		{
-
 
611
			theConsole.Printf("usage:  smooth.laplacian <weight>");
-
 
612
			theConsole.Printf("Perform Laplacian smoothing. weight is the scaling factor for the Laplacian.");
-
 
613
			return "";
-
 
614
		}
302
	float t=1.0;
615
	float t=1.0;
303
	if(args.size()>0)
616
	if(args.size()>0)
304
	{
617
	{
305
		istringstream a0(args[0]);
618
		istringstream a0(args[0]);
306
		a0 >> t;
619
		a0 >> t;
307
	}
620
	}
308
	/// Simple laplacian smoothing with an optional weight.
621
	/// Simple laplacian smoothing with an optional weight.
309
	laplacian_smooth(mani, t);
622
	laplacian_smooth(active_mesh(), t);
310
	return "";
623
	return "";
311
}
624
}
312
 
625
 
313
char* console_taubin_smooth(std::vector<std::string> &args)
626
char* console_taubin_smooth(std::vector<std::string> &args)
314
{
627
{
-
 
628
	if(wantshelp(args)) 
-
 
629
		{
-
 
630
			theConsole.Printf("usage:  smooth.taubin <iter>");
-
 
631
			theConsole.Printf("Perform Taubin smoothing. iter (default=1) is the number of iterations.");
-
 
632
			return "";
-
 
633
		}
315
	int iter=1;
634
	int iter=1;
316
	if(args.size()>0)
635
	if(args.size()>0)
317
	{
636
	{
318
		istringstream a0(args[0]);
637
		istringstream a0(args[0]);
319
		a0 >> iter;
638
		a0 >> iter;
320
	}
639
	}
321
	
640
	
322
	/// Taubin smoothing is similar to laplacian smoothing but reduces shrinkage
641
	/// Taubin smoothing is similar to laplacian smoothing but reduces shrinkage
323
	taubin_smooth(mani,  iter);
642
	taubin_smooth(active_mesh(),  iter);
324
	return "";
643
	return "";
325
}
644
}
326
 
645
 
327
char* console_fvm_smooth(std::vector<std::string> &args)
646
char* console_fvm_smooth(std::vector<std::string> &args)
328
{	
647
{	
-
 
648
	if(wantshelp(args)) 
-
 
649
		{
-
 
650
			theConsole.Printf("usage: smooth.fuzzy_vector_median <iter>");
-
 
651
			theConsole.Printf("Smooth normals using fuzzy vector median smoothing. iter (default=1) is the number of iterations");
-
 
652
			theConsole.Printf("This function does a very good job of preserving sharp edges.");
-
 
653
			return "";
-
 
654
		}
329
	int iter=1;
655
	int iter=1;
330
	if(args.size()>0)
656
	if(args.size()>0)
331
	{
657
	{
332
		istringstream a0(args[0]);
658
		istringstream a0(args[0]);
333
		a0 >> iter;
659
		a0 >> iter;
334
	}
660
	}
335
	/** Fuzzy vector median smoothing is effective when it comes to
661
	/** Fuzzy vector median smoothing is effective when it comes to
336
	 preserving sharp edges. */
662
	 preserving sharp edges. */
337
	fvm_smooth(mani,  iter);
663
	fvm_smooth(active_mesh(),  iter);
338
	return "";
664
	return "";
339
 
665
	
340
}
666
}
341
 
667
 
342
char* console_triangulate(std::vector<std::string> &args)
668
char* console_triangulate(std::vector<std::string> &args)
343
{	
669
{	
-
 
670
	if(wantshelp(args)) 
-
 
671
		{
-
 
672
			theConsole.Printf("usage:  triangulate");
-
 
673
			theConsole.Printf("This function triangulates all non triangular faces of the mesh.");
-
 
674
			theConsole.Printf("you may want to call it after hole closing. For a polygon it simply connects");
-
 
675
			theConsole.Printf("the two closest vertices in a recursive manner until only triangles remain");
-
 
676
			return "";
-
 
677
		}
344
	shortest_edge_triangulate(mani);
678
	shortest_edge_triangulate(active_mesh());
345
	return "";
679
	return "";
346
}
680
}
347
 
681
 
348
 
682
 
349
char* console_remove_caps(std::vector<std::string> &args)
683
char* console_remove_caps(std::vector<std::string> &args)
350
{	
684
{	
-
 
685
	if(wantshelp(args)) 
-
 
686
		{
-
 
687
			theConsole.Printf("usage:  cleanup.remove_caps thresh");
-
 
688
			theConsole.Printf("Remove caps (triangles with one very big angle). The thresh argument is the fraction of PI to");
-
 
689
			theConsole.Printf("use as threshold for big angle. Default is 0.85. Caps are removed by flipping.");
-
 
690
			return "";
-
 
691
		}
-
 
692
	float t=0.85;
-
 
693
	if(args.size()>0)
-
 
694
	{
-
 
695
		istringstream a0(args[0]);
-
 
696
		a0 >> t;
-
 
697
	}
-
 
698
 
351
	remove_caps_from_trimesh(mani, static_cast<float>(M_PI) * 0.85f);
699
	remove_caps_from_trimesh(active_mesh(), static_cast<float>(M_PI) *t);
352
	return "";
700
	return "";
353
}
701
}
354
 
702
 
355
char* console_remove_needles(std::vector<std::string> &args)
703
char* console_remove_needles(std::vector<std::string> &args)
356
{	
704
{	
-
 
705
	if(wantshelp(args)) 
-
 
706
		{
-
 
707
			theConsole.Printf("usage: cleanup.remove_needles <thresh>");
-
 
708
			theConsole.Printf("Removes very short edges by collapse. thresh is multiplied by the average edge length");
-
 
709
			theConsole.Printf("to get the length shorter than which we collapse. Default = 0.1");
-
 
710
			return "";
-
 
711
		}
357
	float thresh = 0.1;
712
	float thresh = 0.1;
358
	if(args.size()>0)
713
	if(args.size()>0)
359
	{
714
	{
360
		istringstream a0(args[0]);
715
		istringstream a0(args[0]);
361
		a0 >> thresh;
716
		a0 >> thresh;
362
	}
717
	}
363
	float avg_length = average_edge_length(mani);
718
	float avg_length = average_edge_length(active_mesh());
364
	remove_needles_from_trimesh(mani, thresh * avg_length);
719
	remove_needles_from_trimesh(active_mesh(), thresh * avg_length);
365
	return "";
720
	return "";
366
}
721
}
367
 
722
 
-
 
723
void reshape(int W, int H)
-
 
724
{
-
 
725
	active_view_control().reshape(W,H);
-
 
726
}
-
 
727
 
368
void display() 
728
void display() 
369
{
729
{
370
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
730
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
371
	
731
	
372
	static CVar<int> display_wireframe("display.wireframe",0);
732
	static CVar<int> display_wireframe("display.wireframe",0);
373
	static CVar<int> display_eigenmodes("display.eigenmodes",0);
733
	static CVar<int> display_eigenmodes("display.harmonics",0);
374
	static CVar<int> display_flat("display.flatshading",0);
734
	static CVar<int> display_flat("display.flatshading",0);
375
	
735
	
376
	glPushMatrix();
736
	glPushMatrix();
377
	
737
	
378
	view_ctrl->set_gl_modelview();
-
 
379
	
-
 
380
	if(create_display_list)
-
 
381
	{
-
 
382
		create_display_list = false;
-
 
383
		
-
 
384
		glNewList(1,GL_COMPILE);
-
 
385
		if(display_wireframe)
-
 
386
			{
-
 
387
				enable_wireframe();
-
 
388
				draw(mani);
-
 
389
				glUseProgram(0);	
-
 
390
			}
-
 
391
		else if(display_eigenmodes)
738
	avo().display(display_wireframe, display_eigenmodes, display_flat);
392
			draw_eigenvalues(mani);
-
 
393
		else 
-
 
394
			draw(mani,!display_flat);
-
 
395
		glEndList();
-
 
396
	}
-
 
397
	glCallList(1);
-
 
398
	
739
	
399
	glPopMatrix();
740
	glPopMatrix();
400
	
741
	
401
	glUseProgram(0);
742
	glUseProgram(0);
402
	theConsole.RenderConsole();
743
	theConsole.RenderConsole();
Line 405... Line 746...
405
}
746
}
406
 
747
 
407
void animate() 
748
void animate() 
408
{	
749
{	
409
	usleep( (int)1e4 );
750
	usleep( (int)1e4 );
410
	view_ctrl->try_spin();
751
	active_view_control().try_spin();
411
	glutPostRedisplay();
752
	glutPostRedisplay();
412
}
753
}
413
 
754
 
414
 
755
 
415
void mouse(int button, int state, int x, int y) 
756
void mouse(int button, int state, int x, int y) 
416
{
757
{
-
 
758
	cout << button << endl;
417
	Vec2i pos(x,y);
759
	Vec2i pos(x,y);
418
	if (state==GLUT_DOWN) 
760
	if (state==GLUT_DOWN) 
419
	{
761
	{
420
		if (button==GLUT_LEFT_BUTTON) 
762
		if (button==GLUT_LEFT_BUTTON) 
421
			view_ctrl->grab_ball(ROTATE_ACTION,pos);
763
			active_view_control().grab_ball(ROTATE_ACTION,pos);
422
		else if (button==GLUT_MIDDLE_BUTTON) 
764
		else if (button==GLUT_MIDDLE_BUTTON) 
423
			view_ctrl->grab_ball(ZOOM_ACTION,pos);
765
			active_view_control().grab_ball(ZOOM_ACTION,pos);
424
		else if (button==GLUT_RIGHT_BUTTON) 
766
		else if (button==GLUT_RIGHT_BUTTON) 
425
			view_ctrl->grab_ball(PAN_ACTION,pos);
767
			active_view_control().grab_ball(PAN_ACTION,pos);
426
	}
768
	}
427
	else if (state==GLUT_UP)
769
	else if (state==GLUT_UP)
428
		view_ctrl->release_ball();
770
		active_view_control().release_ball();
429
}
771
}
430
 
772
 
431
void motion(int x, int y) {
773
void motion(int x, int y) {
432
	Vec2i pos(x,y);
774
	Vec2i pos(x,y);
433
	view_ctrl->roll_ball(Vec2i(x,y));
775
	active_view_control().roll_ball(Vec2i(x,y));
434
}
776
}
435
 
777
 
436
void keyboard_spec(int key, int x, int y)
778
void keyboard_spec(int key, int x, int y)
437
{
779
{
438
   int mod = glutGetModifiers();
780
	int mod = glutGetModifiers();
439
   if( theConsole.isOpen() ) {
781
	if( theConsole.isOpen() ) {
440
        // If shift held, scroll the console
782
		// If shift held, scroll the console
441
        if( mod == GLUT_ACTIVE_SHIFT ) {
783
		if( mod == GLUT_ACTIVE_SHIFT ) {
442
            switch (key){
784
			switch (key){
443
                case GLUT_KEY_UP:
785
				case GLUT_KEY_UP:
444
                    theConsole.ScrollDownLine();
786
					theConsole.ScrollDownLine();
445
                    break;
787
					break;
446
                case GLUT_KEY_DOWN: 
788
				case GLUT_KEY_DOWN: 
447
                    theConsole.ScrollUpLine();
789
					theConsole.ScrollUpLine();
448
                    break;
790
					break;
449
            }
791
			}
450
        } else {
792
		} else {
451
            theConsole.StandardKeyBindings( key );
793
			theConsole.StandardKeyBindings( key );
452
        }
794
		}
453
    }
795
	}
454
}
796
}
455
 
797
 
456
template<typename T>
798
template<typename T>
457
T& get_CVar_ref(const std::string& s)
799
T& get_CVar_ref(const std::string& s)
458
{
800
{
Line 460... Line 802...
460
}
802
}
461
 
803
 
462
void keyboard(unsigned char key, int x, int y) 
804
void keyboard(unsigned char key, int x, int y) 
463
{	
805
{	
464
	if(theConsole.isOpen())
806
	if(theConsole.isOpen())
465
		{
807
	{
466
		switch(key) {
808
		switch(key) {
467
			case '\033': 
809
			case '\033': 
468
				theConsole.ToggleConsole();
810
				theConsole.ToggleConsole();
469
			default:      
811
			default:      
470
				//send keystroke to console
812
				//send keystroke to console
471
				if( theConsole.isOpen() ){
813
				if( theConsole.isOpen() ){
472
					theConsole.EnterCommandCharacter(key);
814
					theConsole.EnterCommandCharacter(key);
473
				}
815
				}
474
				break;
816
				break;
475
		}
817
		}
476
		if(key == 13)	create_display_list = true;
818
		if(key == 13)	avo().post_create_display_list();
477
 
819
		
478
		}	
820
	}	
479
	else {
821
	else {
480
		int& display_eigenvalue = get_CVar_ref<int>("display.harmonics.eigenvalue");
-
 
481
		int& display_wireframe = get_CVar_ref<int>("display.wireframe");
822
		int& display_wireframe = get_CVar_ref<int>("display.wireframe");
482
		int& display_diffuse = get_CVar_ref<int>("display.harmonics.diffuse");
-
 
483
		int& display_highlight = get_CVar_ref<int>("display.harmonics.highlight");
-
 
484
		int& display_flat = get_CVar_ref<int>("display.flatshading");
823
		int& display_flat = get_CVar_ref<int>("display.flatshading");
-
 
824
		int& active  = get_CVar_ref<int>("active_mesh");
-
 
825
		
485
		
826
		
486
		switch(key) {
827
		switch(key) {
487
			case 'q': exit(0);
828
			case 'q': exit(0);
488
			case '\033':
829
			case '\033':
489
				theConsole.ToggleConsole();
830
				theConsole.ToggleConsole();
490
				break;
831
				break;
491
			case 'f': display_flat = !display_flat;
-
 
492
			case '+': 
832
			case '1':
493
				display_eigenvalue = min(display_eigenvalue+1, MAX_E); 
-
 
494
				break;
833
			case '2':
495
			case '-': 
834
			case '3':
496
				display_eigenvalue = max(display_eigenvalue-1, 0); 
-
 
497
				break;
835
			case '4':
498
			case '1': E = 1; reconstruct(mani,E); 
-
 
499
				break;
836
			case '5':
500
			case '>': if(E < MAX_E) partial_reconstruct(mani,E,++E); 
-
 
501
				break;
837
			case '6':
502
			case '<': E = max(E-1, 0); reconstruct(mani,E); 
-
 
503
				break;
838
			case '7':
504
			case 'd':	
839
			case '8':
505
				display_diffuse = !display_diffuse; 
-
 
506
				break;
840
			case '9':
507
			case 'h':
841
				active = key - '1'; break;
508
				display_highlight = !display_highlight;
842
			case 'f': display_flat = !display_flat; break;
509
				break;			
-
 
510
			case 'w':
843
			case 'w':
511
				display_wireframe = !display_wireframe;
844
				display_wireframe = !display_wireframe;
512
				break;
845
				break;
513
		}
846
		}
-
 
847
		
514
		create_display_list = true;
848
		if(get_CVar_ref<int>("display.harmonics"))
-
 
849
			avo().harmonics_parse_key(key);
515
 
850
		
-
 
851
		avo().post_create_display_list();		
516
	}
852
	}
517
}
853
}
518
 
854
 
519
void init_glut(int argc, char** argv)
855
void init_glut(int argc, char** argv)
520
{
856
{
Line 535... Line 871...
535
{
871
{
536
	glewInit();
872
	glewInit();
537
	glEnable(GL_LIGHTING);
873
	glEnable(GL_LIGHTING);
538
	glEnable(GL_LIGHT0);
874
	glEnable(GL_LIGHT0);
539
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
875
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
540
	Vec3f c(0,0,0);
-
 
541
	float r = 5;
-
 
542
	mani.get_bsphere(c,r);
-
 
543
	view_ctrl = new GLViewController(WINX,WINY, c,r*2);
-
 
544
	
876
	
545
	initialize_wireframe_shaders();
877
	initialize_wireframe_shaders();
546
	
878
	
547
	
879
	
548
	// Set the value of a uniform
880
	// Set the value of a uniform
Line 553... Line 885...
553
	glClearColor(0.50f, 0.50f, 0.50f, 0.f);
885
	glClearColor(0.50f, 0.50f, 0.50f, 0.f);
554
	glColor4f(1.0f, 1.0f, 1.0f, 0.f);
886
	glColor4f(1.0f, 1.0f, 1.0f, 0.f);
555
	glEnable(GL_DEPTH_TEST);
887
	glEnable(GL_DEPTH_TEST);
556
	
888
	
557
	static CVar<ConsoleFunc> help( "help", ConsoleHelp );
889
	static CVar<ConsoleFunc> help( "help", ConsoleHelp );
558
	static CVar<ConsoleFunc> rs("harmonics_reset_shape", console_reset_shape);
890
	static CVar<ConsoleFunc> rs("harmonics.reset_shape", console_reset_shape);
559
	static CVar<ConsoleFunc> ha("harmonics_analyze", console_analyze);
891
	static CVar<ConsoleFunc> ha("harmonics.analyze", console_analyze);
560
	static CVar<ConsoleFunc> pr("harmonics_partial_reconstruct", console_partial_reconstruct);
892
	static CVar<ConsoleFunc> pr("harmonics.partial_reconstruct", console_partial_reconstruct);
561
	static CVar<ConsoleFunc> simpl("simplify", console_simplify);
893
	static CVar<ConsoleFunc> simpl("simplify", console_simplify);
562
	static CVar<ConsoleFunc> lsmooth("laplacian_smooth", console_laplacian_smooth);
894
	static CVar<ConsoleFunc> lsmooth("smooth.laplacian", console_laplacian_smooth);
563
	static CVar<ConsoleFunc> tsmooth("taubin_smooth", console_taubin_smooth);
895
	static CVar<ConsoleFunc> tsmooth("smooth.taubin", console_taubin_smooth);
564
	static CVar<ConsoleFunc> fsmooth("fvm_smooth", console_fvm_smooth);
896
	static CVar<ConsoleFunc> fsmooth("smooth.fuzzy_vector_median", console_fvm_smooth);
565
 
897
	
566
	static CVar<ConsoleFunc> opt_val("optimize_valency", console_optimize_valency);
898
	static CVar<ConsoleFunc> opt_val("optimize.valency", console_optimize_valency);
567
	static CVar<ConsoleFunc> min_dih("minimize_dihedral", console_minimize_dihedral);
899
	static CVar<ConsoleFunc> min_dih("optimize.minimize_dihedral_angles", console_minimize_dihedral);
568
	static CVar<ConsoleFunc> min_curv("minimize_curvature", console_minimize_curvature);
900
	static CVar<ConsoleFunc> min_curv("optimize.minimize_curvature", console_minimize_curvature);
569
	static CVar<ConsoleFunc> max_min_angle("maximize_min_angle", console_maximize_min_angle);
901
	static CVar<ConsoleFunc> max_min_angle("optimize.maximize_min_angle", console_maximize_min_angle);
570
	static CVar<ConsoleFunc> close_holes_fun("close_holes", console_close_holes);
902
	static CVar<ConsoleFunc> close_holes_fun("cleanup.close_holes", console_close_holes);
571
	static CVar<ConsoleFunc> reload_fun("reload", console_reload);
903
	static CVar<ConsoleFunc> reload_fun("reload", console_reload);
572
 
904
	
573
	static CVar<ConsoleFunc> rem_caps_fun("remove_caps", console_remove_caps);
905
	static CVar<ConsoleFunc> rem_caps_fun("cleanup.remove_caps", console_remove_caps);
574
	static CVar<ConsoleFunc> rem_needles_fun("remove_needles", console_remove_needles);
906
	static CVar<ConsoleFunc> rem_needles_fun("cleanup.remove_needles", console_remove_needles);
575
	static CVar<ConsoleFunc> triangulate_fun("triangulate", console_triangulate);
907
	static CVar<ConsoleFunc> triangulate_fun("triangulate", console_triangulate);
576
	static CVar<ConsoleFunc> refine_fun("refine_edges", console_refine_edges);
908
	static CVar<ConsoleFunc> refine_fun("refine.split_edges", console_refine_edges);
577
	static CVar<ConsoleFunc> refine_face_fun("refine_faces", console_refine_faces);
909
	static CVar<ConsoleFunc> refine_face_fun("refine.split_faces", console_refine_faces);
578
	static CVar<ConsoleFunc> subd_fun("refine_catmull_clark", console_cc_subdivide);
910
	static CVar<ConsoleFunc> subd_fun("refine.catmull_clark", console_cc_subdivide);
579
	static CVar<ConsoleFunc> save_fun("save", console_save);
911
	static CVar<ConsoleFunc> save_fun("save", console_save);
-
 
912
	static CVar<ConsoleFunc> noise_fun("noise.perturb_vertices", console_vertex_noise);
-
 
913
	static CVar<ConsoleFunc> noise_fun2("noise.perturb_topology", console_noisy_flips);
-
 
914
 
-
 
915
	static CVar<ConsoleFunc> align_fun("align", console_align);
580
	
916
	
581
	
917
	
582
}
918
}
583
 
919
 
584
int main(int argc, char** argv)
920
int main(int argc, char** argv)
585
{
921
{
586
	ArgExtracter ae(argc, argv);
922
	ArgExtracter ae(argc, argv);
587
	ae.extract("-E", E);
-
 
588
    if(argc>1)
-
 
589
	{		
-
 
590
		 file = ae.get_last_arg();
-
 
591
		load(file, mani);
-
 
592
	}
-
 
593
 
-
 
594
	
923
	
595
	init_glut(argc,argv);
924
	init_glut(argc,argv);
596
	init_gl();
925
	init_gl();
-
 
926
	
597
	init_harmonics();
927
	Harmonics::init();
-
 
928
	
-
 
929
		if(argc>1)
-
 
930
	{		
-
 
931
		string file = ae.get_last_arg();
-
 
932
		avo().reload(file);
-
 
933
	}
598
 
934
 
-
 
935
	
599
	glutMainLoop();
936
	glutMainLoop();
600
}
937
}
601
 
938
 
602
 
939