Subversion Repositories gelsvn

Rev

Rev 631 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 631 Rev 640
1
//
1
//
2
//  polarize.cpp
2
//  polarize.cpp
3
//  GEL
3
//  GEL
4
//
4
//
5
//  Created by J. Andreas Bærentzen on 18/03/12.
5
//  Created by J. Andreas Bærentzen on 18/03/12.
6
//  Copyright 2012 __MyCompanyName__. All rights reserved.
6
//  Copyright 2012 __MyCompanyName__. All rights reserved.
7
//
7
//
8
#include <queue>
8
#include <queue>
-
 
9
#include <iomanip>
9
 
10
 
10
#include "polarize.h"
11
#include "polarize.h"
11
#include <CGLA/Vec2d.h>
12
#include <CGLA/Vec2d.h>
12
#include <LinAlg/LapackFunc.h>
13
#include <LinAlg/LapackFunc.h>
13
#include <HMesh/triangulate.h>
14
#include <HMesh/triangulate.h>
14
#include <HMesh/obj_save.h>
15
#include <HMesh/obj_save.h>
15
#include <HMesh/curvature.h>
16
#include <HMesh/curvature.h>
16
#include <HMesh/quadric_simplify.h>
17
#include <HMesh/quadric_simplify.h>
17
#include <HMesh/mesh_optimization.h>
18
#include <HMesh/mesh_optimization.h>
18
#include <HMesh/smooth.h>
19
#include <HMesh/smooth.h>
19
 
20
 
20
#include <complex>
21
#include <complex>
21
 
22
 
22
using namespace CGLA;
23
using namespace CGLA;
23
using namespace std;
24
using namespace std;
24
using namespace HMesh;
25
using namespace HMesh;
25
 
26
 
26
 
27
 
27
 
28
 
28
inline bool same_level(float a, float b) {return abs(a-b) < 0.00001;}
29
inline bool same_level(double a, double b) {return abs(a-b) < 1e-10;}
29
 
30
 
30
 
31
 
31
struct LevelSetInfo
32
struct LevelSetInfo
32
{
33
{
33
    int id;
34
    int id;
34
    int no_vertices;
35
    int no_vertices;
35
    Vec3d avg_pos;
36
    Vec3d avg_pos;
36
    double rad;
37
    double rad;
37
    double length;
38
    double length;
38
    int components;
39
    int components;
39
    HalfEdgeID h;
40
    HalfEdgeID h;
40
    double fun_value;
41
    double fun_value;
41
    
42
    
42
    void print()
43
    void print()
43
    {
44
    {
44
        cout
45
        cout
45
        << " id : " << id
46
        << " id : " << id
46
        << " no vertices : " << no_vertices
47
        << " no vertices : " << no_vertices
47
        << " avg pos : " << avg_pos
48
        << " avg pos : " << avg_pos
48
        << " rad : " << rad
49
        << " rad : " << rad
49
        << " length : " << length
50
        << " length : " << length
50
        << " # : " << components
51
        << " # : " << components
51
        << " F : " << fun_value << endl;
52
        << " F : " << fun_value << endl;
52
    }
53
    }
53
};
54
};
54
 
55
 
55
void compute_edge_weights(Manifold& m, HalfEdgeAttributeVector<double>& edge_weights, FaceAttributeVector<int>& included)
56
void compute_edge_weights(Manifold& m, HalfEdgeAttributeVector<double>& edge_weights, FaceAttributeVector<int>& included)
56
{
57
{
57
    edge_weights = HalfEdgeAttributeVector<double>(m.allocated_halfedges(), 0);
58
    edge_weights = HalfEdgeAttributeVector<double>(m.allocated_halfedges(), 0);
58
    for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f)
59
    for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f)
59
        if(included[*f])
60
        if(included[*f])
60
        {
61
        {
61
            for(Walker wv = m.walker(*f); !wv.full_circle(); wv = wv.circulate_face_ccw())
62
            for(Walker wv = m.walker(*f); !wv.full_circle(); wv = wv.circulate_face_ccw())
62
            {
63
            {
63
                HalfEdgeID h = wv.halfedge();
64
                HalfEdgeID h = wv.halfedge();
64
                Vec3d p1(m.pos(wv.vertex()));
65
                Vec3d p1(m.pos(wv.vertex()));
65
                Vec3d p2(m.pos(wv.next().vertex()));
66
                Vec3d p2(m.pos(wv.next().vertex()));
66
                Vec3d p0(m.pos(wv.opp().vertex()));
67
                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 = 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 ang_opp = acos(min(1.0, max(-1.0, dot(normalize(p2-p1), normalize(p0-p1)))));
69
                double l = (p1-p0).length();
70
                double l = (p1-p0).length();
70
                edge_weights[h] += tan(ang/2) / l;
71
                edge_weights[h] += tan(ang/2) / l;
71
                edge_weights[wv.opp().halfedge()] += tan(ang_opp/2) / l;
72
                edge_weights[wv.opp().halfedge()] += tan(ang_opp/2) / l;
72
            }
73
            }
73
        }
74
        }
74
}
75
}
-
 
76
 
-
 
77
template<typename T>
75
void smooth_fun(Manifold& m,
78
void smooth_fun(Manifold& m,
76
                    VertexAttributeVector<int>& nailed,
79
                VertexAttributeVector<int>& nailed,
77
                    VertexAttributeVector<double>& fun)
80
                VertexAttributeVector<T>& fun, int iter=100)
78
{
81
{
79
    HalfEdgeAttributeVector<double> edge_weights;
82
    HalfEdgeAttributeVector<double> edge_weights;
80
    FaceAttributeVector<int> included(m.allocated_faces(),1);
83
    FaceAttributeVector<int> included(m.allocated_faces(),1);
81
    compute_edge_weights(m,edge_weights, included);
84
    compute_edge_weights(m,edge_weights, included);
82
    VertexAttributeVector<double> new_fun(m.no_vertices());
85
    VertexAttributeVector<T> new_fun(m.no_vertices());
83
    for(int i = 0; i < 1000; ++i)
86
    for(int i = 0; i < iter; ++i)
84
    {
87
    {
85
        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
88
        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
86
            if(!nailed[*v])
89
            if(!nailed[*v])
87
            {
90
            {
88
                double w_sum = 0;
91
                double w_sum = 0;
89
                new_fun[*v] = 0;
92
                new_fun[*v] = T(0);
90
                for(Walker wv = m.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_ccw())
93
                for(Walker wv = m.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_ccw())
91
                {
94
                {
92
                    double w = edge_weights[wv.halfedge()];
95
                    double w = edge_weights[wv.halfedge()];
93
                    new_fun[*v] += w * fun[wv.vertex()];
96
                    new_fun[*v] += w * fun[wv.vertex()];
94
                    w_sum += w;
97
                    w_sum += w;
95
                }
98
                }
96
                new_fun[*v] /= w_sum;
99
                new_fun[*v] /= w_sum;
97
            }
100
            }
98
            else
101
            else
99
                new_fun[*v] = fun[*v];
102
                new_fun[*v] = fun[*v];
100
            fun = new_fun;
103
        fun = new_fun;
101
    }
104
    }
102
}
105
}
103
 
106
 
104
void segment_manifold(Manifold& m, HalfEdgeAttributeVector<int>& ls_id,
107
void segment_manifold(Manifold& m, HalfEdgeAttributeVector<int>& ls_id,
105
                      FaceAttributeVector<int>& segmentation,
108
                      FaceAttributeVector<int>& segmentation,
106
                      vector<vector<int>>& boundaries)
109
                      vector<vector<int>>& boundaries)
107
{
110
{
108
    segmentation = FaceAttributeVector<int>(m.no_faces(), -1);
111
    segmentation = FaceAttributeVector<int>(m.no_faces(), -1);
109
    int SEG_NO = 0;
112
    int SEG_NO = 0;
110
    for(auto f = m.faces_begin(); f != m.faces_end(); ++f)
113
    for(auto f = m.faces_begin(); f != m.faces_end(); ++f)
111
    {
114
    {
112
        if (segmentation[*f] == -1)
115
        if (segmentation[*f] == -1)
113
        {
116
        {
114
            queue<FaceID> q;
117
            queue<FaceID> q;
115
            q.push(*f);
118
            q.push(*f);
116
            vector<int> bound(0);
119
            vector<int> bound(0);
117
            while (!q.empty())
120
            while (!q.empty())
118
            {
121
            {
119
                FaceID face = q.front();
122
                FaceID face = q.front();
120
                q.pop();
123
                q.pop();
121
                segmentation[face] = SEG_NO;
124
                segmentation[face] = SEG_NO;
122
                for(Walker w = m.walker(face); !w.full_circle(); w = w.next())
125
                for(Walker w = m.walker(face); !w.full_circle(); w = w.next())
123
                {
126
                {
124
                    if(ls_id[w.halfedge()] == -1)
127
                    if(ls_id[w.halfedge()] == -1)
125
                    {
128
                    {
126
                        FaceID fopp = w.opp().face();
129
                        FaceID fopp = w.opp().face();
127
                        if(segmentation[fopp] == -1) {
130
                        if(segmentation[fopp] == -1) {
128
                            q.push(fopp);
131
                            q.push(fopp);
129
                        }
132
                        }
130
                    }
133
                    }
131
                    else {
134
                    else {
132
                        bound.push_back(ls_id[w.halfedge()]);
135
                        bound.push_back(ls_id[w.halfedge()]);
133
                    }
136
                    }
134
                    
137
                    
135
                }
138
                }
136
            }
139
            }
137
            sort(begin(bound), end(bound));
140
            sort(begin(bound), end(bound));
138
            auto new_end = unique(begin(bound), end(bound));
141
            auto new_end = unique(begin(bound), end(bound));
139
            boundaries.push_back(vector<int>(begin(bound),new_end));
142
            boundaries.push_back(vector<int>(begin(bound),new_end));
140
            cout << "Boundaries of seg# " << SEG_NO << " : ";
143
            cout << "Boundaries of seg# " << SEG_NO << " : ";
141
            for(auto be:boundaries[SEG_NO])
144
            for(auto be:boundaries[SEG_NO])
142
                cout << be << " ";
145
                cout << be << " ";
143
            cout << endl;
146
            cout << endl;
144
            SEG_NO += 1;
147
            SEG_NO += 1;
145
        }
148
        }
146
    
149
        
147
    }
150
    }
148
}
151
}
149
 
152
 
150
 
153
 
151
void shortest_edge_triangulate_face(Manifold& m, FaceID f0, VertexAttributeVector<int>& level_set_id_vertex)
154
void shortest_edge_triangulate_face(Manifold& m, FaceID f0, VertexAttributeVector<int>& level_set_id_vertex)
152
{
155
{
153
    queue<FaceID> face_queue;
156
    queue<FaceID> face_queue;
154
    
157
    
155
    face_queue.push(f0);
158
    face_queue.push(f0);
156
    
159
    
157
    while(!face_queue.empty())
160
    while(!face_queue.empty())
158
    {
161
    {
159
        FaceID f = face_queue.front();
162
        FaceID f = face_queue.front();
160
        face_queue.pop();
163
        face_queue.pop();
161
        
164
        
162
        // Create a vector of vertices.
165
        // Create a vector of vertices.
163
        vector<VertexID> verts;
166
        vector<VertexID> verts;
164
        for(Walker w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw())
167
        for(Walker w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw())
165
        {
168
        {
166
            FaceID fa = w.face();
169
            FaceID fa = w.face();
167
            FaceID fb = f;
170
            FaceID fb = f;
168
            assert(fa==fb);
171
            assert(fa==fb);
169
            verts.push_back(w.vertex());
172
            verts.push_back(w.vertex());
170
        }
173
        }
171
        // If there are just three we are done.
174
        // If there are just three we are done.
172
        if(verts.size() == 3) continue;
175
        if(verts.size() == 3) continue;
173
        
176
        
174
        // Find vertex pairs that may be connected.
177
        // Find vertex pairs that may be connected.
175
        vector<pair<int,int> > vpairs;
178
        vector<pair<int,int> > vpairs;
176
        const int N = verts.size();
179
        const int N = verts.size();
177
        for(int i = 0; i < N - 2; ++i){
180
        for(int i = 0; i < N - 2; ++i){
178
            for(int j = i + 2; j < N; ++j){
181
            for(int j = i + 2; j < N; ++j){
179
                if(verts[i] != verts[j] &&
182
                if(verts[i] != verts[j] &&
180
                   !connected(m, verts[i], verts[j]) &&
183
                   !connected(m, verts[i], verts[j]) &&
181
                   (level_set_id_vertex[verts[i]] == 0 || level_set_id_vertex[verts[i]] != level_set_id_vertex[verts[j]])
184
                   (level_set_id_vertex[verts[i]] == 0 || level_set_id_vertex[verts[i]] != level_set_id_vertex[verts[j]]) &&
-
 
185
                   valency(m, verts[i])<5 && valency(m,verts[j])<5
182
                   )
186
                   )
183
                    vpairs.push_back(pair<int,int>(i, j));
187
                    vpairs.push_back(pair<int,int>(i, j));
184
            }
188
            }
185
        }
189
        }
186
        if(vpairs.empty()){
190
        if(vpairs.empty()){
187
            cout << "Warning: could not triangulate a face."
191
            cout << "Warning: could not triangulate a face."
188
            << "Probably a vertex appears more than one time in other vertex's one-ring" << endl;
192
            << "Probably a vertex appears more than one time in other vertex's one-ring" << endl;
189
            continue;
193
            continue;
190
        }
194
        }
191
        
195
        
192
        /* For all vertex pairs, find the edge lengths. Combine the
196
        /* For all vertex pairs, find the edge lengths. Combine the
193
         vertices forming the shortest edge. */
197
         vertices forming the shortest edge. */
194
        
198
        
195
        float min_len=FLT_MAX;
199
        float min_len=FLT_MAX;
196
        int min_k = -1;
200
        int min_k = -1;
197
        for(size_t k = 0; k < vpairs.size(); ++k){
201
        for(size_t k = 0; k < vpairs.size(); ++k){
198
            int i = vpairs[k].first;
202
            int i = vpairs[k].first;
199
            int j = vpairs[k].second;
203
            int j = vpairs[k].second;
200
            float len = sqr_length(m.pos(verts[i]) - m.pos(verts[j]));
204
            float len = sqr_length(m.pos(verts[i]) - m.pos(verts[j]));
201
            
205
            
202
            if(len<min_len){
206
            if(len<min_len){
203
                min_len = len;
207
                min_len = len;
204
                min_k = k;
208
                min_k = k;
205
            }
209
            }
206
        }
210
        }
207
        assert(min_k != -1);
211
        assert(min_k != -1);
208
        
212
        
209
        {
213
        {
210
            // Split faces along edge whose midpoint is closest to isovalue
214
            // Split faces along edge whose midpoint is closest to isovalue
211
            int i = vpairs[min_k].first;
215
            int i = vpairs[min_k].first;
212
            int j = vpairs[min_k].second;
216
            int j = vpairs[min_k].second;
213
            FaceID f_new = m.split_face_by_edge(f, verts[i], verts[j]);
217
            FaceID f_new = m.split_face_by_edge(f, verts[i], verts[j]);
214
            
218
            
215
            if(no_edges(m, f)>3)
219
            if(no_edges(m, f)>3)
216
                face_queue.push(f);
220
                face_queue.push(f);
217
            if(no_edges(m, f_new)>3)
221
            if(no_edges(m, f_new)>3)
218
                face_queue.push(f_new);
222
                face_queue.push(f_new);
219
        }
223
        }
220
        
224
        
221
    }
225
    }
222
}
226
}
223
 
227
 
224
 
228
 
225
void shortest_edge_split_face(Manifold& m, FaceID f0, VertexAttributeVector<int>& level_set_id_vertex)
229
void shortest_edge_split_face(Manifold& m, FaceID f0, VertexAttributeVector<int>& level_set_id_vertex)
226
{
230
{
227
    queue<FaceID> face_queue;
231
    queue<FaceID> face_queue;
228
    
232
    
229
    face_queue.push(f0);
233
    face_queue.push(f0);
230
    
234
    
231
    while(!face_queue.empty())
235
    while(!face_queue.empty())
232
    {
236
    {
233
        FaceID f = face_queue.front();
237
        FaceID f = face_queue.front();
234
        face_queue.pop();
238
        face_queue.pop();
235
        
239
        
236
        // Create a vector of vertices.
240
        // Create a vector of vertices.
237
        vector<VertexID> verts;
241
        vector<VertexID> verts;
238
        for(Walker w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw())
242
        for(Walker w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw())
239
        {
243
        {
240
            verts.push_back(w.vertex());
244
            verts.push_back(w.vertex());
241
        }
245
        }
242
        
246
        
243
        // Find vertex pairs that may be connected.
247
        // Find vertex pairs that may be connected.
244
        vector<pair<int,int> > vpairs;
248
        vector<pair<int,int> > vpairs;
245
        const int N = verts.size();
249
        const int N = verts.size();
246
        for(int i = 0; i < N ; ++i){
250
        for(int i = 0; i < N ; ++i){
247
            for(int j = 3; j < N-2; ++j){
251
            for(int j = 3; j < N-2; ++j){
248
                int jj = (j+i)%N;
252
                int jj = (j+i)%N;
249
                if(!connected(m, verts[i], verts[jj]) &&
253
                if(!connected(m, verts[i], verts[jj]) &&
250
                   (level_set_id_vertex[verts[i]] != level_set_id_vertex[verts[jj]]) &&
254
                   (level_set_id_vertex[verts[i]] != level_set_id_vertex[verts[jj]]) &&
251
                   (level_set_id_vertex[verts[(i+1)%N]] == level_set_id_vertex[verts[i]]) &&
255
                   (level_set_id_vertex[verts[(i+1)%N]] == level_set_id_vertex[verts[i]]) &&
252
                   (level_set_id_vertex[verts[(i+N-1)%N]] == level_set_id_vertex[verts[i]]) &&
256
                   (level_set_id_vertex[verts[(i+N-1)%N]] == level_set_id_vertex[verts[i]]) &&
253
                   (level_set_id_vertex[verts[(jj+1)%N]] == level_set_id_vertex[verts[jj]]) &&
257
                   (level_set_id_vertex[verts[(jj+1)%N]] == level_set_id_vertex[verts[jj]]) &&
254
                   (level_set_id_vertex[verts[(jj+N-1)%N]] == level_set_id_vertex[verts[jj]]))
258
                   (level_set_id_vertex[verts[(jj+N-1)%N]] == level_set_id_vertex[verts[jj]]))
255
                    vpairs.push_back(pair<int,int>(i, jj));
259
                    vpairs.push_back(pair<int,int>(i, jj));
256
            }
260
            }
257
        }
261
        }
258
        if(vpairs.empty()) continue;
262
        if(vpairs.empty()) continue;
259
        
263
        
260
        
264
        
261
        /* For all vertex pairs, find the edge lengths. Combine the
265
        /* For all vertex pairs, find the edge lengths. Combine the
262
         vertices forming the shortest edge. */
266
         vertices forming the shortest edge. */
263
        
267
        
264
        float min_len=FLT_MAX;
268
        float min_len=FLT_MAX;
265
        int min_k = -1;
269
        int min_k = -1;
266
        for(size_t k = 0; k < vpairs.size(); ++k){
270
        for(size_t k = 0; k < vpairs.size(); ++k){
267
            int i = vpairs[k].first;
271
            int i = vpairs[k].first;
268
            int j = vpairs[k].second;
272
            int j = vpairs[k].second;
269
            float len = sqr_length(m.pos(verts[i]) - m.pos(verts[j]));
273
            float len = sqr_length(m.pos(verts[i]) - m.pos(verts[j]));
270
            
274
            
271
            if(len<min_len){
275
            if(len<min_len){
272
                min_len = len;
276
                min_len = len;
273
                min_k = k;
277
                min_k = k;
274
            }
278
            }
275
        }
279
        }
276
        assert(min_k != -1);
280
        assert(min_k != -1);
277
        
281
        
278
        {
282
        {
279
            // Split faces along edge whose midpoint is closest to isovalue
283
            // Split faces along edge whose midpoint is closest to isovalue
280
            int i = vpairs[min_k].first;
284
            int i = vpairs[min_k].first;
281
            int j = vpairs[min_k].second;
285
            int j = vpairs[min_k].second;
282
            FaceID f_new = m.split_face_by_edge(f, verts[i], verts[j]);
286
            FaceID f_new = m.split_face_by_edge(f, verts[i], verts[j]);
283
            if(no_edges(m, f)>5)
287
            if(no_edges(m, f)>5)
284
                face_queue.push(f);
288
                face_queue.push(f);
285
            if(no_edges(m, f_new)>5)
289
            if(no_edges(m, f_new)>5)
286
                face_queue.push(f_new);
290
                face_queue.push(f_new);
287
        }
291
        }
288
        
292
        
289
    }
293
    }
290
}
294
}
291
 
295
 
292
 
296
 
293
 
297
 
294
struct EdgeQElem {
298
struct EdgeQElem {
295
    float priority;
299
    float priority;
296
    HalfEdgeID he;
300
    HalfEdgeID he;
297
    EdgeQElem(float _priority, HalfEdgeID _he): priority(_priority), he(_he) {}
301
    EdgeQElem(float _priority, HalfEdgeID _he): priority(_priority), he(_he) {}
298
};
302
};
299
 
303
 
300
bool operator<(const EdgeQElem& l, const EdgeQElem& r)
304
bool operator<(const EdgeQElem& l, const EdgeQElem& r)
301
{
305
{
302
    return l.priority < r.priority;
306
    return l.priority < r.priority;
303
}
307
}
304
 
308
 
305
class FunctionalDifference: public EnergyFun
309
class FunctionalDifference: public EnergyFun
306
{
310
{
307
    VertexAttributeVector<float>& fun;
311
    VertexAttributeVector<float>& fun;
308
    VertexAttributeVector<int>& status;
312
    VertexAttributeVector<int>& status;
309
public:
313
public:
310
    FunctionalDifference(VertexAttributeVector<float>& _fun, VertexAttributeVector<int>& _status): fun(_fun), status(_status) {}
314
    FunctionalDifference(VertexAttributeVector<float>& _fun, VertexAttributeVector<int>& _status): fun(_fun), status(_status) {}
311
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
315
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
312
    {
316
    {
313
        Walker w = m.walker(h);
317
        Walker w = m.walker(h);
314
        if(status[w.vertex()] == 1 && status[w.opp().vertex()]==1)
318
        if(status[w.vertex()] == 1 && status[w.opp().vertex()]==1)
315
            return DBL_MAX;
319
            return DBL_MAX;
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()]));
320
        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()]));
317
    }
321
    }
318
};
322
};
319
 
323
 
320
class TriangleQualityValence: public EnergyFun
324
class TriangleQualityValence: public EnergyFun
321
{
325
{
322
    VertexAttributeVector<int>& idv;
326
    VertexAttributeVector<int>& idv;
323
    MinAngleEnergy mae;
327
    MinAngleEnergy mae;
324
    ValencyEnergy vae;
328
    ValencyEnergy vae;
325
public:
329
public:
326
    TriangleQualityValence(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
330
    TriangleQualityValence(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
327
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
331
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
328
    {
332
    {
329
        Walker w = m.walker(h);
333
        Walker w = m.walker(h);
330
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] ||
334
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] ||
331
           idv[w.vertex()] == idv[w.opp().vertex()])
335
           idv[w.vertex()] == idv[w.opp().vertex()])
332
            return DBL_MAX;
336
            return DBL_MAX;
333
        
337
        
334
        VertexID v1 = w.opp().vertex();
338
        VertexID v1 = w.opp().vertex();
335
        VertexID v2 = w.vertex();
339
        VertexID v2 = w.vertex();
336
        VertexID vo1 = w.next().vertex();
340
        VertexID vo1 = w.next().vertex();
337
        VertexID vo2 = w.opp().next().vertex();
341
        VertexID vo2 = w.opp().next().vertex();
338
        
342
        
339
        int val1  = valency(m, v1);
343
        int val1  = valency(m, v1);
340
        int val2  = valency(m, v2);
344
        int val2  = valency(m, v2);
341
        int valo1 = valency(m, vo1);
345
        int valo1 = valency(m, vo1);
342
        int valo2 = valency(m, vo2);
346
        int valo2 = valency(m, vo2);
343
        
347
        
344
        // The optimal valency is four for a boundary vertex
348
        // The optimal valency is four for a boundary vertex
345
        // and six elsewhere.
349
        // and six elsewhere.
346
        int t1 = boundary(m, v1) ? 4 : 6;
350
        int t1 = boundary(m, v1) ? 4 : 6;
347
        int t2 = boundary(m, v2) ? 4 : 6;
351
        int t2 = boundary(m, v2) ? 4 : 6;
348
        int to1 = boundary(m, vo1) ? 4 : 6;
352
        int to1 = boundary(m, vo1) ? 4 : 6;
349
        int to2 = boundary(m, vo2) ? 4 : 6;
353
        int to2 = boundary(m, vo2) ? 4 : 6;
350
        
354
        
351
        int before =
355
        int before =
352
        max(max(sqr(val1-t1),sqr(val2-t2)), max(sqr(valo1-to1), sqr(valo2-to2)));
356
        max(max(sqr(val1-t1),sqr(val2-t2)), max(sqr(valo1-to1), sqr(valo2-to2)));
353
        int after =
357
        int after =
354
        max(max(sqr(valo1+1-to1),sqr(val1-1-t1)), max(sqr(val2-1-t2),sqr(valo2+1-to2)));
358
        max(max(sqr(valo1+1-to1),sqr(val1-1-t1)), max(sqr(val2-1-t2),sqr(valo2+1-to2)));
355
        
359
        
356
        return static_cast<double>(after-before);
360
        return static_cast<double>(after-before);
357
        
361
        
358
        //        return vae.delta_energy(m,h);
362
        //        return vae.delta_energy(m,h);
359
        float la = length(m.pos(w.next().vertex())-m.pos(w.opp().next().vertex()));
363
        float la = length(m.pos(w.next().vertex())-m.pos(w.opp().next().vertex()));
360
        float lb = length(m.pos(w.vertex())-m.pos(w.opp().vertex()));
364
        float lb = length(m.pos(w.vertex())-m.pos(w.opp().vertex()));
361
        return la-lb;
365
        return la-lb;
362
        return mae.delta_energy(m,h);
366
        return mae.delta_energy(m,h);
363
    }
367
    }
364
};
368
};
365
 
369
 
366
class TriangleQuality: public EnergyFun
370
class TriangleQuality: public EnergyFun
367
{
371
{
368
    VertexAttributeVector<int>& idv;
372
    VertexAttributeVector<int>& idv;
369
    MinAngleEnergy mae;
373
    MinAngleEnergy mae;
370
    ValencyEnergy vae;
374
    ValencyEnergy vae;
371
public:
375
public:
372
    TriangleQuality(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
376
    TriangleQuality(VertexAttributeVector<int>& _idv): idv(_idv), mae(-1) {}
373
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
377
    virtual double delta_energy(const Manifold& m, HalfEdgeID h) const
374
    {
378
    {
375
        Walker w = m.walker(h);
379
        Walker w = m.walker(h);
376
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] ||
380
        if(idv[w.next().vertex()] == idv[w.opp().next().vertex()] ||
377
           idv[w.vertex()] == idv[w.opp().vertex()])
381
           idv[w.vertex()] == idv[w.opp().vertex()])
378
            return DBL_MAX;
382
            return DBL_MAX;
379
        return mae.delta_energy(m,h);
383
        return mae.delta_energy(m,h);
380
    }
384
    }
381
};
385
};
382
 
386
 
383
Vec3d grad(HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun, HMesh::FaceID f)
387
Vec3d grad(HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun, HMesh::FaceID f)
384
{
388
{
385
    if(no_edges(m,f) != 3)
389
    if(no_edges(m,f) != 3)
386
        return Vec3d(0.0);
390
        return Vec3d(0.0);
387
    
391
    
388
    
392
    
389
    Vec3d n = normal(m, f);
393
    Vec3d n = normal(m, f);
390
    
394
    
391
    Vec3d gsum(0.0);
395
    Vec3d gsum(0.0);
392
    for(Walker w = m.walker(f); !w.full_circle(); w = w.next())
396
    for(Walker w = m.walker(f); !w.full_circle(); w = w.next())
393
    {
397
    {
394
        VertexID avid = w.opp().vertex();
398
        VertexID avid = w.opp().vertex();
395
        VertexID bvid = w.vertex();
399
        VertexID bvid = w.vertex();
396
        VertexID cvid = w.next().vertex();
400
        VertexID cvid = w.next().vertex();
397
        Vec3d gdir = normalize(cross(n, m.pos(bvid) - m.pos(avid)));
401
        Vec3d gdir = normalize(cross(n, m.pos(bvid) - m.pos(avid)));
398
        double l = dot(m.pos(cvid)-m.pos(avid), gdir);
402
        double l = dot(m.pos(cvid)-m.pos(avid), gdir);
399
        gdir *= fun[cvid]/l;
403
        gdir *= fun[cvid]/l;
400
        gsum += gdir;
404
        gsum += gdir;
401
    }
405
    }
402
    return gsum;
406
    return gsum;
403
}
407
}
404
 
408
 
-
 
409
Vec2d extend_fun2(HMesh::Manifold& m, HMesh::HalfEdgeID h,
-
 
410
                  HMesh::VertexAttributeVector<double>& fun,
-
 
411
                  HMesh::VertexAttributeVector<Vec2d>& fun2)
-
 
412
{
-
 
413
    Walker w = m.walker(h);
-
 
414
    FaceID f = w.face();
-
 
415
    Vec3d a = m.pos(w.opp().vertex());
-
 
416
    Vec3d b = m.pos(w.vertex());
-
 
417
    Vec3d c = m.pos(w.next().vertex());
-
 
418
    Vec3d g = grad(m, fun, f);
-
 
419
    Vec3d n = normal(m, f);
-
 
420
    Vec3d N = normalize(cross(g, n));
-
 
421
    float dot_nba = dot(N,b-a);
-
 
422
    Vec2d cval;
-
 
423
    if(dot_nba > 1e-5)
-
 
424
    {
-
 
425
        float t = dot(N, c-a)/dot_nba;
-
 
426
        if(t>0 && t < 1) {
-
 
427
            Vec2d aval = fun2[w.opp().vertex()];
-
 
428
            Vec2d bval = fun2[w.vertex()];
-
 
429
            return (1-t)*aval + t*bval;
-
 
430
        }
-
 
431
    }
-
 
432
    return Vec2d(0);
-
 
433
}
-
 
434
 
-
 
435
 
405
double solve_for_orthogonal_gradients(HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
436
double solve_for_orthogonal_gradients(HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
406
                                     HalfEdgeID h, double beta, double gamma)
437
                                      HalfEdgeID h, double beta, double gamma)
407
{
438
{
408
    Vec3d n = normal(m, m.walker(h).face());
439
    Vec3d n = normal(m, m.walker(h).face());
409
    
440
    
410
    Vec3d uvw[3];
441
    Vec3d uvw[3];
411
    Vec3d abc;
442
    Vec3d abc;
412
    Walker w = m.walker(h);
443
    Walker w = m.walker(h);
413
    VertexID vid[] = {w.next().vertex(), w.opp().vertex(),w.vertex()};
444
    VertexID vid[] = {w.next().vertex(), w.opp().vertex(),w.vertex()};
414
 
445
    
415
    for(int i=0; !w.full_circle(); w = w.next(),++  i)
446
    for(int i=0; !w.full_circle(); w = w.next(),++  i)
416
    {
447
    {
417
        uvw[i] = normalize(cross(n, m.pos(vid[(i+1)%3]) - m.pos(vid[(i+2)%3])));
448
        uvw[i] = normalize(cross(n, m.pos(vid[(i+1)%3]) - m.pos(vid[(i+2)%3])));
418
        uvw[i] /= dot(m.pos(vid[i])-m.pos(vid[(i+1)%3]), uvw[i]);
449
        uvw[i] /= dot(m.pos(vid[i])-m.pos(vid[(i+1)%3]), uvw[i]);
419
        abc[i] = fun[vid[i]];
450
        abc[i] = fun[vid[i]];
420
    }
451
    }
421
    Vec3d A(dot(uvw[0],uvw[0]),dot(uvw[0],uvw[1]),dot(uvw[0],uvw[2]));
452
    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]));
453
    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]));
454
    Vec3d C(dot(uvw[2],uvw[0]),dot(uvw[2],uvw[1]),dot(uvw[2],uvw[2]));
424
    
455
    
425
    return - (beta * dot(B, abc) + gamma * dot(C, abc))/dot(A, abc);
456
    return - (beta * dot(B, abc) + gamma * dot(C, abc))/dot(A, abc);
426
}
457
}
427
 
458
 
428
 
459
 
429
void recompute_circle_param(Manifold& m, VertexID v, VertexAttributeVector<double>& fun, VertexAttributeVector<Vec2d>& circle_pos, double f_origin)
460
void recompute_circle_param(Manifold& m, VertexID v, VertexAttributeVector<double>& fun, VertexAttributeVector<Vec2d>& circle_pos, double f_origin)
430
{
461
{
431
    Vec2d c_new(0);
462
    Vec2d c_new(0);
432
    for(auto w = m.walker(v); !w.full_circle(); w = w.circulate_vertex_ccw())
463
    for(auto w = m.walker(v); !w.full_circle(); w = w.circulate_vertex_ccw())
433
    {
464
    {
434
        Walker w_base = w.next();
465
        Walker w_base = w.next();
435
        Vec2d X = circle_pos[w_base.opp().vertex()];
466
        Vec2d X = circle_pos[w_base.opp().vertex()];
436
        Vec2d Y(-X[1], X[0]);
467
        Vec2d Y(-X[1], X[0]);
437
        Vec2d vec = circle_pos[w_base.vertex()];
468
        Vec2d vec = circle_pos[w_base.vertex()];
438
        double angle = atan2(max(-1.0,min(1.0,dot(vec,Y))),
469
        double angle = atan2(max(-1.0,min(1.0,dot(vec,Y))),
439
                             max(-1.0,min(1.0,dot(vec,X))));
470
                             max(-1.0,min(1.0,dot(vec,X))));
440
        double new_angle = solve_for_orthogonal_gradients(m, fun, w_base.halfedge(), 0, angle);
471
        double new_angle = solve_for_orthogonal_gradients(m, fun, w_base.halfedge(), 0, angle);
441
        new_angle = max(-M_PI/4, min(M_PI/4,new_angle));
472
        new_angle = max(-M_PI/4, min(M_PI/4,new_angle));
442
        c_new += cos(new_angle)*X + sin(new_angle)*Y;
473
        c_new += cos(new_angle)*X + sin(new_angle)*Y;
443
    }
474
    }
444
    circle_pos[v] = normalize(c_new);
475
    circle_pos[v] = normalize(c_new);
445
}
476
}
446
 
477
 
-
 
478
template<typename T>
-
 
479
void orthogonal_trajectories(Manifold& m, VertexID v, VertexAttributeVector<double>& f, double min_length_fun,
-
 
480
                             VertexAttributeVector<T>& h_in, VertexAttributeVector<T>& h_out)
-
 
481
{
-
 
482
    h_out[v] = T(0);
-
 
483
 
-
 
484
    T num(0);
-
 
485
    double denom = 0.0001;
-
 
486
    for(Walker w = m.walker(v); !w.full_circle(); w = w.circulate_vertex_ccw())
-
 
487
    {
-
 
488
        double weight = area(m, w.face());
-
 
489
 
-
 
490
        Vec3d a = m.pos(v);
-
 
491
        Vec3d b = m.pos(w.vertex());
-
 
492
        Vec3d c = m.pos(w.next().vertex());
-
 
493
        
-
 
494
        
-
 
495
        Vec3d fvec(f[v],f[w.vertex()], f[w.next().vertex()]);
-
 
496
        if(sqr_length(fvec)>0)
-
 
497
            fvec.normalize();
-
 
498
        double f_a = fvec[0];
-
 
499
        double f_b = fvec[1];
-
 
500
        double f_c = fvec[2];
-
 
501
        
-
 
502
        T h_b = h_in[w.vertex()];
-
 
503
        T h_c = h_in[w.next().vertex()];
-
 
504
        
-
 
505
        Vec3d e_a = c-b;
-
 
506
        Vec3d e_b = a-c;
-
 
507
        Vec3d e_c = b-a;
-
 
508
        
-
 
509
        Vec3d N = normalize(cross(e_b,e_c)+cross(e_c,e_a)+cross(e_a,e_b));
-
 
510
        Vec3d g_a = cross(N, normalize(e_a));
-
 
511
        g_a /= dot(g_a, e_b);
-
 
512
 
-
 
513
        Vec3d g_b = cross(N, normalize(e_b));
-
 
514
        g_b /= dot(g_b, e_c);
-
 
515
 
-
 
516
        Vec3d g_c = cross(N, normalize(e_c));
-
 
517
        g_c /= dot(g_c, e_a);
-
 
518
        
-
 
519
        num -= weight * (h_b * (f_a*dot(g_a, g_b) + f_b*dot(g_b,g_b) + f_c*dot(g_b,g_c)) +
-
 
520
                         h_c * (f_a*dot(g_a, g_c) + f_b*dot(g_b,g_c) + f_c*dot(g_c, g_c)));
-
 
521
        denom += weight * (f_a * dot(g_a,g_a)+ f_b*dot(g_a,g_b) +f_c*dot(g_a, g_c));
-
 
522
 
-
 
523
    }
-
 
524
    h_out[v] = num / denom;
-
 
525
}
-
 
526
 
447
void polarize_mesh(Manifold& m, VertexAttributeVector<double>& fun, double vmin, double vmax, const int divisions, VertexAttributeVector<Vec2d>& parametrization)
527
void polarize_mesh(Manifold& m, VertexAttributeVector<double>& fun, double vmin, double vmax, const int divisions, VertexAttributeVector<Vec2d>& parametrization)
448
{
528
{
449
    vmax -= 0.01 * (vmax-vmin);
-
 
450
    float interval = (vmax-vmin)/divisions;
529
    double interval = (vmax-vmin)/(divisions+1);
451
    
530
    
452
    VertexAttributeVector<int> status(m.allocated_vertices(), 0);
531
    VertexAttributeVector<int> status(m.allocated_vertices(), 0);
453
    
532
    
454
    
533
    
455
    // ----------------------------------------
534
    // ----------------------------------------
456
    cout << "Tracing level set curves" << endl;
535
    cout << "Tracing level set curves" << endl;
457
    
536
    
458
    vector<HalfEdgeID> hidvec;
-
 
459
    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
-
 
460
    {
-
 
461
        Walker w = m.walker(*hid);
-
 
462
        if(fun[w.vertex()] > fun[w.opp().vertex()])
-
 
463
            hidvec.push_back(*hid);
-
 
464
    }
-
 
465
    
537
    
466
    for(size_t i = 0; i<hidvec.size(); ++i)
538
    for(int cut_no=1; cut_no<divisions+1;++cut_no)
467
    {
539
    {
468
        Walker w = m.walker(hidvec[i]);
-
 
469
        
-
 
470
        float b = (fun[w.vertex()]- vmin)/interval;
540
        double cut_val = vmin + cut_no * interval;
471
        float a = (fun[w.opp().vertex()] - vmin)/interval;
-
 
472
        float floor_b = floor(b);
-
 
473
        float floor_a = floor(a);
-
 
474
        
541
        
475
        Vec3d pb = m.pos(w.vertex());
542
        vector<HalfEdgeID> hidvec;
476
        for(int j=floor_b; j>floor_a; --j)
543
        for(HalfEdgeID hid : m.halfedges())
477
        {
544
        {
478
            float t = (j-a) / (b-a);
545
            Walker w = m.walker(hid);
-
 
546
            double bval = fun[w.vertex()];
-
 
547
            double aval = fun[w.opp().vertex()];
-
 
548
            if(aval<bval && aval <= cut_val && cut_val < bval)
-
 
549
            {
-
 
550
                double t = (cut_val-aval)/(bval-aval);
479
            Vec3d p = t * pb + (1.0-t) * m.pos(w.opp().vertex());
551
                Vec3d p = t*m.pos(w.vertex()) + (1.0-t)*m.pos(w.opp().vertex());
480
            VertexID v_new = m.split_edge(w.halfedge());
552
                VertexID vnew = m.split_edge(hid);
481
            w = w.prev();
553
                m.pos(vnew) = p;
482
            status[v_new] = 1;
554
                status[vnew] = 1;
483
            fun[v_new] = j * interval + vmin;
555
                fun[vnew] = cut_val;
484
            m.pos(v_new) = p;
556
            }
485
        }
557
        }
486
    }
-
 
487
    
-
 
488
    bool did_work;
-
 
489
    do
-
 
490
    {
-
 
491
        did_work = false;
-
 
492
        
558
        
493
        for(FaceIDIterator fid = m.faces_begin(); fid != m.faces_end(); ++fid)
559
        for(FaceID fid : m.faces())
494
            for(Walker w = m.walker(*fid);!w.full_circle(); w = w.next())
560
                for(Walker w = m.walker(fid);!w.full_circle(); w = w.next())
495
                if(status[w.vertex()] == 1 && !(status[w.next().vertex()]==1 && same_level(fun[w.vertex()],fun[w.next().vertex()]))
-
 
496
                   && !(status[w.prev().vertex()]==1 && same_level(fun[w.vertex()],fun[w.prev().vertex()])))
561
                    if(status[w.vertex()] == 1 && same_level(fun[w.vertex()],cut_val))
497
                {
-
 
498
                    Walker w0 = w;
-
 
499
                    w = w.next().next();
-
 
500
                    do
-
 
501
                    {
562
                    {
502
                        if(status[w.vertex()] == 1 && w.next().halfedge() != w0.halfedge() &&
563
                        Walker w0 = w;
503
                           same_level(fun[w0.vertex()],fun[w.vertex()]))
564
                        w = w.next().next();
-
 
565
                        do
504
                        {
566
                        {
-
 
567
                            if(status[w.vertex()] == 1 &&
-
 
568
                               w.next().halfedge() != w0.halfedge() &&
-
 
569
                               same_level(fun[w0.vertex()],cut_val))
-
 
570
                            {
505
                            m.split_face_by_edge(*fid, w0.vertex(), w.vertex());
571
                                m.split_face_by_edge(fid, w0.vertex(), w.vertex());
506
                            did_work = true;
572
                                break;
507
                            break;
573
                            }
-
 
574
                            w = w.next();
508
                        }
575
                        }
-
 
576
                        while(!w.full_circle());
509
                        w = w.next();
577
                        break;
510
                    }
578
                    }
511
                    while(!w.full_circle());
-
 
512
                    break;
-
 
513
                }
-
 
514
    }
579
    }
515
    while(did_work);
-
 
516
    
580
 
517
    shortest_edge_triangulate(m);
581
    shortest_edge_triangulate(m);
518
    
582
    
-
 
583
 
-
 
584
    
519
    // ----------------------------
585
    // ----------------------------
520
    cout << "Numbering the level sets" << endl;
586
    cout << "Numbering the level sets" << endl;
521
    VertexAttributeVector<int> nailed(m.no_vertices(),0);
-
 
522
    vector<LevelSetInfo> level_set_info;
587
    vector<LevelSetInfo> level_set_info;
523
    HalfEdgeAttributeVector<int> level_set_id(m.allocated_halfedges(), -1);
588
    HalfEdgeAttributeVector<int> level_set_id(m.allocated_halfedges(), -1);
524
    VertexAttributeVector<int> level_set_id_vertex(m.allocated_vertices(), -1);
589
    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);
-
 
528
    int no_id=0;
590
    int no_id=0;
529
    for(HalfEdgeIDIterator hid = m.halfedges_begin(); hid != m.halfedges_end(); ++hid)
591
    for(HalfEdgeID hid : m.halfedges())
530
    {
592
    {
531
        Walker w = m.walker(*hid);
593
        Walker w = m.walker(hid);
532
        if(status[w.vertex()] == 1 && status[w.opp().vertex()] == 1 &&
594
        if(status[w.vertex()] == 1 && status[w.opp().vertex()] == 1 &&
533
           same_level(fun[w.vertex()], fun[w.opp().vertex()]) &&
595
           same_level(fun[w.vertex()], fun[w.opp().vertex()]) &&
534
           level_set_id[w.halfedge()] == -1)
596
           level_set_id[w.halfedge()] == -1)
535
        {
597
        {
536
            LevelSetInfo lsi;
598
            LevelSetInfo lsi;
537
            lsi.id = no_id;
599
            lsi.id = no_id;
538
            lsi.fun_value = fun[w.vertex()];
600
            lsi.fun_value = fun[w.vertex()];
539
            lsi.components = 1;
601
            lsi.components = 1;
540
            lsi.no_vertices = 0;
602
            lsi.no_vertices = 0;
541
            float level_set_length = 0;
603
            double level_set_length = 0;
542
            while(level_set_id[w.halfedge()] != no_id)
604
            while(level_set_id[w.halfedge()] != no_id)
543
            {
605
            {
544
                level_set_length += length(m,w.halfedge());
606
                level_set_length += length(m,w.halfedge());
545
                level_set_id[w.halfedge()] = no_id;
607
                level_set_id[w.halfedge()] = no_id;
546
                level_set_id[w.opp().halfedge()] = no_id;
608
                level_set_id[w.opp().halfedge()] = no_id;
547
                level_set_id_vertex[w.vertex()] = no_id;
609
                level_set_id_vertex[w.vertex()] = no_id;
548
                w = w.next();
610
                w = w.next();
549
                while(status[w.vertex()] != 1 || !same_level(fun[w.vertex()], fun[w.opp().vertex()]))
611
                while(!(status[w.vertex()] == 1 && same_level(fun[w.vertex()], fun[w.opp().vertex()])))
550
                    w = w.circulate_vertex_cw();
612
                    w = w.circulate_vertex_cw();
551
                lsi.no_vertices += 1;
613
                lsi.no_vertices += 1;
552
                
-
 
553
            }
614
            }
554
            lsi.h = w.halfedge();
615
            lsi.h = w.halfedge();
555
            lsi.length = level_set_length;
616
            lsi.length = level_set_length;
556
            double param = 0;
-
 
557
 
-
 
558
            do
-
 
559
            {
-
 
560
                double angle = 2.0 * M_PI * param / lsi.length;
-
 
561
                circle_pos[w.opp().vertex()] = Vec2d(cos(angle), sin(angle));
-
 
562
                nailed[w.opp().vertex()] = 1;
-
 
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()]))
-
 
566
                    w = w.circulate_vertex_cw();
-
 
567
            }
-
 
568
            while(w.halfedge() != lsi.h);
-
 
569
            level_set_info.push_back(lsi);
617
            level_set_info.push_back(lsi);
570
            level_set_info.back().print();
618
            level_set_info.back().print();
571
            ++no_id;
619
            ++no_id;
572
            assert(level_set_info.size()==no_id);
620
            assert(level_set_info.size()==no_id);
573
        }
621
        }
574
    }
622
    }
575
    
623
    
576
    cout << "ids" << no_id << " " << level_set_info.size() << endl;
624
    cout << "ids" << no_id << " " << level_set_info.size() << endl;
577
    for(int i=0;i<level_set_info.size(); ++i)
625
    for(int i=0;i<level_set_info.size(); ++i)
578
        for(int j=0;j<level_set_info.size(); ++j)
626
        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))
627
            if(i != j && same_level(level_set_info[i].fun_value, level_set_info[j].fun_value))
580
                level_set_info[i].components += 1;
628
                level_set_info[i].components += 1;
581
    
629
    
582
    HalfEdgeID min_length_h;
630
    HalfEdgeID min_length_h;
583
    double min_length_fun;
631
    double min_length_fun;
584
    double min_length=FLT_MAX;
632
    double min_length=FLT_MAX;
585
    int min_length_id = -1;
633
    int min_length_id = -1;
586
    for(int i=0;i<level_set_info.size(); ++i)
634
    for(int i=0;i<level_set_info.size(); ++i)
587
    {
635
    {
588
        LevelSetInfo& lsi = level_set_info[i];
636
        LevelSetInfo& lsi = level_set_info[i];
589
        if(lsi.components==1 && lsi.length<min_length)
637
        if(lsi.components==1 && lsi.length<min_length)
590
        {
638
        {
591
            min_length_h = lsi.h;
639
            min_length_h = lsi.h;
592
            min_length_fun = lsi.fun_value;
640
            min_length_fun = lsi.fun_value;
593
            min_length = lsi.length;
641
            min_length = lsi.length;
594
            min_length_id = lsi.id;
642
            min_length_id = lsi.id;
-
 
643
            
595
        }
644
        }
596
    }
645
    }
597
    
646
    
598
    smooth_fun(m, nailed, fun);
-
 
599
    
-
 
600
    FaceAttributeVector<int> segmentation;
-
 
601
    vector<vector<int>> boundaries;
-
 
602
    segment_manifold(m, level_set_id, segmentation, boundaries);
-
 
603
    
-
 
604
    VertexAttributeVector<Vec3d> cylinder_pos;
-
 
605
    for(auto vid = m.vertices_begin();vid != m.vertices_end(); ++vid)
-
 
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);    
-
 
608
        else
-
 
609
            cylinder_pos[*vid] = Vec3d(0,0,fun[*vid]);
-
 
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)
-
 
614
    {
-
 
615
        if(boundaries[segmentation[*fid]].size() == 1)
-
 
616
            included[*fid] = 0;
-
 
617
    }
-
 
618
    compute_edge_weights(m,edge_weights,included);
-
 
619
    VertexAttributeVector<Vec3d> new_cylinder_pos(m.no_vertices());
-
 
620
    for(int i = 0; i < 1500; ++i)
-
 
621
    {
-
 
622
        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
-
 
623
            if(!nailed[*v])//level_set_id_vertex[*v] != min_length_id)
-
 
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
                {
-
 
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) {
-
 
639
                    new_cylinder_pos[*v][0] /= l;
-
 
640
                    new_cylinder_pos[*v][1] /= l;
-
 
641
                }
-
 
642
                if(level_set_id_vertex[*v] != -1)
-
 
643
                    new_cylinder_pos[*v][2] = fun[*v];
-
 
644
            }
-
 
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];
-
 
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
//    }
-
 
719
    
-
 
720
    
-
 
721
    // ----------------------------
647
    // ----------------------------
722
    cout << "Remove vertices not on level set curves" << endl;
648
    cout << "Remove vertices not on level set curves" << endl;
723
    
649
    
724
    vector<VertexID> vid_vec;
-
 
725
    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
-
 
726
        if(status[*vid]==0)
-
 
727
            vid_vec.push_back(*vid);
-
 
728
    
-
 
729
    random_shuffle(vid_vec.begin(), vid_vec.end());
-
 
730
    for (size_t i=0; i<vid_vec.size(); ++i) {
-
 
731
        FaceID f = m.merge_one_ring(vid_vec[i]);
-
 
732
        if(f != InvalidFaceID)
-
 
733
            shortest_edge_triangulate_face(m, f, level_set_id_vertex);
-
 
734
        else
-
 
735
            cout << "vertex not removed " << valency(m, vid_vec[i]) << endl;
-
 
736
    }
-
 
737
    
-
 
738
    for(FaceIDIterator fid = m.faces_begin(); fid != m.faces_end(); ++fid)
-
 
739
        if(no_edges(m, *fid) > 3)
-
 
740
            shortest_edge_triangulate_face(m, *fid, level_set_id_vertex);
-
 
741
    
-
 
742
    
-
 
743
//    VertexAttributeVector<Vec3d> recalled_positions;
-
 
744
//    for(VertexIDIterator vid = m.vertices_begin(); vid != m.vertices_end(); ++vid)
-
 
745
//        recalled_positions[*vid] = m.pos(*vid);
-
 
746
//    
-
 
747
//    
-
 
748
    TriangleQuality tq_energy(level_set_id_vertex);
-
 
749
    priority_queue_optimization(m, tq_energy);
-
 
750
    
-
 
751
    
-
 
752
    
650
    
753
}
651
}
754
 
652
 
755
void make_height_fun(const HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
653
void make_height_fun(const HMesh::Manifold& m, HMesh::VertexAttributeVector<double>& fun,
756
                     double& vmin, double& vmax)
654
                     double& vmin, double& vmax)
757
{
655
{
758
    VertexIDIterator vid = m.vertices_begin();
656
    VertexIDIterator vid = m.vertices_begin();
759
    vmin = vmax = m.pos(*vid)[2];
657
    vmin = vmax = m.pos(*vid)[1];
760
    for(; vid != m.vertices_end(); ++vid)
658
    for(; vid != m.vertices_end(); ++vid)
761
    {
659
    {
762
        double v = dot(m.pos(*vid),Vec3d(0.0,1,0.00));
660
        double v = dot(m.pos(*vid),Vec3d(0.0,1,0.00));
763
        fun[*vid] = v;
661
        fun[*vid] = v;
764
        vmin = min(v, vmin);
662
        vmin = min(v, vmin);
765
        vmax = max(v, vmax);
663
        vmax = max(v, vmax);
766
    }
664
    }
767
}
665
}
-
 
666
 
768
 
667