Subversion Repositories gelsvn

Rev

Rev 671 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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