Subversion Repositories gelsvn

Rev

Rev 587 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
514 s042372 1
/* ----------------------------------------------------------------------- *
572 jab 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
543 jab 5
 * ----------------------------------------------------------------------- */
514 s042372 6
 
7
#include "flatten.h"
8
 
9
#include <string>
10
#include <fstream>
11
#include <vector>
543 jab 12
#include <CGLA/Vec3d.h>
514 s042372 13
 
14
#include "Manifold.h"
15
#include "AttributeVector.h"
16
 
17
namespace HMesh
18
{
19
    using namespace std;
20
    using namespace CGLA;
543 jab 21
 
514 s042372 22
    void flatten(Manifold& m, WeightScheme ws)
23
    {
586 jab 24
        HalfEdgeAttributeVector<double> edge_weights(m.allocated_halfedges(), 0);
543 jab 25
		for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f)
26
		{
587 jab 27
			for(Walker wv = m.walker(*f); !wv.full_circle(); wv = wv.circulate_face_ccw())
543 jab 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)))));
566 jab 43
					double w = max(0.0000001,0.5/tan(a));
543 jab 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
 
518 s042372 56
        ofstream ofs("parametrized.obj");
543 jab 57
 
518 s042372 58
        ofs << "mtllib parametrized.mtl\nusemtl mat\n" << endl;
543 jab 59
 
518 s042372 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;
543 jab 63
 
586 jab 64
		VertexAttributeVector<double> touched(m.allocated_vertices(), 0);
518 s042372 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;
587 jab 71
        Walker bv = m.walker(*v);
518 s042372 72
        do{
73
            ++n;
74
            bv = bv.next();
75
        }
76
        while(bv.vertex() != *v);
543 jab 77
 
518 s042372 78
        int i = 0;
79
        do{
543 jab 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;
587 jab 83
            m.pos(bv.vertex()) = Vec3d(cos(a), sin(a), 0);
518 s042372 84
            ++i;
85
            bv = bv.next();
86
        }
87
        while(bv.vertex() != *v);
543 jab 88
 
518 s042372 89
        for(v = m.vertices_begin(); v != m.vertices_end(); ++v)
90
            if(!boundary(m, *v))
587 jab 91
                m.pos(*v) = Vec3d(0.0);
543 jab 92
 
587 jab 93
        VertexAttributeVector<Vec3d> new_pos(m.no_vertices());
518 s042372 94
        for(int i = 0; i < 10000; ++i){
95
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v){
543 jab 96
				if(boundary(m, *v))
97
				{
98
					if(ws == LSCM_W && touched[*v] != 1)
99
					{
100
						Vec3d p_new(0);
101
						double w_sum = 0;
102
						Vec3d grad_sum(0.0);
587 jab 103
						Walker wv = m.walker(*v);
566 jab 104
						for(;!wv.full_circle(); wv = wv.circulate_vertex_ccw())
105
                        {
543 jab 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
							}
566 jab 114
                            double w = edge_weights[wv.halfedge()];
115
                            p_new += Vec3d(m.pos(wv.vertex()) * w);
116
                            w_sum += w;                            
117
                        }
587 jab 118
						new_pos[*v] = ((p_new) - (grad_sum))/w_sum;	
543 jab 119
					}
566 jab 120
                    else
121
                        new_pos[*v] = m.pos(*v);
543 jab 122
				}
123
				else
124
				{
125
					Vec3d p_new(0);
126
					double w_sum = 0;
587 jab 127
					for(Walker wv = m.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_ccw()) 
543 jab 128
					{
129
						double w = edge_weights[wv.halfedge()];
130
						p_new += Vec3d(m.pos(wv.vertex()) * w);
131
						w_sum += w;
132
					}
587 jab 133
                    new_pos[*v] = p_new/w_sum;
518 s042372 134
                }
135
            }
566 jab 136
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v)
137
                m.pos(*v) = new_pos[*v];
518 s042372 138
        }
543 jab 139
 
586 jab 140
        VertexAttributeVector<int> vtouched(m.allocated_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 ";
587 jab 151
            for(Walker w = m.walker(*f); !w.full_circle(); w = w.circulate_face_cw()){
518 s042372 152
                int idx = vtouched[w.vertex()] + 1;
153
                ofs << idx << "/" << idx <<" ";
154
            }
155
            ofs << endl;
156
        }
543 jab 157
 
514 s042372 158
    }
159
}