Subversion Repositories gelsvn

Rev

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