Subversion Repositories gelsvn

Rev

Rev 642 | Go to most recent revision | 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>
640 janba 9
#include <iomanip>
568 jab 10
 
642 janba 11
 
12
#include "harmonics.h"
568 jab 13
#include "polarize.h"
631 janba 14
#include <CGLA/Vec2d.h>
643 janba 15
#include <CGLA/Mat4x4d.h>
16
#include <CGLA/Vec3i.h>
631 janba 17
#include <LinAlg/LapackFunc.h>
568 jab 18
#include <HMesh/triangulate.h>
631 janba 19
#include <HMesh/obj_save.h>
568 jab 20
#include <HMesh/curvature.h>
21
#include <HMesh/quadric_simplify.h>
22
#include <HMesh/mesh_optimization.h>
23
#include <HMesh/smooth.h>
643 janba 24
#include <HMesh/dual.h>
568 jab 25
 
643 janba 26
#include <Geometry/GridAlgorithm.h>
27
#include <Geometry/build_bbtree.h>
28
#include <Geometry/RGrid.h>
29
#include <Geometry/TrilinFilter.h>
30
#include <GLGraphics/ManifoldRenderer.h>
31
 
572 jab 32
#include <complex>
33
 
568 jab 34
using namespace CGLA;
643 janba 35
using namespace Geometry;
568 jab 36
using namespace std;
37
using namespace HMesh;
643 janba 38
using namespace GLGraphics;
568 jab 39
 
642 janba 40
inline bool same_level(double a, double b) {return abs(a-b) < 1e-10;}
631 janba 41
 
642 janba 42
enum VertexStatus {
643 janba 43
    RAW, COOKED
642 janba 44
};
631 janba 45
 
46
 
643 janba 47
void shortest_edge_triangulate_face(Manifold& m, FaceID f0, const VertexAttributeVector<int>& level_set_id_vertex)
642 janba 48
{
643 janba 49
    queue<FaceID> face_queue;
642 janba 50
 
643 janba 51
    face_queue.push(f0);
52
 
53
    while(!face_queue.empty())
54
    {
55
        FaceID f = face_queue.front();
56
        face_queue.pop();
57
 
642 janba 58
        // Create a vector of vertices.
59
        vector<VertexID> verts;
643 janba 60
        for(Walker w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw())
61
        {
62
            FaceID fa = w.face();
63
            FaceID fb = f;
64
            assert(fa==fb);
65
            verts.push_back(w.vertex());
66
        }
67
        // If there are just three we are done.
68
        if(verts.size() == 3) continue;
642 janba 69
 
70
        // Find vertex pairs that may be connected.
71
        vector<pair<int,int> > vpairs;
72
        const int N = verts.size();
73
        for(int i = 0; i < N - 2; ++i){
74
            for(int j = i + 2; j < N; ++j){
643 janba 75
                if(verts[i] != verts[j] &&
76
                   !connected(m, verts[i], verts[j]) &&
77
                   (level_set_id_vertex[verts[i]] == 0 || level_set_id_vertex[verts[i]] != level_set_id_vertex[verts[j]])
78
                   )
642 janba 79
                    vpairs.push_back(pair<int,int>(i, j));
80
            }
81
        }
82
        if(vpairs.empty()){
83
            cout << "Warning: could not triangulate a face."
84
            << "Probably a vertex appears more than one time in other vertex's one-ring" << endl;
85
            continue;
86
        }
87
 
88
        /* For all vertex pairs, find the edge lengths. Combine the
89
         vertices forming the shortest edge. */
90
 
643 janba 91
        float min_len=FLT_MAX;
92
        int min_k = -1;
642 janba 93
        for(size_t k = 0; k < vpairs.size(); ++k){
94
            int i = vpairs[k].first;
95
            int j = vpairs[k].second;
643 janba 96
            float len = length(m.pos(verts[i]) - m.pos(verts[j]));
97
            //            cout << m.pos(verts[i]) << m.pos(verts[j]) << len << endl;
98
            if(len<min_len){
99
                min_len = len;
100
                min_k = k;
642 janba 101
            }
102
        }
643 janba 103
        assert(min_k != -1);
642 janba 104
 
643 janba 105
        if(min_k>=0)
642 janba 106
        {
643 janba 107
            // Split faces along edge whose midpoint is closest to isovalue
108
            int i = vpairs[min_k].first;
109
            int j = vpairs[min_k].second;
110
            //           cout << i << " " << j << " " << min_k << " " << vpairs.size() << endl;
111
            FaceID f_new = m.split_face_by_edge(f, verts[i], verts[j]);
112
 
113
            if(no_edges(m, f)>3)
114
                face_queue.push(f);
115
            if(no_edges(m, f_new)>3)
116
                face_queue.push(f_new);
642 janba 117
        }
643 janba 118
        else
119
            cout << "failed to triangle. Suspect NaN vertex positions!!" << endl;
120
 
642 janba 121
    }
122
}
631 janba 123
 
643 janba 124
void flip_edges(Manifold& m, VertexAttributeVector<int> ls_id)
631 janba 125
{
643 janba 126
    vector<HalfEdgeID> hvec;
127
    for(HalfEdgeID hid : m.halfedges())
631 janba 128
    {
643 janba 129
        Walker w = m.walker(hid);
130
        if(hid< w.opp().halfedge() &&
131
           ls_id[w.vertex()] > 0 &&
132
           ls_id[w.opp().vertex()] > 0 &&
133
           ls_id[w.vertex()] != ls_id[w.opp().vertex()])
134
            hvec.push_back(hid);
631 janba 135
    }
643 janba 136
 
137
    ValencyEnergy mae;
138
    bool did_work = false;
139
    int iter=0;
140
    do {
141
        did_work = false;
142
        random_shuffle(begin(hvec), end(hvec));
143
        for(auto hid : hvec)
144
        {
145
            Walker w =m.walker(hid);
146
            if(mae.delta_energy(m, hid)<=0 &&
147
               ls_id[w.next().vertex()] != ls_id[w.opp().next().vertex()]) {
148
                m.flip_edge(hid);
149
                did_work = true;
150
            }
151
        }
152
    }
153
    while (did_work && ++iter<1000);
154
    cout << "flip iter" << iter << endl;
642 janba 155
}
631 janba 156
 
642 janba 157
void compute_edge_weights(const Manifold& m, HalfEdgeAttributeVector<double>& edge_weights, FaceAttributeVector<int>& included)
631 janba 158
{
159
    edge_weights = HalfEdgeAttributeVector<double>(m.allocated_halfedges(), 0);
160
    for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f)
161
        if(included[*f])
162
        {
163
            for(Walker wv = m.walker(*f); !wv.full_circle(); wv = wv.circulate_face_ccw())
164
            {
165
                HalfEdgeID h = wv.halfedge();
166
                Vec3d p1(m.pos(wv.vertex()));
167
                Vec3d p2(m.pos(wv.next().vertex()));
168
                Vec3d p0(m.pos(wv.opp().vertex()));
169
                double ang = acos(min(1.0, max(-1.0, dot(normalize(p1-p0), normalize(p2-p0)))));
170
                double ang_opp = acos(min(1.0, max(-1.0, dot(normalize(p2-p1), normalize(p0-p1)))));
171
                double l = (p1-p0).length();
172
                edge_weights[h] += tan(ang/2) / l;
173
                edge_weights[wv.opp().halfedge()] += tan(ang_opp/2) / l;
174
            }
175
        }
176
}
640 janba 177
 
178
template<typename T>
642 janba 179
void smooth_fun(const Manifold& m,
640 janba 180
                VertexAttributeVector<int>& nailed,
181
                VertexAttributeVector<T>& fun, int iter=100)
631 janba 182
{
183
    HalfEdgeAttributeVector<double> edge_weights;
184
    FaceAttributeVector<int> included(m.allocated_faces(),1);
185
    compute_edge_weights(m,edge_weights, included);
640 janba 186
    VertexAttributeVector<T> new_fun(m.no_vertices());
187
    for(int i = 0; i < iter; ++i)
631 janba 188
    {
189
        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
190
            if(!nailed[*v])
191
            {
192
                double w_sum = 0;
640 janba 193
                new_fun[*v] = T(0);
631 janba 194
                for(Walker wv = m.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_ccw())
195
                {
196
                    double w = edge_weights[wv.halfedge()];
197
                    new_fun[*v] += w * fun[wv.vertex()];
198
                    w_sum += w;
199
                }
200
                new_fun[*v] /= w_sum;
201
            }
202
            else
203
                new_fun[*v] = fun[*v];
640 janba 204
        fun = new_fun;
631 janba 205
    }
206
}
207
 
643 janba 208
void label_connected_components(Manifold&m, int& cur_id, const vector<VertexID>& vertices,
209
                                const VertexAttributeVector<double>& fun,
210
                                const VertexAttributeVector<VertexStatus>& status,
211
                                VertexAttributeVector<int>& level_id)
631 janba 212
{
643 janba 213
    for(auto vid : vertices)
214
    {
215
        if(level_id[vid]>0)
216
            continue;
217
 
218
        queue<VertexID> vq;
219
        vq.push(vid);
220
        while(!vq.empty())
221
        {
222
            VertexID v = vq.front();
223
            vq.pop();
224
            level_id[v] = cur_id;
225
            for(Walker w = m.walker(v); !w.full_circle(); w = w.circulate_vertex_ccw())
226
            {
227
                if(status[w.vertex()]==COOKED && same_level(fun[v], fun[w.vertex()]))
228
                    if(level_id[w.vertex()]==0)
229
                        vq.push(w.vertex());
230
                    else if(level_id[w.vertex()] != cur_id)
231
                        cout << "previously labeled vertex encountered" << endl;
232
            }
233
        }
234
        ++cur_id;
235
    }
236
}
237
 
238
void connect_touched(Manifold& m, const VertexAttributeVector<int>& touched)
239
{
240
    for(FaceID fid : m.faces())
241
        for(Walker w = m.walker(fid);!w.full_circle(); w = w.next())
242
            if(touched[w.vertex()])
243
            {
244
                Walker w0 = w;
245
                w = w.next().next();
246
                do
247
                {
248
                    if(touched[w.vertex()] && w.next().halfedge() != w0.halfedge())
249
                    {
250
                        m.split_face_by_edge(fid, w0.vertex(), w.vertex());
251
                        break;
252
                    }
253
                    w = w.next();
254
                }
255
                while(!w.full_circle());
256
                break;
257
            }
258
}
259
 
260
void remove_shorts(Manifold& m, VertexAttributeVector<int> ls_id)
261
{
262
    double avghlen=0;
263
    for(auto hid : m.halfedges())
264
        avghlen += length(m, hid);
265
    avghlen /= m.no_halfedges();
642 janba 266
 
643 janba 267
    for(auto hid : m.halfedges())
268
        if(m.in_use(hid))
269
        {
270
            Walker w = m.walker(hid);
271
            if(ls_id[w.vertex()] > 0 && 	
272
               ls_id[w.vertex()] == ls_id[w.opp().vertex()] &&
273
               length(m, w.halfedge()) < 0.1 * avghlen &&
274
               precond_collapse_edge(m, hid))
275
                m.collapse_edge(hid);
276
        }
277
}
278
 
279
vector<VertexID> separate_edges(Manifold& m, const vector<VertexID>& vertices, int id,
280
                                VertexAttributeVector<double>& fun,
281
                                VertexAttributeVector<VertexStatus>& status,
282
                                VertexAttributeVector<int>& ls_id)
283
{
284
    VertexAttributeVector<int> touched(m.allocated_vertices(),0);
285
    vector<VertexID> new_vertices;
286
    // Cut all edges to vertices on other LS ID
287
    for(auto vid: vertices)
288
        if(ls_id[vid]==id)
289
        {
290
            vector<HalfEdgeID> edges_to_split;
291
            for(Walker w = m.walker(vid); !w.full_circle(); w = w.circulate_vertex_ccw())
292
            {
293
                int id = ls_id[w.vertex()];
294
                if(id > 0 & id != ls_id[vid])
295
                    edges_to_split.push_back(w.halfedge());
296
            }
297
 
298
            for (auto hid : edges_to_split)
299
            {
300
                VertexID vnew = m.split_edge(hid);
301
                fun[vnew] = fun[vid];
302
                m.pos(vnew) = m.pos(vid);
303
                status[vnew] = COOKED;
304
                ls_id[vnew] = ls_id[vid];
305
                touched[vnew] = 1;
306
                new_vertices.push_back(vnew);
307
            }
308
        }
309
 
310
    // Label old vertices as plain (uncooked)
311
    for(auto vid: vertices)
312
        if(ls_id[vid]==id)
313
        {
314
            status[vid] = RAW;
315
            ls_id[vid] = 0;
316
        }
317
    connect_touched(m, touched);
318
 
319
    return new_vertices;
320
}
321
 
322
vector<VertexID> cut_mesh(Manifold& m, VertexAttributeVector<double>& fun, double cut_val,
323
                          VertexAttributeVector<VertexStatus>& status)
324
{
325
    cout << "cutting @ " << cut_val << endl;
326
 
642 janba 327
    vector<VertexID> new_verts;
328
    vector<HalfEdgeID> hidvec;
643 janba 329
    VertexAttributeVector<int> touched(m.allocated_vertices(), 0);
642 janba 330
    for(HalfEdgeID hid : m.halfedges())
631 janba 331
    {
642 janba 332
        Walker w = m.walker(hid);
333
        double bval = fun[w.vertex()];
334
        double aval = fun[w.opp().vertex()];
335
        if(aval<bval && aval < cut_val && cut_val <= bval)
631 janba 336
        {
642 janba 337
            double t = (cut_val-aval)/(bval-aval);
338
            Vec3d p = t*m.pos(w.vertex()) + (1.0-t)*m.pos(w.opp().vertex());
339
            VertexID vnew = m.split_edge(hid);
340
            m.pos(vnew) = p;
341
            status[vnew] = COOKED;
342
            fun[vnew] = cut_val;
643 janba 343
            touched[vnew] = 1;
642 janba 344
            new_verts.push_back(vnew);
345
        }
346
    }
347
 
643 janba 348
    connect_touched(m, touched);
349
 
642 janba 350
    return new_verts;
631 janba 351
}
352
 
643 janba 353
void smooth_cooked_vertices(Manifold& m, const vector<VertexID>& vertices,
354
                            VertexAttributeVector<VertexStatus>& status, int iter=7)
568 jab 355
{
642 janba 356
    for(int i=0;i<iter;++i)
568 jab 357
    {
643 janba 358
        VertexAttributeVector<Vec3d> npos = m.positions_attribute_vector();
359
        VertexAttributeVector<int> cnt(m.allocated_vertices(), 1);
642 janba 360
        for(auto vid : vertices)
643 janba 361
            if(m.in_use(vid))
362
                for(Walker w = m.walker(vid); !w.full_circle(); w = w.circulate_vertex_ccw())
363
                    if(status[vid]==COOKED) {
364
                        npos[vid] += m.pos(w.vertex());
365
                        ++cnt[vid];
366
                    }
642 janba 367
        for(auto vid : vertices)
368
            if(m.in_use(vid))
643 janba 369
                m.pos(vid) = (npos[vid])/cnt[vid];
568 jab 370
    }
371
}
372
 
643 janba 373
void remove_v5_vertices(Manifold& m, VertexAttributeVector<int>& ls_id, int id_ceiling)
374
{
375
    for(auto vid: m.vertices())
376
    {
377
        int id = ls_id[vid];
378
        if(id>0 && id<id_ceiling)
379
        {
380
            vector<HalfEdgeID> hit_list;
381
            for(Walker w = m.walker(vid); !w.full_circle(); w=w.circulate_vertex_ccw())
382
                if(ls_id[w.vertex()] >= id_ceiling)
383
                    hit_list.push_back(w.halfedge());
384
 
385
            if(hit_list.size()>1)
386
            {
387
                sort(begin(hit_list),end(hit_list),
388
                     [&m](HalfEdgeID a, HalfEdgeID b){return length(m,a)>length(m, b);});
389
                for(int i=1;i<hit_list.size();++i)
390
                {
391
                    HalfEdgeID hid = hit_list[i];
392
                    Walker w = m.walker(hid);
393
                    HalfEdgeID surplus_h = w.opp().prev().halfedge();
394
                    if(precond_collapse_edge(m,surplus_h))
395
                    {
396
                        m.collapse_edge(surplus_h,true);
397
                        m.merge_faces(m.walker(hid).face(), hid);
398
                    }
399
                }
400
            }
401
 
402
        }
403
    }
404
 
405
}
406
 
407
void remove_wedges(Manifold& m, VertexAttributeVector<int>& ls_id)
408
{
409
    for(auto hid : m.halfedges())
410
        if(m.in_use(hid))
411
        {
412
            Walker w = m.walker(hid);
413
            if(ls_id[w.vertex()]>0 &&
414
               ls_id[w.vertex()] == ls_id[w.opp().vertex()] &&
415
               ls_id[w.next().vertex()]>0 &&
416
               no_edges(m, w.face())==3 &&
417
               precond_collapse_edge(m, hid))
418
                m.collapse_edge(hid, true);
419
 
420
        }
421
}
422
 
423
 
424
 
642 janba 425
int ssb(double a, double b)
568 jab 426
{
642 janba 427
    const double THRESH = 1e-6;
428
    double delta = a-b;
429
    if(delta<-THRESH) return -1;
430
    if(delta>THRESH) return 1;
431
    return 0;
568 jab 432
}
433
 
643 janba 434
void remove_vertices(Manifold& m, VertexAttributeVector<double>& fun,
435
                     const VertexAttributeVector<VertexStatus>& status,
436
                     const VertexAttributeVector<int>& level_id, double rmin, double rmax)
568 jab 437
{
642 janba 438
    vector<VertexID> vertices_to_push;
439
    for(auto vid: m.vertices())
440
        if(status[vid]==RAW &&
441
           fun[vid] >= rmin &&
442
           fun[vid] <= rmax)
443
            vertices_to_push.push_back(vid);
631 janba 444
 
642 janba 445
    random_shuffle(begin(vertices_to_push), end(vertices_to_push));
640 janba 446
 
642 janba 447
    for(auto vid : vertices_to_push)
572 jab 448
    {
643 janba 449
        FaceID fid = m.merge_one_ring(vid);
642 janba 450
        if(fid != InvalidFaceID)
643 janba 451
            shortest_edge_triangulate_face(m, fid, level_id);
572 jab 452
    }
453
}
454
 
568 jab 455
 
631 janba 456
void polarize_mesh(Manifold& m, VertexAttributeVector<double>& fun, double vmin, double vmax, const int divisions, VertexAttributeVector<Vec2d>& parametrization)
568 jab 457
{
642 janba 458
    VertexAttributeVector<VertexStatus> status(m.allocated_vertices(), RAW);
643 janba 459
    VertexAttributeVector<int> level_id(m.allocated_vertices(), 0);
460
    int cur_id = 1;
568 jab 461
 
642 janba 462
    double interval = (vmax-vmin)/(divisions+1);
643 janba 463
    double cut_val = vmin + 0.065*(vmax-vmin);
568 jab 464
 
643 janba 465
    vector<VertexID> cut_verts = cut_mesh(m, fun, cut_val, status);
466
    label_connected_components(m, cur_id, cut_verts, fun, status, level_id);
467
    remove_vertices(m, fun, status, level_id, vmin, cut_val);
468
    flip_edges(m, level_id);
469
 
470
    for(int id=1;id<cur_id;++id) {
471
        vector<VertexID> loop_verts = separate_edges(m, cut_verts, id, fun, status, level_id);
472
        smooth_cooked_vertices(m, loop_verts, status, 50);
473
    }
474
 
642 janba 475
    for(int iter=0;iter<divisions+2;++iter)
568 jab 476
    {
643 janba 477
        cut_val += interval;
478
        vector<VertexID> cut_verts = cut_mesh(m, fun,cut_val, status);
479
 
480
        int old_id = cur_id;
481
        label_connected_components(m, cur_id, cut_verts, fun, status, level_id);
482
        remove_vertices(m, fun, status, level_id, cut_val-1.01*interval, cut_val);
483
 
484
        vector<VertexID> loop_verts;
485
        for(int id=old_id;id<cur_id;++id)
486
        {
487
            vector<VertexID> tmp = separate_edges(m, cut_verts, id, fun, status, level_id);
488
            loop_verts.insert(loop_verts.end(), tmp.begin(),tmp.end());
489
        }
490
        remove_wedges(m, level_id);
491
        remove_v5_vertices(m, level_id, old_id);
492
 
493
        smooth_cooked_vertices(m, loop_verts, status);
494
 
568 jab 495
    }
643 janba 496
    dual(m);
497
    m.cleanup();
498
}
499
 
500
void simplify_polar_mesh(Manifold& m, double frac)
501
{
502
    int N_orig = m.no_vertices();
503
    HalfEdgeAttributeVector<int> touched(m.allocated_halfedges(),0);
572 jab 504
 
643 janba 505
    vector<pair<double,vector<HalfEdgeID>>> work_vector;
506
    for(auto hid : m.halfedges())
568 jab 507
    {
643 janba 508
        Walker w = m.walker(hid);
509
        if(!touched[hid] &&
510
           no_edges(m, w.face()) == 4 &&
511
           no_edges(m, w.opp().face()) == 4)
512
        {
513
 
514
            double l_sum=0;
515
            int n=0;
516
            vector<HalfEdgeID> hvec;
517
 
518
            bool abort=false;
519
            for(int i=0;i<2;++i)
520
            {
521
                Walker w0 = (i==0?w:w.opp().next().next().opp());
522
                while(!touched[w0.halfedge()])
523
                {
524
                    touched[w0.halfedge()] = 1;
525
                    touched[w0.opp().halfedge()] = 1;
526
                    hvec.push_back(w0.halfedge());
527
                    ++n;
528
                    l_sum += sqr(area(m,w0.face()));
529
                    if(valency(m,w0.vertex()) != 4 || valency(m, w0.opp().vertex()) != 4)
530
                        abort = true;
531
                    if(no_edges(m, w0.face())==4)
532
                        w0 = w0.next().next().opp();
533
                    else {
534
                        if (valency(m,w0.next().vertex())<5)
535
                            abort = true;
536
                        break;
537
                    }
538
                }
539
            }
540
            if(abort)
541
                continue;
542
            else
543
                work_vector.push_back(make_pair(l_sum/sqr(n),hvec));
568 jab 544
        }
545
    }
643 janba 546
 
547
    sort(begin(work_vector),end(work_vector));
548
 
549
    for(auto work : work_vector)
550
    {
551
        for(HalfEdgeID h :work.second)
552
            if(m.in_use(h) && precond_collapse_edge(m, h))
553
                m.collapse_edge(h,true);
554
            else cout << "Collapse failed ..." << endl;
555
 
556
        if(N_orig * frac > m.no_vertices())
557
            break;
558
    }
559
    m.cleanup();
560
 
568 jab 561
}
562
 
643 janba 563
using namespace Geometry;
564
 
565
const Mat4x4d fit_bounding_volume(const Vec3d& p0,
566
                                  const Vec3d& p7,
567
                                  float buf_reg,
568
                                  int vol_dim)
569
{
570
    Vec3d sz = p7 - p0;
571
    Vec3i dims(vol_dim);
572
    Vec3d scal_vec = (Vec3d(dims)-Vec3d(2*buf_reg+2))/sz;
573
    float scal = min(scal_vec[0], min(scal_vec[1],scal_vec[2]));
574
 
575
    Mat4x4d m = translation_Mat4x4d(Vec3d(0)+Vec3d(buf_reg+1));
576
    m *= scaling_Mat4x4d(Vec3d(scal));
577
    m *= translation_Mat4x4d(-p0);
578
    return m;
579
}
580
 
581
void smooth_and_refit(HMesh::Manifold& m_in,  HMesh::Manifold& m_ref, int iter, int vol_dim)
582
{
583
    AABBTree tree;
584
 
585
    Manifold m_tmp = m_ref;
586
    Vec3d p0,p7;
587
    bbox(m_tmp, p0, p7);
588
    Mat4x4d mat = fit_bounding_volume(p0, p7, 3, vol_dim);
589
    Mat4x4d imat = invert(mat);
590
    for(auto vid : m_tmp.vertices())
591
        m_tmp.pos(vid) = mat.mul_3D_point(m_tmp.pos(vid));
592
    build_AABBTree(m_tmp, tree);
593
 
594
    cout << "Done building AABB tree" << endl;
595
    RGrid<float> grid(Vec3i(vol_dim),FLT_MAX);
596
    auto F = [&](const Vec3i& p,float& v)
597
    {
598
        v =  tree.compute_signed_distance(Vec3f(p));
599
    };
600
    for_each_voxel(grid, F);
601
    cout << "Made distance field" << endl;
602
    TrilinFilter<RGrid<float>> df(&grid);
603
    for (int i=0;i<iter; ++i)
604
    {
605
        auto vsafe = m_in.positions_attribute_vector();
606
        laplacian_smooth(m_in,.25,10);
607
        for(auto vid : m_in.vertices())
608
        {
609
            double w = exp(4-valency(m_in, vid));
610
            m_in.pos(vid) *= w;
611
            m_in.pos(vid) += (1-w) * vsafe[vid];
612
        }
613
        float avg = 0;
614
        for(auto hid : m_in.halfedges())
615
            avg += length(m_in, hid);
616
        avg /= m_in.no_halfedges();
617
        auto npos = m_in.positions_attribute_vector();
618
        for(auto vid : m_in.vertices())
619
        {
620
            npos[vid] += 0.5 * avg * normal(m_in, vid);
621
        }
622
        m_in.positions_attribute_vector() = npos;
623
        for(auto vid : m_in.vertices())
624
        {
625
            Vec3f pos = Vec3f(mat.mul_3D_point(m_in.pos(vid)));
626
            if(df.in_domain(pos))
627
                m_in.pos(vid) = imat.mul_3D_point(Vec3d(pos - df(pos) * df.grad(pos)));
628
            else
629
                cout << "outside domain" << endl;
630
        }
631
    }
632
 
633
}
634
 
572 jab 635
void make_height_fun(const HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
636
                     double& vmin, double& vmax)
568 jab 637
{
638
    VertexIDIterator vid = m.vertices_begin();
642 janba 639
    VertexAttributeVector<int> nailed(m.allocated_vertices(), 0);
640
    smooth_fun(m, nailed, fun,0);
640 janba 641
    vmin = vmax = m.pos(*vid)[1];
568 jab 642
    for(; vid != m.vertices_end(); ++vid)
643
    {
631 janba 644
        double v = dot(m.pos(*vid),Vec3d(0.0,1,0.00));
568 jab 645
        fun[*vid] = v;
646
        vmin = min(v, vmin);
647
        vmax = max(v, vmax);
648
    }
642 janba 649
 
568 jab 650
}
640 janba 651
 
642 janba 652
void make_adf_fun(HMesh::Manifold& m, double t, HMesh::VertexAttributeVector<double>& F,
643 janba 653
                  double& vmin, double& vmax)
642 janba 654
{
655
    Harmonics harm(m);
656
    harm.compute_adf(F, t);
657
    VertexAttributeVector<int> nailed(m.allocated_vertices(), 0);
658
    vmin = vmax = F[*m.vertices_begin()];
659
    for(auto vid : m.vertices())
660
    {
661
        vmin = min(F[vid], vmin);
662
        vmax = max(F[vid], vmax);
663
    }
664
    cout << vmin << vmax << endl;
665
 
666
}
667