Subversion Repositories gelsvn

Rev

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

Rev 519 Rev 543
Line 1... Line 1...
1
/* ----------------------------------------------------------------------- *
1
/* ----------------------------------------------------------------------- *
2
* This file is part of GEL, www.imm.dtu.dk/GEL
2
 * This file is part of GEL, www.imm.dtu.dk/GEL
3
* Copyright (C) the authors (see AUTHORS.txt) and DTU Informatics
3
 * Copyright (C) the authors (see AUTHORS.txt) and DTU Informatics
4
*
4
 *
5
* Principal authors:
5
 * Principal authors:
6
*  Christian Thode Larsen (thode2d@gmail.com)
6
 *  Christian Thode Larsen (thode2d@gmail.com)
7
*  J. Andreas Baerentzen (jab@imm.dtu.dk)
7
 *  J. Andreas Baerentzen (jab@imm.dtu.dk)
8
*
8
 *
9
* See LICENSE.txt for licensing information
9
 * See LICENSE.txt for licensing information
10
* ----------------------------------------------------------------------- */
10
 * ----------------------------------------------------------------------- */
11
 
11
 
12
#include "flatten.h"
12
#include "flatten.h"
13
 
13
 
14
#include <string>
14
#include <string>
15
#include <fstream>
15
#include <fstream>
16
#include <vector>
16
#include <vector>
17
#include <CGLA/Vec3f.h>
17
#include <CGLA/Vec3d.h>
18
 
18
 
19
#include "Manifold.h"
19
#include "Manifold.h"
20
#include "AttributeVector.h"
20
#include "AttributeVector.h"
21
 
21
 
22
namespace HMesh
22
namespace HMesh
23
{
23
{
24
    using namespace std;
24
    using namespace std;
25
    using namespace CGLA;
25
    using namespace CGLA;
26
 
26
	
27
    void flatten(Manifold& m, WeightScheme ws)
27
    void flatten(Manifold& m, WeightScheme ws)
28
    {
28
    {
29
        HalfEdgeAttributeVector<float> edge_weights(m.total_halfedges(), 0);
29
        HalfEdgeAttributeVector<double> edge_weights(m.total_halfedges(), 0);
30
        for(HalfEdgeIDIterator h = m.halfedges_begin(); h != m.halfedges_end(); ++h){      
30
		for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f)
31
            if(boundary(m, *h))
-
 
32
                continue;
-
 
33
 
31
		{
34
            HalfEdgeWalker wv = m.halfedgewalker(*h);
32
			for(HalfEdgeWalker wv = m.halfedgewalker(*f); !wv.full_circle(); wv = wv.circulate_face_ccw())
-
 
33
			{
35
            Vec3f p0 = m.pos(wv.vertex());
34
				HalfEdgeID h = wv.halfedge();
36
            Vec3f p1 = m.pos(wv.next().vertex());
35
				Vec3d p1(m.pos(wv.vertex()));
37
            Vec3f p2 = m.pos(wv.opp().vertex());
36
				Vec3d p2(m.pos(wv.next().vertex()));
38
            Vec3f p3 = m.pos(wv.opp().next().vertex());
37
				Vec3d p0(m.pos(wv.opp().vertex()));
39
 
38
				
40
            if(ws == FLOATER_W){
39
				if(ws == FLOATER_W){
41
                float d = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p0), normalize(p3-p0)))));
40
					double ang = acos(min(1.0, max(-1.0, dot(normalize(p1-p0), normalize(p2-p0)))));
42
                float g = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p0), normalize(p1-p0)))));
41
					double ang_opp = acos(min(1.0, max(-1.0, dot(normalize(p2-p1), normalize(p0-p1)))));
43
                edge_weights[wv.opp().halfedge()]  = (tan(d/2) + tan(g/2)) / (p0-p2).length();
42
					double l = (p1-p0).length();
44
 
-
 
45
 
-
 
46
                d = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p2), normalize(p1-p2)))));
-
 
47
                g = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p2), normalize(p3-p2)))));
43
					edge_weights[h]  += tan(ang/2) / l;
48
                edge_weights[*h]  = (tan(d/2) + tan(g/2)) / (p0-p2).length();
44
					edge_weights[wv.opp().halfedge()]  += tan(ang_opp/2) / l;
49
            }
45
				}
50
            else if(ws == HARMONIC_W){
46
				else if(ws == HARMONIC_W || ws == LSCM_W){
51
                float a = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p3), normalize(p2-p3)))));
47
					double a = acos(min(1.0, max(-1.0, dot(normalize(p0-p2), normalize(p1-p2)))));
52
                float b = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p1), normalize(p0-p1)))));
-
 
53
                float w=0;
-
 
54
                if(a+b < M_PI)
-
 
55
                    w = sin(a+b)/(sin(a)+sin(b));
48
					double w = max(0.0001,0.5/tan(a));
56
                edge_weights[*h]  = w;
49
					edge_weights[h]  += w;
57
                edge_weights[wv.opp().halfedge()]  = w;
50
					edge_weights[wv.opp().halfedge()]  += w;
58
            }
51
				}
59
            else{
52
				else{
60
                edge_weights[*h]  = valency(m, wv.opp().vertex());
53
					edge_weights[h]  = valency(m, wv.opp().vertex());
61
                edge_weights[wv.opp().halfedge()]  = valency(m, wv.vertex());
54
					edge_weights[wv.opp().halfedge()]  = valency(m, wv.vertex());
62
            }	
55
				}
63
        }
56
			}
-
 
57
			
-
 
58
		}
-
 
59
		
64
 
60
		
65
        ofstream ofs("parametrized.obj");
61
        ofstream ofs("parametrized.obj");
66
 
62
		
67
        ofs << "mtllib parametrized.mtl\nusemtl mat\n" << endl;
63
        ofs << "mtllib parametrized.mtl\nusemtl mat\n" << endl;
68
 
64
		
69
        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
65
        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
70
            ofs << "v " << m.pos(*v)[0] << " " << m.pos(*v)[1] << " " << m.pos(*v)[2] << endl;
66
            ofs << "v " << m.pos(*v)[0] << " " << m.pos(*v)[1] << " " << m.pos(*v)[2] << endl;
71
        ofs << endl;
67
        ofs << endl;
72
 
68
		
-
 
69
		VertexAttributeVector<double> touched(m.total_vertices(), 0);
73
        VertexIDIterator v = m.vertices_begin();
70
        VertexIDIterator v = m.vertices_begin();
74
        for(; v != m.vertices_end(); ++v){
71
        for(; v != m.vertices_end(); ++v){
75
            if(boundary(m, *v))
72
            if(boundary(m, *v))
76
                break;
73
                break;
77
        }
74
        }
Line 80... Line 77...
80
        do{
77
        do{
81
            ++n;
78
            ++n;
82
            bv = bv.next();
79
            bv = bv.next();
83
        }
80
        }
84
        while(bv.vertex() != *v);
81
        while(bv.vertex() != *v);
85
 
82
		
86
        int i = 0;
83
        int i = 0;
87
        do{
84
        do{
-
 
85
			if(i==int(n*0.25) || i==int(n*0.75))
-
 
86
				touched[bv.vertex()]=1;
88
            float a = 2.0*M_PI*float(i)/n;
87
            double a = 2.0*M_PI*double(i)/n;
89
            m.pos(bv.vertex()) = Vec3f(cos(a), sin(a), 0);
88
            m.pos(bv.vertex()) = Vec3f(cos(a), sin(a), 0);
90
            ++i;
89
            ++i;
91
            bv = bv.next();
90
            bv = bv.next();
92
        }
91
        }
93
        while(bv.vertex() != *v);
92
        while(bv.vertex() != *v);
94
 
93
		
95
        for(v = m.vertices_begin(); v != m.vertices_end(); ++v)
94
        for(v = m.vertices_begin(); v != m.vertices_end(); ++v)
96
            if(!boundary(m, *v))
95
            if(!boundary(m, *v))
97
                m.pos(*v) = Vec3f(0.0);
96
                m.pos(*v) = Vec3f(0.0);
98
 
97
		
99
        for(int i = 0; i < 10000; ++i){
98
        for(int i = 0; i < 10000; ++i){
100
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v){
99
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v){
101
                if(!boundary(m, *v)){
100
				if(boundary(m, *v))
-
 
101
				{
-
 
102
					if(ws == LSCM_W && touched[*v] != 1)
-
 
103
					{
102
                    Vec3f p_new(0);
104
						Vec3d p_new(0);
103
                    float w_sum = 0;
105
						double w_sum = 0;
-
 
106
						Vec3d grad_sum(0.0);
-
 
107
						HalfEdgeWalker wv = m.halfedgewalker(*v);
-
 
108
						int steps=0;
104
                    for(HalfEdgeWalker wv = m.halfedgewalker(*v); !wv.full_circle(); wv = wv.circulate_vertex_cw()){
109
						for(;!wv.full_circle(); wv = wv.circulate_vertex_cw())
-
 
110
							if(wv.face() != InvalidFaceID)
-
 
111
							{
-
 
112
								Vec3d p1(m.pos(wv.next().vertex()));
-
 
113
								Vec3d p0(m.pos(wv.vertex()));
-
 
114
								Vec3d area_grad = 0.5*(p1 - p0); 
-
 
115
								grad_sum[0] += -area_grad[1];
-
 
116
								grad_sum[1] += area_grad[0];
105
                        float w = edge_weights[wv.halfedge()];
117
								double w = edge_weights[wv.halfedge()];
106
                        p_new += m.pos(wv.vertex()) * w;
118
								p_new += Vec3d(m.pos(wv.vertex()) * w);
107
                        w_sum += w;
119
								w_sum += w;
-
 
120
								++steps;
-
 
121
							}
-
 
122
						m.pos(*v) = m.pos(*v)*.5 + .5*Vec3f((grad_sum + p_new)/w_sum);	
-
 
123
					}
-
 
124
				}
-
 
125
				else
-
 
126
				{
-
 
127
					Vec3d p_new(0);
108
                    }
128
					double w_sum = 0;
-
 
129
					for(HalfEdgeWalker wv = m.halfedgewalker(*v); !wv.full_circle(); wv = wv.circulate_vertex_cw()) 
-
 
130
					{
-
 
131
						double w = edge_weights[wv.halfedge()];
-
 
132
						p_new += Vec3d(m.pos(wv.vertex()) * w);
-
 
133
						w_sum += w;
-
 
134
					}
109
                    m.pos(*v) = p_new/w_sum;
135
                    m.pos(*v) = m.pos(*v)*.5 + .5*Vec3f(p_new/w_sum);
110
                }
136
                }
111
            }
137
            }
112
        }
138
        }
113
 
139
		
114
        VertexAttributeVector<int> vtouched(m.total_vertices(), 0);
140
        VertexAttributeVector<int> vtouched(m.total_vertices(), 0);
115
        i = 0;
141
        i = 0;
116
        for(v = m.vertices_begin(); v != m.vertices_end(); ++v, ++i){
142
        for(v = m.vertices_begin(); v != m.vertices_end(); ++v, ++i){
117
            ofs << "vt " << (0.5*m.pos(*v)[0]+0.5) << " " << (0.5*m.pos(*v)[1]+0.5)  << endl;
143
            ofs << "vt " << (0.5*m.pos(*v)[0]+0.5) << " " << (0.5*m.pos(*v)[1]+0.5)  << endl;
118
            vtouched[*v] = i;
144
            vtouched[*v] = i;
119
        }
145
        }
120
 
146
		
121
        ofs << endl;
147
        ofs << endl;
122
 
148
		
123
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
149
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
124
            ofs << "f ";
150
            ofs << "f ";
125
            for(HalfEdgeWalker w = m.halfedgewalker(*f); !w.full_circle(); w = w.circulate_face_cw()){
151
            for(HalfEdgeWalker w = m.halfedgewalker(*f); !w.full_circle(); w = w.circulate_face_cw()){
126
                int idx = vtouched[w.vertex()] + 1;
152
                int idx = vtouched[w.vertex()] + 1;
127
                ofs << idx << "/" << idx <<" ";
153
                ofs << idx << "/" << idx <<" ";
128
            }
154
            }
129
            ofs << endl;
155
            ofs << endl;
130
        }
156
        }
131
 
157
		
132
    }
158
    }
133
}
159
}
134
 
160