Subversion Repositories gelsvn

Rev

Rev 412 | Rev 416 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 412 Rev 415
1
/*
1
/*
2
 *  MeshEdit is a small application which allows you to load and edit a mesh.
2
 *  MeshEdit is a small application which allows you to load and edit a mesh.
3
 *  The mesh will be stored in GEL's half edge based Manifold data structure.
3
 *  The mesh will be stored in GEL's half edge based Manifold data structure.
4
 *  A number of editing operations are supported. Most of these are accessible from the 
4
 *  A number of editing operations are supported. Most of these are accessible from the 
5
 *  console that pops up when you hit 'esc'.
5
 *  console that pops up when you hit 'esc'.
6
 *
6
 *
7
 *  Created by J. Andreas Bærentzen on 15/08/08.
7
 *  Created by J. Andreas Bærentzen on 15/08/08.
8
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
8
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
9
 *
9
 *
10
 */
10
 */
11
 
11
 
12
#include <string>
12
#include <string>
13
#include <iostream>
13
#include <iostream>
14
#include <CGLA/eigensolution.h>
14
#include <CGLA/eigensolution.h>
15
#include <CGLA/Vec2d.h>
15
#include <CGLA/Vec2d.h>
16
#include <CGLA/Vec3d.h>
16
#include <CGLA/Vec3d.h>
17
#include <CGLA/Mat3x3d.h>
17
#include <CGLA/Mat3x3d.h>
18
#include <CGLA/Mat2x2d.h>
18
#include <CGLA/Mat2x2d.h>
19
#include <CGLA/Mat2x3d.h>
19
#include <CGLA/Mat2x3d.h>
20
 
20
 
21
#include <LinAlg/Matrix.h>
21
#include <LinAlg/Matrix.h>
22
#include <LinAlg/Vector.h>
22
#include <LinAlg/Vector.h>
23
#include <LinAlg/LapackFunc.h>
23
#include <LinAlg/LapackFunc.h>
24
 
24
 
25
#include <Util/Timer.h>
25
#include <Util/Timer.h>
26
#include <Util/ArgExtracter.h>
26
#include <Util/ArgExtracter.h>
27
 
27
 
28
#include <GL/glew.h>
28
#include <GL/glew.h>
29
#include <GLGraphics/gel_glut.h>
29
#include <GLGraphics/gel_glut.h>
30
 
30
 
31
#include <HMesh/Manifold.h>
31
#include <HMesh/Manifold.h>
32
#include <HMesh/VertexCirculator.h>
32
#include <HMesh/VertexCirculator.h>
33
#include <HMesh/FaceCirculator.h>
33
#include <HMesh/FaceCirculator.h>
34
#include <HMesh/build_manifold.h>
34
#include <HMesh/build_manifold.h>
35
#include <HMesh/mesh_optimization.h>
35
#include <HMesh/mesh_optimization.h>
36
#include <HMesh/triangulate.h>
36
#include <HMesh/triangulate.h>
37
#include <HMesh/load.h>
37
#include <HMesh/load.h>
38
#include <HMesh/quadric_simplify.h>
38
#include <HMesh/quadric_simplify.h>
39
#include <HMesh/smooth.h>
39
#include <HMesh/smooth.h>
40
#include <HMesh/x3d_save.h>
40
#include <HMesh/x3d_save.h>
41
#include <HMesh/obj_save.h>
41
#include <HMesh/obj_save.h>
42
#include <HMesh/mesh_optimization.h>
42
#include <HMesh/mesh_optimization.h>
43
#include <HMesh/triangulate.h>
43
#include <HMesh/triangulate.h>
44
#include <HMesh/close_holes.h>
44
#include <HMesh/close_holes.h>
45
#include <HMesh/caps_and_needles.h>
45
#include <HMesh/caps_and_needles.h>
46
#include <HMesh/refine_edges.h>
46
#include <HMesh/refine_edges.h>
47
#include <HMesh/subdivision.h>
47
#include <HMesh/subdivision.h>
48
 
48
 
49
#include <GLConsole/GLConsole.h>
49
#include <GLConsole/GLConsole.h>
50
#include <Util/Timer.h>
50
#include <Util/Timer.h>
51
#include "harmonics.h"
51
#include "harmonics.h"
52
#include "curvature.h"
52
#include "curvature.h"
53
#include "Renderer.h"
53
#include "Renderer.h"
54
#include "VisObj.h"
54
#include "VisObj.h"
55
 
55
 
56
using namespace std;
56
using namespace std;
57
using namespace HMesh;
57
using namespace HMesh;
58
using namespace Geometry;
58
using namespace Geometry;
59
using namespace GLGraphics;
59
using namespace GLGraphics;
60
using namespace CGLA;
60
using namespace CGLA;
61
using namespace Util;
61
using namespace Util;
62
using namespace LinAlg;
62
using namespace LinAlg;
63
using namespace CVarUtils;
63
using namespace CVarUtils;
64
 
64
 
65
inline VisObj& get_vis_obj(int i)
65
inline VisObj& get_vis_obj(int i)
66
{
66
{
67
	static VisObj vo[9];
67
	static VisObj vo[9];
68
	return vo[i];
68
	return vo[i];
69
}
69
}
70
 
70
 
71
inline VisObj& avo()
71
inline VisObj& avo()
72
{
72
{
73
	static int& active = CreateCVar("active_mesh",0);
73
	static int& active = CreateCVar("active_mesh",0);
74
	return get_vis_obj(active);
74
	return get_vis_obj(active);
75
}
75
}
76
 
76
 
77
inline Manifold& active_mesh()
77
inline Manifold& active_mesh()
78
{
78
{
79
	return avo().mesh();
79
	return avo().mesh();
80
}
80
}
81
 
81
 
82
inline GLViewController& active_view_control()
82
inline GLViewController& active_view_control()
83
{
83
{
84
	return avo().view_control();
84
	return avo().view_control();
85
}
85
}
86
 
86
 
87
// Single global instance so glut can get access
87
// Single global instance so glut can get access
88
Trie CVarTrie;
88
Trie CVarTrie;
89
GLConsole theConsole;
89
GLConsole theConsole;
90
 
90
 
91
////////////////////////////////////////////////////////////////////////////////
91
////////////////////////////////////////////////////////////////////////////////
92
char* ConsoleHelp(std::vector<std::string> &args)
92
char* ConsoleHelp(std::vector<std::string> &args)
93
{
93
{
94
    theConsole.Printf("");
94
    theConsole.Printf("");
95
    theConsole.Printf("----------------- HELP -----------------");
95
    theConsole.Printf("----------------- HELP -----------------");
96
    theConsole.Printf("Press ESC key to open and close console");
96
    theConsole.Printf("Press ESC key to open and close console");
97
    theConsole.Printf("Press TAB to see the available commands and functions");
97
    theConsole.Printf("Press TAB to see the available commands and functions");
98
    theConsole.Printf("Functions are shown in green and variables in yellow");
98
    theConsole.Printf("Functions are shown in green and variables in yellow");
99
    theConsole.Printf("Setting a value: [command] = value");
99
    theConsole.Printf("Setting a value: [command] = value");
100
    theConsole.Printf("Getting a value: [command]");
100
    theConsole.Printf("Getting a value: [command]");
101
    theConsole.Printf("Functions: [function] [arg1] [arg2] ...");
101
    theConsole.Printf("Functions: [function] [arg1] [arg2] ...");
102
    theConsole.Printf("Entering arg1=? or arg1=help will give a description.");
102
    theConsole.Printf("Entering arg1=? or arg1=help will give a description.");
103
    theConsole.Printf("History: Up and Down arrow keys move through history.");
103
    theConsole.Printf("History: Up and Down arrow keys move through history.");
104
    theConsole.Printf("Tab Completion: TAB does tab completion and makes suggestions.");
104
    theConsole.Printf("Tab Completion: TAB does tab completion and makes suggestions.");
105
    theConsole.Printf("");
105
    theConsole.Printf("");
106
    theConsole.Printf("Keyboard commands (when console is not active):");
106
    theConsole.Printf("Keyboard commands (when console is not active):");
107
    theConsole.Printf("w   : switch to display.render_mode = wireframe");
107
    theConsole.Printf("w   : switch to display.render_mode = wireframe");
108
    theConsole.Printf("i   : switch to display.render_mode = isophotes");
108
    theConsole.Printf("i   : switch to display.render_mode = isophotes");
109
    theConsole.Printf("r   : switch to display.render_mode = reflection");
109
    theConsole.Printf("r   : switch to display.render_mode = reflection");
110
    theConsole.Printf("m   : switch to display.render_mode = metallic");
110
    theConsole.Printf("m   : switch to display.render_mode = metallic");
111
    theConsole.Printf("g   : switch to display.render_mode = glazed");
111
    theConsole.Printf("g   : switch to display.render_mode = glazed");
112
    theConsole.Printf("n   : switch to display.render_mode = normal");
112
    theConsole.Printf("n   : switch to display.render_mode = normal");
113
    theConsole.Printf("h   : switch to display.render_mode = harmonics");
113
    theConsole.Printf("h   : switch to display.render_mode = harmonics");
114
    theConsole.Printf("f   : toggle smooth/flat shading");
114
    theConsole.Printf("f   : toggle smooth/flat shading");
115
    theConsole.Printf("1-9 : switch between active meshes.");
115
    theConsole.Printf("1-9 : switch between active meshes.");
116
    theConsole.Printf("d   : (display.render_mode = harmonics) diffuse light on and off");
116
    theConsole.Printf("d   : (display.render_mode = harmonics) diffuse light on and off");
117
    theConsole.Printf("h   : (display.render_mode = harmonics) highlight on and off ");
117
    theConsole.Printf("h   : (display.render_mode = harmonics) highlight on and off ");
118
    theConsole.Printf("+/- : (display.render_mode = harmonics) which eigenvector to show");
118
    theConsole.Printf("+/- : (display.render_mode = harmonics) which eigenvector to show");
119
    theConsole.Printf("q   : quit program");
119
    theConsole.Printf("q   : quit program");
120
    theConsole.Printf("ESC : open console");
120
    theConsole.Printf("ESC : open console");
121
    theConsole.Printf("");
121
    theConsole.Printf("");
122
    theConsole.Printf("Mouse: Left button rotates, middle zooms, right pans");
122
    theConsole.Printf("Mouse: Left button rotates, middle zooms, right pans");
123
    theConsole.Printf("----------------- HELP -----------------");
123
    theConsole.Printf("----------------- HELP -----------------");
124
    theConsole.Printf("");
124
    theConsole.Printf("");
125
    return "";
125
    return "";
126
}
126
}
127
 
127
 
128
bool wantshelp(std::vector<std::string> &args)
128
bool wantshelp(std::vector<std::string> &args)
129
{
129
{
130
	if(args.size()==0) return false;
130
	if(args.size()==0) return false;
131
	string str = args[0];
131
	string str = args[0];
132
	if(str=="help" || str=="HELP" || str=="Help" || str=="?") return true;
132
	if(str=="help" || str=="HELP" || str=="Help" || str=="?") return true;
133
	return false;
133
	return false;
134
}
134
}
135
 
135
 
136
/// Function that aligns two meshes.
136
/// Function that aligns two meshes.
137
char* console_align(std::vector<std::string> &args)
137
char* console_align(std::vector<std::string> &args)
138
{
138
{
139
	if(wantshelp(args)) 
139
	if(wantshelp(args)) 
140
	{
140
	{
141
		theConsole.Printf("usage: align <dest> <src>");
141
		theConsole.Printf("usage: align <dest> <src>");
142
		theConsole.Printf("This function aligns dest mesh with src");
142
		theConsole.Printf("This function aligns dest mesh with src");
143
		theConsole.Printf("In practice the GLViewController of src is copied to dst.");
143
		theConsole.Printf("In practice the GLViewController of src is copied to dst.");
144
		theConsole.Printf("both arguments are mandatory and must be numbers between 1 and 9.");
144
		theConsole.Printf("both arguments are mandatory and must be numbers between 1 and 9.");
145
		theConsole.Printf("Note that results might be unexpexted if the meshes are not on the same scale");
145
		theConsole.Printf("Note that results might be unexpexted if the meshes are not on the same scale");
146
		return "";
146
		return "";
147
	}
147
	}
148
	
148
	
149
	int dest = 0;
149
	int dest = 0;
150
	if(args.size()>0)
150
	if(args.size()>0)
151
	{
151
	{
152
		istringstream a0(args[0]);
152
		istringstream a0(args[0]);
153
		a0 >> dest;
153
		a0 >> dest;
154
		--dest;
154
		--dest;
155
		if(dest <0 || dest>8) return "dest mesh out of range (1-9)";
155
		if(dest <0 || dest>8) return "dest mesh out of range (1-9)";
156
	}
156
	}
157
	else return "neither source nor destination mesh?!";
157
	else return "neither source nor destination mesh?!";
158
	int src = 0;
158
	int src = 0;
159
	if(args.size()>1)
159
	if(args.size()>1)
160
	{
160
	{
161
		istringstream a1(args[1]);
161
		istringstream a1(args[1]);
162
		a1 >> src;
162
		a1 >> src;
163
		--src;
163
		--src;
164
		if(src <0 || src>8) return "src mesh out of range (1-9)";
164
		if(src <0 || src>8) return "src mesh out of range (1-9)";
165
	}	
165
	}	
166
	else return "no src mesh?";
166
	else return "no src mesh?";
167
	
167
	
168
	get_vis_obj(dest).view_control() = get_vis_obj(src).view_control();
168
	get_vis_obj(dest).view_control() = get_vis_obj(src).view_control();
169
	
169
	
170
	return "";
170
	return "";
171
}
171
}
172
 
172
 
173
 
173
 
174
char* console_save(std::vector<std::string> &args)
174
char* console_save(std::vector<std::string> &args)
175
{
175
{
176
	if(wantshelp(args)) 
176
	if(wantshelp(args)) 
177
	{
177
	{
178
		theConsole.Printf("usage: save <name.x3d|name.obj> ");
178
		theConsole.Printf("usage: save <name.x3d|name.obj> ");
179
		return "";
179
		return "";
180
	}
180
	}
181
	string& file_name = args[0];
181
	string& file_name = args[0];
182
	if(args.size() == 1)
182
	if(args.size() == 1)
183
	{
183
	{
184
		if(file_name.substr(file_name.length()-4,file_name.length())==".obj")
184
		if(file_name.substr(file_name.length()-4,file_name.length())==".obj")
185
		{
185
		{
186
			obj_save(file_name, active_mesh());
186
			obj_save(file_name, active_mesh());
187
			return "";
187
			return "";
188
		}
188
		}
189
		else if(file_name.substr(file_name.length()-4,file_name.length())==".x3d")
189
		else if(file_name.substr(file_name.length()-4,file_name.length())==".x3d")
190
		{
190
		{
191
			x3d_save(file_name, active_mesh());
191
			x3d_save(file_name, active_mesh());
192
			return "";
192
			return "";
193
		}
193
		}
194
		return "unknown format";
194
		return "unknown format";
195
	}
195
	}
196
	return "usage: save <name.x3d|name.obj> ";
196
	return "usage: save <name.x3d|name.obj> ";
197
}
197
}
198
 
198
 
-
 
199
////////////////////////////////////////////////////////////////////////////////
-
 
200
/**
-
 
201
 */
199
char* console_save_history(std::vector<std::string> &args)
202
char* ConsoleSaveHistory( std::vector<std::string> &vArgs )
200
{
203
{
201
	if(wantshelp(args)) 
204
    if( vArgs.size() != 0 ) {
202
	{
-
 
203
		theConsole.Printf("usage: save_history <file> ... writes history to file");
205
        theConsole.SaveHistory( vArgs[0] );
204
		return "";
-
 
205
	}
206
    }
206
	if(args.size()>0)
207
    else {
207
	{
-
 
208
		string& file_name = args[0];
-
 
209
		theConsole.SaveHistoryScript(file_name.c_str());
208
        theConsole.SaveHistory();
210
		return "";
-
 
211
	}
209
    }
212
	return "must supply file name\n";
210
	return "";
213
}
211
}
214
 
212
 
-
 
213
////////////////////////////////////////////////////////////////////////////////
-
 
214
/**
-
 
215
 */
215
char* console_exec_script(std::vector<std::string> &args)
216
char* ConsoleLoadHistory( std::vector<std::string> &vArgs )
216
{
217
{
-
 
218
    if( vArgs.size() != 0 ) {
-
 
219
        theConsole.LoadHistory( vArgs[0] );
-
 
220
    }
-
 
221
    else {
-
 
222
        theConsole.LoadHistory();
-
 
223
    }
-
 
224
	return "";
-
 
225
}
-
 
226
 
-
 
227
////////////////////////////////////////////////////////////////////////////////
-
 
228
/**
-
 
229
 */
-
 
230
char* ConsoleClearHistory( std::vector<std::string> &vArgs )
-
 
231
{
217
	if(wantshelp(args)) 
232
	theConsole.ClearHistory();
-
 
233
	return "";
-
 
234
}
-
 
235
 
-
 
236
////////////////////////////////////////////////////////////////////////////////
-
 
237
/**
-
 
238
 */
-
 
239
char* ConsoleStartScript( std::vector<std::string> &vArgs )
-
 
240
{
-
 
241
    theConsole.StartScript();
-
 
242
	return "";
-
 
243
}
-
 
244
 
-
 
245
////////////////////////////////////////////////////////////////////////////////
-
 
246
/**
-
 
247
 */
-
 
248
char* ConsoleStopScript( std::vector<std::string> &vArgs )
218
	{
249
{
-
 
250
    theConsole.StopScript();
-
 
251
	return "";
-
 
252
}
-
 
253
 
-
 
254
////////////////////////////////////////////////////////////////////////////////
-
 
255
/**
-
 
256
 */
219
		theConsole.Printf("usage: source <file> ... runs script");
257
char* ConsoleShowScript( std::vector<std::string> &vArgs )
-
 
258
{
-
 
259
    theConsole.ShowScript();
220
		return "";
260
	return "";
-
 
261
}
-
 
262
 
-
 
263
////////////////////////////////////////////////////////////////////////////////
-
 
264
/**
-
 
265
 */
-
 
266
char* ConsoleRunScript( std::vector<std::string> &vArgs )
-
 
267
{
-
 
268
    theConsole.RunScript();
-
 
269
    return "";
221
	}
270
}
-
 
271
 
-
 
272
////////////////////////////////////////////////////////////////////////////////
-
 
273
/**
-
 
274
 */
-
 
275
char* ConsoleSaveScript( std::vector<std::string> &vArgs )
-
 
276
{
222
	if(args.size()>0)
277
    if( vArgs.size() != 0 ) {
-
 
278
        theConsole.SaveScript( vArgs[0] );
-
 
279
    }
-
 
280
    else {
-
 
281
        theConsole.SaveScript();
-
 
282
    }
-
 
283
	return "";
-
 
284
}
-
 
285
 
-
 
286
////////////////////////////////////////////////////////////////////////////////
-
 
287
/**
-
 
288
 */
-
 
289
char* ConsoleLaunchScript( std::vector<std::string> &vArgs )
223
	{
290
{
224
		string& file_name = args[0];
291
    if( vArgs.size() != 0 ) {
225
		theConsole.ExecuteScript(file_name.c_str());
292
        theConsole.LaunchScript( vArgs[0] );
-
 
293
    } 
-
 
294
    else {
-
 
295
        theConsole.LaunchScript();
-
 
296
    }
226
		return "";
297
	return "";
227
	}
298
}
-
 
299
 
-
 
300
 
-
 
301
////////////////////////////////////////////////////////////////////////////////
-
 
302
/**
-
 
303
 */
-
 
304
char* ConsoleLoad( std::vector<std::string> &vArgs )
-
 
305
{
228
	return "must supply file name\n";
306
    std::string sFile = "cvars.xml";
-
 
307
    std::vector< std::string > vAcceptedSubstrings;
-
 
308
    
-
 
309
    if( vArgs.size() > 0 ) {
-
 
310
        sFile = vArgs[0]; 
-
 
311
        for( size_t i=1; i<vArgs.size(); i++ ) {
-
 
312
            vAcceptedSubstrings.push_back( vArgs[i] );
-
 
313
        }
-
 
314
    }
-
 
315
    theConsole.Printf("Loading file from \"%s\".", sFile.c_str() );
-
 
316
    if( !CVarUtils::Load( sFile, vAcceptedSubstrings) ) {
-
 
317
        theConsole.Printf( "Error loading file.\n" );
-
 
318
    }
-
 
319
    return "";
229
}
320
}
230
 
321
 
231
 
322
 
232
char* console_refine_edges(std::vector<std::string> &args)
323
char* console_refine_edges(std::vector<std::string> &args)
233
{
324
{
234
	if(wantshelp(args)) 
325
	if(wantshelp(args)) 
235
	{
326
	{
236
		theConsole.Printf("usage: refine.split_edges <length>");
327
		theConsole.Printf("usage: refine.split_edges <length>");
237
		theConsole.Printf("splits edges longer than <length>; default is 0.5 times average length");
328
		theConsole.Printf("splits edges longer than <length>; default is 0.5 times average length");
238
		return "";
329
		return "";
239
	}
330
	}
240
	
331
	
241
	float thresh = 0.5;
332
	float thresh = 0.5;
242
	if(args.size()>0)
333
	if(args.size()>0)
243
	{
334
	{
244
		istringstream a0(args[0]);
335
		istringstream a0(args[0]);
245
		a0 >> thresh;
336
		a0 >> thresh;
246
	}
337
	}
247
	float avg_length = average_edge_length(active_mesh());
338
	float avg_length = average_edge_length(active_mesh());
248
	refine_edges(active_mesh(), thresh * avg_length);
339
	refine_edges(active_mesh(), thresh * avg_length);
249
	return "";
340
	return "";
250
	
341
	
251
}
342
}
252
 
343
 
253
char* console_refine_faces(std::vector<std::string> &args)
344
char* console_refine_faces(std::vector<std::string> &args)
254
{
345
{
255
	if(wantshelp(args)) 
346
	if(wantshelp(args)) 
256
	{
347
	{
257
		theConsole.Printf("usage: refine.split_faces ");
348
		theConsole.Printf("usage: refine.split_faces ");
258
		theConsole.Printf("usage:  Takes no arguments. Inserts a vertex at the centre of each face.");
349
		theConsole.Printf("usage:  Takes no arguments. Inserts a vertex at the centre of each face.");
259
		return "";
350
		return "";
260
	}
351
	}
261
	
352
	
262
	safe_triangulate(active_mesh());
353
	safe_triangulate(active_mesh());
263
	return "";
354
	return "";
264
	
355
	
265
}
356
}
266
 
357
 
267
char* console_cc_subdivide(std::vector<std::string> &args)
358
char* console_cc_subdivide(std::vector<std::string> &args)
268
{
359
{
269
	if(wantshelp(args)) 
360
	if(wantshelp(args)) 
270
	{
361
	{
271
		theConsole.Printf("usage: refine.catmull_clark ");
362
		theConsole.Printf("usage: refine.catmull_clark ");
272
		theConsole.Printf("Splits each polygon into four (Catmull Clark style)");
363
		theConsole.Printf("Splits each polygon into four (Catmull Clark style)");
273
		return "";
364
		return "";
274
	}
365
	}
275
	cc_split(active_mesh(),active_mesh());
366
	cc_split(active_mesh(),active_mesh());
276
	return "";
367
	return "";
277
}
368
}
278
 
369
 
279
char* console_dual(std::vector<std::string> &args)
370
char* console_dual(std::vector<std::string> &args)
280
{
371
{
281
	if(wantshelp(args)) 
372
	if(wantshelp(args)) 
282
	{
373
	{
283
		theConsole.Printf("usage: dual ");
374
		theConsole.Printf("usage: dual ");
284
		theConsole.Printf("Produces the dual by converting each face to a vertex placed at the barycenter.");
375
		theConsole.Printf("Produces the dual by converting each face to a vertex placed at the barycenter.");
285
		return "";
376
		return "";
286
	}
377
	}
287
	
378
	
288
	Manifold& m = active_mesh();
379
	Manifold& m = active_mesh();
289
	
380
	
290
	// make sure every face knows its number
381
	// make sure every face knows its number
291
	m.enumerate_faces();
382
	m.enumerate_faces();
292
	
383
	
293
	vector<Vec3f> vertices(m.no_faces());
384
	vector<Vec3f> vertices(m.no_faces());
294
	vector<int> faces;
385
	vector<int> faces;
295
	vector<int> indices;
386
	vector<int> indices;
296
	
387
	
297
	// Create new vertices. Each face becomes a vertex whose position
388
	// Create new vertices. Each face becomes a vertex whose position
298
	// is the centre of the face
389
	// is the centre of the face
299
	int i=0;
390
	int i=0;
300
	for(FaceIter f=m.faces_begin(); f!=m.faces_end(); ++f,++i)
391
	for(FaceIter f=m.faces_begin(); f!=m.faces_end(); ++f,++i)
301
		vertices[i] = centre(f);
392
		vertices[i] = centre(f);
302
	
393
	
303
	// Create new faces. Each vertex is a new face with N=valency of vertex
394
	// Create new faces. Each vertex is a new face with N=valency of vertex
304
	// edges.
395
	// edges.
305
	i=0;
396
	i=0;
306
	for(VertexIter v=m.vertices_begin(); v!= m.vertices_end(); ++v,++i)
397
	for(VertexIter v=m.vertices_begin(); v!= m.vertices_end(); ++v,++i)
307
		if(!is_boundary(v))
398
		if(!is_boundary(v))
308
		{
399
		{
309
			VertexCirculator vc(v);
400
			VertexCirculator vc(v);
310
			vector<int> index_tmp;
401
			vector<int> index_tmp;
311
			for(; !vc.end(); ++vc)
402
			for(; !vc.end(); ++vc)
312
				index_tmp.push_back(vc.get_face()->touched);
403
				index_tmp.push_back(vc.get_face()->touched);
313
			
404
			
314
			// Push vertex indices for this face onto indices vector.
405
			// Push vertex indices for this face onto indices vector.
315
			// The circulator moves around the face in a clockwise fashion
406
			// The circulator moves around the face in a clockwise fashion
316
			// so we just reverse the ordering.
407
			// so we just reverse the ordering.
317
			indices.insert(indices.end(), index_tmp.rbegin(), index_tmp.rend());
408
			indices.insert(indices.end(), index_tmp.rbegin(), index_tmp.rend());
318
			
409
			
319
			// Insert face valency in the face vector.
410
			// Insert face valency in the face vector.
320
			faces.push_back(vc.no_steps());
411
			faces.push_back(vc.no_steps());
321
		}
412
		}
322
	
413
	
323
	// Clear the manifold before new geometry is inserted.
414
	// Clear the manifold before new geometry is inserted.
324
	m.clear();
415
	m.clear();
325
	
416
	
326
	// And build
417
	// And build
327
	build_manifold(m, vertices.size(), &vertices[0], faces.size(),
418
	build_manifold(m, vertices.size(), &vertices[0], faces.size(),
328
				   &faces[0],&indices[0]);
419
				   &faces[0],&indices[0]);
329
	
420
	
330
	return "";
421
	return "";
331
}
422
}
332
 
423
 
333
 
424
 
334
char* console_minimize_curvature(std::vector<std::string> &args)
425
char* console_minimize_curvature(std::vector<std::string> &args)
335
{
426
{
336
	if(wantshelp(args)) 
427
	if(wantshelp(args)) 
337
	{
428
	{
338
		theConsole.Printf("usage: optimize.minimize_curvature <anneal>");
429
		theConsole.Printf("usage: optimize.minimize_curvature <anneal>");
339
		theConsole.Printf("Flip edges to minimize mean curvature.");
430
		theConsole.Printf("Flip edges to minimize mean curvature.");
340
		theConsole.Printf("If anneal is true, simulated annealing (slow) is used rather than a greedy scheme");
431
		theConsole.Printf("If anneal is true, simulated annealing (slow) is used rather than a greedy scheme");
341
		return "";
432
		return "";
342
	}
433
	}
343
	bool anneal=false;
434
	bool anneal=false;
344
	if(args.size()>0)
435
	if(args.size()>0)
345
	{
436
	{
346
		istringstream a0(args[0]);
437
		istringstream a0(args[0]);
347
		a0 >> anneal;
438
		a0 >> anneal;
348
	}
439
	}
349
	
440
	
350
	minimize_curvature(active_mesh(), anneal);
441
	minimize_curvature(active_mesh(), anneal);
351
	avo().post_create_display_list();
442
	avo().post_create_display_list();
352
	return "";
443
	return "";
353
}
444
}
354
 
445
 
355
char* console_minimize_dihedral(std::vector<std::string> &args)
446
char* console_minimize_dihedral(std::vector<std::string> &args)
356
{
447
{
357
	if(wantshelp(args)) 
448
	if(wantshelp(args)) 
358
	{
449
	{
359
		theConsole.Printf("usage: optimize.minimize_dihedral <iter> <anneal> <use_alpha> <gamma> ");
450
		theConsole.Printf("usage: optimize.minimize_dihedral <iter> <anneal> <use_alpha> <gamma> ");
360
		theConsole.Printf("Flip edges to minimize dihedral angles.");
451
		theConsole.Printf("Flip edges to minimize dihedral angles.");
361
		theConsole.Printf("Iter is the max number of iterations. anneal tells us whether to use ");
452
		theConsole.Printf("Iter is the max number of iterations. anneal tells us whether to use ");
362
		theConsole.Printf("simulated annealing and not greedy optimization. use_alpha (default=true) ");
453
		theConsole.Printf("simulated annealing and not greedy optimization. use_alpha (default=true) ");
363
		theConsole.Printf("means to use angle and not cosine of anglegamma (default=4) is the power ");
454
		theConsole.Printf("means to use angle and not cosine of anglegamma (default=4) is the power ");
364
		theConsole.Printf("to which we raise the dihedral angle");
455
		theConsole.Printf("to which we raise the dihedral angle");
365
		return "";
456
		return "";
366
	}
457
	}
367
	int iter = 1000;
458
	int iter = 1000;
368
	if(args.size()>0)
459
	if(args.size()>0)
369
	{
460
	{
370
		istringstream a0(args[0]);
461
		istringstream a0(args[0]);
371
		a0 >> iter;
462
		a0 >> iter;
372
	}
463
	}
373
	
464
	
374
	bool anneal = false;
465
	bool anneal = false;
375
	if(args.size()>1)
466
	if(args.size()>1)
376
	{
467
	{
377
		istringstream a0(args[0]);
468
		istringstream a0(args[0]);
378
		a0 >> anneal;
469
		a0 >> anneal;
379
	}
470
	}
380
	
471
	
381
	bool use_alpha = true;
472
	bool use_alpha = true;
382
	if(args.size()>2)
473
	if(args.size()>2)
383
	{
474
	{
384
		istringstream a0(args[0]);
475
		istringstream a0(args[0]);
385
		a0 >> use_alpha;
476
		a0 >> use_alpha;
386
	}
477
	}
387
	
478
	
388
	float gamma = 4.0;
479
	float gamma = 4.0;
389
	if(args.size()>3)
480
	if(args.size()>3)
390
	{
481
	{
391
		istringstream a0(args[0]);
482
		istringstream a0(args[0]);
392
		a0 >> gamma;
483
		a0 >> gamma;
393
	}
484
	}
394
	
485
	
395
	
486
	
396
	minimize_dihedral_angle(active_mesh(), iter, anneal, use_alpha, gamma);
487
	minimize_dihedral_angle(active_mesh(), iter, anneal, use_alpha, gamma);
397
	return "";
488
	return "";
398
}
489
}
399
 
490
 
400
char* console_maximize_min_angle(std::vector<std::string> &args)
491
char* console_maximize_min_angle(std::vector<std::string> &args)
401
{
492
{
402
	if(wantshelp(args)) 
493
	if(wantshelp(args)) 
403
	{
494
	{
404
		theConsole.Printf("usage: optimize.maximize_min_angle <thresh> <anneal>");
495
		theConsole.Printf("usage: optimize.maximize_min_angle <thresh> <anneal>");
405
		theConsole.Printf("Flip edges to maximize min angle - to make mesh more Delaunay.");
496
		theConsole.Printf("Flip edges to maximize min angle - to make mesh more Delaunay.");
406
		theConsole.Printf("If the dot product of the normals between adjacent faces < thresh");
497
		theConsole.Printf("If the dot product of the normals between adjacent faces < thresh");
407
		theConsole.Printf("no flip will be made. anneal selects simulated annealing rather ");
498
		theConsole.Printf("no flip will be made. anneal selects simulated annealing rather ");
408
		theConsole.Printf("nthan greedy optimization.");
499
		theConsole.Printf("nthan greedy optimization.");
409
		return "";
500
		return "";
410
	}
501
	}
411
	float thresh=0.0;
502
	float thresh=0.0;
412
	if(args.size()>0)
503
	if(args.size()>0)
413
	{
504
	{
414
		istringstream a0(args[0]);
505
		istringstream a0(args[0]);
415
		a0 >> thresh;
506
		a0 >> thresh;
416
	}
507
	}
417
	bool anneal=false;
508
	bool anneal=false;
418
	if(args.size()>1)
509
	if(args.size()>1)
419
	{
510
	{
420
		istringstream a0(args[0]);
511
		istringstream a0(args[0]);
421
		a0 >> anneal;
512
		a0 >> anneal;
422
	}
513
	}
423
	maximize_min_angle(active_mesh(),thresh,anneal);
514
	maximize_min_angle(active_mesh(),thresh,anneal);
424
	return "";
515
	return "";
425
}
516
}
426
 
517
 
427
 
518
 
428
char* console_optimize_valency(std::vector<std::string> &args)
519
char* console_optimize_valency(std::vector<std::string> &args)
429
{
520
{
430
	if(wantshelp(args)) 
521
	if(wantshelp(args)) 
431
	{
522
	{
432
		theConsole.Printf("usage: optimize.valency <anneal> ");
523
		theConsole.Printf("usage: optimize.valency <anneal> ");
433
		theConsole.Printf("Optimizes valency for triangle meshes. Anneal selects simulated annealing rather than greedy optim.");
524
		theConsole.Printf("Optimizes valency for triangle meshes. Anneal selects simulated annealing rather than greedy optim.");
434
		return "";
525
		return "";
435
	}
526
	}
436
	bool anneal=false;
527
	bool anneal=false;
437
	if(args.size()>0)
528
	if(args.size()>0)
438
	{
529
	{
439
		istringstream a0(args[0]);
530
		istringstream a0(args[0]);
440
		a0 >> anneal;
531
		a0 >> anneal;
441
	}
532
	}
442
	optimize_valency(active_mesh(), anneal);
533
	optimize_valency(active_mesh(), anneal);
443
	return "";
534
	return "";
444
}
535
}
445
 
536
 
446
char* console_analyze(std::vector<std::string> &args)
537
char* console_analyze(std::vector<std::string> &args)
447
{
538
{
448
	if(wantshelp(args)) 
539
	if(wantshelp(args)) 
449
	{
540
	{
450
		theConsole.Printf("usage:  harmonics.analyze");
541
		theConsole.Printf("usage:  harmonics.analyze");
451
		theConsole.Printf("Creates the Laplace Beltrami operator for the mesh and finds all eigensolutions.");
542
		theConsole.Printf("Creates the Laplace Beltrami operator for the mesh and finds all eigensolutions.");
452
		theConsole.Printf("It also projects the vertices onto the eigenvectors - thus transforming the mesh");
543
		theConsole.Printf("It also projects the vertices onto the eigenvectors - thus transforming the mesh");
453
		theConsole.Printf("to this basis.");
544
		theConsole.Printf("to this basis.");
454
		theConsole.Printf("Note that this will stall the computer for a large mesh - as long as we use Lapack.");
545
		theConsole.Printf("Note that this will stall the computer for a large mesh - as long as we use Lapack.");
455
		return "";
546
		return "";
456
	}
547
	}
457
	avo().harmonics_analyze_mesh();
548
	avo().harmonics_analyze_mesh();
458
	return "";
549
	return "";
459
}
550
}
460
 
551
 
461
 
552
 
462
char* console_partial_reconstruct(std::vector<std::string> &args)
553
char* console_partial_reconstruct(std::vector<std::string> &args)
463
{
554
{
464
  if(args.size() != 3)
555
  if(args.size() != 3)
465
		theConsole.Printf("usage: haramonics.partial_reconstruct <e0> <e1> <s>");
556
		theConsole.Printf("usage: haramonics.partial_reconstruct <e0> <e1> <s>");
466
 
557
 
467
  if(wantshelp(args)) 
558
  if(wantshelp(args)) 
468
	{
559
	{
469
		theConsole.Printf("Reconstruct from projections onto eigenvectors. The two first arguments indicate");
560
		theConsole.Printf("Reconstruct from projections onto eigenvectors. The two first arguments indicate");
470
		theConsole.Printf("the eigenvector interval that we reconstruct from. The last argument is the ");
561
		theConsole.Printf("the eigenvector interval that we reconstruct from. The last argument is the ");
471
		theConsole.Printf("scaling factor. Thus, for a vertex, v, the formula for computing the position, p, is:");
562
		theConsole.Printf("scaling factor. Thus, for a vertex, v, the formula for computing the position, p, is:");
472
		theConsole.Printf("for (i=e0; i<=e1;++i) p += proj[i] * Q[i][v] * s;");
563
		theConsole.Printf("for (i=e0; i<=e1;++i) p += proj[i] * Q[i][v] * s;");
473
		theConsole.Printf("where proj[i] is the 3D vector containing the x, y, and z projections of the mesh onto");
564
		theConsole.Printf("where proj[i] is the 3D vector containing the x, y, and z projections of the mesh onto");
474
		theConsole.Printf("eigenvector i. Q[i][v] is the v'th coordinate of the i'th eigenvector.");
565
		theConsole.Printf("eigenvector i. Q[i][v] is the v'th coordinate of the i'th eigenvector.");
475
		theConsole.Printf("Note that if vertex coordinates are not first reset, the result is probably unexpected.");
566
		theConsole.Printf("Note that if vertex coordinates are not first reset, the result is probably unexpected.");
476
	}
567
	}
477
 
568
 
478
  if(args.size() != 3)
569
  if(args.size() != 3)
479
		return "";
570
		return "";
480
 
571
 
481
  int E0,E1;
572
  int E0,E1;
482
	float scale;
573
	float scale;
483
	istringstream a0(args[0]);
574
	istringstream a0(args[0]);
484
	a0 >> E0;
575
	a0 >> E0;
485
	istringstream a1(args[1]);
576
	istringstream a1(args[1]);
486
	a1 >> E1;
577
	a1 >> E1;
487
	istringstream a2(args[2]);
578
	istringstream a2(args[2]);
488
	a2 >> scale;
579
	a2 >> scale;
489
	avo().harmonics_partial_reconstruct(E0,E1,scale);
580
	avo().harmonics_partial_reconstruct(E0,E1,scale);
490
	return "";
581
	return "";
491
}
582
}
492
 
583
 
493
char* console_reset_shape(std::vector<std::string> &args)
584
char* console_reset_shape(std::vector<std::string> &args)
494
{
585
{
495
	if(wantshelp(args)) 
586
	if(wantshelp(args)) 
496
	{
587
	{
497
		theConsole.Printf("usage: harmonics.reset_shape ");
588
		theConsole.Printf("usage: harmonics.reset_shape ");
498
		theConsole.Printf("Simply sets all vertices to 0,0,0. Call this before doing partial_reconstruct");
589
		theConsole.Printf("Simply sets all vertices to 0,0,0. Call this before doing partial_reconstruct");
499
		theConsole.Printf("unless you know what you are doing.");
590
		theConsole.Printf("unless you know what you are doing.");
500
		return "";
591
		return "";
501
	}
592
	}
502
	avo().harmonics_reset_shape();
593
	avo().harmonics_reset_shape();
503
	return "";
594
	return "";
504
}
595
}
505
 
596
 
506
 
597
 
507
char* console_close_holes(std::vector<std::string> &args)
598
char* console_close_holes(std::vector<std::string> &args)
508
{
599
{
509
	if(wantshelp(args)) 
600
	if(wantshelp(args)) 
510
	{
601
	{
511
		theConsole.Printf("usage: cleanup.close_holes");
602
		theConsole.Printf("usage: cleanup.close_holes");
512
		theConsole.Printf("This function closes holes. It simply follows the loop of halfvectors which");
603
		theConsole.Printf("This function closes holes. It simply follows the loop of halfvectors which");
513
		theConsole.Printf("enclose the hole and add a face to which they all point.");
604
		theConsole.Printf("enclose the hole and add a face to which they all point.");
514
		return "";
605
		return "";
515
	}
606
	}
516
	close_holes(active_mesh());
607
	close_holes(active_mesh());
517
	return "";
608
	return "";
518
}
609
}
519
 
610
 
520
char* console_reload(std::vector<std::string> &args)
611
char* console_reload(std::vector<std::string> &args)
521
{
612
{
522
	if(wantshelp(args)) 
613
	if(wantshelp(args)) 
523
	{
614
	{
524
		theConsole.Printf("usage:  load <file>");
615
		theConsole.Printf("usage:  load <file>");
525
		theConsole.Printf("(Re)loads the current file if no argument is given, but");
616
		theConsole.Printf("(Re)loads the current file if no argument is given, but");
526
		theConsole.Printf("if an argument is given, then that becomes the current file");
617
		theConsole.Printf("if an argument is given, then that becomes the current file");
527
		return "";
618
		return "";
528
	}
619
	}
529
	if(!avo().reload(args.size()>0 ? args[0]:""))
620
	if(!avo().reload(args.size()>0 ? args[0]:""))
530
		return "failed to load";
621
		return "failed to load";
531
	return "";
622
	return "";
532
}
623
}
533
 
624
 
534
 
625
 
535
char* console_simplify(std::vector<std::string> &args)
626
char* console_simplify(std::vector<std::string> &args)
536
{
627
{
537
	if(wantshelp(args)) 
628
	if(wantshelp(args)) 
538
	{
629
	{
539
		theConsole.Printf("usage: simplify <fraction> ");
630
		theConsole.Printf("usage: simplify <fraction> ");
540
		theConsole.Printf("Performs Garland Heckbert (quadric based) mesh simplification.");
631
		theConsole.Printf("Performs Garland Heckbert (quadric based) mesh simplification.");
541
		theConsole.Printf("The only argument is the fraction of vertices to keep.");
632
		theConsole.Printf("The only argument is the fraction of vertices to keep.");
542
		return "";
633
		return "";
543
	}
634
	}
544
	float keep_fraction;
635
	float keep_fraction;
545
	if(args.size()==0) return "you must specify fraction of vertices to keep";
636
	if(args.size()==0) return "you must specify fraction of vertices to keep";
546
	istringstream a0(args[0]);
637
	istringstream a0(args[0]);
547
	a0 >> keep_fraction;
638
	a0 >> keep_fraction;
548
	
639
	
549
	Vec3f p0, p7;
640
	Vec3f p0, p7;
550
	active_mesh().get_bbox(p0, p7);
641
	active_mesh().get_bbox(p0, p7);
551
	Vec3f d = p7-p0;
642
	Vec3f d = p7-p0;
552
	float s = 1.0/d.max_coord();
643
	float s = 1.0/d.max_coord();
553
	Vec3f pcentre = (p7+p0)/2.0;
644
	Vec3f pcentre = (p7+p0)/2.0;
554
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
645
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
555
		vi->pos = (vi->pos - pcentre) * s;
646
		vi->pos = (vi->pos - pcentre) * s;
556
	quadric_simplify(active_mesh(),keep_fraction,0.0001f,true);
647
	quadric_simplify(active_mesh(),keep_fraction,0.0001f,true);
557
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
648
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
558
		vi->pos = vi->pos*d.max_coord() + pcentre;
649
		vi->pos = vi->pos*d.max_coord() + pcentre;
559
	return "";
650
	return "";
560
}
651
}
561
 
652
 
562
char* console_vertex_noise(std::vector<std::string> &args)
653
char* console_vertex_noise(std::vector<std::string> &args)
563
{
654
{
564
	if(wantshelp(args)) 
655
	if(wantshelp(args)) 
565
	{
656
	{
566
		theConsole.Printf("usage: noise.perturb_vertices <amplitude>");
657
		theConsole.Printf("usage: noise.perturb_vertices <amplitude>");
567
		theConsole.Printf("adds a random vector to each vertex. A random vector in the unit cube is generated and");
658
		theConsole.Printf("adds a random vector to each vertex. A random vector in the unit cube is generated and");
568
		theConsole.Printf("to ensure an isotropic distribution, vectors outside the unit ball are discarded.");
659
		theConsole.Printf("to ensure an isotropic distribution, vectors outside the unit ball are discarded.");
569
		theConsole.Printf("The vector is multiplied by the average edge length and then by the amplitude specified.");
660
		theConsole.Printf("The vector is multiplied by the average edge length and then by the amplitude specified.");
570
		theConsole.Printf("If no amplitude is specified, the default (0.5) is used.");
661
		theConsole.Printf("If no amplitude is specified, the default (0.5) is used.");
571
		return "";
662
		return "";
572
	}
663
	}
573
	float avg_length = average_edge_length(active_mesh());
664
	float avg_length = average_edge_length(active_mesh());
574
	
665
	
575
	float noise_amplitude = 0.5;
666
	float noise_amplitude = 0.5;
576
	if(args.size()>0) 
667
	if(args.size()>0) 
577
	{
668
	{
578
		istringstream a0(args[0]);
669
		istringstream a0(args[0]);
579
		a0 >> noise_amplitude;
670
		a0 >> noise_amplitude;
580
	}
671
	}
581
	
672
	
582
	srand(0);
673
	srand(0);
583
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
674
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
584
	{
675
	{
585
		Vec3f v;
676
		Vec3f v;
586
		do {
677
		do {
587
			v = Vec3f(rand(),rand(),rand());
678
			v = Vec3f(rand(),rand(),rand());
588
			v /= RAND_MAX;
679
			v /= RAND_MAX;
589
		} while(sqr_length(v) > 1.0);
680
		} while(sqr_length(v) > 1.0);
590
		v -= Vec3f(0.5);
681
		v -= Vec3f(0.5);
591
		v *= 2.0;
682
		v *= 2.0;
592
		v *= noise_amplitude;
683
		v *= noise_amplitude;
593
		v *= avg_length;
684
		v *= avg_length;
594
		vi->pos += v;
685
		vi->pos += v;
595
	}		
686
	}		
596
	return "";
687
	return "";
597
}
688
}
598
 
689
 
599
char* console_perpendicular_vertex_noise(std::vector<std::string> &args)
690
char* console_perpendicular_vertex_noise(std::vector<std::string> &args)
600
{
691
{
601
	if(wantshelp(args)) 
692
	if(wantshelp(args)) 
602
	{
693
	{
603
		theConsole.Printf("usage: noise.perturb_vertices_perpendicular <amplitude>");
694
		theConsole.Printf("usage: noise.perturb_vertices_perpendicular <amplitude>");
604
		theConsole.Printf("adds the normal times a random scalar times amplitude times");
695
		theConsole.Printf("adds the normal times a random scalar times amplitude times");
605
		theConsole.Printf("times average edge length to the vertex. (default amplitude=0.5)");
696
		theConsole.Printf("times average edge length to the vertex. (default amplitude=0.5)");
606
		return "";
697
		return "";
607
	}
698
	}
608
	float avg_length = average_edge_length(active_mesh());
699
	float avg_length = average_edge_length(active_mesh());
609
	
700
	
610
	float noise_amplitude = 0.5;
701
	float noise_amplitude = 0.5;
611
	if(args.size()>0) 
702
	if(args.size()>0) 
612
	{
703
	{
613
		istringstream a0(args[0]);
704
		istringstream a0(args[0]);
614
		a0 >> noise_amplitude;
705
		a0 >> noise_amplitude;
615
	}
706
	}
616
	
707
	
617
	vector<Vec3f> normals(active_mesh().no_vertices());
708
	vector<Vec3f> normals(active_mesh().no_vertices());
618
	int i=0;
709
	int i=0;
619
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi,++i)
710
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi,++i)
620
		normals[i] = normal(vi);
711
		normals[i] = normal(vi);
621
	i=0;
712
	i=0;
622
	srandom(0);
713
	srandom(0);
623
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi,++i)
714
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi,++i)
624
	{
715
	{
625
		float rval = 0.5-random()/float(RAND_MAX);
716
		float rval = 0.5-random()/float(RAND_MAX);
626
		vi->pos += normals[i]*rval*noise_amplitude*avg_length*2.0;
717
		vi->pos += normals[i]*rval*noise_amplitude*avg_length*2.0;
627
	}
718
	}
628
	return "";
719
	return "";
629
}
720
}
630
 
721
 
631
char* console_noisy_flips(std::vector<std::string> &args)
722
char* console_noisy_flips(std::vector<std::string> &args)
632
{
723
{
633
	if(wantshelp(args)) 
724
	if(wantshelp(args)) 
634
	{
725
	{
635
		theConsole.Printf("usage:  noise.perturb_topology <iter>");
726
		theConsole.Printf("usage:  noise.perturb_topology <iter>");
636
		theConsole.Printf("Perform random flips. iter (default=1) is the number of iterations.");
727
		theConsole.Printf("Perform random flips. iter (default=1) is the number of iterations.");
637
		theConsole.Printf("mostly for making nasty synthetic test cases.");
728
		theConsole.Printf("mostly for making nasty synthetic test cases.");
638
		return "";
729
		return "";
639
	}
730
	}
640
	int iter=1;
731
	int iter=1;
641
	if(args.size()>0)
732
	if(args.size()>0)
642
	{
733
	{
643
		istringstream a0(args[0]);
734
		istringstream a0(args[0]);
644
		a0 >> iter;
735
		a0 >> iter;
645
	}
736
	}
646
	
737
	
647
	randomize_mesh(active_mesh(),  iter);
738
	randomize_mesh(active_mesh(),  iter);
648
	return "";
739
	return "";
649
}
740
}
650
 
741
 
651
char* console_laplacian_smooth(std::vector<std::string> &args)
742
char* console_laplacian_smooth(std::vector<std::string> &args)
652
{
743
{
653
	if(wantshelp(args)) 
744
	if(wantshelp(args)) 
654
	{
745
	{
655
		theConsole.Printf("usage:  smooth.laplacian <weight> <iter>");
746
		theConsole.Printf("usage:  smooth.laplacian <weight> <iter>");
656
		theConsole.Printf("Perform Laplacian smoothing. weight is the scaling factor for the Laplacian.");
747
		theConsole.Printf("Perform Laplacian smoothing. weight is the scaling factor for the Laplacian.");
657
		theConsole.Printf("default weight = 1.0. Default number of iterations = 1");
748
		theConsole.Printf("default weight = 1.0. Default number of iterations = 1");
658
		return "";
749
		return "";
659
	}
750
	}
660
	float t=1.0;
751
	float t=1.0;
661
	if(args.size()>0)
752
	if(args.size()>0)
662
	{
753
	{
663
		istringstream a0(args[0]);
754
		istringstream a0(args[0]);
664
		a0 >> t;
755
		a0 >> t;
665
	}
756
	}
666
	int iter=1;
757
	int iter=1;
667
	if(args.size()>1)
758
	if(args.size()>1)
668
	{
759
	{
669
		istringstream a0(args[1]);
760
		istringstream a0(args[1]);
670
		a0 >> iter;
761
		a0 >> iter;
671
	}
762
	}
672
	
763
	
673
	/// Simple laplacian smoothing with an optional weight.
764
	/// Simple laplacian smoothing with an optional weight.
674
	for(int i=0;i<iter;++i) laplacian_smooth(active_mesh(), t);
765
	for(int i=0;i<iter;++i) laplacian_smooth(active_mesh(), t);
675
	return "";
766
	return "";
676
}
767
}
677
 
768
 
678
char* console_mean_curvature_smooth(std::vector<std::string> &args)
769
char* console_mean_curvature_smooth(std::vector<std::string> &args)
679
{
770
{
680
	if(wantshelp(args)) 
771
	if(wantshelp(args)) 
681
	{
772
	{
682
		theConsole.Printf("usage:  smooth.mean_curvature <weight> <iter>");
773
		theConsole.Printf("usage:  smooth.mean_curvature <weight> <iter>");
683
		theConsole.Printf("Perform mean curvature smoothing. weight is the scaling factor for the");
774
		theConsole.Printf("Perform mean curvature smoothing. weight is the scaling factor for the");
684
		theConsole.Printf("mean curvature vector which has been normalized by dividing by edge lengths");
775
		theConsole.Printf("mean curvature vector which has been normalized by dividing by edge lengths");
685
		theConsole.Printf("this allows for larger steps as suggested by Desbrun et al.");
776
		theConsole.Printf("this allows for larger steps as suggested by Desbrun et al.");
686
		theConsole.Printf("default weight = 1.0. Default number of iterations = 1");
777
		theConsole.Printf("default weight = 1.0. Default number of iterations = 1");
687
		return "";
778
		return "";
688
	}
779
	}
689
	float t=1.0;
780
	float t=1.0;
690
	if(args.size()>0)
781
	if(args.size()>0)
691
	{
782
	{
692
		istringstream a0(args[0]);
783
		istringstream a0(args[0]);
693
		a0 >> t;
784
		a0 >> t;
694
	}
785
	}
695
	int iter=1;
786
	int iter=1;
696
	if(args.size()>1)
787
	if(args.size()>1)
697
	{
788
	{
698
		istringstream a0(args[1]);
789
		istringstream a0(args[1]);
699
		a0 >> iter;
790
		a0 >> iter;
700
	}	
791
	}	
701
	vector<Vec3d> new_pos(active_mesh().no_vertices());
792
	vector<Vec3d> new_pos(active_mesh().no_vertices());
702
	for(int j=0;j<iter;++j)
793
	for(int j=0;j<iter;++j)
703
	{
794
	{
704
		int i=0;
795
		int i=0;
705
		for(VertexIter v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v,++i) {
796
		for(VertexIter v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v,++i) {
706
			Vec3d m;
797
			Vec3d m;
707
			double w_sum;
798
			double w_sum;
708
			unnormalized_mean_curvature_normal(v, m, w_sum);
799
			unnormalized_mean_curvature_normal(v, m, w_sum);
709
			new_pos[i] = Vec3d(v->pos)  - (t * m/w_sum);
800
			new_pos[i] = Vec3d(v->pos)  - (t * m/w_sum);
710
		}
801
		}
711
		i=0;
802
		i=0;
712
		for(VertexIter v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v,++i)
803
		for(VertexIter v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v,++i)
713
			v->pos = Vec3f(new_pos[i]);
804
			v->pos = Vec3f(new_pos[i]);
714
	}
805
	}
715
	return "";
806
	return "";
716
}
807
}
717
 
808
 
718
 
809
 
719
char* console_taubin_smooth(std::vector<std::string> &args)
810
char* console_taubin_smooth(std::vector<std::string> &args)
720
{
811
{
721
	if(wantshelp(args)) 
812
	if(wantshelp(args)) 
722
	{
813
	{
723
		theConsole.Printf("usage:  smooth.taubin <iter>");
814
		theConsole.Printf("usage:  smooth.taubin <iter>");
724
		theConsole.Printf("Perform Taubin smoothing. iter (default=1) is the number of iterations.");
815
		theConsole.Printf("Perform Taubin smoothing. iter (default=1) is the number of iterations.");
725
		return "";
816
		return "";
726
	}
817
	}
727
	int iter=1;
818
	int iter=1;
728
	if(args.size()>0)
819
	if(args.size()>0)
729
	{
820
	{
730
		istringstream a0(args[0]);
821
		istringstream a0(args[0]);
731
		a0 >> iter;
822
		a0 >> iter;
732
	}
823
	}
733
	
824
	
734
	/// Taubin smoothing is similar to laplacian smoothing but reduces shrinkage
825
	/// Taubin smoothing is similar to laplacian smoothing but reduces shrinkage
735
	taubin_smooth(active_mesh(),  iter);
826
	taubin_smooth(active_mesh(),  iter);
736
	return "";
827
	return "";
737
}
828
}
738
 
829
 
739
char* console_fvm_smooth(std::vector<std::string> &args)
830
char* console_fvm_smooth(std::vector<std::string> &args)
740
{	
831
{	
741
	if(wantshelp(args)) 
832
	if(wantshelp(args)) 
742
	{
833
	{
743
		theConsole.Printf("usage: smooth.fuzzy_vector_median <iter>");
834
		theConsole.Printf("usage: smooth.fuzzy_vector_median <iter>");
744
		theConsole.Printf("Smooth normals using fuzzy vector median smoothing. iter (default=1) is the number of iterations");
835
		theConsole.Printf("Smooth normals using fuzzy vector median smoothing. iter (default=1) is the number of iterations");
745
		theConsole.Printf("This function does a very good job of preserving sharp edges.");
836
		theConsole.Printf("This function does a very good job of preserving sharp edges.");
746
		return "";
837
		return "";
747
	}
838
	}
748
	int iter=1;
839
	int iter=1;
749
	if(args.size()>0)
840
	if(args.size()>0)
750
	{
841
	{
751
		istringstream a0(args[0]);
842
		istringstream a0(args[0]);
752
		a0 >> iter;
843
		a0 >> iter;
753
	}
844
	}
754
	/** Fuzzy vector median smoothing is effective when it comes to
845
	/** Fuzzy vector median smoothing is effective when it comes to
755
	 preserving sharp edges. */
846
	 preserving sharp edges. */
756
	fvm_smooth(active_mesh(),  iter);
847
	fvm_smooth(active_mesh(),  iter);
757
	return "";
848
	return "";
758
	
849
	
759
}
850
}
760
 
851
 
761
char* console_triangulate(std::vector<std::string> &args)
852
char* console_triangulate(std::vector<std::string> &args)
762
{	
853
{	
763
	if(wantshelp(args)) 
854
	if(wantshelp(args)) 
764
	{
855
	{
765
		theConsole.Printf("usage:  triangulate");
856
		theConsole.Printf("usage:  triangulate");
766
		theConsole.Printf("This function triangulates all non triangular faces of the mesh.");
857
		theConsole.Printf("This function triangulates all non triangular faces of the mesh.");
767
		theConsole.Printf("you may want to call it after hole closing. For a polygon it simply connects");
858
		theConsole.Printf("you may want to call it after hole closing. For a polygon it simply connects");
768
		theConsole.Printf("the two closest vertices in a recursive manner until only triangles remain");
859
		theConsole.Printf("the two closest vertices in a recursive manner until only triangles remain");
769
		return "";
860
		return "";
770
	}
861
	}
771
	shortest_edge_triangulate(active_mesh());
862
	shortest_edge_triangulate(active_mesh());
772
	return "";
863
	return "";
773
}
864
}
774
 
865
 
775
 
866
 
776
char* console_remove_caps(std::vector<std::string> &args)
867
char* console_remove_caps(std::vector<std::string> &args)
777
{	
868
{	
778
	if(wantshelp(args)) 
869
	if(wantshelp(args)) 
779
	{
870
	{
780
		theConsole.Printf("usage:  cleanup.remove_caps thresh");
871
		theConsole.Printf("usage:  cleanup.remove_caps thresh");
781
		theConsole.Printf("Remove caps (triangles with one very big angle). The thresh argument is the fraction of PI to");
872
		theConsole.Printf("Remove caps (triangles with one very big angle). The thresh argument is the fraction of PI to");
782
		theConsole.Printf("use as threshold for big angle. Default is 0.85. Caps are removed by flipping.");
873
		theConsole.Printf("use as threshold for big angle. Default is 0.85. Caps are removed by flipping.");
783
		return "";
874
		return "";
784
	}
875
	}
785
	float t=0.85;
876
	float t=0.85;
786
	if(args.size()>0)
877
	if(args.size()>0)
787
	{
878
	{
788
		istringstream a0(args[0]);
879
		istringstream a0(args[0]);
789
		a0 >> t;
880
		a0 >> t;
790
	}
881
	}
791
	
882
	
792
	remove_caps_from_trimesh(active_mesh(), static_cast<float>(M_PI) *t);
883
	remove_caps_from_trimesh(active_mesh(), static_cast<float>(M_PI) *t);
793
	return "";
884
	return "";
794
}
885
}
795
 
886
 
796
char* console_remove_needles(std::vector<std::string> &args)
887
char* console_remove_needles(std::vector<std::string> &args)
797
{	
888
{	
798
	if(wantshelp(args)) 
889
	if(wantshelp(args)) 
799
	{
890
	{
800
		theConsole.Printf("usage: cleanup.remove_needles <thresh>");
891
		theConsole.Printf("usage: cleanup.remove_needles <thresh>");
801
		theConsole.Printf("Removes very short edges by collapse. thresh is multiplied by the average edge length");
892
		theConsole.Printf("Removes very short edges by collapse. thresh is multiplied by the average edge length");
802
		theConsole.Printf("to get the length shorter than which we collapse. Default = 0.1");
893
		theConsole.Printf("to get the length shorter than which we collapse. Default = 0.1");
803
		return "";
894
		return "";
804
	}
895
	}
805
	float thresh = 0.1;
896
	float thresh = 0.1;
806
	if(args.size()>0)
897
	if(args.size()>0)
807
	{
898
	{
808
		istringstream a0(args[0]);
899
		istringstream a0(args[0]);
809
		a0 >> thresh;
900
		a0 >> thresh;
810
	}
901
	}
811
	float avg_length = average_edge_length(active_mesh());
902
	float avg_length = average_edge_length(active_mesh());
812
	remove_needles_from_trimesh(active_mesh(), thresh * avg_length);
903
	remove_needles_from_trimesh(active_mesh(), thresh * avg_length);
813
	return "";
904
	return "";
814
}
905
}
815
 
906
 
816
void reshape(int W, int H)
907
void reshape(int W, int H)
817
{
908
{
818
	active_view_control().reshape(W,H);
909
	active_view_control().reshape(W,H);
819
}
910
}
820
 
911
 
821
void display() 
912
void display() 
822
{
913
{
823
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
914
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
824
	
915
	
825
	static string& display_render_mode = CreateCVar<string>("display.render_mode","");
916
	static string& display_render_mode = CreateCVar<string>("display.render_mode","");
826
	static int& display_smooth= CreateCVar<int>("display.smooth_shading",1);
917
	static int& display_smooth= CreateCVar<int>("display.smooth_shading",1);
827
	
918
	
828
	glPushMatrix();
919
	glPushMatrix();
829
	
920
	
830
	avo().display(display_render_mode, display_smooth);
921
	avo().display(display_render_mode, display_smooth);
831
	
922
	
832
	glPopMatrix();
923
	glPopMatrix();
833
	
924
	
834
	glUseProgram(0);
925
	glUseProgram(0);
835
	theConsole.RenderConsole();
926
	theConsole.RenderConsole();
836
	
927
	
837
	glutSwapBuffers();
928
	glutSwapBuffers();
838
}
929
}
839
 
930
 
840
void animate() 
931
void animate() 
841
{	
932
{	
842
	//usleep( (int)1e4 );
933
	//usleep( (int)1e4 );
843
	active_view_control().try_spin();
934
	active_view_control().try_spin();
844
	glutPostRedisplay();
935
	glutPostRedisplay();
845
}
936
}
846
 
937
 
847
 
938
 
848
void mouse(int button, int state, int x, int y) 
939
void mouse(int button, int state, int x, int y) 
849
{
940
{
850
	Vec2i pos(x,y);
941
	Vec2i pos(x,y);
851
	if (state==GLUT_DOWN) 
942
	if (state==GLUT_DOWN) 
852
	{
943
	{
853
		if (button==GLUT_LEFT_BUTTON) 
944
		if (button==GLUT_LEFT_BUTTON) 
854
			active_view_control().grab_ball(ROTATE_ACTION,pos);
945
			active_view_control().grab_ball(ROTATE_ACTION,pos);
855
		else if (button==GLUT_MIDDLE_BUTTON) 
946
		else if (button==GLUT_MIDDLE_BUTTON) 
856
			active_view_control().grab_ball(ZOOM_ACTION,pos);
947
			active_view_control().grab_ball(ZOOM_ACTION,pos);
857
		else if (button==GLUT_RIGHT_BUTTON) 
948
		else if (button==GLUT_RIGHT_BUTTON) 
858
			active_view_control().grab_ball(PAN_ACTION,pos);
949
			active_view_control().grab_ball(PAN_ACTION,pos);
859
	}
950
	}
860
	else if (state==GLUT_UP)
951
	else if (state==GLUT_UP)
861
		active_view_control().release_ball();
952
		active_view_control().release_ball();
862
}
953
}
863
 
954
 
864
void motion(int x, int y) {
955
void motion(int x, int y) {
865
	Vec2i pos(x,y);
956
	Vec2i pos(x,y);
866
	active_view_control().roll_ball(Vec2i(x,y));
957
	active_view_control().roll_ball(Vec2i(x,y));
867
}
958
}
868
 
959
 
869
void keyboard_spec(int key, int x, int y)
960
void keyboard_spec(int key, int x, int y)
870
{
961
{
871
	int mod = glutGetModifiers();
962
	int mod = glutGetModifiers();
872
	if( theConsole.IsOpen() ) {
963
	if( theConsole.IsOpen() ) {
873
		// If shift held, scroll the console
964
		// If shift held, scroll the console
874
		if( mod == GLUT_ACTIVE_SHIFT ) {
965
		if( mod == GLUT_ACTIVE_SHIFT ) {
875
			switch (key){
966
			switch (key){
876
				case GLUT_KEY_UP:
967
				case GLUT_KEY_UP:
877
					theConsole.ScrollDownLine();
968
					theConsole.ScrollDownLine();
878
					break;
969
					break;
879
				case GLUT_KEY_DOWN: 
970
				case GLUT_KEY_DOWN: 
880
					theConsole.ScrollUpLine();
971
					theConsole.ScrollUpLine();
881
					break;
972
					break;
882
			}
973
			}
883
		} else {
974
		} else {
884
			theConsole.StandardKeyBindings( key );
975
			theConsole.StandardKeyBindings( key );
885
		}
976
		}
886
	}
977
	}
887
}
978
}
888
 
979
 
889
 
980
 
890
void keyboard(unsigned char key, int x, int y) 
981
void keyboard(unsigned char key, int x, int y) 
891
{	
982
{	
892
	if(theConsole.IsOpen())
983
	if(theConsole.IsOpen())
893
	{
984
	{
894
		switch(key) {
985
		switch(key) {
895
			case '\033': 
986
			case '\033': 
896
				theConsole.ToggleConsole();
987
				theConsole.ToggleConsole();
897
			default:
988
			default:
898
				theConsole.EnterCommandCharacter(key);
989
				theConsole.EnterCommandCharacter(key);
899
			break;
990
			break;
900
		}
991
		}
901
		if(key == 13)	avo().post_create_display_list();
992
		if(key == 13)	avo().post_create_display_list();
902
		
993
		
903
	}	
994
	}	
904
	else {
995
	else {
905
		string& display_render_mode = GetCVarRef<string>("display.render_mode");
996
		string& display_render_mode = GetCVarRef<string>("display.render_mode");
906
		int& display_smooth = GetCVarRef<int>("display.smooth_shading");
997
		int& display_smooth = GetCVarRef<int>("display.smooth_shading");
907
		int& active  = GetCVarRef<int>("active_mesh");
998
		int& active  = GetCVarRef<int>("active_mesh");
908
		
999
		
909
		
1000
		
910
		switch(key) {
1001
		switch(key) {
911
			case 'q': exit(0);
1002
			case 'q': exit(0);
912
			case '\033':
1003
			case '\033':
913
				theConsole.ToggleConsole();
1004
				theConsole.ToggleConsole();
914
				break;
1005
				break;
915
			case '1':
1006
			case '1':
916
			case '2':
1007
			case '2':
917
			case '3':
1008
			case '3':
918
			case '4':
1009
			case '4':
919
			case '5':
1010
			case '5':
920
			case '6':
1011
			case '6':
921
			case '7':
1012
			case '7':
922
			case '8':
1013
			case '8':
923
			case '9':
1014
			case '9':
924
				active = key - '1'; break;
1015
				active = key - '1'; break;
925
			case 'f': display_smooth = !display_smooth; break;
1016
			case 'f': display_smooth = !display_smooth; break;
926
			case 'w':
1017
			case 'w':
927
				display_render_mode = "wire"; break;
1018
				display_render_mode = "wire"; break;
928
			case 'n':
1019
			case 'n':
929
				display_render_mode = "normal"; break;
1020
				display_render_mode = "normal"; break;
930
			case 'i':
1021
			case 'i':
931
				display_render_mode = "isophotes"; break;
1022
				display_render_mode = "isophotes"; break;
932
			case 'r':
1023
			case 'r':
933
				display_render_mode = "reflection"; break;
1024
				display_render_mode = "reflection"; break;
934
			case 'h':
1025
			case 'h':
935
				display_render_mode = "harmonics"; break;
1026
				display_render_mode = "harmonics"; break;
936
			case 't':
1027
			case 't':
937
				display_render_mode = "toon"; break;
1028
				display_render_mode = "toon"; break;
938
			case 'g':
1029
			case 'g':
939
				display_render_mode = "glazed"; break;
1030
				display_render_mode = "glazed"; break;
940
			case 'a':
1031
			case 'a':
941
				display_render_mode = "ambient_occlusion"; break;
1032
				display_render_mode = "ambient_occlusion"; break;
942
			case 'c':
1033
			case 'c':
943
				display_render_mode = "copper"; break;
1034
				display_render_mode = "copper"; break;
944
			case 'C':
1035
			case 'C':
945
				display_render_mode = "curvature_lines"; break;
1036
				display_render_mode = "curvature_lines"; break;
946
			case 'M':
1037
			case 'M':
947
				display_render_mode = "mean_curvature"; break;
1038
				display_render_mode = "mean_curvature"; break;
948
			case 'G':
1039
			case 'G':
949
				display_render_mode = "gaussian_curvature"; break;
1040
				display_render_mode = "gaussian_curvature"; break;
950
		}
1041
		}
951
		
1042
		
952
		if(display_render_mode.substr(0,4) == "harm")
1043
		if(display_render_mode.substr(0,4) == "harm")
953
			avo().harmonics_parse_key(key);
1044
			avo().harmonics_parse_key(key);
954
		
1045
		
955
		if(key != '\033') avo().post_create_display_list();		
1046
		if(key != '\033') avo().post_create_display_list();		
956
	}
1047
	}
957
}
1048
}
958
 
1049
 
959
void init_glut(int argc, char** argv)
1050
void init_glut(int argc, char** argv)
960
{
1051
{
961
	glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_ALPHA);
1052
	glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_ALPHA);
962
	glutInitWindowSize(WINX, WINY);
1053
	glutInitWindowSize(WINX, WINY);
963
	glutInit(&argc, argv);
1054
	glutInit(&argc, argv);
964
	glutCreateWindow("Shape Harmonics");
1055
	glutCreateWindow("Shape Harmonics");
965
	glutDisplayFunc(display);
1056
	glutDisplayFunc(display);
966
	glutKeyboardFunc(keyboard);
1057
	glutKeyboardFunc(keyboard);
967
	glutSpecialFunc(keyboard_spec);
1058
	glutSpecialFunc(keyboard_spec);
968
	glutReshapeFunc(reshape);
1059
	glutReshapeFunc(reshape);
969
	glutMouseFunc(mouse);
1060
	glutMouseFunc(mouse);
970
	glutMotionFunc(motion);
1061
	glutMotionFunc(motion);
971
	glutIdleFunc(animate);
1062
	glutIdleFunc(animate);
972
}
1063
}
973
 
1064
 
974
void init_gl()
1065
void init_gl()
975
{
1066
{
976
	glewInit();
1067
	glewInit();
977
	glEnable(GL_LIGHTING);
1068
	glEnable(GL_LIGHTING);
978
	glEnable(GL_LIGHT0);
1069
	glEnable(GL_LIGHT0);
979
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
1070
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
980
	
1071
	
981
	// Set the value of a uniform
1072
	// Set the value of a uniform
982
	//glUniform2f(glGetUniformLocation(prog_P0,"WIN_SCALE"), win_size_x/2.0, win_size_y/2.0);
1073
	//glUniform2f(glGetUniformLocation(prog_P0,"WIN_SCALE"), win_size_x/2.0, win_size_y/2.0);
983
	
1074
	
984
	glMatrixMode(GL_MODELVIEW);
1075
	glMatrixMode(GL_MODELVIEW);
985
	glLoadIdentity();
1076
	glLoadIdentity();
986
	glClearColor(0.50f, 0.50f, 0.50f, 0.f);
1077
	glClearColor(0.50f, 0.50f, 0.50f, 0.f);
987
	glColor4f(1.0f, 1.0f, 1.0f, 0.f);
1078
	glColor4f(1.0f, 1.0f, 1.0f, 0.f);
988
	float material[4] = {1,1,1,1};
1079
	float material[4] = {1,1,1,1};
989
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material);
1080
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material);
990
	glEnable(GL_DEPTH_TEST);
1081
	glEnable(GL_DEPTH_TEST);
991
	
1082
	
992
	CreateCVar( "help", ConsoleHelp );
1083
	CreateCVar( "help", ConsoleHelp );
993
	CreateCVar("harmonics.reset_shape", console_reset_shape);
1084
	CreateCVar("harmonics.reset_shape", console_reset_shape);
994
	CreateCVar("harmonics.analyze", console_analyze);
1085
	CreateCVar("harmonics.analyze", console_analyze);
995
	CreateCVar("harmonics.partial_reconstruct", console_partial_reconstruct);
1086
	CreateCVar("harmonics.partial_reconstruct", console_partial_reconstruct);
996
	CreateCVar("simplify", console_simplify);
1087
	CreateCVar("simplify", console_simplify);
997
	CreateCVar("smooth.mean_curvature", console_mean_curvature_smooth);
1088
	CreateCVar("smooth.mean_curvature", console_mean_curvature_smooth);
998
	CreateCVar("smooth.laplacian", console_laplacian_smooth);
1089
	CreateCVar("smooth.laplacian", console_laplacian_smooth);
999
	CreateCVar("smooth.taubin", console_taubin_smooth);
1090
	CreateCVar("smooth.taubin", console_taubin_smooth);
1000
	CreateCVar("smooth.fuzzy_vector_median", console_fvm_smooth);
1091
	CreateCVar("smooth.fuzzy_vector_median", console_fvm_smooth);
1001
	
1092
	
1002
	CreateCVar("optimize.valency", console_optimize_valency);
1093
	CreateCVar("optimize.valency", console_optimize_valency);
1003
	CreateCVar("optimize.minimize_dihedral_angles", console_minimize_dihedral);
1094
	CreateCVar("optimize.minimize_dihedral_angles", console_minimize_dihedral);
1004
	CreateCVar("optimize.minimize_curvature", console_minimize_curvature);
1095
	CreateCVar("optimize.minimize_curvature", console_minimize_curvature);
1005
	CreateCVar("optimize.maximize_min_angle", console_maximize_min_angle);
1096
	CreateCVar("optimize.maximize_min_angle", console_maximize_min_angle);
1006
	CreateCVar("cleanup.close_holes", console_close_holes);
1097
	CreateCVar("cleanup.close_holes", console_close_holes);
1007
	CreateCVar("load", console_reload);
1098
	CreateCVar("load", console_reload);
1008
	
1099
	
1009
	CreateCVar("cleanup.remove_caps", console_remove_caps);
1100
	CreateCVar("cleanup.remove_caps", console_remove_caps);
1010
	CreateCVar("cleanup.remove_needles", console_remove_needles);
1101
	CreateCVar("cleanup.remove_needles", console_remove_needles);
1011
	CreateCVar("triangulate", console_triangulate);
1102
	CreateCVar("triangulate", console_triangulate);
1012
	CreateCVar("refine.split_edges", console_refine_edges);
1103
	CreateCVar("refine.split_edges", console_refine_edges);
1013
	CreateCVar("refine.split_faces", console_refine_faces);
1104
	CreateCVar("refine.split_faces", console_refine_faces);
1014
	CreateCVar("refine.catmull_clark", console_cc_subdivide);
1105
	CreateCVar("refine.catmull_clark", console_cc_subdivide);
1015
	CreateCVar("save", console_save);
1106
	CreateCVar("save", console_save);
1016
	CreateCVar("noise.perturb_vertices", console_vertex_noise);
1107
	CreateCVar("noise.perturb_vertices", console_vertex_noise);
1017
	CreateCVar("noise.perturb_vertices_perpendicular", console_perpendicular_vertex_noise);
1108
	CreateCVar("noise.perturb_vertices_perpendicular", console_perpendicular_vertex_noise);
1018
	CreateCVar("noise.perturb_topology", console_noisy_flips);
1109
	CreateCVar("noise.perturb_topology", console_noisy_flips);
1019
	
1110
	
1020
	CreateCVar("dual", console_dual);
1111
	CreateCVar("dual", console_dual);
1021
	
1112
	
1022
	CreateCVar("align", console_align);
1113
	CreateCVar("align", console_align);
-
 
1114
	
1023
	CreateCVar("save_history", console_save_history);
1115
	CVarUtils::CreateCVar( "history.load", ConsoleLoadHistory );
-
 
1116
    CVarUtils::CreateCVar( "history.save", ConsoleSaveHistory );
-
 
1117
    CVarUtils::CreateCVar( "history.clear", ConsoleClearHistory );
-
 
1118
	
-
 
1119
    CVarUtils::CreateCVar( "script.start", ConsoleStartScript );
-
 
1120
    CVarUtils::CreateCVar( "script.stop", ConsoleStopScript );
-
 
1121
    CVarUtils::CreateCVar( "script.show", ConsoleShowScript );
-
 
1122
    CVarUtils::CreateCVar( "script.run", ConsoleRunScript );
-
 
1123
    CVarUtils::CreateCVar( "script.save", ConsoleSaveScript );
1024
	CreateCVar("source", console_exec_script);
1124
    CVarUtils::CreateCVar( "script.launch", ConsoleLaunchScript );
1025
	
1125
	
1026
	
1126
	
1027
}
1127
}
1028
 
1128
 
1029
int main(int argc, char** argv)
1129
int main(int argc, char** argv)
1030
{
1130
{
1031
	ArgExtracter ae(argc, argv);
1131
	ArgExtracter ae(argc, argv);
1032
	
1132
	
1033
	init_glut(argc,argv);
1133
	init_glut(argc,argv);
1034
	init_gl();
1134
	init_gl();
1035
	
1135
	
1036
	Harmonics::init();
1136
	Harmonics::init();
1037
	
1137
	
1038
	if(argc>1)
1138
	if(argc>1)
1039
	{		
1139
	{		
1040
		string file = ae.get_last_arg();
1140
		string file = ae.get_last_arg();
1041
		avo().reload(file);
1141
		avo().reload(file);
1042
	}
1142
	}
1043
	
1143
	
1044
	
1144
	
1045
	glutMainLoop();
1145
	glutMainLoop();
1046
}
1146
}
1047
 
1147
 
1048
 
1148
 
1049
 
1149