Subversion Repositories gelsvn

Rev

Rev 632 | Rev 635 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 632 Rev 633
Line 20... Line 20...
20
namespace HMesh
20
namespace HMesh
21
{
21
{
22
    using namespace std;
22
    using namespace std;
23
    using namespace CGLA;
23
    using namespace CGLA;
24
    
24
    
-
 
25
    
-
 
26
    class range {
-
 
27
    public:
-
 
28
        class iterator {
-
 
29
            friend class range;
-
 
30
        public:
-
 
31
            long int operator *() const { return i_; }
-
 
32
            const iterator &operator ++() { ++i_; return *this; }
-
 
33
            iterator operator ++(int) { iterator copy(*this); ++i_; return copy; }
-
 
34
            
-
 
35
            bool operator ==(const iterator &other) const { return i_ == other.i_; }
-
 
36
            bool operator !=(const iterator &other) const { return i_ != other.i_; }
-
 
37
            
-
 
38
        protected:
-
 
39
            iterator(long int start) : i_ (start) { }
-
 
40
            
-
 
41
        private:
-
 
42
            unsigned long i_;
-
 
43
        };
-
 
44
        
-
 
45
        iterator begin() const { return begin_; }
-
 
46
        iterator end() const { return end_; }
-
 
47
        range(long int  begin, long int end) : begin_(begin), end_(end) {}
-
 
48
    private:
-
 
49
        iterator begin_;
-
 
50
        iterator end_;
-
 
51
    };
-
 
52
 
25
 
53
 
26
 
54
 
27
    
55
    
28
    void for_each_vertex(Manifold& m, function<void(VertexID)> f) { for(auto v : m.vertices()) f(v); }
56
    void for_each_vertex(Manifold& m, function<void(VertexID)> f) { for(auto v : m.vertices()) f(v); }
29
    void for_each_face(Manifold& m, function<void(FaceID)> f) { for(auto p : m.faces()) f(p); }
57
    void for_each_face(Manifold& m, function<void(FaceID)> f) { for(auto p : m.faces()) f(p); }
30
    void for_each_halfedge(Manifold& m, function<void(HalfEdgeID)> f) { for(auto h : m.halfedges()) f(h); }
58
    void for_each_halfedge(Manifold& m, function<void(HalfEdgeID)> f) { for(auto h : m.halfedges()) f(h); }
31
 
59
 
32
    
60
    
33
    Vec3d laplacian(const Manifold& m, VertexID v)
61
    inline Vec3d laplacian(const Manifold& m, VertexID v)
34
    {
62
    {
35
        Vec3d avg_pos(0);
63
        Vec3d p(0);
36
        int n = 0;
-
 
37
        
-
 
38
        circulate_vertex_ccw(m, v, [&](VertexID v){
64
        int n = circulate_vertex_ccw(m, v, [&](VertexID v){ p += m.pos(v); });
39
            avg_pos += m.pos(v);
-
 
40
            ++n;
-
 
41
        });
-
 
42
        return avg_pos / n - m.pos(v);
65
        return p / n - m.pos(v);
43
    }
66
    }
44
    
67
    
45
    
68
    
46
    int CORES = 8;
69
    int CORES = 8;
47
    
70
    
Line 137... Line 160...
137
        }
160
        }
138
    }
161
    }
139
    
162
    
140
    
163
    
141
    
164
    
142
    inline void laplacian_smooth_vertex(Manifold& m,vector<VertexID>& vids,
165
    inline void laplacian_smooth_vertex(Manifold& m, const vector<VertexID>& vids,
143
                                        VertexAttributeVector<Vec3d>& new_pos,
166
                                        VertexAttributeVector<Vec3d>& new_pos,
144
                                        float weight){
167
                                        float weight){
145
        for(VertexID v: vids)
168
        for(VertexID v: vids)
146
            new_pos[v] = m.pos(v)+weight*laplacian(m, v);
169
            new_pos[v] = m.pos(v)+weight*laplacian(m, v);
147
    }
170
    }
148
    
171
    
-
 
172
    
149
    void laplacian_smooth6(Manifold& m, float weight, int max_iter)
173
    void laplacian_smooth6(Manifold& m, float weight, int max_iter)
150
    {
174
    {
151
        vector<vector<VertexID>> vertex_ids(CORES);
175
        vector<vector<VertexID>> vertex_ids(CORES);
152
        auto batch_size = m.no_vertices()/CORES;
176
        auto batch_size = m.no_vertices()/CORES;
153
        int cnt = 0;
177
        int cnt = 0;
Line 167... Line 191...
167
            swap(m.positions_attribute_vector(), new_pos);
191
            swap(m.positions_attribute_vector(), new_pos);
168
        }
192
        }
169
        
193
        
170
    }
194
    }
171
    
195
    
-
 
196
    typedef vector<vector<VertexID>> VertexIDBatches;
-
 
197
    
-
 
198
    template<typename  T>
-
 
199
    void for_each_vertex_parallel(int no_threads, const VertexIDBatches& batches, const T& f) {
-
 
200
        vector<thread> t_vec(no_threads);
-
 
201
        for(auto t : range(0, no_threads))
-
 
202
            t_vec[t] = thread(f, ref(batches[t]));
-
 
203
        for(auto t : range(0, no_threads))
-
 
204
            t_vec[t].join();
-
 
205
    }
-
 
206
    
-
 
207
    VertexIDBatches batch_vertices(Manifold& m) {
-
 
208
        VertexIDBatches vertex_ids(CORES);
-
 
209
        auto batch_size = m.no_vertices()/CORES;
-
 
210
        int cnt = 0;
-
 
211
        for_each_vertex(m, [&](VertexID v) {
-
 
212
            if (!boundary(m, v))
-
 
213
                vertex_ids[(cnt++/batch_size)%CORES].push_back(v);
-
 
214
        });
-
 
215
        return vertex_ids;
-
 
216
    }
-
 
217
 
-
 
218
    void laplacian_smooth7(Manifold& m, float weight, int max_iter)
-
 
219
    {
-
 
220
        auto vertex_ids = batch_vertices(m);
-
 
221
        auto new_pos = m.positions_attribute_vector();
-
 
222
        auto f = [&](const vector<VertexID>& vids) {
-
 
223
            for(VertexID v: vids)
-
 
224
                new_pos[v] = m.pos(v)+weight*laplacian(m, v);
-
 
225
        };
-
 
226
 
-
 
227
        for(auto _ : range(0, max_iter)) {
-
 
228
            for_each_vertex_parallel(CORES, vertex_ids, f);
-
 
229
            swap(m.positions_attribute_vector(), new_pos);
-
 
230
        }
-
 
231
    }
-
 
232
 
-
 
233
 
-
 
234
 
-
 
235
 
172
    void laplacian_smooth(Manifold& m,float weight, int max_iter)
236
    void laplacian_smooth(Manifold& m,float weight, int max_iter)
173
    {
237
    {
174
        laplacian_smooth4(m,weight,max_iter);
238
        laplacian_smooth6(m,weight,max_iter);
175
//        Util::Timer tim;
239
//        Util::Timer tim;
176
//
240
//
177
//        cout << "Method 0: ";
241
//        cout << "Method 0: ";
178
//        for(int i=0;i<5;++i) {
242
//        for(int i=0;i<5;++i) {
179
//            Manifold m2 = m;
243
//            Manifold m2 = m;