Subversion Repositories gelsvn

Rev

Rev 631 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 631 Rev 643
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 <vector>
14
#include <vector>
15
#include <algorithm>
15
#include <algorithm>
16
 
16
 
17
#include <GL/glew.h>
17
#include <GL/glew.h>
18
 
18
 
19
#include <GLGraphics/Console.h>
19
#include <GLGraphics/Console.h>
20
 
20
 
21
 
21
 
22
#include <CGLA/eigensolution.h>
22
#include <CGLA/eigensolution.h>
23
#include <CGLA/Vec2d.h>
23
#include <CGLA/Vec2d.h>
24
#include <CGLA/Vec3d.h>
24
#include <CGLA/Vec3d.h>
25
#include <CGLA/Mat3x3d.h>
25
#include <CGLA/Mat3x3d.h>
26
#include <CGLA/Mat2x2d.h>
26
#include <CGLA/Mat2x2d.h>
27
#include <CGLA/Mat2x3d.h>
27
#include <CGLA/Mat2x3d.h>
28
#include <CGLA/Mat4x4d.h>
28
#include <CGLA/Mat4x4d.h>
29
 
29
 
30
#include <LinAlg/Matrix.h>
30
#include <LinAlg/Matrix.h>
31
#include <LinAlg/Vector.h>
31
#include <LinAlg/Vector.h>
32
#include <LinAlg/LapackFunc.h>
32
#include <LinAlg/LapackFunc.h>
33
 
33
 
34
#include <GLGraphics/gel_glut.h>
34
#include <GLGraphics/gel_glut.h>
35
 
35
 
36
#include <HMesh/Manifold.h>
36
#include <HMesh/Manifold.h>
37
#include <HMesh/AttributeVector.h>
37
#include <HMesh/AttributeVector.h>
38
#include <HMesh/mesh_optimization.h>
38
#include <HMesh/mesh_optimization.h>
39
#include <HMesh/curvature.h>
39
#include <HMesh/curvature.h>
40
#include <HMesh/triangulate.h>
40
#include <HMesh/triangulate.h>
41
#include <HMesh/flatten.h>
41
#include <HMesh/flatten.h>
42
#include <HMesh/dual.h>
42
#include <HMesh/dual.h>
43
#include <HMesh/load.h>
43
#include <HMesh/load.h>
44
#include <HMesh/quadric_simplify.h>
44
#include <HMesh/quadric_simplify.h>
45
#include <HMesh/smooth.h>
45
#include <HMesh/smooth.h>
46
#include <HMesh/x3d_save.h>
46
#include <HMesh/x3d_save.h>
47
#include <HMesh/obj_save.h>
47
#include <HMesh/obj_save.h>
48
#include <HMesh/off_save.h>
48
#include <HMesh/off_save.h>
49
#include <HMesh/mesh_optimization.h>
49
#include <HMesh/mesh_optimization.h>
50
#include <HMesh/triangulate.h>
50
#include <HMesh/triangulate.h>
51
#include <HMesh/cleanup.h>
51
#include <HMesh/cleanup.h>
52
#include <HMesh/cleanup.h>
52
#include <HMesh/cleanup.h>
53
#include <HMesh/refine_edges.h>
53
#include <HMesh/refine_edges.h>
54
#include <HMesh/subdivision.h>
54
#include <HMesh/subdivision.h>
55
 
55
 
56
#include <Util/Timer.h>
56
#include <Util/Timer.h>
57
#include <Util/ArgExtracter.h>
57
#include <Util/ArgExtracter.h>
58
 
58
 
59
#include "polarize.h"
59
#include "polarize.h"
60
#include "harmonics.h"
60
#include "harmonics.h"
61
#include "VisObj.h"
61
#include "VisObj.h"
62
 
62
 
63
using namespace std;
63
using namespace std;
64
using namespace HMesh;
64
using namespace HMesh;
65
using namespace Geometry;
65
using namespace Geometry;
66
using namespace GLGraphics;
66
using namespace GLGraphics;
67
using namespace CGLA;
67
using namespace CGLA;
68
using namespace Util;
68
using namespace Util;
69
using namespace LinAlg;
69
using namespace LinAlg;
70
 
70
 
71
// Single global instance so glut can get access
71
// Single global instance so glut can get access
72
Console theConsole;
72
Console theConsole;
73
bool console_visible = false;
73
bool console_visible = false;
74
 
74
 
75
 
75
 
76
inline VisObj& get_vis_obj(int i)
76
inline VisObj& get_vis_obj(int i)
77
{
77
{
78
    static VisObj vo[9];
78
    static VisObj vo[9];
79
    return vo[i];
79
    return vo[i];
80
}
80
}
81
 
81
 
82
Console::variable<int> active(0);
82
Console::variable<int> active(0);
83
 
83
 
84
inline VisObj& avo()
84
inline VisObj& avo()
85
{
85
{
86
    return get_vis_obj(active);
86
    return get_vis_obj(active);
87
}
87
}
88
 
88
 
89
inline Manifold& active_mesh()
89
inline Manifold& active_mesh()
90
{
90
{
91
    return avo().mesh();
91
    return avo().mesh();
92
}
92
}
93
 
93
 
94
inline GLViewController& active_view_control()
94
inline GLViewController& active_view_control()
95
{
95
{
96
    return avo().view_control();
96
    return avo().view_control();
97
}
97
}
98
 
98
 
99
 
99
 
100
 
100
 
101
////////////////////////////////////////////////////////////////////////////////
101
////////////////////////////////////////////////////////////////////////////////
102
bool MyConsoleHelp(const std::vector<std::string> & args)
102
bool MyConsoleHelp(const std::vector<std::string> & args)
103
{
103
{
104
    theConsole.printf("");
104
    theConsole.printf("");
105
    theConsole.printf("----------------- HELP -----------------");
105
    theConsole.printf("----------------- HELP -----------------");
106
    theConsole.printf("Press ESC key to open and close console");
106
    theConsole.printf("Press ESC key to open and close console");
107
    theConsole.printf("Press TAB to see the available commands and functions");
107
    theConsole.printf("Press TAB to see the available commands and functions");
108
    theConsole.printf("Functions are shown in green and variables in yellow");
108
    theConsole.printf("Functions are shown in green and variables in yellow");
109
    theConsole.printf("Setting a value: [command] = value");
109
    theConsole.printf("Setting a value: [command] = value");
110
    theConsole.printf("Getting a value: [command]");
110
    theConsole.printf("Getting a value: [command]");
111
    theConsole.printf("Functions: [function] [arg1] [arg2] ...");
111
    theConsole.printf("Functions: [function] [arg1] [arg2] ...");
112
    theConsole.printf("Entering arg1=? or arg1=help will give a description.");
112
    theConsole.printf("Entering arg1=? or arg1=help will give a description.");
113
    theConsole.printf("History: Up and Down arrow keys move through history.");
113
    theConsole.printf("History: Up and Down arrow keys move through history.");
114
    theConsole.printf("Tab Completion: TAB does tab completion and makes suggestions.");
114
    theConsole.printf("Tab Completion: TAB does tab completion and makes suggestions.");
115
    theConsole.printf("");
115
    theConsole.printf("");
116
    theConsole.printf("Keyboard commands (when console is not active):");
116
    theConsole.printf("Keyboard commands (when console is not active):");
117
    theConsole.printf("w   : switch to display.render_mode = wireframe");
117
    theConsole.printf("w   : switch to display.render_mode = wireframe");
118
    theConsole.printf("i   : switch to display.render_mode = isophotes");
118
    theConsole.printf("i   : switch to display.render_mode = isophotes");
119
    theConsole.printf("r   : switch to display.render_mode = reflection");
119
    theConsole.printf("r   : switch to display.render_mode = reflection");
120
    theConsole.printf("m   : switch to display.render_mode = metallic");
120
    theConsole.printf("m   : switch to display.render_mode = metallic");
121
    theConsole.printf("g   : switch to display.render_mode = glazed");
121
    theConsole.printf("g   : switch to display.render_mode = glazed");
122
    theConsole.printf("n   : switch to display.render_mode = normal");
122
    theConsole.printf("n   : switch to display.render_mode = normal");
123
    theConsole.printf("h   : switch to display.render_mode = harmonics");
123
    theConsole.printf("h   : switch to display.render_mode = harmonics");
124
    theConsole.printf("f   : toggle smooth/flat shading");
124
    theConsole.printf("f   : toggle smooth/flat shading");
125
    theConsole.printf("1-9 : switch between active meshes.");
125
    theConsole.printf("1-9 : switch between active meshes.");
126
    theConsole.printf("d   : (display.render_mode = harmonics) diffuse light on and off");
126
    theConsole.printf("d   : (display.render_mode = harmonics) diffuse light on and off");
127
    theConsole.printf("h   : (display.render_mode = harmonics) highlight on and off ");
127
    theConsole.printf("h   : (display.render_mode = harmonics) highlight on and off ");
128
    theConsole.printf("+/- : (display.render_mode = harmonics) which eigenvector to show");
128
    theConsole.printf("+/- : (display.render_mode = harmonics) which eigenvector to show");
129
    theConsole.printf("q   : quit program");
129
    theConsole.printf("q   : quit program");
130
    theConsole.printf("ESC : open console");
130
    theConsole.printf("ESC : open console");
131
    theConsole.printf("");
131
    theConsole.printf("");
132
    theConsole.printf("Mouse: Left button rotates, middle zooms, right pans");
132
    theConsole.printf("Mouse: Left button rotates, middle zooms, right pans");
133
    theConsole.printf("----------------- HELP -----------------");
133
    theConsole.printf("----------------- HELP -----------------");
134
    theConsole.printf("");
134
    theConsole.printf("");
135
    return true;
135
    return true;
136
}
136
}
137
 
137
 
138
bool wantshelp(const std::vector<std::string> & args)
138
bool wantshelp(const std::vector<std::string> & args)
139
{
139
{
140
    if(args.size() == 0) 
140
    if(args.size() == 0) 
141
        return false;
141
        return false;
142
	
142
	
143
    string str = args[0];
143
    string str = args[0];
144
	
144
	
145
    if(str=="help" || str=="HELP" || str=="Help" || str=="?") 
145
    if(str=="help" || str=="HELP" || str=="Help" || str=="?") 
146
        return true;
146
        return true;
147
	
147
	
148
    return false;
148
    return false;
149
}
149
}
150
 
150
 
151
/// Function that aligns two meshes.
151
/// Function that aligns two meshes.
152
void console_align(const std::vector<std::string> & args)
152
void console_align(const std::vector<std::string> & args)
153
{
153
{
154
    if(wantshelp(args)) {
154
    if(wantshelp(args)) {
155
        theConsole.printf("usage: align <dest> <src>");
155
        theConsole.printf("usage: align <dest> <src>");
156
        theConsole.printf("This function aligns dest mesh with src");
156
        theConsole.printf("This function aligns dest mesh with src");
157
        theConsole.printf("In practice the GLViewController of src is copied to dst.");
157
        theConsole.printf("In practice the GLViewController of src is copied to dst.");
158
        theConsole.printf("both arguments are mandatory and must be numbers between 1 and 9.");
158
        theConsole.printf("both arguments are mandatory and must be numbers between 1 and 9.");
159
        theConsole.printf("Note that results might be unexpexted if the meshes are not on the same scale");
159
        theConsole.printf("Note that results might be unexpexted if the meshes are not on the same scale");
160
    }
160
    }
161
	
161
	
162
    int dest = 0;
162
    int dest = 0;
163
	
163
	
164
    if(args.size()>0){
164
    if(args.size()>0){
165
        istringstream a0(args[0]);
165
        istringstream a0(args[0]);
166
        a0 >> dest;
166
        a0 >> dest;
167
        --dest;
167
        --dest;
168
		
168
		
169
        if(dest <0 || dest>8)
169
        if(dest <0 || dest>8)
170
        {
170
        {
171
            theConsole.printf("dest mesh out of range (1-9)");
171
            theConsole.printf("dest mesh out of range (1-9)");
172
            return;
172
            return;
173
        }
173
        }
174
    }
174
    }
175
    else
175
    else
176
    {
176
    {
177
        theConsole.printf("neither source nor destination mesh?!");
177
        theConsole.printf("neither source nor destination mesh?!");
178
        return;
178
        return;
179
    }
179
    }
180
	
180
	
181
    int src = 0;
181
    int src = 0;
182
    if(args.size()>1){
182
    if(args.size()>1){
183
        istringstream a1(args[1]);
183
        istringstream a1(args[1]);
184
        a1 >> src;
184
        a1 >> src;
185
        --src;
185
        --src;
186
		
186
		
187
        if(src <0 || src>8)
187
        if(src <0 || src>8)
188
        {
188
        {
189
            theConsole.printf("src mesh out of range (1-9)");
189
            theConsole.printf("src mesh out of range (1-9)");
190
            return;
190
            return;
191
        }
191
        }
192
    }
192
    }
193
    else
193
    else
194
    {
194
    {
195
        theConsole.printf("no src mesh?");
195
        theConsole.printf("no src mesh?");
196
        return;
196
        return;
197
    }
197
    }
198
    get_vis_obj(dest).view_control() = get_vis_obj(src).view_control();
198
    get_vis_obj(dest).view_control() = get_vis_obj(src).view_control();
199
}
199
}
200
 
200
 
201
void console_polarize(const std::vector<std::string> & args)
201
void console_polarize(const std::vector<std::string> & args)
202
{
202
{
203
    if(wantshelp(args)) {
203
    if(wantshelp(args)) {
204
        theConsole.printf("usage: polarize");
204
        theConsole.printf("usage: polarize");
205
        return;
205
        return;
206
    }
206
    }
207
    int divisions = 10;
207
    int divisions = 50;
208
	
208
	
209
    if(args.size() > 0){
209
    if(args.size() > 0){
210
        istringstream a0(args[0]);
210
        istringstream a0(args[0]);
211
        a0 >> divisions;
211
        a0 >> divisions;
212
    }
212
    }
213
 
213
 
-
 
214
    double t=1;
-
 
215
	
-
 
216
    if(args.size() > 1){
-
 
217
        istringstream a0(args[1]);
-
 
218
        a0 >> t;
-
 
219
    }
-
 
220
 
214
    avo().save_old();
221
    avo().save_old();
215
 
222
 
216
	double vmin, vmax;
223
	double vmin, vmax;
217
    VertexAttributeVector<double> fun;
224
    VertexAttributeVector<double> fun;
218
    VertexAttributeVector<Vec2d> par;
225
    VertexAttributeVector<Vec2d> par;
219
    make_height_fun(active_mesh(), fun, vmin, vmax);
226
    make_adf_fun(active_mesh(), t, fun, vmin, vmax);
220
    polarize_mesh(active_mesh(), fun, vmin, vmax, divisions, par);
227
    polarize_mesh(active_mesh(), fun, vmin, vmax, divisions, par);
221
}
228
}
222
 
229
 
-
 
230
void console_simplify_polar(const std::vector<std::string> & args)
-
 
231
{
-
 
232
    if(wantshelp(args)) {
-
 
233
        theConsole.printf("usage: simplify.polar <frac>");
-
 
234
        return;
-
 
235
    }
-
 
236
    double frac = 0.9;
-
 
237
    if(args.size() > 0){
-
 
238
        istringstream a0(args[0]);
-
 
239
        a0 >> frac;
-
 
240
    }
-
 
241
    
-
 
242
    
-
 
243
    avo().save_old();
-
 
244
    
-
 
245
    simplify_polar_mesh(avo().mesh(), frac);
-
 
246
}
-
 
247
 
-
 
248
void console_refit_polar(const std::vector<std::string> & args)
-
 
249
{
-
 
250
    if(wantshelp(args)) {
-
 
251
        theConsole.printf("usage: simplify.polar <mesh 1> <mesh 2> <iter>");
-
 
252
        return;
-
 
253
    }
-
 
254
    int m1=1;
-
 
255
    int m2=2;
-
 
256
    int iter=1;
-
 
257
    int dim = 64;
-
 
258
    if(args.size() > 0){
-
 
259
        istringstream a0(args[0]);
-
 
260
        a0 >> m1;
-
 
261
    }
-
 
262
    if(args.size() > 1){
-
 
263
        istringstream a0(args[1]);
-
 
264
        a0 >> m2;
-
 
265
    }
-
 
266
    if(args.size() > 2){
-
 
267
        istringstream a0(args[2]);
-
 
268
        a0 >> iter;
-
 
269
    }
-
 
270
 
-
 
271
    if(args.size() > 3){
-
 
272
        istringstream a0(args[3]);
-
 
273
        a0 >> dim;
-
 
274
    }
-
 
275
 
-
 
276
    
-
 
277
    
-
 
278
    avo().save_old();
-
 
279
    
-
 
280
    smooth_and_refit(get_vis_obj(m1-1).mesh() , get_vis_obj(m2-1).mesh(), iter, dim);
-
 
281
}
-
 
282
 
-
 
283
 
223
void transform_mesh(Manifold& mani, const Mat4x4d& m)
284
void transform_mesh(Manifold& mani, const Mat4x4d& m)
224
{
285
{
225
    for(VertexIDIterator vid = mani.vertices_begin(); vid != mani.vertices_end(); ++vid)
286
    for(VertexIDIterator vid = mani.vertices_begin(); vid != mani.vertices_end(); ++vid)
226
        mani.pos(*vid) = m.mul_3D_point(mani.pos(*vid));
287
        mani.pos(*vid) = m.mul_3D_point(mani.pos(*vid));
227
}
288
}
228
 
289
 
229
void console_scale(const std::vector<std::string> & args)
290
void console_scale(const std::vector<std::string> & args)
230
{
291
{
231
    if(wantshelp(args)) {
292
    if(wantshelp(args)) {
232
        theConsole.printf("usage: scale sx sy sz");
293
        theConsole.printf("usage: scale sx sy sz");
233
        return;
294
        return;
234
    }
295
    }
235
    
296
    
236
    Vec3d s;
297
    Vec3d s;
237
 
298
 
238
    if(args.size() > 0){
299
    if(args.size() > 0){
239
        istringstream a0(args[0]);
300
        istringstream a0(args[0]);
240
        a0 >> s[0];
301
        a0 >> s[0];
241
    }
302
    }
242
    if(args.size() > 1){
303
    if(args.size() > 1){
243
        istringstream a0(args[0]);
304
        istringstream a0(args[0]);
244
        a0 >> s[1];
305
        a0 >> s[1];
245
    }
306
    }
246
    if(args.size() > 2){
307
    if(args.size() > 2){
247
        istringstream a0(args[0]);
308
        istringstream a0(args[0]);
248
        a0 >> s[2];
309
        a0 >> s[2];
249
    }
310
    }
250
    
311
    
251
    avo().save_old();
312
    avo().save_old();
252
    transform_mesh(avo().mesh(),scaling_Mat4x4d(s));
313
    transform_mesh(avo().mesh(),scaling_Mat4x4d(s));
253
    avo().refit();
314
    avo().refit();
254
}
315
}
255
 
316
 
256
 
317
 
257
void console_flatten(const std::vector<std::string> & args)
318
void console_flatten(const std::vector<std::string> & args)
258
{
319
{
259
    if(wantshelp(args)) {
320
    if(wantshelp(args)) {
260
        theConsole.printf("usage: flatten <floater|harmonic|barycentric>");
321
        theConsole.printf("usage: flatten <floater|harmonic|barycentric>");
261
        theConsole.printf("This function flattens a meshs with a simple boundary. It is mostly for showing mesh");
322
        theConsole.printf("This function flattens a meshs with a simple boundary. It is mostly for showing mesh");
262
        theConsole.printf("parametrization methods. The current mesh MUST have a SINGLE boundary loop");
323
        theConsole.printf("parametrization methods. The current mesh MUST have a SINGLE boundary loop");
263
        theConsole.printf("This loop is mapped to the unit circle in a regular fashion (equal angle intervals).");
324
        theConsole.printf("This loop is mapped to the unit circle in a regular fashion (equal angle intervals).");
264
        theConsole.printf("All non boundary vertices are placed at the origin. Then the system is relaxed iteratively");
325
        theConsole.printf("All non boundary vertices are placed at the origin. Then the system is relaxed iteratively");
265
        theConsole.printf("using the weight scheme given as argument.");
326
        theConsole.printf("using the weight scheme given as argument.");
266
        return;
327
        return;
267
    }
328
    }
268
	
329
	
269
    avo().save_old();
330
    avo().save_old();
270
	
331
	
271
    WeightScheme ws = BARYCENTRIC_W;
332
    WeightScheme ws = BARYCENTRIC_W;
272
    if(args.size()>0){
333
    if(args.size()>0){
273
        if(args[0] == "floater")
334
        if(args[0] == "floater")
274
            ws = FLOATER_W;
335
            ws = FLOATER_W;
275
        else if(args[0] == "harmonic")
336
        else if(args[0] == "harmonic")
276
            ws = HARMONIC_W;
337
            ws = HARMONIC_W;
277
        else if(args[0] == "lscm")
338
        else if(args[0] == "lscm")
278
            ws = LSCM_W;
339
            ws = LSCM_W;
279
    }
340
    }
280
    else
341
    else
281
        return;
342
        return;
282
	
343
	
283
    flatten(active_mesh(), ws);
344
    flatten(active_mesh(), ws);
284
	
345
	
285
    return;
346
    return;
286
}
347
}
287
 
348
 
288
void console_save(const std::vector<std::string> & args)
349
void console_save(const std::vector<std::string> & args)
289
{
350
{
290
    if(wantshelp(args)) {
351
    if(wantshelp(args)) {
291
        theConsole.printf("usage: save <name.x3d|name.obj> ");
352
        theConsole.printf("usage: save <name.x3d|name.obj> ");
292
		
353
		
293
        return;
354
        return;
294
    }
355
    }
295
    const string& file_name = args[0];
356
    const string& file_name = args[0];
296
    if(args.size() == 1){
357
    if(args.size() == 1){
297
        if(file_name.substr(file_name.length()-4,file_name.length())==".obj"){
358
        if(file_name.substr(file_name.length()-4,file_name.length())==".obj"){
298
            obj_save(file_name, active_mesh());
359
            obj_save(file_name, active_mesh());
299
			
360
			
300
            return;
361
            return;
301
        }
362
        }
302
        else if(file_name.substr(file_name.length()-4,file_name.length())==".off"){
363
        else if(file_name.substr(file_name.length()-4,file_name.length())==".off"){
303
            off_save(file_name, active_mesh());
364
            off_save(file_name, active_mesh());
304
			
365
			
305
            return;
366
            return;
306
        }
367
        }
307
        else if(file_name.substr(file_name.length()-4,file_name.length())==".x3d"){
368
        else if(file_name.substr(file_name.length()-4,file_name.length())==".x3d"){
308
            x3d_save(file_name, active_mesh());
369
            x3d_save(file_name, active_mesh());
309
			
370
			
310
            return;
371
            return;
311
        }
372
        }
312
        theConsole.printf("unknown format");
373
        theConsole.printf("unknown format");
313
        return; 
374
        return; 
314
    }
375
    }
315
    theConsole.printf("usage: save <name.x3d|name.obj> ");
376
    theConsole.printf("usage: save <name.x3d|name.obj> ");
316
}
377
}
317
 
378
 
318
 
379
 
319
void console_refine_edges(const std::vector<std::string> & args)
380
void console_refine_edges(const std::vector<std::string> & args)
320
{
381
{
321
    if(wantshelp(args)) {
382
    if(wantshelp(args)) {
322
        theConsole.printf("usage: refine.split_edges <length>");
383
        theConsole.printf("usage: refine.split_edges <length>");
323
        theConsole.printf("splits edges longer than <length>; default is 0.5 times average length");
384
        theConsole.printf("splits edges longer than <length>; default is 0.5 times average length");
324
        return;
385
        return;
325
    }
386
    }
326
	
387
	
327
    avo().save_old();
388
    avo().save_old();
328
	
389
	
329
    float thresh = 0.5f;
390
    float thresh = 0.5f;
330
	
391
	
331
    if(args.size() > 0){
392
    if(args.size() > 0){
332
        istringstream a0(args[0]);
393
        istringstream a0(args[0]);
333
        a0 >> thresh;
394
        a0 >> thresh;
334
    }
395
    }
335
	
396
	
336
    float avg_length = average_edge_length(active_mesh());
397
    float avg_length = average_edge_length(active_mesh());
337
	
398
	
338
    refine_edges(active_mesh(), thresh * avg_length);
399
    refine_edges(active_mesh(), thresh * avg_length);
339
	
400
	
340
    return;
401
    return;
341
	
402
	
342
}
403
}
343
 
404
 
344
void console_refine_faces(const std::vector<std::string> & args)
405
void console_refine_faces(const std::vector<std::string> & args)
345
{
406
{
346
    if(wantshelp(args)) {
407
    if(wantshelp(args)) {
347
        theConsole.printf("usage: refine.split_faces ");
408
        theConsole.printf("usage: refine.split_faces ");
348
        theConsole.printf("usage:  Takes no arguments. Inserts a vertex at the centre of each face.");
409
        theConsole.printf("usage:  Takes no arguments. Inserts a vertex at the centre of each face.");
349
		
410
		
350
        return;
411
        return;
351
    }
412
    }
352
    avo().save_old();
413
    avo().save_old();
353
	
414
	
354
    triangulate_by_vertex_face_split(active_mesh());
415
    triangulate_by_vertex_face_split(active_mesh());
355
	
416
	
356
    return;
417
    return;
357
	
418
	
358
}
419
}
359
 
420
 
360
void console_cc_subdivide(const std::vector<std::string> & args)
421
void console_cc_subdivide(const std::vector<std::string> & args)
361
{
422
{
362
    if(wantshelp(args)) {
423
    if(wantshelp(args)) {
363
        theConsole.printf("usage: subdivide.catmull_clark ");
424
        theConsole.printf("usage: subdivide.catmull_clark ");
364
        theConsole.printf("Does one step of Catmull-Clark subdivision");
425
        theConsole.printf("Does one step of Catmull-Clark subdivision");
365
		
426
		
366
        return;
427
        return;
367
    }
428
    }
368
    avo().save_old();
429
    avo().save_old();
369
	
430
	
370
    cc_split(active_mesh(),active_mesh());
431
    cc_split(active_mesh(),active_mesh());
371
    cc_smooth(active_mesh());
432
    cc_smooth(active_mesh());
372
	
433
	
373
    return;
434
    return;
374
}
435
}
375
 
436
 
376
void console_loop_subdivide(const std::vector<std::string> & args)
437
void console_loop_subdivide(const std::vector<std::string> & args)
377
{
438
{
378
    if(wantshelp(args)) {
439
    if(wantshelp(args)) {
379
        theConsole.printf("usage: subdivide.loop");
440
        theConsole.printf("usage: subdivide.loop");
380
        theConsole.printf("Does one step of Loop subdivision");
441
        theConsole.printf("Does one step of Loop subdivision");
381
		
442
		
382
        return;
443
        return;
383
    }
444
    }
384
    avo().save_old();
445
    avo().save_old();
385
	
446
	
386
    loop_split(active_mesh(),active_mesh());
447
    loop_split(active_mesh(),active_mesh());
387
    loop_smooth(active_mesh());
448
    loop_smooth(active_mesh());
388
	
449
	
389
    return;
450
    return;
390
}
451
}
391
 
452
 
392
void console_root3_subdivide(const std::vector<std::string> & args)
453
void console_root3_subdivide(const std::vector<std::string> & args)
393
{
454
{
394
    if(wantshelp(args)) {
455
    if(wantshelp(args)) {
395
        theConsole.printf("usage: subdivide.root3");
456
        theConsole.printf("usage: subdivide.root3");
396
        theConsole.printf("Does one step of sqrt(3) subdivision");
457
        theConsole.printf("Does one step of sqrt(3) subdivision");
397
		
458
		
398
        return;
459
        return;
399
    }
460
    }
400
    avo().save_old();
461
    avo().save_old();
401
	
462
	
402
    root3_subdivide(active_mesh(),active_mesh());
463
    root3_subdivide(active_mesh(),active_mesh());
403
	
464
	
404
    return;
465
    return;
405
}
466
}
406
 
467
 
407
 
468
 
408
void console_doosabin_subdivide(const std::vector<std::string> & args)
469
void console_doosabin_subdivide(const std::vector<std::string> & args)
409
{
470
{
410
    if(wantshelp(args)) {
471
    if(wantshelp(args)) {
411
        theConsole.printf("usage: subdivide.doo_sabin ");
472
        theConsole.printf("usage: subdivide.doo_sabin ");
412
        theConsole.printf("Does one step of Doo-Sabin Subdivision");
473
        theConsole.printf("Does one step of Doo-Sabin Subdivision");
413
		
474
		
414
        return;
475
        return;
415
    }
476
    }
416
    avo().save_old();
477
    avo().save_old();
417
	
478
	
418
    cc_split(active_mesh(),active_mesh());
479
    cc_split(active_mesh(),active_mesh());
419
    dual(active_mesh());
480
    dual(active_mesh());
420
    
481
    
421
    return;
482
    return;
422
}
483
}
423
 
484
 
424
void console_butterfly_subdivide(const std::vector<std::string> & args)
485
void console_butterfly_subdivide(const std::vector<std::string> & args)
425
{
486
{
426
    if(wantshelp(args)) {
487
    if(wantshelp(args)) {
427
        theConsole.printf("usage: subdivide.butterfly ");
488
        theConsole.printf("usage: subdivide.butterfly ");
428
        theConsole.printf("Does one step of Modified Butterfly Subdivision");
489
        theConsole.printf("Does one step of Modified Butterfly Subdivision");
429
		
490
		
430
        return;
491
        return;
431
    }
492
    }
432
    avo().save_old();
493
    avo().save_old();
433
	
494
	
434
    butterfly_subdivide(active_mesh(),active_mesh());
495
    butterfly_subdivide(active_mesh(),active_mesh());
435
    
496
    
436
    return;
497
    return;
437
}
498
}
438
 
499
 
439
void console_dual(const std::vector<std::string> & args)
500
void console_dual(const std::vector<std::string> & args)
440
{
501
{
441
    if(wantshelp(args)) 
502
    if(wantshelp(args)) 
442
    {
503
    {
443
        theConsole.printf("usage: dual ");
504
        theConsole.printf("usage: dual ");
444
        theConsole.printf("Produces the dual by converting each face to a vertex placed at the barycenter.");
505
        theConsole.printf("Produces the dual by converting each face to a vertex placed at the barycenter.");
445
        return;
506
        return;
446
    }
507
    }
447
    avo().save_old();
508
    avo().save_old();
448
	
509
	
449
    dual(active_mesh());
510
    dual(active_mesh());
450
	
511
	
451
    return;
512
    return;
452
}
513
}
453
 
514
 
454
 
515
 
455
void console_minimize_curvature(const std::vector<std::string> & args)
516
void console_minimize_curvature(const std::vector<std::string> & args)
456
{
517
{
457
    if(wantshelp(args)) 
518
    if(wantshelp(args)) 
458
    {
519
    {
459
        theConsole.printf("usage: optimize.minimize_curvature <anneal>");
520
        theConsole.printf("usage: optimize.minimize_curvature <anneal>");
460
        theConsole.printf("Flip edges to minimize mean curvature.");
521
        theConsole.printf("Flip edges to minimize mean curvature.");
461
        theConsole.printf("If anneal is true, simulated annealing (slow) is used rather than a greedy scheme");
522
        theConsole.printf("If anneal is true, simulated annealing (slow) is used rather than a greedy scheme");
462
        return;
523
        return;
463
    }
524
    }
464
    avo().save_old();
525
    avo().save_old();
465
	
526
	
466
    bool anneal=false;
527
    bool anneal=false;
467
    if(args.size() > 0)
528
    if(args.size() > 0)
468
    {
529
    {
469
        istringstream a0(args[0]);
530
        istringstream a0(args[0]);
470
        a0 >> anneal;
531
        a0 >> anneal;
471
    }
532
    }
472
	
533
	
473
    minimize_curvature(active_mesh(), anneal);
534
    minimize_curvature(active_mesh(), anneal);
474
    avo().post_create_display_list();
535
    avo().post_create_display_list();
475
    return;
536
    return;
476
}
537
}
477
 
538
 
478
void console_minimize_dihedral(const std::vector<std::string> & args)
539
void console_minimize_dihedral(const std::vector<std::string> & args)
479
{
540
{
480
    if(wantshelp(args))
541
    if(wantshelp(args))
481
    {
542
    {
482
        theConsole.printf("usage: optimize.minimize_dihedral <iter> <anneal> <use_alpha> <gamma> ");
543
        theConsole.printf("usage: optimize.minimize_dihedral <iter> <anneal> <use_alpha> <gamma> ");
483
        theConsole.printf("Flip edges to minimize dihedral angles.");
544
        theConsole.printf("Flip edges to minimize dihedral angles.");
484
        theConsole.printf("Iter is the max number of iterations. anneal tells us whether to use ");
545
        theConsole.printf("Iter is the max number of iterations. anneal tells us whether to use ");
485
        theConsole.printf("simulated annealing and not greedy optimization. use_alpha (default=true) ");
546
        theConsole.printf("simulated annealing and not greedy optimization. use_alpha (default=true) ");
486
        theConsole.printf("means to use angle and not cosine of anglegamma (default=4) is the power ");
547
        theConsole.printf("means to use angle and not cosine of anglegamma (default=4) is the power ");
487
        theConsole.printf("to which we raise the dihedral angle");
548
        theConsole.printf("to which we raise the dihedral angle");
488
        return;
549
        return;
489
    }
550
    }
490
    avo().save_old();
551
    avo().save_old();
491
	
552
	
492
    int iter = 1000;
553
    int iter = 1000;
493
    if(args.size() > 0)
554
    if(args.size() > 0)
494
    {
555
    {
495
        istringstream a0(args[0]);
556
        istringstream a0(args[0]);
496
        a0 >> iter;
557
        a0 >> iter;
497
    }
558
    }
498
	
559
	
499
    bool anneal = false;
560
    bool anneal = false;
500
    if(args.size() > 1)
561
    if(args.size() > 1)
501
    {
562
    {
502
        istringstream a0(args[1]);
563
        istringstream a0(args[1]);
503
        a0 >> anneal;
564
        a0 >> anneal;
504
    }
565
    }
505
	
566
	
506
    bool use_alpha = true;
567
    bool use_alpha = true;
507
    if(args.size() > 2)
568
    if(args.size() > 2)
508
    {
569
    {
509
        istringstream a0(args[2]);
570
        istringstream a0(args[2]);
510
        a0 >> use_alpha;
571
        a0 >> use_alpha;
511
    }
572
    }
512
	
573
	
513
    float gamma = 4.0f;
574
    float gamma = 4.0f;
514
    if(args.size() > 3)
575
    if(args.size() > 3)
515
    {
576
    {
516
        istringstream a0(args[3]);
577
        istringstream a0(args[3]);
517
        a0 >> gamma;
578
        a0 >> gamma;
518
    }
579
    }
519
	
580
	
520
	
581
	
521
    minimize_dihedral_angle(active_mesh(), iter, anneal, use_alpha, gamma);
582
    minimize_dihedral_angle(active_mesh(), iter, anneal, use_alpha, gamma);
522
    return;
583
    return;
523
}
584
}
524
 
585
 
525
void console_maximize_min_angle(const std::vector<std::string> & args)
586
void console_maximize_min_angle(const std::vector<std::string> & args)
526
{
587
{
527
    if(wantshelp(args)) 
588
    if(wantshelp(args)) 
528
    {
589
    {
529
        theConsole.printf("usage: optimize.maximize_min_angle <thresh> <anneal>");
590
        theConsole.printf("usage: optimize.maximize_min_angle <thresh> <anneal>");
530
        theConsole.printf("Flip edges to maximize min angle - to make mesh more Delaunay.");
591
        theConsole.printf("Flip edges to maximize min angle - to make mesh more Delaunay.");
531
        theConsole.printf("If the dot product of the normals between adjacent faces < thresh");
592
        theConsole.printf("If the dot product of the normals between adjacent faces < thresh");
532
        theConsole.printf("no flip will be made. anneal selects simulated annealing rather ");
593
        theConsole.printf("no flip will be made. anneal selects simulated annealing rather ");
533
        theConsole.printf("nthan greedy optimization.");
594
        theConsole.printf("nthan greedy optimization.");
534
        return;
595
        return;
535
    }
596
    }
536
    avo().save_old();
597
    avo().save_old();
537
	
598
	
538
    float thresh = 0.0f;
599
    float thresh = 0.0f;
539
    if(args.size() > 0)
600
    if(args.size() > 0)
540
    {
601
    {
541
        istringstream a0(args[0]);
602
        istringstream a0(args[0]);
542
        a0 >> thresh;
603
        a0 >> thresh;
543
    }
604
    }
544
    bool anneal = false;
605
    bool anneal = false;
545
    if(args.size() > 1)
606
    if(args.size() > 1)
546
    {
607
    {
547
        istringstream a0(args[1]);
608
        istringstream a0(args[1]);
548
        a0 >> anneal;
609
        a0 >> anneal;
549
    }
610
    }
550
    maximize_min_angle(active_mesh(),thresh,anneal);
611
    maximize_min_angle(active_mesh(),thresh,anneal);
551
    return;
612
    return;
552
}
613
}
553
 
614
 
554
 
615
 
555
void console_optimize_valency(const std::vector<std::string> & args)
616
void console_optimize_valency(const std::vector<std::string> & args)
556
{
617
{
557
    if(wantshelp(args)) 
618
    if(wantshelp(args)) 
558
    {
619
    {
559
        theConsole.printf("usage: optimize.valency <anneal> ");
620
        theConsole.printf("usage: optimize.valency <anneal> ");
560
        theConsole.printf("Optimizes valency for triangle meshes. Anneal selects simulated annealing rather than greedy optim.");
621
        theConsole.printf("Optimizes valency for triangle meshes. Anneal selects simulated annealing rather than greedy optim.");
561
        return;
622
        return;
562
    }
623
    }
563
    avo().save_old();
624
    avo().save_old();
564
	
625
	
565
    bool anneal = false;
626
    bool anneal = false;
566
    if(args.size() > 0)
627
    if(args.size() > 0)
567
    {
628
    {
568
        istringstream a0(args[0]);
629
        istringstream a0(args[0]);
569
        a0 >> anneal;
630
        a0 >> anneal;
570
    }
631
    }
571
    optimize_valency(active_mesh(), anneal);
632
    optimize_valency(active_mesh(), anneal);
572
    return;
633
    return;
573
}
634
}
574
 
635
 
575
void console_analyze(const std::vector<std::string> & args)
636
void console_analyze(const std::vector<std::string> & args)
576
{
637
{
577
    if(wantshelp(args)) 
638
    if(wantshelp(args)) 
578
    {
639
    {
579
        theConsole.printf("usage:  harmonics.analyze");
640
        theConsole.printf("usage:  harmonics.analyze");
580
        theConsole.printf("Creates the Laplace Beltrami operator for the mesh and finds all eigensolutions.");
641
        theConsole.printf("Creates the Laplace Beltrami operator for the mesh and finds all eigensolutions.");
581
        theConsole.printf("It also projects the vertices onto the eigenvectors - thus transforming the mesh");
642
        theConsole.printf("It also projects the vertices onto the eigenvectors - thus transforming the mesh");
582
        theConsole.printf("to this basis.");
643
        theConsole.printf("to this basis.");
583
        theConsole.printf("Note that this will stall the computer for a large mesh - as long as we use Lapack.");
644
        theConsole.printf("Note that this will stall the computer for a large mesh - as long as we use Lapack.");
584
        return;
645
        return;
585
    }
646
    }
586
    avo().harmonics_analyze_mesh(theConsole);
647
    avo().harmonics_analyze_mesh();
587
    return;
648
    return;
588
}
649
}
589
 
650
 
590
 
651
 
591
void console_partial_reconstruct(const std::vector<std::string> & args)
652
void console_partial_reconstruct(const std::vector<std::string> & args)
592
{
653
{
593
    if(args.size() != 3)
654
    if(args.size() != 3)
594
        theConsole.printf("usage: haramonics.partial_reconstruct <e0> <e1> <s>");
655
        theConsole.printf("usage: haramonics.partial_reconstruct <e0> <e1> <s>");
595
	
656
	
596
    if(wantshelp(args)) {
657
    if(wantshelp(args)) {
597
        theConsole.printf("Reconstruct from projections onto eigenvectors. The two first arguments indicate");
658
        theConsole.printf("Reconstruct from projections onto eigenvectors. The two first arguments indicate");
598
        theConsole.printf("the eigenvector interval that we reconstruct from. The last argument is the ");
659
        theConsole.printf("the eigenvector interval that we reconstruct from. The last argument is the ");
599
        theConsole.printf("scaling factor. Thus, for a vertex, v, the formula for computing the position, p, is:");
660
        theConsole.printf("scaling factor. Thus, for a vertex, v, the formula for computing the position, p, is:");
600
        theConsole.printf("for (i=e0; i<=e1;++i) p += proj[i] * Q[i][v] * s;");
661
        theConsole.printf("for (i=e0; i<=e1;++i) p += proj[i] * Q[i][v] * s;");
601
        theConsole.printf("where proj[i] is the 3D vector containing the x, y, and z projections of the mesh onto");
662
        theConsole.printf("where proj[i] is the 3D vector containing the x, y, and z projections of the mesh onto");
602
        theConsole.printf("eigenvector i. Q[i][v] is the v'th coordinate of the i'th eigenvector.");
663
        theConsole.printf("eigenvector i. Q[i][v] is the v'th coordinate of the i'th eigenvector.");
603
        theConsole.printf("Note that if vertex coordinates are not first reset, the result is probably unexpected.");
664
        theConsole.printf("Note that if vertex coordinates are not first reset, the result is probably unexpected.");
604
    }
665
    }
605
    avo().save_old();
666
    avo().save_old();
606
	
667
	
607
    if(args.size() != 3)
668
    if(args.size() != 3)
608
        return;
669
        return;
609
	
670
	
610
    int E0,E1;
671
    int E0,E1;
611
    float scale;
672
    float scale;
612
    istringstream a0(args[0]);
673
    istringstream a0(args[0]);
613
    a0 >> E0;
674
    a0 >> E0;
614
    istringstream a1(args[1]);
675
    istringstream a1(args[1]);
615
    a1 >> E1;
676
    a1 >> E1;
616
    istringstream a2(args[2]);
677
    istringstream a2(args[2]);
617
    a2 >> scale;
678
    a2 >> scale;
618
    avo().harmonics_partial_reconstruct(E0,E1,scale);
679
    avo().harmonics_partial_reconstruct(E0,E1,scale);
619
    return;
680
    return;
620
}
681
}
621
 
682
 
622
void console_reset_shape(const std::vector<std::string> & args)
683
void console_reset_shape(const std::vector<std::string> & args)
623
{
684
{
624
    if(wantshelp(args)) 
685
    if(wantshelp(args)) 
625
    {
686
    {
626
        theConsole.printf("usage: harmonics.reset_shape ");
687
        theConsole.printf("usage: harmonics.reset_shape ");
627
        theConsole.printf("Simply sets all vertices to 0,0,0. Call this before doing partial_reconstruct");
688
        theConsole.printf("Simply sets all vertices to 0,0,0. Call this before doing partial_reconstruct");
628
        theConsole.printf("unless you know what you are doing.");
689
        theConsole.printf("unless you know what you are doing.");
629
        return;
690
        return;
630
    }
691
    }
631
    avo().save_old();
692
    avo().save_old();
632
    avo().harmonics_reset_shape();
693
    avo().harmonics_reset_shape();
633
    return;
694
    return;
634
}
695
}
635
 
696
 
636
 
697
 
637
void console_close_holes(const std::vector<std::string> & args)
698
void console_close_holes(const std::vector<std::string> & args)
638
{
699
{
639
    if(wantshelp(args)) 
700
    if(wantshelp(args)) 
640
    {
701
    {
641
        theConsole.printf("usage: cleanup.close_holes");
702
        theConsole.printf("usage: cleanup.close_holes");
642
        theConsole.printf("This function closes holes. It simply follows the loop of halfvectors which");
703
        theConsole.printf("This function closes holes. It simply follows the loop of halfvectors which");
643
        theConsole.printf("enclose the hole and add a face to which they all point.");
704
        theConsole.printf("enclose the hole and add a face to which they all point.");
644
        return;
705
        return;
645
    }
706
    }
646
    avo().save_old();
707
    avo().save_old();
647
	
708
	
648
    close_holes(active_mesh());
709
    close_holes(active_mesh());
649
    return;
710
    return;
650
}
711
}
651
 
712
 
652
void console_reload(const std::vector<std::string> & args)
713
void console_reload(const std::vector<std::string> & args)
653
{
714
{
654
    if(wantshelp(args)) 
715
    if(wantshelp(args)) 
655
    {
716
    {
656
        theConsole.printf("usage:  load <file>");
717
        theConsole.printf("usage:  load <file>");
657
        theConsole.printf("(Re)loads the current file if no argument is given, but");
718
        theConsole.printf("(Re)loads the current file if no argument is given, but");
658
        theConsole.printf("if an argument is given, then that becomes the current file");
719
        theConsole.printf("if an argument is given, then that becomes the current file");
659
        return;
720
        return;
660
    }
721
    }
661
    avo().save_old();
722
    avo().save_old();
662
	
723
	
663
    if(!avo().reload(args.size() > 0 ? args[0]:""))
724
    if(!avo().reload(args.size() > 0 ? args[0]:""))
664
        theConsole.printf("failed to load");
725
        theConsole.printf("failed to load");
665
	
726
	
666
    return;
727
    return;
667
}
728
}
668
 
729
 
669
 
730
 
670
void console_add_mesh(const std::vector<std::string> & args)
731
void console_add_mesh(const std::vector<std::string> & args)
671
{
732
{
672
    if(wantshelp(args)) 
733
    if(wantshelp(args)) 
673
    {
734
    {
674
        theConsole.printf("usage:  add_mesh <file>");
735
        theConsole.printf("usage:  add_mesh <file>");
675
        theConsole.printf("Loads the file but without clearing the mesh. Thus, the loaded mesh is added to the");
736
        theConsole.printf("Loads the file but without clearing the mesh. Thus, the loaded mesh is added to the");
676
        theConsole.printf("current model.");
737
        theConsole.printf("current model.");
677
        return;
738
        return;
678
    }
739
    }
679
    avo().save_old();
740
    avo().save_old();
680
	
741
	
681
    if(!avo().add_mesh(args.size() > 0 ? args[0]:""))
742
    if(!avo().add_mesh(args.size() > 0 ? args[0]:""))
682
        theConsole.printf("failed to load");
743
        theConsole.printf("failed to load");
683
	
744
	
684
    return;
745
    return;
685
}
746
}
686
void console_valid(const std::vector<std::string> & args)
747
void console_valid(const std::vector<std::string> & args)
687
{
748
{
688
    if(wantshelp(args)) 
749
    if(wantshelp(args)) 
689
    {
750
    {
690
        theConsole.printf("usage:  validity");
751
        theConsole.printf("usage:  validity");
691
        theConsole.printf("Tests validity of Manifold");
752
        theConsole.printf("Tests validity of Manifold");
692
        return;
753
        return;
693
    }
754
    }
694
	if(valid(active_mesh()))
755
	if(valid(active_mesh()))
695
		theConsole.printf("Mesh is valid");
756
		theConsole.printf("Mesh is valid");
696
	else
757
	else
697
		theConsole.printf("Mesh is invalid - check console output");
758
		theConsole.printf("Mesh is invalid - check console output");
698
	return;
759
	return;
699
}
760
}
700
 
761
 
701
void console_info(const std::vector<std::string> & args)
762
void console_info(const std::vector<std::string> & args)
702
{
763
{
703
    if(wantshelp(args)) 
764
    if(wantshelp(args)) 
704
    {
765
    {
705
        theConsole.printf("usage:  info");
766
        theConsole.printf("usage:  info");
706
        theConsole.printf("Provides information about mesh.");
767
        theConsole.printf("Provides information about mesh.");
707
        return;
768
        return;
708
    }
769
    }
709
    Vec3d p0, p7;
770
    Vec3d p0, p7;
710
    bbox(active_mesh(), p0, p7);
771
    bbox(active_mesh(), p0, p7);
711
    stringstream bbox_corners;
772
    stringstream bbox_corners;
712
    bbox_corners << p0 << " - " << p7 << endl;
773
    bbox_corners << p0 << " - " << p7 << endl;
713
	theConsole.printf("Bounding box corners : %s", bbox_corners.str().c_str());
774
	theConsole.printf("Bounding box corners : %s", bbox_corners.str().c_str());
714
    map<int,int> val_hist;
775
    map<int,int> val_hist;
715
    
776
    
716
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
777
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
717
    {
778
    {
718
        int val = valency(active_mesh(), *vi);
779
        int val = valency(active_mesh(), *vi);
719
        if(val_hist.find(val) == val_hist.end())
780
        if(val_hist.find(val) == val_hist.end())
720
            val_hist[val] = 0;
781
            val_hist[val] = 0;
721
        ++val_hist[val];
782
        ++val_hist[val];
722
    }
783
    }
723
    
784
    
724
    theConsole.printf("Valency histogam");
785
    theConsole.printf("Valency histogam");
725
    for(map<int,int>::iterator iter = val_hist.begin(); iter != val_hist.end(); ++iter)
786
    for(map<int,int>::iterator iter = val_hist.begin(); iter != val_hist.end(); ++iter)
726
    {
787
    {
727
        stringstream vhl;
788
        stringstream vhl;
728
        vhl << iter->first << ", " << iter->second;
789
        vhl << iter->first << ", " << iter->second;
729
        theConsole.printf("%d, %d", iter->first, iter->second);
790
        theConsole.printf("%d, %d", iter->first, iter->second);
730
    }
791
    }
731
 
792
 
732
	theConsole.printf("Mesh contains %d faces", active_mesh().no_faces());
793
	theConsole.printf("Mesh contains %d faces", active_mesh().no_faces());
733
	theConsole.printf("Mesh contains %d halfedges", active_mesh().no_halfedges());
794
	theConsole.printf("Mesh contains %d halfedges", active_mesh().no_halfedges());
734
	theConsole.printf("Mesh contains %d vertices", active_mesh().no_vertices());
795
	theConsole.printf("Mesh contains %d vertices", active_mesh().no_vertices());
735
	return;
796
	return;
736
}
797
}
737
 
798
 
738
 
799
 
739
void console_simplify(const std::vector<std::string> & args)
800
void console_simplify(const std::vector<std::string> & args)
740
{
801
{
741
    if(wantshelp(args)) 
802
    if(wantshelp(args)) 
742
    {
803
    {
743
        theConsole.printf("usage: simplify <fraction> ");
804
        theConsole.printf("usage: simplify <fraction> ");
744
        theConsole.printf("Performs Garland Heckbert (quadric based) mesh simplification.");
805
        theConsole.printf("Performs Garland Heckbert (quadric based) mesh simplification.");
745
        theConsole.printf("The only argument is the fraction of vertices to keep.");
806
        theConsole.printf("The only argument is the fraction of vertices to keep.");
746
        return;
807
        return;
747
    }
808
    }
748
    avo().save_old();
809
    avo().save_old();
749
	
810
	
750
    float keep_fraction;
811
    float keep_fraction;
751
    if(args.size() == 0)
812
    if(args.size() == 0)
752
    {
813
    {
753
        theConsole.print("you must specify fraction of vertices to keep");
814
        theConsole.print("you must specify fraction of vertices to keep");
754
        return;
815
        return;
755
    }
816
    }
756
    istringstream a0(args[0]);
817
    istringstream a0(args[0]);
757
    a0 >> keep_fraction;
818
    a0 >> keep_fraction;
758
	
819
	
759
    Vec3d p0, p7;
820
    Vec3d p0, p7;
760
    bbox(active_mesh(), p0, p7);
821
    bbox(active_mesh(), p0, p7);
761
    Vec3d d = p7-p0;
822
    Vec3d d = p7-p0;
762
    float s = 1.0/d.max_coord();
823
    float s = 1.0/d.max_coord();
763
    Vec3d pcentre = (p7+p0)/2.0;
824
    Vec3d pcentre = (p7+p0)/2.0;
764
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi){
825
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi){
765
        active_mesh().pos(*vi) = (active_mesh().pos(*vi) - pcentre) * s;
826
        active_mesh().pos(*vi) = (active_mesh().pos(*vi) - pcentre) * s;
766
    }
827
    }
767
    cout << "Timing the Garland Heckbert (quadric based) mesh simplication..." << endl;
828
    cout << "Timing the Garland Heckbert (quadric based) mesh simplication..." << endl;
768
    Timer timer;
829
    Timer timer;
769
    timer.start();
830
    timer.start();
770
	
831
	
771
    //simplify
832
    //simplify
772
    quadric_simplify(active_mesh(),keep_fraction,0.0001f,true);
833
    quadric_simplify(active_mesh(),keep_fraction,0.0001f,true);
773
	
834
	
774
    cout << "Simplification complete, process time: " << timer.get_secs() << " seconds" << endl;
835
    cout << "Simplification complete, process time: " << timer.get_secs() << " seconds" << endl;
775
	
836
	
776
    //clean up the mesh, a lot of edges were just collapsed 
837
    //clean up the mesh, a lot of edges were just collapsed 
777
    active_mesh().cleanup();
838
    active_mesh().cleanup();
778
	
839
	
779
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
840
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
780
        active_mesh().pos(*vi) = active_mesh().pos(*vi)*d.max_coord() + pcentre;
841
        active_mesh().pos(*vi) = active_mesh().pos(*vi)*d.max_coord() + pcentre;
781
    return;
842
    return;
782
}
843
}
783
 
844
 
784
void console_vertex_noise(const std::vector<std::string> & args)
845
void console_vertex_noise(const std::vector<std::string> & args)
785
{
846
{
786
    if(wantshelp(args)) 
847
    if(wantshelp(args)) 
787
    {
848
    {
788
        theConsole.printf("usage: noise.perturb_vertices <amplitude>");
849
        theConsole.printf("usage: noise.perturb_vertices <amplitude>");
789
        theConsole.printf("adds a random vector to each vertex. A random vector in the unit cube is generated and");
850
        theConsole.printf("adds a random vector to each vertex. A random vector in the unit cube is generated and");
790
        theConsole.printf("to ensure an isotropic distribution, vectors outside the unit ball are discarded.");
851
        theConsole.printf("to ensure an isotropic distribution, vectors outside the unit ball are discarded.");
791
        theConsole.printf("The vector is multiplied by the average edge length and then by the amplitude specified.");
852
        theConsole.printf("The vector is multiplied by the average edge length and then by the amplitude specified.");
792
        theConsole.printf("If no amplitude is specified, the default (0.5) is used.");
853
        theConsole.printf("If no amplitude is specified, the default (0.5) is used.");
793
        return;
854
        return;
794
    }
855
    }
795
    avo().save_old();
856
    avo().save_old();
796
	
857
	
797
    float avg_length = average_edge_length(active_mesh());
858
    float avg_length = average_edge_length(active_mesh());
798
	
859
	
799
    float noise_amplitude = 0.5f;
860
    float noise_amplitude = 0.5f;
800
    if(args.size() > 0) {
861
    if(args.size() > 0) {
801
        istringstream a0(args[0]);
862
        istringstream a0(args[0]);
802
        a0 >> noise_amplitude;
863
        a0 >> noise_amplitude;
803
    }
864
    }
804
	
865
	
805
    gel_srand(0);
866
    gel_srand(0);
806
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi){
867
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi){
807
        Vec3d v;
868
        Vec3d v;
808
        do{
869
        do{
809
            v = Vec3d(gel_rand(),gel_rand(),gel_rand());
870
            v = Vec3d(gel_rand(),gel_rand(),gel_rand());
810
            v /= (float)(GEL_RAND_MAX);
871
            v /= (float)(GEL_RAND_MAX);
811
            v -= Vec3d(0.5);
872
            v -= Vec3d(0.5);
812
            v *= 2.0;
873
            v *= 2.0;
813
        }
874
        }
814
        while(sqr_length(v) > 1.0);
875
        while(sqr_length(v) > 1.0);
815
		
876
		
816
        v *= noise_amplitude;
877
        v *= noise_amplitude;
817
        v *= avg_length;
878
        v *= avg_length;
818
        active_mesh().pos(*vi) += v;
879
        active_mesh().pos(*vi) += v;
819
    }		
880
    }		
820
    return;
881
    return;
821
}
882
}
822
 
883
 
823
void console_perpendicular_vertex_noise(const std::vector<std::string> & args)
884
void console_perpendicular_vertex_noise(const std::vector<std::string> & args)
824
{
885
{
825
    if(wantshelp(args)) {
886
    if(wantshelp(args)) {
826
        theConsole.printf("usage: noise.perturb_vertices_perpendicular <amplitude>");
887
        theConsole.printf("usage: noise.perturb_vertices_perpendicular <amplitude>");
827
        theConsole.printf("adds the normal times a random scalar times amplitude times");
888
        theConsole.printf("adds the normal times a random scalar times amplitude times");
828
        theConsole.printf("times average edge length to the vertex. (default amplitude=0.5)");
889
        theConsole.printf("times average edge length to the vertex. (default amplitude=0.5)");
829
        return;
890
        return;
830
    }
891
    }
831
    avo().save_old();
892
    avo().save_old();
832
	
893
	
833
    float avg_length = average_edge_length(active_mesh());
894
    float avg_length = average_edge_length(active_mesh());
834
	
895
	
835
    float noise_amplitude = 0.5;
896
    float noise_amplitude = 0.5;
836
    if(args.size() > 0) 
897
    if(args.size() > 0) 
837
    {
898
    {
838
        istringstream a0(args[0]);
899
        istringstream a0(args[0]);
839
        a0 >> noise_amplitude;
900
        a0 >> noise_amplitude;
840
    }
901
    }
841
	
902
	
842
    VertexAttributeVector<Vec3d> normals(active_mesh().allocated_vertices());
903
    VertexAttributeVector<Vec3d> normals(active_mesh().allocated_vertices());
843
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
904
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
844
        normals[*vi] = normal(active_mesh(), *vi);
905
        normals[*vi] = normal(active_mesh(), *vi);
845
	
906
	
846
    gel_srand(0);
907
    gel_srand(0);
847
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
908
    for(VertexIDIterator vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
848
    {
909
    {
849
        float rval = 0.5-gel_rand() / float(GEL_RAND_MAX);
910
        float rval = 0.5-gel_rand() / float(GEL_RAND_MAX);
850
        active_mesh().pos(*vi) += normals[*vi]*rval*noise_amplitude*avg_length*2.0;
911
        active_mesh().pos(*vi) += normals[*vi]*rval*noise_amplitude*avg_length*2.0;
851
    }
912
    }
852
    return;
913
    return;
853
}
914
}
854
 
915
 
855
void console_noisy_flips(const std::vector<std::string> & args)
916
void console_noisy_flips(const std::vector<std::string> & args)
856
{
917
{
857
    if(wantshelp(args)){
918
    if(wantshelp(args)){
858
        theConsole.printf("usage:  noise.perturb_topology <iter>");
919
        theConsole.printf("usage:  noise.perturb_topology <iter>");
859
        theConsole.printf("Perform random flips. iter (default=1) is the number of iterations.");
920
        theConsole.printf("Perform random flips. iter (default=1) is the number of iterations.");
860
        theConsole.printf("mostly for making nasty synthetic test cases.");
921
        theConsole.printf("mostly for making nasty synthetic test cases.");
861
        return;
922
        return;
862
    }
923
    }
863
    avo().save_old();
924
    avo().save_old();
864
	
925
	
865
    int iter = 1;
926
    int iter = 1;
866
    if(args.size() > 0){
927
    if(args.size() > 0){
867
        istringstream a0(args[0]);
928
        istringstream a0(args[0]);
868
        a0 >> iter;
929
        a0 >> iter;
869
    }
930
    }
870
	
931
	
871
    randomize_mesh(active_mesh(),  iter);
932
    randomize_mesh(active_mesh(),  iter);
872
    return;
933
    return;
873
}
934
}
874
 
935
 
875
void console_laplacian_smooth(const std::vector<std::string> & args)
936
void console_laplacian_smooth(const std::vector<std::string> & args)
876
{
937
{
877
    if(wantshelp(args)) {
938
    if(wantshelp(args)) {
878
        theConsole.printf("usage:  smooth.laplacian <weight> <iter>");
939
        theConsole.printf("usage:  smooth.laplacian <weight> <iter>");
879
        theConsole.printf("Perform Laplacian smoothing. weight is the scaling factor for the Laplacian.");
940
        theConsole.printf("Perform Laplacian smoothing. weight is the scaling factor for the Laplacian.");
880
        theConsole.printf("default weight = 1.0. Default number of iterations = 1");
941
        theConsole.printf("default weight = 1.0. Default number of iterations = 1");
881
        return;
942
        return;
882
    }
943
    }
883
    avo().save_old();
944
    avo().save_old();
884
	
945
	
885
    float t=1.0;
946
    float t=1.0;
886
    if(args.size() > 0){
947
    if(args.size() > 0){
887
        istringstream a0(args[0]);
948
        istringstream a0(args[0]);
888
        a0 >> t;
949
        a0 >> t;
889
    }
950
    }
890
    int iter = 1;
951
    int iter = 1;
891
    if(args.size()>1){
952
    if(args.size()>1){
892
        istringstream a0(args[1]);
953
        istringstream a0(args[1]);
893
        a0 >> iter;
954
        a0 >> iter;
894
    }
955
    }
895
    Util::Timer tim;
956
    Util::Timer tim;
896
    tim.start();
957
    tim.start();
897
    /// Simple laplacian smoothing with an optional weight.
958
    /// Simple laplacian smoothing with an optional weight.
898
    laplacian_smooth(active_mesh(), t, iter);
959
    laplacian_smooth(active_mesh(), t, iter);
899
    cout << "It took "<< tim.get_secs();
960
    cout << "It took "<< tim.get_secs();
900
    return;
961
    return;
901
}
962
}
902
 
963
 
903
 
964
 
904
void console_mean_curvature_smooth(const std::vector<std::string> & args){
965
void console_mean_curvature_smooth(const std::vector<std::string> & args){
905
    if(wantshelp(args)) {
966
    if(wantshelp(args)) {
906
        theConsole.printf("usage:  smooth.mean_curvature <weight> <iter>");
967
        theConsole.printf("usage:  smooth.mean_curvature <weight> <iter>");
907
        theConsole.printf("Perform mean curvature smoothing. weight is the scaling factor for the");
968
        theConsole.printf("Perform mean curvature smoothing. weight is the scaling factor for the");
908
        theConsole.printf("mean curvature vector which has been normalized by dividing by edge lengths");
969
        theConsole.printf("mean curvature vector which has been normalized by dividing by edge lengths");
909
        theConsole.printf("this allows for larger steps as suggested by Desbrun et al.");
970
        theConsole.printf("this allows for larger steps as suggested by Desbrun et al.");
910
        theConsole.printf("default weight = 1.0. Default number of iterations = 1");
971
        theConsole.printf("default weight = 1.0. Default number of iterations = 1");
911
        return;
972
        return;
912
    }
973
    }
913
    avo().save_old();
974
    avo().save_old();
914
	
975
	
915
    double t=1.0;
976
    double t=1.0;
916
    if(args.size() > 0){
977
    if(args.size() > 0){
917
        istringstream a0(args[0]);
978
        istringstream a0(args[0]);
918
        a0 >> t;
979
        a0 >> t;
919
    }
980
    }
920
    int iter=1;
981
    int iter=1;
921
    if(args.size() > 1){
982
    if(args.size() > 1){
922
        istringstream a0(args[1]);
983
        istringstream a0(args[1]);
923
        a0 >> iter;
984
        a0 >> iter;
924
    }	
985
    }	
925
    VertexAttributeVector<Vec3d> new_pos(active_mesh().allocated_vertices());
986
    VertexAttributeVector<Vec3d> new_pos(active_mesh().allocated_vertices());
926
    for(int j = 0; j < iter; ++j){
987
    for(int j = 0; j < iter; ++j){
927
        for(VertexIDIterator v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v) {
988
        for(VertexIDIterator v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v) {
928
            Vec3d m;
989
            Vec3d m;
929
            double w_sum;
990
            double w_sum;
930
            unnormalized_mean_curvature_normal(active_mesh(), *v, m, w_sum);
991
            unnormalized_mean_curvature_normal(active_mesh(), *v, m, w_sum);
931
            new_pos[*v] = Vec3d(active_mesh().pos(*v))  + (t * m/w_sum);
992
            new_pos[*v] = Vec3d(active_mesh().pos(*v))  + (t * m/w_sum);
932
        }
993
        }
933
        for(VertexIDIterator v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v)
994
        for(VertexIDIterator v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v)
934
            active_mesh().pos(*v) = new_pos[*v];
995
            active_mesh().pos(*v) = new_pos[*v];
935
    }
996
    }
936
    return;
997
    return;
937
}
998
}
938
 
999
 
939
void console_taubin_smooth(const std::vector<std::string> & args)
1000
void console_taubin_smooth(const std::vector<std::string> & args)
940
{
1001
{
941
    if(wantshelp(args)){
1002
    if(wantshelp(args)){
942
        theConsole.printf("usage:  smooth.taubin <iter>");
1003
        theConsole.printf("usage:  smooth.taubin <iter>");
943
        theConsole.printf("Perform Taubin smoothing. iter (default=1) is the number of iterations.");
1004
        theConsole.printf("Perform Taubin smoothing. iter (default=1) is the number of iterations.");
944
        return;
1005
        return;
945
    }
1006
    }
946
    avo().save_old();
1007
    avo().save_old();
947
	
1008
	
948
    int iter = 1;
1009
    int iter = 1;
949
    if(args.size() > 0){
1010
    if(args.size() > 0){
950
        istringstream a0(args[0]);
1011
        istringstream a0(args[0]);
951
        a0 >> iter;
1012
        a0 >> iter;
952
    }
1013
    }
953
    /// Taubin smoothing is similar to laplacian smoothing but reduces shrinkage
1014
    /// Taubin smoothing is similar to laplacian smoothing but reduces shrinkage
954
    taubin_smooth(active_mesh(),  iter);
1015
    taubin_smooth(active_mesh(),  iter);
955
	
1016
	
956
    return;
1017
    return;
957
}
1018
}
958
 
1019
 
959
void console_fvm_anisotropic_smooth(const std::vector<std::string> & args)
1020
void console_fvm_anisotropic_smooth(const std::vector<std::string> & args)
960
{
1021
{
961
    if(wantshelp(args)){
1022
    if(wantshelp(args)){
962
        theConsole.printf("usage: smooth.fuzzy_vector_median <iter>");
1023
        theConsole.printf("usage: smooth.fuzzy_vector_median <iter>");
963
        theConsole.printf("Smooth normals using fuzzy vector median smoothing. iter (default=1) is the number of iterations");
1024
        theConsole.printf("Smooth normals using fuzzy vector median smoothing. iter (default=1) is the number of iterations");
964
        theConsole.printf("This function does a very good job of preserving sharp edges.");
1025
        theConsole.printf("This function does a very good job of preserving sharp edges.");
965
        return;
1026
        return;
966
    }
1027
    }
967
    avo().save_old();
1028
    avo().save_old();
968
	
1029
	
969
    int iter=1;
1030
    int iter=1;
970
    if(args.size() > 0){
1031
    if(args.size() > 0){
971
        istringstream a0(args[0]);
1032
        istringstream a0(args[0]);
972
        a0 >> iter;
1033
        a0 >> iter;
973
    }
1034
    }
974
    // Fuzzy vector median smoothing is effective when it comes to preserving sharp edges.
1035
    // Fuzzy vector median smoothing is effective when it comes to preserving sharp edges.
975
    anisotropic_smooth(active_mesh(),  iter, FVM_NORMAL_SMOOTH);
1036
    anisotropic_smooth(active_mesh(),  iter, FVM_NORMAL_SMOOTH);
976
	
1037
	
977
    return;
1038
    return;
978
}
1039
}
979
 
1040
 
980
void console_bilateral_anisotropic_smooth(const std::vector<std::string> & args)
1041
void console_bilateral_anisotropic_smooth(const std::vector<std::string> & args)
981
{
1042
{
982
    if(wantshelp(args)){
1043
    if(wantshelp(args)){
983
        theConsole.printf("usage: smooth.fuzzy_vector_median <iter>");
1044
        theConsole.printf("usage: smooth.fuzzy_vector_median <iter>");
984
        theConsole.printf("Smooth normals using fuzzy vector median smoothing. iter (default=1) is the number of iterations");
1045
        theConsole.printf("Smooth normals using fuzzy vector median smoothing. iter (default=1) is the number of iterations");
985
        theConsole.printf("This function does a very good job of preserving sharp edges.");
1046
        theConsole.printf("This function does a very good job of preserving sharp edges.");
986
        return;
1047
        return;
987
    }
1048
    }
988
    avo().save_old();
1049
    avo().save_old();
989
	
1050
	
990
    int iter=1;
1051
    int iter=1;
991
    if(args.size() > 0){
1052
    if(args.size() > 0){
992
        istringstream a0(args[0]);
1053
        istringstream a0(args[0]);
993
        a0 >> iter;
1054
        a0 >> iter;
994
    }
1055
    }
995
    
1056
    
996
    anisotropic_smooth(active_mesh(),  iter, BILATERAL_NORMAL_SMOOTH);
1057
    anisotropic_smooth(active_mesh(),  iter, BILATERAL_NORMAL_SMOOTH);
997
	
1058
	
998
    return;
1059
    return;
999
}
1060
}
1000
 
1061
 
1001
void console_triangulate(const std::vector<std::string> & args)
1062
void console_triangulate(const std::vector<std::string> & args)
1002
{	
1063
{	
1003
    if(wantshelp(args)) {
1064
    if(wantshelp(args)) {
1004
        theConsole.printf("usage:  triangulate");
1065
        theConsole.printf("usage:  triangulate");
1005
        theConsole.printf("This function triangulates all non triangular faces of the mesh.");
1066
        theConsole.printf("This function triangulates all non triangular faces of the mesh.");
1006
        theConsole.printf("you may want to call it after hole closing. For a polygon it simply connects");
1067
        theConsole.printf("you may want to call it after hole closing. For a polygon it simply connects");
1007
        theConsole.printf("the two closest vertices in a recursive manner until only triangles remain");
1068
        theConsole.printf("the two closest vertices in a recursive manner until only triangles remain");
1008
        return;
1069
        return;
1009
    }
1070
    }
1010
    avo().save_old();
1071
    avo().save_old();
1011
	
1072
	
1012
    shortest_edge_triangulate(active_mesh());
1073
    shortest_edge_triangulate(active_mesh());
1013
    active_mesh().cleanup();
1074
    active_mesh().cleanup();
1014
	valid(active_mesh());
1075
	valid(active_mesh());
1015
    return;
1076
    return;
1016
}
1077
}
1017
 
1078
 
1018
void console_remove_faces(const std::vector<std::string> & args)
1079
void console_remove_faces(const std::vector<std::string> & args)
1019
{
1080
{
1020
    avo().save_old();
1081
    avo().save_old();
1021
    
1082
    
1022
    gel_srand(0);
1083
    gel_srand(0);
1023
 
1084
 
1024
//    for (FaceIDIterator f= active_mesh().faces_begin(); f != active_mesh().faces_end(); ++f) {
1085
//    for (FaceIDIterator f= active_mesh().faces_begin(); f != active_mesh().faces_end(); ++f) {
1025
//        if(gel_rand() < 0.5 * GEL_RAND_MAX)
1086
//        if(gel_rand() < 0.5 * GEL_RAND_MAX)
1026
//        {
1087
//        {
1027
//            active_mesh().remove_face(*f);
1088
//            active_mesh().remove_face(*f);
1028
//        }
1089
//        }
1029
//    }
1090
//    }
1030
 
1091
 
1031
//    for (VertexIDIterator v= active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v) {
1092
//    for (VertexIDIterator v= active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v) {
1032
//        if(gel_rand() < 0.005 * GEL_RAND_MAX)
1093
//        if(gel_rand() < 0.005 * GEL_RAND_MAX)
1033
//        {
1094
//        {
1034
//            active_mesh().remove_vertex(*v);
1095
//            active_mesh().remove_vertex(*v);
1035
//        }
1096
//        }
1036
//    }
1097
//    }
1037
    for (HalfEdgeIDIterator h= active_mesh().halfedges_begin(); h != active_mesh().halfedges_end(); ++h) {
1098
    for (HalfEdgeIDIterator h= active_mesh().halfedges_begin(); h != active_mesh().halfedges_end(); ++h) {
1038
        if(gel_rand() < 0.005 * GEL_RAND_MAX)
1099
        if(gel_rand() < 0.005 * GEL_RAND_MAX)
1039
        {
1100
        {
1040
            active_mesh().remove_edge(*h);
1101
            active_mesh().remove_edge(*h);
1041
        }
1102
        }
1042
    }
1103
    }
1043
 
1104
 
1044
    active_mesh().cleanup();
1105
    active_mesh().cleanup();
1045
    valid(active_mesh());
1106
    valid(active_mesh());
1046
	
1107
	
1047
    return;
1108
    return;
1048
}
1109
}
1049
 
1110
 
1050
 
1111
 
1051
void console_remove_caps(const std::vector<std::string> & args)
1112
void console_remove_caps(const std::vector<std::string> & args)
1052
{	
1113
{	
1053
    if(wantshelp(args)) {
1114
    if(wantshelp(args)) {
1054
        theConsole.printf("usage:  cleanup.remove_caps thresh");
1115
        theConsole.printf("usage:  cleanup.remove_caps thresh");
1055
        theConsole.printf("Remove caps (triangles with one very big angle). The thresh argument is the fraction of PI to");
1116
        theConsole.printf("Remove caps (triangles with one very big angle). The thresh argument is the fraction of PI to");
1056
        theConsole.printf("use as threshold for big angle. Default is 0.85. Caps are removed by flipping.");
1117
        theConsole.printf("use as threshold for big angle. Default is 0.85. Caps are removed by flipping.");
1057
        return;
1118
        return;
1058
    }
1119
    }
1059
    avo().save_old();
1120
    avo().save_old();
1060
	
1121
	
1061
    float t = 0.85f;
1122
    float t = 0.85f;
1062
    if(args.size() > 0){
1123
    if(args.size() > 0){
1063
        istringstream a0(args[0]);
1124
        istringstream a0(args[0]);
1064
        a0 >> t;
1125
        a0 >> t;
1065
    }
1126
    }
1066
    remove_caps(active_mesh(), static_cast<float>(M_PI) *t);
1127
    remove_caps(active_mesh(), static_cast<float>(M_PI) *t);
1067
    active_mesh().cleanup();
1128
    active_mesh().cleanup();
1068
	
1129
	
1069
    return;
1130
    return;
1070
}
1131
}
1071
 
1132
 
1072
void console_remove_needles(const std::vector<std::string> & args)
1133
void console_remove_needles(const std::vector<std::string> & args)
1073
{	
1134
{	
1074
    if(wantshelp(args)){
1135
    if(wantshelp(args)){
1075
        theConsole.printf("usage: cleanup.remove_needles <thresh>");
1136
        theConsole.printf("usage: cleanup.remove_needles <thresh>");
1076
        theConsole.printf("Removes very short edges by collapse. thresh is multiplied by the average edge length");
1137
        theConsole.printf("Removes very short edges by collapse. thresh is multiplied by the average edge length");
1077
        theConsole.printf("to get the length shorter than which we collapse. Default = 0.1");
1138
        theConsole.printf("to get the length shorter than which we collapse. Default = 0.1");
1078
        return;
1139
        return;
1079
    }
1140
    }
1080
    avo().save_old();
1141
    avo().save_old();
1081
	
1142
	
1082
    float thresh = 0.1f;
1143
    float thresh = 0.1f;
1083
    if(args.size() > 0){
1144
    if(args.size() > 0){
1084
        istringstream a0(args[0]);
1145
        istringstream a0(args[0]);
1085
        a0 >> thresh;
1146
        a0 >> thresh;
1086
    }
1147
    }
1087
    float avg_length = average_edge_length(active_mesh());
1148
    float avg_length = average_edge_length(active_mesh());
1088
    remove_needles(active_mesh(), thresh * avg_length);
1149
    remove_needles(active_mesh(), thresh * avg_length);
1089
    active_mesh().cleanup();
1150
    active_mesh().cleanup();
1090
	
1151
	
1091
    return;
1152
    return;
1092
}
1153
}
1093
 
1154
 
1094
void console_undo(const std::vector<std::string> & args)
1155
void console_undo(const std::vector<std::string> & args)
1095
{	
1156
{	
1096
    if(wantshelp(args)) {
1157
    if(wantshelp(args)) {
1097
        theConsole.printf("usage:  undo");
1158
        theConsole.printf("usage:  undo");
1098
        theConsole.printf("This function undoes one operation. Repeated undo does nothing");
1159
        theConsole.printf("This function undoes one operation. Repeated undo does nothing");
1099
        return;
1160
        return;
1100
    }
1161
    }
1101
    avo().restore_old();
1162
    avo().restore_old();
1102
    avo().refit();
1163
    //avo().refit();
1103
    return;
1164
    return;
1104
}
1165
}
1105
 
1166
 
1106
 
1167
 
1107
void reshape(int W, int H)
1168
void reshape(int W, int H)
1108
{
1169
{
1109
    active_view_control().reshape(W,H);
1170
    active_view_control().reshape(W,H);
1110
}
1171
}
1111
 
1172
 
1112
Console::variable<string> display_render_mode("normal");
1173
Console::variable<string> display_render_mode("normal");
1113
Console::variable<int> display_smooth_shading(true);
1174
Console::variable<int> display_smooth_shading(true);
1114
Console::variable<float> display_gamma(2.2);
1175
Console::variable<float> display_gamma(2.2);
1115
 
1176
 
1116
void display()
1177
void display()
1117
{
1178
{
1118
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1179
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1119
	
1180
	
1120
 
1181
 
1121
    glPushMatrix();
1182
    glPushMatrix();
1122
 
1183
 
1123
    avo().display(display_render_mode, theConsole, display_smooth_shading, display_gamma);
1184
    avo().display(display_render_mode, theConsole, display_smooth_shading, display_gamma);
1124
	
1185
	
1125
    glPopMatrix();
1186
    glPopMatrix();
1126
	
1187
	
1127
    if(console_visible)
1188
    if(console_visible)
1128
    {
1189
    {
1129
        glUseProgram(0);
1190
        glUseProgram(0);
1130
        theConsole.display();
1191
        theConsole.display();
1131
	}
1192
	}
1132
    
1193
    
1133
    glutSwapBuffers();
1194
    glutSwapBuffers();
1134
}
1195
}
1135
 
1196
 
1136
void animate() 
1197
void animate() 
1137
{	
1198
{	
1138
    //usleep( (int)1e4 );
1199
    //usleep( (int)1e4 );
1139
    active_view_control().try_spin();
1200
    active_view_control().try_spin();
1140
    glutPostRedisplay();
1201
    glutPostRedisplay();
1141
}
1202
}
1142
 
1203
 
1143
 
1204
 
1144
void mouse(int button, int state, int x, int y)     
1205
void mouse(int button, int state, int x, int y)     
1145
{
1206
{
1146
    Vec2i pos(x,y);
1207
    Vec2i pos(x,y);
1147
    if (state==GLUT_DOWN) 
1208
    if (state==GLUT_DOWN) 
1148
    {
1209
    {
1149
        if (button==GLUT_LEFT_BUTTON && glutGetModifiers() == 0)
1210
        if (button==GLUT_LEFT_BUTTON && glutGetModifiers() == 0)
1150
            active_view_control().grab_ball(ROTATE_ACTION,pos);
1211
            active_view_control().grab_ball(ROTATE_ACTION,pos);
1151
        else if (button==GLUT_MIDDLE_BUTTON || glutGetModifiers() == GLUT_ACTIVE_CTRL) 
1212
        else if (button==GLUT_MIDDLE_BUTTON || glutGetModifiers() == GLUT_ACTIVE_CTRL) 
1152
            active_view_control().grab_ball(ZOOM_ACTION,pos);
1213
            active_view_control().grab_ball(ZOOM_ACTION,pos);
1153
        else if (button==GLUT_RIGHT_BUTTON || glutGetModifiers() == GLUT_ACTIVE_ALT)
1214
        else if (button==GLUT_RIGHT_BUTTON || glutGetModifiers() == GLUT_ACTIVE_ALT)
1154
            active_view_control().grab_ball(PAN_ACTION,pos);
1215
            active_view_control().grab_ball(PAN_ACTION,pos);
1155
    }
1216
    }
1156
    else if (state==GLUT_UP)
1217
    else if (state==GLUT_UP)
1157
        active_view_control().release_ball();
1218
        active_view_control().release_ball();
1158
}
1219
}
1159
 
1220
 
1160
void motion(int x, int y) {
1221
void motion(int x, int y) {
1161
    Vec2i pos(x,y);
1222
    Vec2i pos(x,y);
1162
    active_view_control().roll_ball(Vec2i(x,y));
1223
    active_view_control().roll_ball(Vec2i(x,y));
1163
}
1224
}
1164
 
1225
 
1165
 
1226
 
1166
void keyboard_spec(int key, int x, int y)
1227
void keyboard_spec(int key, int x, int y)
1167
{
1228
{
1168
    if (console_visible)
1229
    if (console_visible)
1169
        theConsole.special(key);
1230
        theConsole.special(key);
1170
    glutPostRedisplay();
1231
    glutPostRedisplay();
1171
}
1232
}
1172
 
1233
 
1173
 
1234
 
1174
void keyboard(unsigned char key, int x, int y) 
1235
void keyboard(unsigned char key, int x, int y) 
1175
{
1236
{
1176
    //toggle console with ESC
1237
    //toggle console with ESC
1177
    if (key == 27)
1238
    if (key == 27)
1178
    {
1239
    {
1179
        console_visible = !console_visible;
1240
        console_visible = !console_visible;
1180
        glutPostRedisplay();
1241
        glutPostRedisplay();
1181
        return;
1242
        return;
1182
    }
1243
    }
1183
    
1244
    
1184
    if (console_visible)
1245
    if (console_visible)
1185
    {
1246
    {
1186
        theConsole.keyboard(key);
1247
        theConsole.keyboard(key);
1187
        if(key == 13)
1248
        if(key == 13)
1188
        {
1249
        {
1189
            avo().post_create_display_list();
1250
            avo().post_create_display_list();
1190
            glutPostRedisplay();
1251
            glutPostRedisplay();
1191
        }
1252
        }
1192
        return;
1253
        return;
1193
    }
1254
    }
1194
    else {		
1255
    else {		
1195
		
1256
		
1196
        switch(key) {
1257
        switch(key) {
1197
			case 'q': exit(0);
1258
			case 'q': exit(0);
1198
			case '\033':
1259
			case '\033':
1199
                console_visible = false;
1260
                console_visible = false;
1200
				break;
1261
				break;
1201
			case '1':
1262
			case '1':
1202
			case '2':
1263
			case '2':
1203
			case '3':
1264
			case '3':
1204
			case '4':
1265
			case '4':
1205
			case '5':
1266
			case '5':
1206
			case '6':
1267
			case '6':
1207
			case '7':
1268
			case '7':
1208
			case '8':
1269
			case '8':
1209
			case '9':
1270
			case '9':
1210
				active = key - '1'; break;
1271
				active = key - '1'; break;
1211
			case 'f': display_smooth_shading = !display_smooth_shading; break;
1272
			case 'f': display_smooth_shading = !display_smooth_shading; break;
1212
			case 'w':
1273
			case 'w':
1213
				display_render_mode = "wire"; break;
1274
				display_render_mode = "wire"; break;
1214
			case 'n':
1275
			case 'n':
1215
				display_render_mode = "normal"; break;
1276
				display_render_mode = "normal"; break;
1216
			case 'i':
1277
			case 'i':
1217
				display_render_mode = "isophotes"; break;
1278
				display_render_mode = "isophotes"; break;
1218
			case 'r':
1279
			case 'r':
1219
				display_render_mode = "reflection"; break;
1280
				display_render_mode = "reflection"; break;
1220
			case 'h':
1281
			case 'h':
1221
				display_render_mode = "harmonics"; break;
1282
				display_render_mode = "harmonics"; break;
1222
			case 't':
1283
			case 't':
1223
				display_render_mode = "toon"; break;
1284
				display_render_mode = "toon"; break;
1224
			case 'g':
1285
			case 'g':
1225
				display_render_mode = "glazed"; break;
1286
				display_render_mode = "glazed"; break;
1226
			case 'a':
1287
			case 'a':
1227
				display_render_mode = "ambient_occlusion"; break;
1288
				display_render_mode = "ambient_occlusion"; break;
1228
			case 'c':
1289
			case 'c':
1229
				display_render_mode = "copper"; break;
1290
				display_render_mode = "copper"; break;
1230
			case 'C':
1291
			case 'C':
1231
				display_render_mode = "curvature_lines"; break;
1292
				display_render_mode = "curvature_lines"; break;
1232
			case 'M':
1293
			case 'M':
1233
				display_render_mode = "mean_curvature"; break;
1294
				display_render_mode = "mean_curvature"; break;
1234
			case 'G':
1295
			case 'G':
1235
				display_render_mode = "gaussian_curvature"; break;
1296
				display_render_mode = "gaussian_curvature"; break;
1236
        }
1297
        }
1237
		
-
 
1238
        if(string(display_render_mode).substr(0,3) == "har")
-
 
1239
            avo().harmonics_parse_key(key);
-
 
1240
		
1298
				
1241
        if(key != '\033') avo().post_create_display_list();
1299
        if(key != '\033') avo().post_create_display_list();
1242
    }
1300
    }
1243
    
1301
    
1244
    glutPostRedisplay();
1302
    glutPostRedisplay();
1245
}
1303
}
1246
 
1304
 
1247
void init_glut(int argc, char** argv)
1305
void init_glut(int argc, char** argv)
1248
{  
1306
{  
1249
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_ALPHA);
1307
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_ALPHA);
1250
    glutInitWindowSize(WINX, WINY);
1308
    glutInitWindowSize(WINX, WINY);
1251
    glutInit(&argc, argv);
1309
    glutInit(&argc, argv);
1252
    glutCreateWindow("MeshEdit");
1310
    glutCreateWindow("MeshEdit");
1253
    glutDisplayFunc(display);
1311
    glutDisplayFunc(display);
1254
    glutKeyboardFunc(keyboard);
1312
    glutKeyboardFunc(keyboard);
1255
    glutSpecialFunc(keyboard_spec);
1313
    glutSpecialFunc(keyboard_spec);
1256
    glutReshapeFunc(reshape);
1314
    glutReshapeFunc(reshape);
1257
    glutMouseFunc(mouse);
1315
    glutMouseFunc(mouse);
1258
    glutMotionFunc(motion);
1316
    glutMotionFunc(motion);
1259
    glutIdleFunc(animate);
1317
    glutIdleFunc(animate);
1260
}
1318
}
1261
void init_gl()
1319
void init_gl()
1262
{
1320
{
1263
    glewInit();
1321
    glewInit();
1264
    glEnable(GL_CULL_FACE);
1322
    glEnable(GL_CULL_FACE);
1265
    glCullFace(GL_BACK);
1323
    glCullFace(GL_BACK);
1266
    glEnable(GL_LIGHTING);
1324
    glEnable(GL_LIGHTING);
1267
    glEnable(GL_LIGHT0);
1325
    glEnable(GL_LIGHT0);
1268
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
1326
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
1269
	
1327
	
1270
    // Set the value of a uniform
1328
    // Set the value of a uniform
1271
    //glUniform2f(glGetUniformLocation(prog_P0,"WIN_SCALE"), win_size_x/2.0, win_size_y/2.0);
1329
    //glUniform2f(glGetUniformLocation(prog_P0,"WIN_SCALE"), win_size_x/2.0, win_size_y/2.0);
1272
	
1330
	
1273
    glMatrixMode(GL_MODELVIEW);
1331
    glMatrixMode(GL_MODELVIEW);
1274
    glLoadIdentity();
1332
    glLoadIdentity();
1275
    glClearColor(1,1,1, 0.f);
1333
    glClearColor(1,1,1, 0.f);
1276
    glColor4f(1.0f, 1.0f, 1.0f, 0.f);
1334
    glColor4f(1.0f, 1.0f, 1.0f, 0.f);
1277
    float material[4] = {1,1,1,1};
1335
    float material[4] = {1,1,1,1};
1278
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material);
1336
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material);
1279
    glEnable(GL_DEPTH_TEST);
1337
    glEnable(GL_DEPTH_TEST);
1280
	
1338
	
1281
    theConsole.reg_cmdN("harmonics.reset_shape", console_reset_shape, "");
1339
    theConsole.reg_cmdN("harmonics.reset_shape", console_reset_shape, "");
1282
    theConsole.reg_cmdN("harmonics.analyze", console_analyze, "");
1340
    theConsole.reg_cmdN("harmonics.analyze", console_analyze, "");
1283
    theConsole.reg_cmdN("harmonics.partial_reconstruct", console_partial_reconstruct,"");
1341
    theConsole.reg_cmdN("harmonics.partial_reconstruct", console_partial_reconstruct,"");
1284
    theConsole.reg_cmdN("simplify", console_simplify,"");
1342
    theConsole.reg_cmdN("simplify", console_simplify,"");
1285
    theConsole.reg_cmdN("smooth.mean_curvature", console_mean_curvature_smooth,"");
1343
    theConsole.reg_cmdN("smooth.mean_curvature", console_mean_curvature_smooth,"");
1286
    theConsole.reg_cmdN("smooth.laplacian", console_laplacian_smooth,"");
1344
    theConsole.reg_cmdN("smooth.laplacian", console_laplacian_smooth,"");
1287
    theConsole.reg_cmdN("smooth.taubin", console_taubin_smooth,"");
1345
    theConsole.reg_cmdN("smooth.taubin", console_taubin_smooth,"");
1288
    theConsole.reg_cmdN("smooth.fuzzy_vector_median_anisotropic", console_fvm_anisotropic_smooth ,"");
1346
    theConsole.reg_cmdN("smooth.fuzzy_vector_median_anisotropic", console_fvm_anisotropic_smooth ,"");
1289
    theConsole.reg_cmdN("smooth.bilateral_anisotropic", console_bilateral_anisotropic_smooth ,"");
1347
    theConsole.reg_cmdN("smooth.bilateral_anisotropic", console_bilateral_anisotropic_smooth ,"");
1290
	
1348
	
1291
    theConsole.reg_cmdN("optimize.valency", console_optimize_valency,"");
1349
    theConsole.reg_cmdN("optimize.valency", console_optimize_valency,"");
1292
    theConsole.reg_cmdN("optimize.minimize_dihedral_angles", console_minimize_dihedral,"");
1350
    theConsole.reg_cmdN("optimize.minimize_dihedral_angles", console_minimize_dihedral,"");
1293
    theConsole.reg_cmdN("optimize.minimize_curvature", console_minimize_curvature,"");
1351
    theConsole.reg_cmdN("optimize.minimize_curvature", console_minimize_curvature,"");
1294
    theConsole.reg_cmdN("optimize.maximize_min_angle", console_maximize_min_angle,"");
1352
    theConsole.reg_cmdN("optimize.maximize_min_angle", console_maximize_min_angle,"");
1295
    theConsole.reg_cmdN("cleanup.close_holes", console_close_holes,"");
1353
    theConsole.reg_cmdN("cleanup.close_holes", console_close_holes,"");
1296
    theConsole.reg_cmdN("load_mesh", console_reload,"");
1354
    theConsole.reg_cmdN("load_mesh", console_reload,"");
1297
    theConsole.reg_cmdN("add_mesh", console_add_mesh,"");
1355
    theConsole.reg_cmdN("add_mesh", console_add_mesh,"");
1298
	
1356
	
1299
    theConsole.reg_cmdN("cleanup.remove_caps", console_remove_caps,"");
1357
    theConsole.reg_cmdN("cleanup.remove_caps", console_remove_caps,"");
1300
    theConsole.reg_cmdN("cleanup.remove_needles", console_remove_needles,"");
1358
    theConsole.reg_cmdN("cleanup.remove_needles", console_remove_needles,"");
1301
    theConsole.reg_cmdN("triangulate", console_triangulate,"");
1359
    theConsole.reg_cmdN("triangulate", console_triangulate,"");
1302
    theConsole.reg_cmdN("refine.split_edges", console_refine_edges,"");
1360
    theConsole.reg_cmdN("refine.split_edges", console_refine_edges,"");
1303
    theConsole.reg_cmdN("refine.split_faces", console_refine_faces,"");
1361
    theConsole.reg_cmdN("refine.split_faces", console_refine_faces,"");
1304
    theConsole.reg_cmdN("subdivide.catmull_clark", console_cc_subdivide,"");
1362
    theConsole.reg_cmdN("subdivide.catmull_clark", console_cc_subdivide,"");
1305
    theConsole.reg_cmdN("subdivide.loop", console_loop_subdivide,"");
1363
    theConsole.reg_cmdN("subdivide.loop", console_loop_subdivide,"");
1306
    theConsole.reg_cmdN("subdivide.root3", console_root3_subdivide,"");
1364
    theConsole.reg_cmdN("subdivide.root3", console_root3_subdivide,"");
1307
    theConsole.reg_cmdN("subdivide.doo_sabin", console_doosabin_subdivide,"");
1365
    theConsole.reg_cmdN("subdivide.doo_sabin", console_doosabin_subdivide,"");
1308
    theConsole.reg_cmdN("subdivide.butterfly", console_butterfly_subdivide,"");
1366
    theConsole.reg_cmdN("subdivide.butterfly", console_butterfly_subdivide,"");
1309
    theConsole.reg_cmdN("save_mesh", console_save,"");
1367
    theConsole.reg_cmdN("save_mesh", console_save,"");
1310
    theConsole.reg_cmdN("noise.perturb_vertices", console_vertex_noise,"");
1368
    theConsole.reg_cmdN("noise.perturb_vertices", console_vertex_noise,"");
1311
    theConsole.reg_cmdN("noise.perturb_vertices_perpendicular", console_perpendicular_vertex_noise,"");
1369
    theConsole.reg_cmdN("noise.perturb_vertices_perpendicular", console_perpendicular_vertex_noise,"");
1312
    theConsole.reg_cmdN("noise.perturb_topology", console_noisy_flips,"");
1370
    theConsole.reg_cmdN("noise.perturb_topology", console_noisy_flips,"");
1313
 
1371
 
1314
    theConsole.reg_cmdN("remove_faces", console_remove_faces,"");
1372
    theConsole.reg_cmdN("remove_faces", console_remove_faces,"");
1315
 
1373
 
1316
    theConsole.reg_cmdN("dual", console_dual,"");
1374
    theConsole.reg_cmdN("dual", console_dual,"");
1317
    theConsole.reg_cmdN("flatten", console_flatten,"");
1375
    theConsole.reg_cmdN("flatten", console_flatten,"");
1318
	
1376
	
1319
    theConsole.reg_cmdN("align", console_align,"");
1377
    theConsole.reg_cmdN("align", console_align,"");
1320
	
1378
	
1321
    theConsole.reg_cmdN("undo", console_undo,"");
1379
    theConsole.reg_cmdN("undo", console_undo,"");
1322
	
1380
	
1323
	theConsole.reg_cmdN("validity", console_valid,"");
1381
	theConsole.reg_cmdN("validity", console_valid,"");
1324
	theConsole.reg_cmdN("info", console_info,"");
1382
	theConsole.reg_cmdN("info", console_info,"");
1325
 
1383
 
1326
    theConsole.reg_cmdN("polarize", console_polarize ,"");
1384
    theConsole.reg_cmdN("polarize", console_polarize ,"");
-
 
1385
    theConsole.reg_cmdN("polar.simplify", console_simplify_polar ,"");
-
 
1386
    theConsole.reg_cmdN("polar.refit", console_refit_polar ,"");
1327
    
1387
    
1328
    theConsole.reg_cmdN("transform.scale", console_scale, "Scale mesh");
1388
    theConsole.reg_cmdN("transform.scale", console_scale, "Scale mesh");
1329
    
1389
    
1330
    active.reg(theConsole, "active_mesh", "The active mesh");
1390
    active.reg(theConsole, "active_mesh", "The active mesh");
1331
    display_render_mode.reg(theConsole, "display.render_mode", "Display render mode");
1391
    display_render_mode.reg(theConsole, "display.render_mode", "Display render mode");
1332
    display_smooth_shading.reg(theConsole, "display.smooth_shading", "1 for smooth shading 0 for flat");
1392
    display_smooth_shading.reg(theConsole, "display.smooth_shading", "1 for smooth shading 0 for flat");
1333
    display_gamma.reg(theConsole, "display.gamma", "The gamma setting for the display");
1393
    display_gamma.reg(theConsole, "display.gamma", "The gamma setting for the display");
1334
 
1394
 
1335
}
1395
}
1336
 
1396
 
1337
int main(int argc, char** argv)
1397
int main(int argc, char** argv)
1338
{
1398
{
1339
    ArgExtracter ae(argc, argv);
1399
    ArgExtracter ae(argc, argv);
1340
	
1400
	
1341
    init_glut(argc, argv);
1401
    init_glut(argc, argv);
1342
    init_gl();
1402
    init_gl();
1343
	
1403
	
1344
    theConsole.print("Welcome to MeshEdit");
1404
    theConsole.print("Welcome to MeshEdit");
1345
    theConsole.newline();
1405
    theConsole.newline();
1346
   
1406
   
1347
    if(argc>1){		
1407
    if(argc>1){		
1348
        vector<string> files;
1408
        vector<string> files;
1349
		ae.get_all_args(files);
1409
		ae.get_all_args(files);
1350
		for(size_t i=1;i<files.size();++i)
1410
		for(size_t i=1;i<files.size();++i)
1351
			get_vis_obj(i-1).reload(files[i]);
1411
			get_vis_obj(i-1).reload(files[i]);
1352
    }
1412
    }
1353
    glutMainLoop();
1413
    glutMainLoop();
1354
    return 0;
1414
    return 0;
1355
}
1415
}
1356
 
1416
 
1357
 
1417
 
1358
 
1418
 
1359
 
1419
 
1360
 
1420
 
1361
 
1421