Subversion Repositories gelsvn

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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