Subversion Repositories gelsvn

Rev

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

Rev 630 Rev 631
Line 6... Line 6...
6
//  Copyright 2012 __MyCompanyName__. All rights reserved.
6
//  Copyright 2012 __MyCompanyName__. All rights reserved.
7
//
7
//
8
#include <queue>
8
#include <queue>
9
 
9
 
10
#include "polarize.h"
10
#include "polarize.h"
-
 
11
#include <CGLA/Vec2d.h>
-
 
12
#include <LinAlg/LapackFunc.h>
11
#include <HMesh/triangulate.h>
13
#include <HMesh/triangulate.h>
-
 
14
#include <HMesh/obj_save.h>
12
#include <HMesh/curvature.h>
15
#include <HMesh/curvature.h>
13
#include <HMesh/quadric_simplify.h>
16
#include <HMesh/quadric_simplify.h>
14
#include <HMesh/mesh_optimization.h>
17
#include <HMesh/mesh_optimization.h>
15
#include <HMesh/smooth.h>
18
#include <HMesh/smooth.h>
16
 
19
 
Line 18... Line 21...
18
 
21
 
19
using namespace CGLA;
22
using namespace CGLA;
20
using namespace std;
23
using namespace std;
21
using namespace HMesh;
24
using namespace HMesh;
22
 
25
 
-
 
26
 
-
 
27
 
-
 
28
inline bool same_level(float a, float b) {return abs(a-b) < 0.00001;}
-
 
29
 
-
 
30
 
-
 
31
struct LevelSetInfo
-
 
32
{
-
 
33
    int id;
-
 
34
    int no_vertices;
-
 
35
    Vec3d avg_pos;
-
 
36
    double rad;
-
 
37
    double length;
-
 
38
    int components;
-
 
39
    HalfEdgeID h;
-
 
40
    double fun_value;
-
 
41
    
-
 
42
    void print()
-
 
43
    {
-
 
44
        cout
-
 
45
        << " id : " << id
-
 
46
        << " no vertices : " << no_vertices
-
 
47
        << " avg pos : " << avg_pos
-
 
48
        << " rad : " << rad
-
 
49
        << " length : " << length
-
 
50
        << " # : " << components
-
 
51
        << " F : " << fun_value << endl;
-
 
52
    }
-
 
53
};
-
 
54
 
-
 
55
void compute_edge_weights(Manifold& m, HalfEdgeAttributeVector<double>& edge_weights, FaceAttributeVector<int>& included)
-
 
56
{
-
 
57
    edge_weights = HalfEdgeAttributeVector<double>(m.allocated_halfedges(), 0);
-
 
58
    for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f)
-
 
59
        if(included[*f])
-
 
60
        {
-
 
61
            for(Walker wv = m.walker(*f); !wv.full_circle(); wv = wv.circulate_face_ccw())
-
 
62
            {
-
 
63
                HalfEdgeID h = wv.halfedge();
-
 
64
                Vec3d p1(m.pos(wv.vertex()));
-
 
65
                Vec3d p2(m.pos(wv.next().vertex()));
-
 
66
                Vec3d p0(m.pos(wv.opp().vertex()));
-
 
67
                double ang = acos(min(1.0, max(-1.0, dot(normalize(p1-p0), normalize(p2-p0)))));
-
 
68
                double ang_opp = acos(min(1.0, max(-1.0, dot(normalize(p2-p1), normalize(p0-p1)))));
-
 
69
                double l = (p1-p0).length();
-
 
70
                edge_weights[h] += tan(ang/2) / l;
-
 
71
                edge_weights[wv.opp().halfedge()] += tan(ang_opp/2) / l;
-
 
72
            }
-
 
73
        }
-
 
74
}
-
 
75
void smooth_fun(Manifold& m,
-
 
76
                    VertexAttributeVector<int>& nailed,
-
 
77
                    VertexAttributeVector<double>& fun)
-
 
78
{
-
 
79
    HalfEdgeAttributeVector<double> edge_weights;
-
 
80
    FaceAttributeVector<int> included(m.allocated_faces(),1);
-
 
81
    compute_edge_weights(m,edge_weights, included);
-
 
82
    VertexAttributeVector<double> new_fun(m.no_vertices());
-
 
83
    for(int i = 0; i < 1000; ++i)
-
 
84
    {
-
 
85
        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
-
 
86
            if(!nailed[*v])
-
 
87
            {
-
 
88
                double w_sum = 0;
-
 
89
                new_fun[*v] = 0;
-
 
90
                for(Walker wv = m.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_ccw())
-
 
91
                {
-
 
92
                    double w = edge_weights[wv.halfedge()];
-
 
93
                    new_fun[*v] += w * fun[wv.vertex()];
-
 
94
                    w_sum += w;
-
 
95
                }
-
 
96
                new_fun[*v] /= w_sum;
-
 
97
            }
-
 
98
            else
-
 
99
                new_fun[*v] = fun[*v];
-
 
100
            fun = new_fun;
-
 
101
    }
-
 
102
}
-
 
103
 
-
 
104
void segment_manifold(Manifold& m, HalfEdgeAttributeVector<int>& ls_id,
-
 
105
                      FaceAttributeVector<int>& segmentation,
-
 
106
                      vector<vector<int>>& boundaries)
-
 
107
{
-
 
108
    segmentation = FaceAttributeVector<int>(m.no_faces(), -1);
-
 
109
    int SEG_NO = 0;
-
 
110
    for(auto f = m.faces_begin(); f != m.faces_end(); ++f)
-
 
111
    {
-
 
112
        if (segmentation[*f] == -1)
-
 
113
        {
-
 
114
            queue<FaceID> q;
-
 
115
            q.push(*f);
-
 
116
            vector<int> bound(0);
-
 
117
            while (!q.empty())
-
 
118
            {
-
 
119
                FaceID face = q.front();
-
 
120
                q.pop();
-
 
121
                segmentation[face] = SEG_NO;
-
 
122
                for(Walker w = m.walker(face); !w.full_circle(); w = w.next())
-
 
123
                {
-
 
124
                    if(ls_id[w.halfedge()] == -1)
-
 
125
                    {
-
 
126
                        FaceID fopp = w.opp().face();
-
 
127
                        if(segmentation[fopp] == -1) {
-
 
128
                            q.push(fopp);
-
 
129
                        }
-
 
130
                    }
-
 
131
                    else {
-
 
132
                        bound.push_back(ls_id[w.halfedge()]);
-
 
133
                    }
-
 
134
                    
-
 
135
                }
-
 
136
            }
-
 
137
            sort(begin(bound), end(bound));
-
 
138
            auto new_end = unique(begin(bound), end(bound));
-
 
139
            boundaries.push_back(vector<int>(begin(bound),new_end));
-
 
140
            cout << "Boundaries of seg# " << SEG_NO << " : ";
-
 
141
            for(auto be:boundaries[SEG_NO])
-
 
142
                cout << be << " ";
-
 
143
            cout << endl;
-
 
144
            SEG_NO += 1;
-
 
145
        }
-
 
146
    
-
 
147
    }
-
 
148
}
-
 
149
 
-
 
150
 
23
void shortest_edge_triangulate_face(Manifold& m, FaceID f0, VertexAttributeVector<int>& level_set_id_vertex)
151
void shortest_edge_triangulate_face(Manifold& m, FaceID f0, VertexAttributeVector<int>& level_set_id_vertex)
24
{
152
{
25
    queue<FaceID> face_queue;
153
    queue<FaceID> face_queue;
26
    
154
    
27
    face_queue.push(f0);
155
    face_queue.push(f0);
Line 46... Line 174...
46
        // Find vertex pairs that may be connected.
174
        // Find vertex pairs that may be connected.
47
        vector<pair<int,int> > vpairs;
175
        vector<pair<int,int> > vpairs;
48
        const int N = verts.size();
176
        const int N = verts.size();
49
        for(int i = 0; i < N - 2; ++i){
177
        for(int i = 0; i < N - 2; ++i){
50
            for(int j = i + 2; j < N; ++j){
178
            for(int j = i + 2; j < N; ++j){
51
                if(verts[i] != verts[j] && 
179
                if(verts[i] != verts[j] &&
52
                   !connected(m, verts[i], verts[j]) &&
180
                   !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]])
181
                   (level_set_id_vertex[verts[i]] == 0 || level_set_id_vertex[verts[i]] != level_set_id_vertex[verts[j]])
54
                   )
182
                   )
55
                    vpairs.push_back(pair<int,int>(i, j));
183
                    vpairs.push_back(pair<int,int>(i, j));
56
            }
184
            }
57
        }
185
        }
58
        if(vpairs.empty()){
186
        if(vpairs.empty()){
59
            cout << "Warning: could not triangulate a face." 
187
            cout << "Warning: could not triangulate a face."
60
            << "Probably a vertex appears more than one time in other vertex's one-ring" << endl;
188
            << "Probably a vertex appears more than one time in other vertex's one-ring" << endl;
61
            continue;
189
            continue;
62
        }
190
        }
63
        
191
        
64
        /* For all vertex pairs, find the edge lengths. Combine the
192
        /* For all vertex pairs, find the edge lengths. Combine the
Line 178... Line 306...
178
{
306
{
179
    VertexAttributeVector<float>& fun;
307
    VertexAttributeVector<float>& fun;
180
    VertexAttributeVector<int>& status;
308
    VertexAttributeVector<int>& status;
181
public:
309
public:
182
    FunctionalDifference(VertexAttributeVector<float>& _fun, VertexAttributeVector<int>& _status): fun(_fun), status(_status) {}
310
    FunctionalDifference(VertexAttributeVector<float>& _fun, VertexAttributeVector<int>& _status): fun(_fun), status(_status) {}
183
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const 
311
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
184
    {
312
    {
185
        Walker w = m.walker(h);
313
        Walker w = m.walker(h);
186
        if(status[w.vertex()] == 1 && status[w.opp().vertex()]==1)
314
        if(status[w.vertex()] == 1 && status[w.opp().vertex()]==1)
187
            return DBL_MAX;
315
            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()]));
316
        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()]));
Line 194... Line 322...
194
    VertexAttributeVector<int>& idv;
322
    VertexAttributeVector<int>& idv;
195
    MinAngleEnergy mae;
323
    MinAngleEnergy mae;
196
    ValencyEnergy vae;
324
    ValencyEnergy vae;
197
public:
325
public:
198
    TriangleQualityValence(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
326
    TriangleQualityValence(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
199
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const 
327
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
200
    {
328
    {
201
        Walker w = m.walker(h);
329
        Walker w = m.walker(h);
202
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] || 
330
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] ||
203
           idv[w.vertex()] == idv[w.opp().vertex()])
331
           idv[w.vertex()] == idv[w.opp().vertex()])
204
            return DBL_MAX;
332
            return DBL_MAX;
205
        
333
        
206
        VertexID v1 = w.opp().vertex();
334
        VertexID v1 = w.opp().vertex();
207
        VertexID v2 = w.vertex();
335
        VertexID v2 = w.vertex();
Line 218... Line 346...
218
        int t1 = boundary(m, v1) ? 4 : 6;
346
        int t1 = boundary(m, v1) ? 4 : 6;
219
        int t2 = boundary(m, v2) ? 4 : 6;
347
        int t2 = boundary(m, v2) ? 4 : 6;
220
        int to1 = boundary(m, vo1) ? 4 : 6;
348
        int to1 = boundary(m, vo1) ? 4 : 6;
221
        int to2 = boundary(m, vo2) ? 4 : 6;
349
        int to2 = boundary(m, vo2) ? 4 : 6;
222
        
350
        
223
        int before = 
351
        int before =
224
        max(max(sqr(val1-t1),sqr(val2-t2)), max(sqr(valo1-to1), sqr(valo2-to2)));
352
        max(max(sqr(val1-t1),sqr(val2-t2)), max(sqr(valo1-to1), sqr(valo2-to2)));
225
        int after = 
353
        int after =
226
        max(max(sqr(valo1+1-to1),sqr(val1-1-t1)), max(sqr(val2-1-t2),sqr(valo2+1-to2)));
354
        max(max(sqr(valo1+1-to1),sqr(val1-1-t1)), max(sqr(val2-1-t2),sqr(valo2+1-to2)));
227
        
355
        
228
        return static_cast<double>(after-before);
356
        return static_cast<double>(after-before);
229
        
357
        
230
        //        return vae.delta_energy(m,h);
358
        //        return vae.delta_energy(m,h);
Line 240... Line 368...
240
    VertexAttributeVector<int>& idv;
368
    VertexAttributeVector<int>& idv;
241
    MinAngleEnergy mae;
369
    MinAngleEnergy mae;
242
    ValencyEnergy vae;
370
    ValencyEnergy vae;
243
public:
371
public:
244
    TriangleQuality(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
372
    TriangleQuality(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
245
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const 
373
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
246
    {
374
    {
247
        Walker w = m.walker(h);
375
        Walker w = m.walker(h);
248
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] || 
376
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] ||
249
           idv[w.vertex()] == idv[w.opp().vertex()])
377
           idv[w.vertex()] == idv[w.opp().vertex()])
250
            return DBL_MAX;
378
            return DBL_MAX;
251
        return mae.delta_energy(m,h);
379
        return mae.delta_energy(m,h);
252
    }
380
    }
253
};
381
};
Line 261... Line 389...
261
    Vec3d n = normal(m, f);
389
    Vec3d n = normal(m, f);
262
    
390
    
263
    Vec3d gsum(0.0);
391
    Vec3d gsum(0.0);
264
    for(Walker w = m.walker(f); !w.full_circle(); w = w.next())
392
    for(Walker w = m.walker(f); !w.full_circle(); w = w.next())
265
    {
393
    {
-
 
394
        VertexID avid = w.opp().vertex();
-
 
395
        VertexID bvid = w.vertex();
-
 
396
        VertexID cvid = w.next().vertex();
266
        Vec3d gdir = normalize(cross(n, m.pos(w.vertex()) - m.pos(w.opp().vertex())));
397
        Vec3d gdir = normalize(cross(n, m.pos(bvid) - m.pos(avid)));
267
        float l = dot(m.pos(w.next().vertex())-m.pos(w.vertex()), gdir);
398
        double l = dot(m.pos(cvid)-m.pos(avid), gdir);
268
        gdir *= fun[w.next().vertex()]/l;
399
        gdir *= fun[cvid]/l;
269
        gsum += gdir;
400
        gsum += gdir;
270
    }
401
    }
271
    return gsum;
402
    return gsum;
272
}
403
}
273
 
404
 
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, 
405
double solve_for_orthogonal_gradients(HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
288
                 HMesh::VertexAttributeVector<double>& fun2)
406
                                     HalfEdgeID h, double beta, double gamma)
289
{
407
{
-
 
408
    Vec3d n = normal(m, m.walker(h).face());
-
 
409
    
-
 
410
    Vec3d uvw[3];
-
 
411
    Vec3d abc;
290
    Walker w = m.walker(h);
412
    Walker w = m.walker(h);
291
    FaceID f = w.face();
-
 
292
    Vec3d a = m.pos(w.opp().vertex());
413
    VertexID vid[] = {w.next().vertex(), w.opp().vertex(),w.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));
-
 
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
 
-
 
314
inline bool same_level(float a, float b) {return abs(a-b) < 0.00001;}
-
 
315
 
414
 
316
Vec3d laplacian(const Manifold& m, VertexID v)
415
    for(int i=0; !w.full_circle(); w = w.next(),++  i)
317
{
-
 
318
    Vec3d avg_pos(0);
-
 
319
    float asum = 0;
-
 
320
    
416
    {
321
    for(Walker w = m.walker(v); !w.full_circle(); w = w.circulate_vertex_cw()){
417
        uvw[i] = normalize(cross(n, m.pos(vid[(i+1)%3]) - m.pos(vid[(i+2)%3])));
322
        float  a = barycentric_area(m, w.vertex());
-
 
323
        avg_pos += a * m.pos(w.vertex());
418
        uvw[i] /= dot(m.pos(vid[i])-m.pos(vid[(i+1)%3]), uvw[i]);
324
        asum += a;
419
        abc[i] = fun[vid[i]];
325
    }
420
    }
-
 
421
    Vec3d A(dot(uvw[0],uvw[0]),dot(uvw[0],uvw[1]),dot(uvw[0],uvw[2]));
-
 
422
    Vec3d B(dot(uvw[1],uvw[0]),dot(uvw[1],uvw[1]),dot(uvw[1],uvw[2]));
-
 
423
    Vec3d C(dot(uvw[2],uvw[0]),dot(uvw[2],uvw[1]),dot(uvw[2],uvw[2]));
-
 
424
    
326
    return avg_pos / asum - m.pos(v);
425
    return - (beta * dot(B, abc) + gamma * dot(C, abc))/dot(A, abc);
327
}
426
}
328
 
427
 
-
 
428
 
329
void aw_laplacian_smooth(Manifold& m, float t)
429
void recompute_circle_param(Manifold& m, VertexID v, VertexAttributeVector<double>& fun, VertexAttributeVector<Vec2d>& circle_pos, double f_origin)
330
{
430
{
-
 
431
    Vec2d c_new(0);
331
    VertexAttributeVector<Vec3d> pos(m.allocated_vertices());
432
    for(auto w = m.walker(v); !w.full_circle(); w = w.circulate_vertex_ccw())
332
    
433
    {
333
    for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v){
-
 
334
        if(!boundary(m, *v))
434
        Walker w_base = w.next();
335
        {
-
 
336
            Vec3d n = normal(m, *v);
435
        Vec2d X = circle_pos[w_base.opp().vertex()];
337
            Vec3d l = laplacian(m, *v);
436
        Vec2d Y(-X[1], X[0]);
338
            if(sqr_length(n) > 0.8)
437
        Vec2d vec = circle_pos[w_base.vertex()];
339
                l -= n * dot(n,l);
438
        double angle = atan2(max(-1.0,min(1.0,dot(vec,Y))),
340
            pos[*v] =  t * l + m.pos(*v);
439
                             max(-1.0,min(1.0,dot(vec,X))));
341
        }
-
 
342
    }
-
 
343
    
-
 
344
    for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v){
440
        double new_angle = solve_for_orthogonal_gradients(m, fun, w_base.halfedge(), 0, angle);
345
        if(!boundary(m, *v))
441
        new_angle = max(-M_PI/4, min(M_PI/4,new_angle));
346
            m.pos(*v) = pos[*v];
442
        c_new += cos(new_angle)*X + sin(new_angle)*Y;
347
    }
443
    }
-
 
444
    circle_pos[v] = normalize(c_new);
348
}
445
}
349
 
446
 
350
void polarize_mesh(Manifold& m, VertexAttributeVector<double>& fun, double vmin, double vmax, const int divisions, VertexAttributeVector<double>& parametrization)
447
void polarize_mesh(Manifold& m, VertexAttributeVector<double>& fun, double vmin, double vmax, const int divisions, VertexAttributeVector<Vec2d>& parametrization)
351
{
448
{
352
    vmax -= 0.01 * (vmax-vmin);
449
    vmax -= 0.01 * (vmax-vmin);
353
    float interval = (vmax-vmin)/divisions;
450
    float interval = (vmax-vmin)/divisions;
354
    
451
    
355
    VertexAttributeVector<int> status(m.allocated_vertices(), 0);
452
    VertexAttributeVector<int> status(m.allocated_vertices(), 0);
Line 415... Line 512...
415
                    break;
512
                    break;
416
                }
513
                }
417
    }
514
    }
418
    while(did_work);
515
    while(did_work);
419
    
516
    
420
    
-
 
421
    
517
    shortest_edge_triangulate(m);
422
    
518
    
423
    // ----------------------------
519
    // ----------------------------
424
    cout << "Numbering the level sets" << endl;
520
    cout << "Numbering the level sets" << endl;
425
    
-
 
426
    float max_length = 0;
-
 
427
    double max_length_fun = 0;
521
    VertexAttributeVector<int> nailed(m.no_vertices(),0);
428
    int max_length_id =-1;
-
 
429
    HalfEdgeID max_length_h;
522
    vector<LevelSetInfo> level_set_info;
430
    HalfEdgeAttributeVector<int> level_set_id(m.allocated_halfedges(), 0);
523
    HalfEdgeAttributeVector<int> level_set_id(m.allocated_halfedges(), -1);
431
    VertexAttributeVector<int> level_set_id_vertex(m.allocated_vertices(), 0);
524
    VertexAttributeVector<int> level_set_id_vertex(m.allocated_vertices(), -1);
-
 
525
    VertexAttributeVector<Vec2d> circle_pos;
-
 
526
    for(auto vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
-
 
527
        circle_pos[*vid] = Vec2d(0,0);
432
    int no_id=1;
528
    int no_id=0;
433
    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
529
    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
434
    {
530
    {
435
        Walker w = m.walker(*hid);
531
        Walker w = m.walker(*hid);
436
        if(status[w.vertex()] == 1 && status[w.opp().vertex()] == 1 &&
532
        if(status[w.vertex()] == 1 && status[w.opp().vertex()] == 1 &&
437
           same_level(fun[w.vertex()], fun[w.opp().vertex()]) &&
533
           same_level(fun[w.vertex()], fun[w.opp().vertex()]) &&
438
           level_set_id[w.halfedge()] == 0)
534
           level_set_id[w.halfedge()] == -1)
439
        {
535
        {
-
 
536
            LevelSetInfo lsi;
-
 
537
            lsi.id = no_id;
-
 
538
            lsi.fun_value = fun[w.vertex()];
-
 
539
            lsi.components = 1;
-
 
540
            lsi.no_vertices = 0;
440
            float level_set_length = 0;
541
            float level_set_length = 0;
441
            while(level_set_id[w.halfedge()] != no_id)
542
            while(level_set_id[w.halfedge()] != no_id)
442
            {
543
            {
443
                level_set_length += length(m,w.halfedge());
544
                level_set_length += length(m,w.halfedge());
444
                level_set_id[w.halfedge()] = no_id;
545
                level_set_id[w.halfedge()] = no_id;
445
                level_set_id[w.opp().halfedge()] = no_id;
546
                level_set_id[w.opp().halfedge()] = no_id;
446
                level_set_id_vertex[w.vertex()] = no_id;
547
                level_set_id_vertex[w.vertex()] = no_id;
447
                w = w.next();
548
                w = w.next();
448
                while(status[w.vertex()] != 1 || !same_level(fun[w.vertex()], fun[w.opp().vertex()]))
549
                while(status[w.vertex()] != 1 || !same_level(fun[w.vertex()], fun[w.opp().vertex()]))
449
                    w = w.circulate_vertex_cw();
550
                    w = w.circulate_vertex_cw();
-
 
551
                lsi.no_vertices += 1;
450
            }            
552
                
-
 
553
            }
-
 
554
            lsi.h = w.halfedge();
451
            if(level_set_length > max_length)
555
            lsi.length = level_set_length;
-
 
556
            double param = 0;
-
 
557
 
-
 
558
            do
452
            {
559
            {
453
                max_length = level_set_length;
560
                double angle = 2.0 * M_PI * param / lsi.length;
-
 
561
                circle_pos[w.opp().vertex()] = Vec2d(cos(angle), sin(angle));
454
                max_length_id = no_id;
562
                nailed[w.opp().vertex()] = 1;
455
                max_length_h = w.halfedge();
563
                param += length(m, w.halfedge());
-
 
564
                w = w.next();
-
 
565
                while(status[w.vertex()] != 1 || !same_level(fun[w.vertex()], fun[w.opp().vertex()]))
456
                max_length_fun = fun[w.vertex()];
566
                    w = w.circulate_vertex_cw();
457
            }
567
            }
-
 
568
            while(w.halfedge() != lsi.h);
-
 
569
            level_set_info.push_back(lsi);
-
 
570
            level_set_info.back().print();
458
            ++no_id;
571
            ++no_id;
-
 
572
            assert(level_set_info.size()==no_id);
459
        }
573
        }
460
    }
574
    }
461
    cout << max_length << " " << max_length_id << endl;
-
 
462
    cout << "Number of level sets : " << (no_id-1);
-
 
463
    // ----------------------------
-
 
464
    
575
    
-
 
576
    cout << "ids" << no_id << " " << level_set_info.size() << endl;
-
 
577
    for(int i=0;i<level_set_info.size(); ++i)
-
 
578
        for(int j=0;j<level_set_info.size(); ++j)
-
 
579
            if(i != j && same_level(level_set_info[i].fun_value, level_set_info[j].fun_value))
-
 
580
                level_set_info[i].components += 1;
-
 
581
    
465
    shortest_edge_triangulate(m);
582
    HalfEdgeID min_length_h;
-
 
583
    double min_length_fun;
-
 
584
    double min_length=FLT_MAX;
-
 
585
    int min_length_id = -1;
-
 
586
    for(int i=0;i<level_set_info.size(); ++i)
-
 
587
    {
-
 
588
        LevelSetInfo& lsi = level_set_info[i];
-
 
589
        if(lsi.components==1 && lsi.length<min_length)
-
 
590
        {
-
 
591
            min_length_h = lsi.h;
-
 
592
            min_length_fun = lsi.fun_value;
-
 
593
            min_length = lsi.length;
-
 
594
            min_length_id = lsi.id;
-
 
595
        }
-
 
596
    }
466
    
597
    
-
 
598
    smooth_fun(m, nailed, fun);
467
    
599
    
-
 
600
    FaceAttributeVector<int> segmentation;
468
    // -------------
601
    vector<vector<int>> boundaries;
469
    cout << "Parametrize level sets " << endl;
602
    segment_manifold(m, level_set_id, segmentation, boundaries);
470
    
603
    
471
    queue<HalfEdgeID> hq;
604
    VertexAttributeVector<Vec3d> cylinder_pos;
472
    HalfEdgeAttributeVector<int> touched(m.no_halfedges(), 0);
605
    for(auto vid = m.vertices_begin();vid != m.vertices_end(); ++vid)
473
    Walker w = m.walker(max_length_h);
606
        if (nailed[*vid])//level_set_id_vertex[*vid] == min_length_id)
-
 
607
            cylinder_pos[*vid] = Vec3d(circle_pos[*vid][0], circle_pos[*vid][1],min_length_fun);    
474
    float param = 0;
608
        else
-
 
609
            cylinder_pos[*vid] = Vec3d(0,0,fun[*vid]);
475
    do
610
    
-
 
611
    HalfEdgeAttributeVector<double> edge_weights(m.allocated_halfedges(), 0);
-
 
612
    FaceAttributeVector<int> included(m.allocated_faces(), 1);
-
 
613
    for(auto fid = m.faces_begin(); fid != m.faces_end(); ++fid)
476
    {
614
    {
477
        parametrization[w.opp().vertex()] = 2.0 * M_PI * param / max_length;
-
 
478
        param += length(m, w.halfedge());
615
        if(boundaries[segmentation[*fid]].size() == 1)
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;
616
            included[*fid] = 0;
485
        touched[w.opp().halfedge()] = 1;
-
 
486
    }            
-
 
487
    while(w.halfedge() != max_length_h);
-
 
488
    
-
 
489
    while(!hq.empty())
-
 
490
    {
617
    }
491
        HalfEdgeID h = hq.front();
-
 
492
        hq.pop();
-
 
493
        if(!touched[w.next().halfedge()])
-
 
494
        {
-
 
495
            extend_fun2(m, h, fun, parametrization);
618
    compute_edge_weights(m,edge_weights,included);
496
            touched[w.next().halfedge()] = 1;
619
    VertexAttributeVector<Vec3d> new_cylinder_pos(m.no_vertices());
497
            touched[w.prev().halfedge()] = 1;
-
 
498
            Walker w = m.walker(h);
620
    for(int i = 0; i < 1500; ++i)
499
            if(!touched[w.next().opp().halfedge()])
-
 
500
            {
621
    {
501
                touched[w.next().opp().halfedge()] = 1;
622
        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
502
                hq.push(w.next().opp().halfedge());
-
 
503
            }
-
 
504
            if(!touched[w.prev().opp().halfedge()])
623
            if(!nailed[*v])//level_set_id_vertex[*v] != min_length_id)
505
            {
624
            {
-
 
625
//                recompute_circle_param(m, *v, fun, circle_pos, min_length_fun);
-
 
626
                double w_sum = 0;
-
 
627
                new_cylinder_pos[*v] = Vec3d(0);
-
 
628
                for(Walker wv = m.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_ccw())
-
 
629
                {
506
                touched[w.prev().opp().halfedge()] = 1;
630
                    double w = edge_weights[wv.halfedge()];
-
 
631
                    new_cylinder_pos[*v] += w * cylinder_pos[wv.vertex()];
-
 
632
                    w_sum += w;
-
 
633
                }
-
 
634
                if(w_sum> 0.0)
-
 
635
                    new_cylinder_pos[*v] /= w_sum;
-
 
636
                Vec2d v2d(new_cylinder_pos[*v][0], new_cylinder_pos[*v][1]);
-
 
637
                double l =length(v2d);
-
 
638
                if(l>0.1) {
507
                hq.push(w.prev().opp().halfedge());
639
                    new_cylinder_pos[*v][0] /= l;
-
 
640
                    new_cylinder_pos[*v][1] /= l;
508
                
641
                }
-
 
642
                if(level_set_id_vertex[*v] != -1)
-
 
643
                    new_cylinder_pos[*v][2] = fun[*v];
509
            }
644
            }
510
        }
645
            else
-
 
646
                new_cylinder_pos[*v] = cylinder_pos[*v];
-
 
647
        for(auto v = m.vertices_begin();v != m.vertices_end(); ++v)
-
 
648
            cylinder_pos[*v] = 0.9*cylinder_pos[*v]+ 0.1*new_cylinder_pos[*v];
511
    }
649
    }
-
 
650
  for(auto vid = m.vertices_begin();vid != m.vertices_end(); ++vid)
-
 
651
        parametrization[*vid] = Vec2d(cylinder_pos[*vid][0],cylinder_pos[*vid][1]);
-
 
652
    return;
-
 
653
 
-
 
654
//    for(auto vid = m.vertices_begin();vid != m.vertices_end(); ++vid)
-
 
655
//        m.pos(*vid) = cylinder_pos[*vid];// Vec2d(cylinder_pos[*vid][0],cylinder_pos[*vid][1]);
-
 
656
 
-
 
657
    
-
 
658
//    vector<pair<double,VertexID>> verts;
-
 
659
//    for(auto vid = m.vertices_begin();vid != m.vertices_end(); ++vid)
-
 
660
//        if(!same_level(min_length_fun, fun[*vid]))
-
 
661
//            verts.push_back(pair<double,VertexID>(abs(fun[*vid]-min_length_fun),*vid));
-
 
662
//    sort(verts.begin(), verts.end());
-
 
663
//    
-
 
664
//    for(auto p:verts)
-
 
665
//    {
-
 
666
//        VertexID vid = p.second;
-
 
667
//        recompute_circle_param(m, vid, fun, circle_pos, min_length_fun);
-
 
668
//    }
-
 
669
//    parametrization = circle_pos;
-
 
670
//    return;
-
 
671
    
-
 
672
    
-
 
673
//    // nail max length level set to circle.
-
 
674
//    Walker w = m.walker(min_length_h);
-
 
675
//    priority_queue<pair<double, HalfEdgeID>> hq;
-
 
676
//    float param = 0;
-
 
677
//    do
-
 
678
//    {
-
 
679
//        hq.push(pair<double,HalfEdgeID>(-abs(fun[w.next().vertex()]-min_length_fun),w.halfedge()));
-
 
680
//        hq.push(pair<double,HalfEdgeID>(-abs(fun[w.opp().next().vertex()]-min_length_fun),w.opp().halfedge()));
-
 
681
//        
-
 
682
//        nailed[w.opp().vertex()] = 1;
-
 
683
//        w = w.next();
-
 
684
//        while(level_set_id[w.halfedge()] != min_length_id)
-
 
685
//            w = w.circulate_vertex_cw();
-
 
686
//    }
-
 
687
//    while(w.halfedge() != min_length_h);
-
 
688
    
-
 
689
//    parametrize(m, nailed, circle_pos, parametrization, fun, min_length_fun);
-
 
690
//    propagate_values(m, nailed, circle_pos, parametrization, level_set_id_vertex, level_set_info, fun, min_length_fun);
-
 
691
    
-
 
692
////    for(int i=0;i<level_set_info.size(); ++i)
-
 
693
////        level_set_info[i].print();
-
 
694
//    
-
 
695
//    VertexAttributeVector<Vec3d> circle_center_attrib(m.no_vertices(),Vec3d(0,0,0));
-
 
696
//    for(auto vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
-
 
697
//    {
-
 
698
//        if(level_set_id_vertex[*vid]>-1)
-
 
699
//        {
-
 
700
//            LevelSetInfo& lsi = level_set_info[level_set_id_vertex[*vid]];
-
 
701
//            circle_center_attrib[*vid] = lsi.avg_pos;
-
 
702
//            nailed[*vid] = 1;
-
 
703
//        }
-
 
704
//    }
-
 
705
////    propagate(m, nailed, circle_center_attrib);
-
 
706
//    Manifold m2 = m;
-
 
707
//    for(auto vid = m2.vertices_begin(); vid != m2.vertices_end(); ++vid)
-
 
708
//    {
-
 
709
//        m2.pos(*vid) = circle_pos[*vid];
-
 
710
//        m2.pos(*vid)[2] = 0.01 * fun[*vid];
-
 
711
//    }
-
 
712
//    obj_save("blob.obj", m2);
-
 
713
    
-
 
714
//    for(auto vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
-
 
715
//    {
-
 
716
//        Vec3d p =circle_pos[*vid];//-circle_center_attrib[*vid];
-
 
717
//        parametrization[*vid] = Vec2d(p[0],p[1]);
-
 
718
//    }
512
    
719
    
513
    return; 
-
 
514
    
720
    
515
    // ----------------------------
721
    // ----------------------------
516
    cout << "Remove vertices not on level set curves" << endl;
722
    cout << "Remove vertices not on level set curves" << endl;
517
    
723
    
518
    vector<VertexID> vid_vec;
724
    vector<VertexID> vid_vec;
Line 524... Line 730...
524
    for (size_t i=0; i<vid_vec.size(); ++i) {
730
    for (size_t i=0; i<vid_vec.size(); ++i) {
525
        FaceID f = m.merge_one_ring(vid_vec[i]);
731
        FaceID f = m.merge_one_ring(vid_vec[i]);
526
        if(f != InvalidFaceID)
732
        if(f != InvalidFaceID)
527
            shortest_edge_triangulate_face(m, f, level_set_id_vertex);
733
            shortest_edge_triangulate_face(m, f, level_set_id_vertex);
528
        else
734
        else
529
            cout << "vertex not removed " << valency(m, vid_vec[i]) << endl; 
735
            cout << "vertex not removed " << valency(m, vid_vec[i]) << endl;
530
    }
736
    }
531
    
737
    
532
    for(FaceIDIterator fid = m.faces_begin(); fid != m.faces_end(); ++fid)
738
    for(FaceIDIterator fid = m.faces_begin(); fid != m.faces_end(); ++fid)
533
        if(no_edges(m, *fid) > 3)
739
        if(no_edges(m, *fid) > 3)
534
            shortest_edge_triangulate_face(m, *fid, level_set_id_vertex);
740
            shortest_edge_triangulate_face(m, *fid, level_set_id_vertex);
535
    
741
    
536
    
742
    
537
    VertexAttributeVector<Vec3d> recalled_positions;
743
//    VertexAttributeVector<Vec3d> recalled_positions;
538
    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
744
//    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
539
        recalled_positions[*vid] = m.pos(*vid);
745
//        recalled_positions[*vid] = m.pos(*vid);
540
    
746
//    
541
    
747
//    
542
    TriangleQuality tq_energy(level_set_id_vertex);
748
    TriangleQuality tq_energy(level_set_id_vertex);
543
    priority_queue_optimization(m, tq_energy);
749
    priority_queue_optimization(m, tq_energy);
544
    
750
    
545
    
751
    
546
    
752
    
547
    //// ----------------------------
-
 
548
    cout << "smooth level set curves" << endl;
-
 
549
    
-
 
550
    
-
 
551
    for(int iter=0;iter< 14;++iter)
-
 
552
    {
-
 
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
        
-
 
558
        VertexAttributeVector<Vec3d> new_pos(m.allocated_vertices(), Vec3d(0));
-
 
559
        VertexAttributeVector<float> new_pos_wsum(m.allocated_vertices(), 0.0);
-
 
560
        for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
-
 
561
        {
-
 
562
            Walker w = m.walker(*hid);
-
 
563
            if(level_set_id[w.halfedge()] != 0)
-
 
564
            {
-
 
565
                float weight = 1.0;//sqr(valency(m,w.opp().vertex())-2);
-
 
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
            float weight = 1.0;//sqr(valency(m,*vid)-2);
-
 
573
            new_pos[*vid] += weight*m.pos(*vid);
-
 
574
            new_pos_wsum[*vid] += weight;
-
 
575
            m.pos(*vid) = 0.75*m.pos(*vid) + 0.25 *new_pos[*vid] / new_pos_wsum[*vid];
-
 
576
        }
-
 
577
        
-
 
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
        {
-
 
583
            Walker w = m.walker(*hid);
-
 
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
        }
-
 
596
        
-
 
597
        for(size_t i=0;i<hidvec.size(); ++i)
-
 
598
        {
-
 
599
            Walker w = m.walker(hidvec[i]);
-
 
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
        }
-
 
607
        
-
 
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
        {
-
 
613
            Walker w = m.walker(*hid);
-
 
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
    }
-
 
628
    
-
 
629
    return;
-
 
630
    
-
 
631
    priority_queue<EdgeQElem> edge_queue;
-
 
632
    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
-
 
633
    {
-
 
634
        Walker w = m.walker(*hid);
-
 
635
        if(w.halfedge()<w.opp().halfedge() &&
-
 
636
           level_set_id[w.halfedge()] == 0)
-
 
637
        {
-
 
638
            Vec3d v = normalize(m.pos(w.vertex()) - m.pos(w.opp().vertex()));
-
 
639
            
-
 
640
            float weight = 0;
-
 
641
            Walker wo = m.walker(w.opp().vertex());
-
 
642
            for(; !w.full_circle(); w = w.circulate_vertex_ccw())
-
 
643
                if(level_set_id[w.halfedge()] != 0)
-
 
644
                {
-
 
645
                    Vec3d e = normalize(m.pos(w.vertex()) - m.pos(w.opp().vertex()));
-
 
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
                {
-
 
651
                    Vec3d e = normalize(m.pos(wo.vertex()) - m.pos(wo.opp().vertex()));
-
 
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
        
-
 
663
        Walker w = m.walker(h);
-
 
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()]))
-
 
667
            m.merge_faces(w.face(), w.halfedge());
-
 
668
    }
-
 
669
    
-
 
670
    
-
 
671
    return;
-
 
672
    
-
 
673
    
-
 
674
    do{
-
 
675
        did_work = false;
-
 
676
        for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
-
 
677
        {
-
 
678
            Walker w = m.walker(*hid);
-
 
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
            }
-
 
686
        }
-
 
687
    }
-
 
688
    while(did_work);
-
 
689
    
-
 
690
    
-
 
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
        {
-
 
700
            Walker w0 = m.walker(*hid);
-
 
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
                
-
 
706
                Walker w = w0;
-
 
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
                }
-
 
730
            
-
 
731
        }
-
 
732
    } while (did_work && k<1);
-
 
733
    
-
 
734
    
-
 
735
}
753
}
736
 
754
 
737
void make_height_fun(const HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
755
void make_height_fun(const HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
738
                     double& vmin, double& vmax)
756
                     double& vmin, double& vmax)
739
{
757
{
740
    VertexIDIterator vid = m.vertices_begin();
758
    VertexIDIterator vid = m.vertices_begin();
741
    vmin = vmax = m.pos(*vid)[2];
759
    vmin = vmax = m.pos(*vid)[2];
742
    for(; vid != m.vertices_end(); ++vid)
760
    for(; vid != m.vertices_end(); ++vid)
743
    {
761
    {
744
        double v = m.pos(*vid)[1];
762
        double v = dot(m.pos(*vid),Vec3d(0.0,1,0.00));
745
        fun[*vid] = v;
763
        fun[*vid] = v;
746
        vmin = min(v, vmin);
764
        vmin = min(v, vmin);
747
        vmax = max(v, vmax);
765
        vmax = max(v, vmax);
748
    }
766
    }
749
}
767
}
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
//        {
-
 
757
//            Walker w = m.walker(*hid);
-
 
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
//        {
-
 
774
//            Walker w = m.walker(*hid);
-
 
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
//        {
-
 
783
//            Walker w = m.walker(hidvec[i]);
-
 
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
//{
-
 
802
//    VertexAttributeVector<Vec3d> new_pos(m.allocated_vertices(), Vec3d(0));
-
 
803
//    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
-
 
804
//    {
-
 
805
//        Walker w = m.walker(*hid);
-
 
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
//    }    
-
 
842
// --------------------------
-
 
843
// Triangulate polygons by connecting only vertices on different curves.
-
 
844
 
-
 
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
//            {
-
 
858
//                Walker w = m.walker(*hid);
-
 
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
 
-
 
886
//priority_queue<EdgeQElem> edge_queue;
-
 
887
//HalfEdgeAttributeVector<int> time_stamp(m.allocated_halfedges(), 0);
-
 
888
//for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
-
 
889
//if(level_set_id[*hid]==0)
-
 
890
//{
-
 
891
//    Walker w = m.walker(*hid);
-
 
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
//    {
-
 
903
//        Walker w = m.walker(hid);
-
 
904
//        Walker wa = w.next();
-
 
905
//        Walker wb = w.prev().opp();
-
 
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
//    {
-
 
944
//        Walker w = m.walker(*hid);
-
 
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;
-
 
964
//        Walker w = m.walker(*vid);
-
 
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
 
-