Subversion Repositories gelsvn

Rev

Rev 596 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
568 jab 1
//
2
//  polarize.cpp
3
//  GEL
4
//
5
//  Created by J. Andreas Bærentzen on 18/03/12.
6
//  Copyright 2012 __MyCompanyName__. All rights reserved.
7
//
8
#include <queue>
9
 
10
#include "polarize.h"
11
#include <HMesh/triangulate.h>
12
#include <HMesh/curvature.h>
13
#include <HMesh/quadric_simplify.h>
14
#include <HMesh/mesh_optimization.h>
15
#include <HMesh/smooth.h>
16
 
572 jab 17
#include <complex>
18
 
568 jab 19
using namespace CGLA;
20
using namespace std;
21
using namespace HMesh;
22
 
23
void shortest_edge_triangulate_face(Manifold& m, FaceID f0, VertexAttributeVector<int>& level_set_id_vertex)
24
{
25
    queue<FaceID> face_queue;
26
 
27
    face_queue.push(f0);
28
 
29
    while(!face_queue.empty())
30
    {
31
        FaceID f = face_queue.front();
32
        face_queue.pop();
33
 
34
        // Create a vector of vertices.
35
        vector<VertexID> verts;
587 jab 36
        for(Walker w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw())
568 jab 37
        {
38
            FaceID fa = w.face();
39
            FaceID fb = f;
40
            assert(fa==fb);
41
            verts.push_back(w.vertex());
42
        }
43
        // If there are just three we are done.
44
        if(verts.size() == 3) continue;
45
 
46
        // Find vertex pairs that may be connected.
47
        vector<pair<int,int> > vpairs;
48
        const int N = verts.size();
49
        for(int i = 0; i < N - 2; ++i){
50
            for(int j = i + 2; j < N; ++j){
51
                if(verts[i] != verts[j] && 
52
                   !connected(m, verts[i], verts[j]) &&
53
                   (level_set_id_vertex[verts[i]] == 0 || level_set_id_vertex[verts[i]] != level_set_id_vertex[verts[j]])
54
                   )
55
                    vpairs.push_back(pair<int,int>(i, j));
56
            }
57
        }
58
        if(vpairs.empty()){
59
            cout << "Warning: could not triangulate a face." 
60
            << "Probably a vertex appears more than one time in other vertex's one-ring" << endl;
61
            continue;
62
        }
63
 
64
        /* For all vertex pairs, find the edge lengths. Combine the
65
         vertices forming the shortest edge. */
66
 
67
        float min_len=FLT_MAX;
68
        int min_k = -1;
69
        for(size_t k = 0; k < vpairs.size(); ++k){
70
            int i = vpairs[k].first;
71
            int j = vpairs[k].second;
72
            float len = sqr_length(m.pos(verts[i]) - m.pos(verts[j]));
73
 
74
            if(len<min_len){
75
                min_len = len;
76
                min_k = k;
77
            }
78
        }
79
        assert(min_k != -1);
80
 
81
        {
82
            // Split faces along edge whose midpoint is closest to isovalue
83
            int i = vpairs[min_k].first;
84
            int j = vpairs[min_k].second;
85
            FaceID f_new = m.split_face_by_edge(f, verts[i], verts[j]);
86
 
87
            if(no_edges(m, f)>3)
88
                face_queue.push(f);
89
            if(no_edges(m, f_new)>3)
90
                face_queue.push(f_new);
91
        }
92
 
93
    }
94
}
95
 
96
 
97
void shortest_edge_split_face(Manifold& m, FaceID f0, VertexAttributeVector<int>& level_set_id_vertex)
98
{
99
    queue<FaceID> face_queue;
100
 
101
    face_queue.push(f0);
102
 
103
    while(!face_queue.empty())
104
    {
105
        FaceID f = face_queue.front();
106
        face_queue.pop();
107
 
108
        // Create a vector of vertices.
109
        vector<VertexID> verts;
587 jab 110
        for(Walker w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw())
568 jab 111
        {
112
            verts.push_back(w.vertex());
113
        }
114
 
115
        // Find vertex pairs that may be connected.
116
        vector<pair<int,int> > vpairs;
117
        const int N = verts.size();
118
        for(int i = 0; i < N ; ++i){
119
            for(int j = 3; j < N-2; ++j){
120
                int jj = (j+i)%N;
121
                if(!connected(m, verts[i], verts[jj]) &&
122
                   (level_set_id_vertex[verts[i]] != level_set_id_vertex[verts[jj]]) &&
572 jab 123
                   (level_set_id_vertex[verts[(i+1)%N]] == level_set_id_vertex[verts[i]]) &&
124
                   (level_set_id_vertex[verts[(i+N-1)%N]] == level_set_id_vertex[verts[i]]) &&
125
                   (level_set_id_vertex[verts[(jj+1)%N]] == level_set_id_vertex[verts[jj]]) &&
126
                   (level_set_id_vertex[verts[(jj+N-1)%N]] == level_set_id_vertex[verts[jj]]))
568 jab 127
                    vpairs.push_back(pair<int,int>(i, jj));
128
            }
129
        }
130
        if(vpairs.empty()) continue;
131
 
132
 
133
        /* For all vertex pairs, find the edge lengths. Combine the
134
         vertices forming the shortest edge. */
135
 
136
        float min_len=FLT_MAX;
137
        int min_k = -1;
138
        for(size_t k = 0; k < vpairs.size(); ++k){
139
            int i = vpairs[k].first;
140
            int j = vpairs[k].second;
141
            float len = sqr_length(m.pos(verts[i]) - m.pos(verts[j]));
142
 
143
            if(len<min_len){
144
                min_len = len;
145
                min_k = k;
146
            }
147
        }
148
        assert(min_k != -1);
149
 
150
        {
151
            // Split faces along edge whose midpoint is closest to isovalue
152
            int i = vpairs[min_k].first;
153
            int j = vpairs[min_k].second;
154
            FaceID f_new = m.split_face_by_edge(f, verts[i], verts[j]);
155
            if(no_edges(m, f)>5)
156
                face_queue.push(f);
157
            if(no_edges(m, f_new)>5)
158
                face_queue.push(f_new);
159
        }
160
 
161
    }
162
}
163
 
164
 
165
 
166
struct EdgeQElem {
167
    float priority;
168
    HalfEdgeID he;
169
    EdgeQElem(float _priority, HalfEdgeID _he): priority(_priority), he(_he) {}
170
};
171
 
172
bool operator<(const EdgeQElem& l, const EdgeQElem& r)
173
{
174
    return l.priority < r.priority;
175
}
176
 
177
class FunctionalDifference: public EnergyFun
178
{
179
    VertexAttributeVector<float>& fun;
180
    VertexAttributeVector<int>& status;
181
public:
182
    FunctionalDifference(VertexAttributeVector<float>& _fun, VertexAttributeVector<int>& _status): fun(_fun), status(_status) {}
183
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const 
184
    {
587 jab 185
        Walker w = m.walker(h);
568 jab 186
        if(status[w.vertex()] == 1 && status[w.opp().vertex()]==1)
187
            return DBL_MAX;
188
        return sqr_length(m.pos(w.next().vertex())-m.pos(w.opp().next().vertex()))/(1e-6+abs(fun[w.next().vertex()]-fun[w.opp().next().vertex()])) - sqr_length(m.pos(w.vertex())-m.pos(w.opp().vertex()))/(1e-6+abs(fun[w.vertex()]-fun[w.opp().vertex()]));
189
    }
190
};
191
 
572 jab 192
class TriangleQualityValence: public EnergyFun
193
{
194
    VertexAttributeVector<int>& idv;
195
    MinAngleEnergy mae;
196
    ValencyEnergy vae;
197
public:
198
    TriangleQualityValence(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
199
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const 
200
    {
587 jab 201
        Walker w = m.walker(h);
572 jab 202
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] || 
203
           idv[w.vertex()] == idv[w.opp().vertex()])
204
            return DBL_MAX;
205
 
206
        VertexID v1 = w.opp().vertex();
207
        VertexID v2 = w.vertex();
208
        VertexID vo1 = w.next().vertex();
209
        VertexID vo2 = w.opp().next().vertex();
210
 
211
        int val1  = valency(m, v1);
212
        int val2  = valency(m, v2);
213
        int valo1 = valency(m, vo1);
214
        int valo2 = valency(m, vo2);
215
 
216
        // The optimal valency is four for a boundary vertex
217
        // and six elsewhere.
218
        int t1 = boundary(m, v1) ? 4 : 6;
219
        int t2 = boundary(m, v2) ? 4 : 6;
220
        int to1 = boundary(m, vo1) ? 4 : 6;
221
        int to2 = boundary(m, vo2) ? 4 : 6;
222
 
223
        int before = 
224
        max(max(sqr(val1-t1),sqr(val2-t2)), max(sqr(valo1-to1), sqr(valo2-to2)));
225
        int after = 
226
        max(max(sqr(valo1+1-to1),sqr(val1-1-t1)), max(sqr(val2-1-t2),sqr(valo2+1-to2)));
227
 
228
        return static_cast<double>(after-before);
229
 
230
        //        return vae.delta_energy(m,h);
231
        float la = length(m.pos(w.next().vertex())-m.pos(w.opp().next().vertex()));
232
        float lb = length(m.pos(w.vertex())-m.pos(w.opp().vertex()));
233
        return la-lb;
234
        return mae.delta_energy(m,h);
235
    }
236
};
237
 
568 jab 238
class TriangleQuality: public EnergyFun
239
{
240
    VertexAttributeVector<int>& idv;
241
    MinAngleEnergy mae;
242
    ValencyEnergy vae;
243
public:
244
    TriangleQuality(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
245
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const 
246
    {
587 jab 247
        Walker w = m.walker(h);
568 jab 248
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] || 
249
           idv[w.vertex()] == idv[w.opp().vertex()])
250
            return DBL_MAX;
251
        return mae.delta_energy(m,h);
252
    }
253
};
254
 
587 jab 255
Vec3d grad(HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun, HMesh::FaceID f)
572 jab 256
{
257
    if(no_edges(m,f) != 3)
587 jab 258
        return Vec3d(0.0);
572 jab 259
 
260
 
587 jab 261
    Vec3d n = normal(m, f);
572 jab 262
 
587 jab 263
    Vec3d gsum(0.0);
264
    for(Walker w = m.walker(f); !w.full_circle(); w = w.next())
572 jab 265
    {
587 jab 266
        Vec3d gdir = normalize(cross(n, m.pos(w.vertex()) - m.pos(w.opp().vertex())));
572 jab 267
        float l = dot(m.pos(w.next().vertex())-m.pos(w.vertex()), gdir);
268
        gdir *= fun[w.next().vertex()]/l;
269
        gsum += gdir;
270
    }
271
    return gsum;
272
}
568 jab 273
 
572 jab 274
complex<double> complex_slerp(double t, const complex<double>& a, const complex<double>&b)
275
{
276
    double omega = (arg(a/b));
277
    cout << omega << endl;
278
    return (a*sin((1-t)*omega) + b*sin(t*omega))/sin(omega);
279
}
280
 
281
double mod_2pi(double x)
282
{
283
    return x-floor(x/(2.0 * M_PI))*2.0 * M_PI;
284
}
285
 
286
void extend_fun2(HMesh::Manifold& m, HMesh::HalfEdgeID h,
287
                 HMesh::VertexAttributeVector<double>& fun, 
288
                 HMesh::VertexAttributeVector<double>& fun2)
289
{
587 jab 290
    Walker w = m.walker(h);
572 jab 291
    FaceID f = w.face();
587 jab 292
    Vec3d a = m.pos(w.opp().vertex());
293
    Vec3d b = m.pos(w.vertex());
294
    Vec3d c = m.pos(w.next().vertex());
295
    Vec3d g = grad(m, fun, f);
296
    Vec3d n = normal(m, f);
297
    Vec3d N = -normalize(cross(g, n));
572 jab 298
    float dot_nba = dot(N,b-a);
299
    float v;
300
    if(dot_nba > 1e-5)
301
    {
302
        float t = dot(N, c-a)/dot_nba;
303
        double aval = fun2[w.opp().vertex()];
304
        double bval = fun2[w.vertex()];
305
        double val = (1-t)*aval + t*bval;
306
        v = mod_2pi(val);
307
        cout << t << " , " << v << endl; 
308
    }
309
    else
310
        v =  fun2[w.vertex()];
311
    fun2[w.next().vertex()] = v;
312
}
313
 
568 jab 314
inline bool same_level(float a, float b) {return abs(a-b) < 0.00001;}
315
 
587 jab 316
Vec3d laplacian(const Manifold& m, VertexID v)
568 jab 317
{
587 jab 318
    Vec3d avg_pos(0);
568 jab 319
    float asum = 0;
320
 
587 jab 321
    for(Walker w = m.walker(v); !w.full_circle(); w = w.circulate_vertex_cw()){
568 jab 322
        float  a = barycentric_area(m, w.vertex());
323
        avg_pos += a * m.pos(w.vertex());
324
        asum += a;
325
    }
326
    return avg_pos / asum - m.pos(v);
327
}
328
 
329
void aw_laplacian_smooth(Manifold& m, float t)
330
{
587 jab 331
    VertexAttributeVector<Vec3d> pos(m.allocated_vertices());
568 jab 332
 
333
    for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v){
334
        if(!boundary(m, *v))
335
        {
587 jab 336
            Vec3d n = normal(m, *v);
337
            Vec3d l = laplacian(m, *v);
568 jab 338
            if(sqr_length(n) > 0.8)
339
                l -= n * dot(n,l);
340
            pos[*v] =  t * l + m.pos(*v);
341
        }
342
    }
343
 
344
    for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v){
345
        if(!boundary(m, *v))
346
            m.pos(*v) = pos[*v];
347
    }
348
}
349
 
572 jab 350
void polarize_mesh(Manifold& m, VertexAttributeVector<double>& fun, double vmin, double vmax, const int divisions, VertexAttributeVector<double>& parametrization)
568 jab 351
{
572 jab 352
    vmax -= 0.01 * (vmax-vmin);
568 jab 353
    float interval = (vmax-vmin)/divisions;
354
 
586 jab 355
    VertexAttributeVector<int> status(m.allocated_vertices(), 0);
568 jab 356
 
357
 
358
    // ----------------------------------------
359
    cout << "Tracing level set curves" << endl;
360
 
361
    vector<HalfEdgeID> hidvec;
362
    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
363
    {
587 jab 364
        Walker w = m.walker(*hid);
568 jab 365
        if(fun[w.vertex()] > fun[w.opp().vertex()])
366
            hidvec.push_back(*hid);
367
    }
368
 
607 jrf 369
    for(size_t i = 0; i<hidvec.size(); ++i)
568 jab 370
    {
587 jab 371
        Walker w = m.walker(hidvec[i]);
568 jab 372
 
373
        float b = (fun[w.vertex()]- vmin)/interval;
374
        float a = (fun[w.opp().vertex()] - vmin)/interval;
375
        float floor_b = floor(b);
376
        float floor_a = floor(a);
377
 
587 jab 378
        Vec3d pb = m.pos(w.vertex());
568 jab 379
        for(int j=floor_b; j>floor_a; --j)
380
        {
381
            float t = (j-a) / (b-a);
587 jab 382
            Vec3d p = t * pb + (1.0-t) * m.pos(w.opp().vertex());
568 jab 383
            VertexID v_new = m.split_edge(w.halfedge());
384
            w = w.prev();
385
            status[v_new] = 1;
386
            fun[v_new] = j * interval + vmin;
387
            m.pos(v_new) = p;
388
        }
389
    }
390
 
391
    bool did_work;
392
    do
393
    {
394
        did_work = false;
395
 
396
        for(FaceIDIterator fid = m.faces_begin(); fid != m.faces_end(); ++fid)
587 jab 397
            for(Walker w = m.walker(*fid);!w.full_circle(); w = w.next())
568 jab 398
                if(status[w.vertex()] == 1 && !(status[w.next().vertex()]==1 && same_level(fun[w.vertex()],fun[w.next().vertex()]))
399
                   && !(status[w.prev().vertex()]==1 && same_level(fun[w.vertex()],fun[w.prev().vertex()])))
400
                {
587 jab 401
                    Walker w0 = w;
568 jab 402
                    w = w.next().next();
403
                    do
404
                    {
405
                        if(status[w.vertex()] == 1 && w.next().halfedge() != w0.halfedge() &&
406
                           same_level(fun[w0.vertex()],fun[w.vertex()]))
407
                        {
408
                            m.split_face_by_edge(*fid, w0.vertex(), w.vertex());
409
                            did_work = true;
410
                            break;
411
                        }
412
                        w = w.next();
413
                    }
414
                    while(!w.full_circle());
415
                    break;
416
                }
417
    }
418
    while(did_work);
419
 
572 jab 420
 
421
 
422
 
568 jab 423
    // ----------------------------
424
    cout << "Numbering the level sets" << endl;
572 jab 425
 
426
    float max_length = 0;
427
    double max_length_fun = 0;
428
    int max_length_id =-1;
429
    HalfEdgeID max_length_h;
586 jab 430
    HalfEdgeAttributeVector<int> level_set_id(m.allocated_halfedges(), 0);
431
    VertexAttributeVector<int> level_set_id_vertex(m.allocated_vertices(), 0);
568 jab 432
    int no_id=1;
433
    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
434
    {
587 jab 435
        Walker w = m.walker(*hid);
568 jab 436
        if(status[w.vertex()] == 1 && status[w.opp().vertex()] == 1 &&
437
           same_level(fun[w.vertex()], fun[w.opp().vertex()]) &&
438
           level_set_id[w.halfedge()] == 0)
439
        {
572 jab 440
            float level_set_length = 0;
568 jab 441
            while(level_set_id[w.halfedge()] != no_id)
442
            {
572 jab 443
                level_set_length += length(m,w.halfedge());
568 jab 444
                level_set_id[w.halfedge()] = no_id;
445
                level_set_id[w.opp().halfedge()] = no_id;
446
                level_set_id_vertex[w.vertex()] = no_id;
447
                w = w.next();
448
                while(status[w.vertex()] != 1 || !same_level(fun[w.vertex()], fun[w.opp().vertex()]))
449
                    w = w.circulate_vertex_cw();
450
            }            
572 jab 451
            if(level_set_length > max_length)
452
            {
453
                max_length = level_set_length;
454
                max_length_id = no_id;
455
                max_length_h = w.halfedge();
456
                max_length_fun = fun[w.vertex()];
457
            }
458
            ++no_id;
568 jab 459
        }
460
    }
572 jab 461
    cout << max_length << " " << max_length_id << endl;
568 jab 462
    cout << "Number of level sets : " << (no_id-1);
463
    // ----------------------------
464
 
572 jab 465
    shortest_edge_triangulate(m);
466
 
467
 
468
    // -------------
469
    cout << "Parametrize level sets " << endl;
470
 
471
    queue<HalfEdgeID> hq;
586 jab 472
    HalfEdgeAttributeVector<int> touched(m.no_halfedges(), 0);
587 jab 473
    Walker w = m.walker(max_length_h);
572 jab 474
    float param = 0;
475
    do
476
    {
477
        parametrization[w.opp().vertex()] = 2.0 * M_PI * param / max_length;
478
        param += length(m, w.halfedge());
479
        w = w.next();
480
        while(level_set_id[w.halfedge()] != max_length_id)
481
            w = w.circulate_vertex_cw();
482
        hq.push(w.halfedge());
483
        hq.push(w.opp().halfedge());
484
        touched[w.halfedge()] = 1;
485
        touched[w.opp().halfedge()] = 1;
486
    }            
487
    while(w.halfedge() != max_length_h);
488
 
489
    while(!hq.empty())
490
    {
491
        HalfEdgeID h = hq.front();
492
        hq.pop();
493
        if(!touched[w.next().halfedge()])
494
        {
495
            extend_fun2(m, h, fun, parametrization);
496
            touched[w.next().halfedge()] = 1;
497
            touched[w.prev().halfedge()] = 1;
587 jab 498
            Walker w = m.walker(h);
572 jab 499
            if(!touched[w.next().opp().halfedge()])
500
            {
501
                touched[w.next().opp().halfedge()] = 1;
502
                hq.push(w.next().opp().halfedge());
503
            }
504
            if(!touched[w.prev().opp().halfedge()])
505
            {
506
                touched[w.prev().opp().halfedge()] = 1;
507
                hq.push(w.prev().opp().halfedge());
508
 
509
            }
510
        }
511
    }
512
 
513
    return; 
514
 
568 jab 515
    // ----------------------------
516
    cout << "Remove vertices not on level set curves" << endl;
572 jab 517
 
568 jab 518
    vector<VertexID> vid_vec;
519
    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
520
        if(status[*vid]==0)
521
            vid_vec.push_back(*vid);
522
 
523
    random_shuffle(vid_vec.begin(), vid_vec.end());
607 jrf 524
    for (size_t i=0; i<vid_vec.size(); ++i) {
568 jab 525
        FaceID f = m.merge_one_ring(vid_vec[i]);
526
        if(f != InvalidFaceID)
527
            shortest_edge_triangulate_face(m, f, level_set_id_vertex);
528
        else
529
            cout << "vertex not removed " << valency(m, vid_vec[i]) << endl; 
530
    }
572 jab 531
 
568 jab 532
    for(FaceIDIterator fid = m.faces_begin(); fid != m.faces_end(); ++fid)
533
        if(no_edges(m, *fid) > 3)
534
            shortest_edge_triangulate_face(m, *fid, level_set_id_vertex);
535
 
572 jab 536
 
587 jab 537
    VertexAttributeVector<Vec3d> recalled_positions;
568 jab 538
    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
539
        recalled_positions[*vid] = m.pos(*vid);
540
 
572 jab 541
 
542
    TriangleQuality tq_energy(level_set_id_vertex);
543
    priority_queue_optimization(m, tq_energy);
544
 
545
 
546
 
547
    //// ----------------------------
548
    cout << "smooth level set curves" << endl;
549
 
550
 
551
    for(int iter=0;iter< 14;++iter)
568 jab 552
    {
572 jab 553
        TriangleQualityValence tqv_energy(level_set_id_vertex);
554
        TriangleQuality tq_energy(level_set_id_vertex);
555
        priority_queue_optimization(m, tqv_energy);
556
        priority_queue_optimization(m, tq_energy);
557
 
587 jab 558
        VertexAttributeVector<Vec3d> new_pos(m.allocated_vertices(), Vec3d(0));
586 jab 559
        VertexAttributeVector<float> new_pos_wsum(m.allocated_vertices(), 0.0);
568 jab 560
        for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
561
        {
587 jab 562
            Walker w = m.walker(*hid);
568 jab 563
            if(level_set_id[w.halfedge()] != 0)
564
            {
572 jab 565
                float weight = 1.0;//sqr(valency(m,w.opp().vertex())-2);
568 jab 566
                new_pos[w.vertex()] += weight*m.pos(w.opp().vertex());
567
                new_pos_wsum[w.vertex()] += weight;
568
            }
569
        }
570
        for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
571
        {
572 jab 572
            float weight = 1.0;//sqr(valency(m,*vid)-2);
568 jab 573
            new_pos[*vid] += weight*m.pos(*vid);
574
            new_pos_wsum[*vid] += weight;
572 jab 575
            m.pos(*vid) = 0.75*m.pos(*vid) + 0.25 *new_pos[*vid] / new_pos_wsum[*vid];
568 jab 576
        }
577
 
572 jab 578
        priority_queue_optimization(m, tqv_energy);
579
        priority_queue_optimization(m, tq_energy);
580
        vector<HalfEdgeID> hidvec;
581
        for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
582
        {
587 jab 583
            Walker w = m.walker(*hid);
572 jab 584
            if(w.halfedge() < w.opp().halfedge() && 
585
               level_set_id[w.halfedge()] != 0 &&
586
               (
587
                ((level_set_id[w.opp().halfedge()] == level_set_id[w.opp().next().halfedge()] ||
588
                  level_set_id[w.halfedge()] == level_set_id[w.next().halfedge()]) &&
589
                 valency(m, w.vertex())+valency(m,w.opp().vertex())>10) ||
590
 
591
                valency(m, w.vertex())+valency(m,w.opp().vertex())>14
592
                )
593
               )
594
                hidvec.push_back(w.halfedge());
595
        }
568 jab 596
 
607 jrf 597
        for(size_t i=0;i<hidvec.size(); ++i)
572 jab 598
        {
587 jab 599
            Walker w = m.walker(hidvec[i]);
572 jab 600
            VertexID v = m.split_edge(hidvec[i]);
601
            level_set_id_vertex[v] = level_set_id[w.halfedge()];
602
            level_set_id[w.prev().halfedge()] = level_set_id[w.halfedge()];
603
            level_set_id[w.prev().opp().halfedge()] = level_set_id[w.halfedge()];
604
            shortest_edge_triangulate_face(m, w.face(), level_set_id_vertex);
605
            shortest_edge_triangulate_face(m, w.opp().face(), level_set_id_vertex);
606
        }
568 jab 607
 
572 jab 608
        priority_queue_optimization(m, tqv_energy);
609
        priority_queue_optimization(m, tq_energy);
610
 
611
        for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
612
        {
587 jab 613
            Walker w = m.walker(*hid);
572 jab 614
            if(level_set_id[w.halfedge()] != 0 &&
615
               !(level_set_id[w.opp().halfedge()] == level_set_id[w.opp().next().halfedge()] ||
616
                 level_set_id[w.halfedge()] == level_set_id[w.next().halfedge()])  &&
617
               valency(m, w.vertex())<5 &&
618
               valency(m, w.opp().vertex())<5 &&
619
               precond_collapse_edge(m, w.halfedge()))
620
            {
621
                m.collapse_edge(w.halfedge(), true);
622
                did_work = true;
623
            }
624
        }
625
 
626
 
627
    }
568 jab 628
 
572 jab 629
    return;
630
 
568 jab 631
    priority_queue<EdgeQElem> edge_queue;
632
    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
633
    {
587 jab 634
        Walker w = m.walker(*hid);
568 jab 635
        if(w.halfedge()<w.opp().halfedge() &&
636
           level_set_id[w.halfedge()] == 0)
637
        {
587 jab 638
            Vec3d v = normalize(m.pos(w.vertex()) - m.pos(w.opp().vertex()));
568 jab 639
 
640
            float weight = 0;
587 jab 641
            Walker wo = m.walker(w.opp().vertex());
568 jab 642
            for(; !w.full_circle(); w = w.circulate_vertex_ccw())
643
                if(level_set_id[w.halfedge()] != 0)
644
                {
587 jab 645
                    Vec3d e = normalize(m.pos(w.vertex()) - m.pos(w.opp().vertex()));
568 jab 646
                    weight += abs(dot(v,e));
647
                }
648
            for(; !wo.full_circle(); wo = wo.circulate_vertex_ccw())
649
                if(level_set_id[wo.halfedge()] != 0)
650
                {
587 jab 651
                    Vec3d e = normalize(m.pos(wo.vertex()) - m.pos(wo.opp().vertex()));
568 jab 652
                    weight += abs(dot(v,e));
653
                }
654
            edge_queue.push(EdgeQElem(weight, *hid));        
655
        }
656
    }
657
 
658
    while(!edge_queue.empty())
659
    {
660
        HalfEdgeID h = edge_queue.top().he;
661
        edge_queue.pop();
662
 
587 jab 663
        Walker w = m.walker(h);
572 jab 664
        if(no_edges(m, w.face())==3 && no_edges(m,w.opp().face())==3 &&
665
           !(level_set_id[w.next().halfedge()] == level_set_id[w.opp().prev().halfedge()] ||
666
             level_set_id[w.prev().halfedge()] == level_set_id[w.opp().next().halfedge()]))
568 jab 667
            m.merge_faces(w.face(), w.halfedge());
668
    }
669
 
670
 
572 jab 671
    return;
568 jab 672
 
572 jab 673
 
674
    do{
675
        did_work = false;
676
        for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
568 jab 677
        {
587 jab 678
            Walker w = m.walker(*hid);
572 jab 679
 
680
            if(level_set_id[w.halfedge()] != 0 && no_edges(m, w.face())==3 &&
681
               precond_collapse_edge(m, w.halfedge()))
682
            {
683
                m.collapse_edge(w.halfedge(), true);
684
                did_work = true;
685
            }
568 jab 686
        }
687
    }
572 jab 688
    while(did_work);
568 jab 689
 
572 jab 690
 
568 jab 691
    return;
692
 
693
 
694
    int k=0;
695
    do {
696
        ++k;
697
        did_work = false;
698
        for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
699
        {
587 jab 700
            Walker w0 = m.walker(*hid);
568 jab 701
 
702
            if(level_set_id[w0.halfedge()] != 0 &&
703
               (level_set_id[w0.next().halfedge()] == 0 && level_set_id[w0.prev().halfedge()] == 0))
704
            {
705
 
587 jab 706
                Walker w = w0;
568 jab 707
                bool do_split = false;
708
                for(;!w.full_circle(); w = w.next())
709
                {
710
                    if(level_set_id[w.halfedge()] != 0 &&
711
                       (level_set_id[w.next().halfedge()] == level_set_id[w.halfedge()]))
712
                        do_split = true;
713
                }
714
                if(do_split)
715
                {
716
                    VertexID v = m.split_edge(w0.halfedge());
717
                    level_set_id_vertex[v] = level_set_id[w0.halfedge()];
718
                    level_set_id[w0.prev().halfedge()] = level_set_id[w0.halfedge()];
719
                    level_set_id[w0.prev().opp().halfedge()] = level_set_id[w0.halfedge()];
720
                    did_work = true;
721
                }
722
            }
723
 
724
            for(FaceIDIterator fid = m.faces_begin(); fid != m.faces_end(); ++fid)
725
                if(no_edges(m,*fid) >= 6)
726
                {
727
                    shortest_edge_split_face(m, *fid, level_set_id_vertex);
728
                    did_work = true;
729
                }
572 jab 730
 
568 jab 731
        }
732
    } while (did_work && k<1);
572 jab 733
 
734
 
568 jab 735
}
736
 
572 jab 737
void make_height_fun(const HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
738
                     double& vmin, double& vmax)
568 jab 739
{
740
    VertexIDIterator vid = m.vertices_begin();
741
    vmin = vmax = m.pos(*vid)[2];
742
    for(; vid != m.vertices_end(); ++vid)
743
    {
572 jab 744
        double v = m.pos(*vid)[1];
568 jab 745
        fun[*vid] = v;
746
        vmin = min(v, vmin);
747
        vmax = max(v, vmax);
748
    }
749
}
750
 
751
//    //-------------------------
752
//    cout << "Remove short level set edges" << endl;
753
//    float avglen=0;
754
//    int n=0;
755
//    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
756
//        {
587 jab 757
//            Walker w = m.walker(*hid);
568 jab 758
//            if(level_set_id[w.halfedge()] != 0)
759
//            {
760
//                avglen += length(m, w.halfedge());
761
//                ++n;
762
//            }
763
//        }
764
//    avglen /= n;
765
//    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
766
//        if (length(m,*hid)<0.25*avglen && precond_collapse_edge(m, *hid)) {
767
//            m.collapse_edge(*hid);
768
//        }    
769
 
770
 
771
//        vector<HalfEdgeID> hidvec;
772
//        for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
773
//        {
587 jab 774
//            Walker w = m.walker(*hid);
568 jab 775
//            if(w.halfedge() < w.opp().halfedge() && 
776
//               level_set_id[w.halfedge()] != 0 &&
777
//               valency(m, w.vertex())+valency(m,w.opp().vertex())>12)
778
//                hidvec.push_back(w.halfedge());
779
//        }
780
//        
781
//        for(int i=0;i<hidvec.size(); ++i)
782
//        {
587 jab 783
//            Walker w = m.walker(hidvec[i]);
568 jab 784
//            VertexID v = m.split_edge(hidvec[i]);
785
//            level_set_id_vertex[v] = level_set_id[w.halfedge()];
786
//            level_set_id[w.prev().halfedge()] = level_set_id[w.halfedge()];
787
//            level_set_id[w.prev().opp().halfedge()] = level_set_id[w.halfedge()];
788
//            shortest_edge_triangulate_face(m, w.face(), level_set_id_vertex);
789
//            shortest_edge_triangulate_face(m, w.opp().face(), level_set_id_vertex);
790
//        }
791
//        
792
//        //     priority_queue_optimization(m, tq_energy);
793
 
794
 
795
 
796
 
797
//// ----------------------------
798
//cout << "smooth level set curves" << endl;
799
//
800
//for(int iter=0;iter<2;++iter)
801
//{
587 jab 802
//    VertexAttributeVector<Vec3d> new_pos(m.allocated_vertices(), Vec3d(0));
568 jab 803
//    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
804
//    {
587 jab 805
//        Walker w = m.walker(*hid);
568 jab 806
//        if(status[w.vertex()] == 1 && status[w.opp().vertex()] == 1 &&
807
//           same_level(fun[w.vertex()], fun[w.opp().vertex()]))
808
//        {
809
//            new_pos[w.vertex()] += m.pos(w.vertex()) + m.pos(w.opp().vertex());
810
//        }
811
//    }
812
//    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
813
//        if(status[*vid] == 1)
814
//            m.pos(*vid) = new_pos[*vid] / (4.0);
815
//}
816
 
817
 
818
 
819
//return;
820
//
821
//for (int iter=0; iter<1; ++iter) {
822
//    cout << __FILE__ << __LINE__ << endl;
823
//    cout << __FILE__ << __LINE__ << endl;
824
//    TriangleQuality tq_energy(level_set_id, level_set_id_vertex);
825
//    priority_queue_optimization(m, tq_energy);
826
//    //        FunctionalDifference energy(fun, status);
827
//    //        priority_queue_optimization(m, energy);
828
//    
829
//    // ----------------------------
830
//    cout << "Remove vertices not on level set curves" << endl;
831
//    
832
//    vector<VertexID> vid_vec;
833
//    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
834
//    if(status[*vid]==0)
835
//    vid_vec.push_back(*vid);
836
//    
837
//    for (int i=0; i<vid_vec.size(); ++i) {
838
//        FaceID f = m.merge_one_ring(vid_vec[i]);
839
//    }
840
//    cout << "-" << endl;
841
//    }    
572 jab 842
// --------------------------
843
// Triangulate polygons by connecting only vertices on different curves.
568 jab 844
 
572 jab 845
//    shortest_edge_triangulate(m);
846
//    TriangleQuality tq_energy(level_set_id);
847
//    priority_queue_optimization(m, tq_energy);
848
 
849
 
850
//        k=0;
851
//        do {
852
//            ++k;
853
//            did_work = false;
854
//            priority_queue<EdgeQElem> edge_queue;
855
//            
856
//            for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
857
//            {
587 jab 858
//                Walker w = m.walker(*hid);
572 jab 859
//                if(status[w.opp().vertex()] == 0 && status[w.vertex()] == 1)
860
//                {
861
//                    float weight = (abs(fun[w.vertex()] - fun[w.opp().vertex()]*length(m, w.halfedge())) + 1e-6);            
862
//                    edge_queue.push(EdgeQElem(weight, w.halfedge()));
863
//                }
864
//                
865
//                
866
//                while(!edge_queue.empty())
867
//                {
868
//                    HalfEdgeID he = edge_queue.top().he;
869
//                    edge_queue.pop();
870
//                    if(m.in_use(he))
871
//                    {
872
//                        if(precond_collapse_edge(m,he))
873
//                        {
874
//                            m.collapse_edge(he);
875
//                            did_work = true;
876
//                       }
877
//                    }
878
//                }
879
//            } 
880
//        }while (did_work && k < 100);
881
//            
882
//            cout << "k=" << k << endl;
883
//    priority_queue_optimization(m, energy);
884
 
885
 
568 jab 886
//priority_queue<EdgeQElem> edge_queue;
586 jab 887
//HalfEdgeAttributeVector<int> time_stamp(m.allocated_halfedges(), 0);
568 jab 888
//for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
889
//if(level_set_id[*hid]==0)
890
//{
587 jab 891
//    Walker w = m.walker(*hid);
568 jab 892
//    if(w.halfedge()<w.opp().halfedge() && !(status[w.vertex()]==1 && status[w.opp().vertex()]==1))
893
//        edge_queue.push(EdgeQElem(-(sqr(fun[w.vertex()]-fun[w.opp().vertex()]))*sqr_length(m.pos(w.vertex())-m.pos(w.opp().vertex())),*hid,0));
894
//        }
895
//
896
//shortest_edge_triangulate(m);
897
//int k=0;
898
//while(!edge_queue.empty())
899
//{
900
//    HalfEdgeID hid = edge_queue.top().he;
901
//    if(m.in_use(hid) && time_stamp[hid]== edge_queue.top().time_stamp)
902
//    {
587 jab 903
//        Walker w = m.walker(hid);
904
//        Walker wa = w.next();
905
//        Walker wb = w.prev().opp();
568 jab 906
//        
907
//        if(m.merge_faces(w.face(), hid))
908
//        {
909
//            cout << ".";
910
//            if(valency(m, wa.opp().vertex())==2 && precond_collapse_edge(m, wa.halfedge()))
911
//            {
912
//                HalfEdgeID h = wa.halfedge();
913
//                wa = wa.prev();
914
//                m.collapse_edge(h, false);
915
//                ++time_stamp[wa.halfedge()];
916
//                ++time_stamp[wa.opp().halfedge()];
917
//                if(level_set_id[wa.halfedge()]==0 && !(status[wa.vertex()]==1 && status[wa.opp().vertex()]==1))
918
//                    edge_queue.push(EdgeQElem(-(sqr(fun[wa.vertex()]-fun[wa.opp().vertex()]))*sqr_length(m.pos(wa.vertex())-m.pos(wa.opp().vertex())),wa.halfedge(),time_stamp[wa.halfedge()]));
919
//            }
920
//            if(valency(m, wb.opp().vertex())==2 && precond_collapse_edge(m, wb.halfedge()))
921
//            {
922
//                HalfEdgeID h = wb.halfedge();
923
//                wb = wb.prev();
924
//                m.collapse_edge(h, false);
925
//                ++time_stamp[wb.halfedge()];
926
//                ++time_stamp[wb.opp().halfedge()];
927
//                if(level_set_id[wb.halfedge()]==0 && !(status[wb.vertex()]==1 && status[wb.opp().vertex()]==1))
928
//                    edge_queue.push(EdgeQElem(-(sqr(fun[wb.vertex()]-fun[wb.opp().vertex()]))*sqr_length(m.pos(wb.vertex())-m.pos(wb.opp().vertex())),wb.halfedge(),time_stamp[wb.halfedge()]));
929
//            }
930
//            
931
//            }
932
//            
933
//            }
934
//            
935
//            edge_queue.pop();
936
//            }
937
//
938
 
939
//   // bool did_work;
940
//    do{
941
//        did_work = false;
942
//    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
943
//    {
587 jab 944
//        Walker w = m.walker(*hid);
568 jab 945
//        if(level_set_id[w.halfedge()] != 0 &&
946
//           valency(m, w.vertex())==3 &&
947
//           valency(m, w.opp().vertex())==3 &&
948
//           ((level_set_id[w.next().halfedge()] == 0 &&level_set_id[w.opp().next().halfedge()] == 0) ||
949
//           (level_set_id[w.prev().halfedge()] == 0 &&level_set_id[w.opp().prev().halfedge()] == 0)) &&
950
//           precond_collapse_edge(m, w.halfedge()))
951
//        {
952
//            cout << "collapsing!!!" << endl;
953
//            m.collapse_edge(w.halfedge(), true);
954
//            did_work = true;
955
//        }
956
//    }
957
//    }while (did_work);
958
 
959
 
960
//    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
961
//    {
962
//        bool is_max = true;
963
//        bool is_min = true;
587 jab 964
//        Walker w = m.walker(*vid);
568 jab 965
//        float f = fun[*vid];
966
//        for(;!w.full_circle(); w = w.circulate_vertex_ccw())
967
//        {
968
//            if(fun[w.vertex()] < f)
969
//                is_min = false;
970
//            if(fun[w.vertex()] > f)
971
//                is_max = false;
972
//            
973
//        }
974
//        if(is_max || is_min)
975
//            status[*vid] = 2;
976
//    }
977
 
978
 
979