Subversion Repositories gelsvn

Rev

Rev 543 | Rev 572 | Go to most recent revision | Details | Compare with Previous | 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)))));
566 jab 48
					double w = max(0.0000001,0.5/tan(a));
543 jab 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
 
566 jab 98
        VertexAttributeVector<Vec3f> new_pos(m.active_vertices());
518 s042372 99
        for(int i = 0; i < 10000; ++i){
100
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v){
543 jab 101
				if(boundary(m, *v))
102
				{
103
					if(ws == LSCM_W && touched[*v] != 1)
104
					{
105
						Vec3d p_new(0);
106
						double w_sum = 0;
107
						Vec3d grad_sum(0.0);
108
						HalfEdgeWalker wv = m.halfedgewalker(*v);
566 jab 109
						for(;!wv.full_circle(); wv = wv.circulate_vertex_ccw())
110
                        {
543 jab 111
							if(wv.face() != InvalidFaceID)
112
							{
113
								Vec3d p1(m.pos(wv.next().vertex()));
114
								Vec3d p0(m.pos(wv.vertex()));
115
								Vec3d area_grad = 0.5*(p1 - p0); 
116
								grad_sum[0] += -area_grad[1];
117
								grad_sum[1] += area_grad[0];
118
							}
566 jab 119
                            double w = edge_weights[wv.halfedge()];
120
                            p_new += Vec3d(m.pos(wv.vertex()) * w);
121
                            w_sum += w;                            
122
                        }
123
						new_pos[*v] = (Vec3f(p_new) - Vec3f(grad_sum))/w_sum;	
543 jab 124
					}
566 jab 125
                    else
126
                        new_pos[*v] = m.pos(*v);
543 jab 127
				}
128
				else
129
				{
130
					Vec3d p_new(0);
131
					double w_sum = 0;
566 jab 132
					for(HalfEdgeWalker wv = m.halfedgewalker(*v); !wv.full_circle(); wv = wv.circulate_vertex_ccw()) 
543 jab 133
					{
134
						double w = edge_weights[wv.halfedge()];
135
						p_new += Vec3d(m.pos(wv.vertex()) * w);
136
						w_sum += w;
137
					}
566 jab 138
                    new_pos[*v] = Vec3f(p_new/w_sum);
518 s042372 139
                }
140
            }
566 jab 141
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v)
142
                m.pos(*v) = new_pos[*v];
518 s042372 143
        }
543 jab 144
 
519 s042372 145
        VertexAttributeVector<int> vtouched(m.total_vertices(), 0);
518 s042372 146
        i = 0;
147
        for(v = m.vertices_begin(); v != m.vertices_end(); ++v, ++i){
148
            ofs << "vt " << (0.5*m.pos(*v)[0]+0.5) << " " << (0.5*m.pos(*v)[1]+0.5)  << endl;
149
            vtouched[*v] = i;
150
        }
543 jab 151
 
518 s042372 152
        ofs << endl;
543 jab 153
 
518 s042372 154
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
155
            ofs << "f ";
156
            for(HalfEdgeWalker w = m.halfedgewalker(*f); !w.full_circle(); w = w.circulate_face_cw()){
157
                int idx = vtouched[w.vertex()] + 1;
158
                ofs << idx << "/" << idx <<" ";
159
            }
160
            ofs << endl;
161
        }
543 jab 162
 
514 s042372 163
    }
164
}