Subversion Repositories gelsvn

Rev

Details | Last modification | View Log | RSS feed

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