Subversion Repositories gelsvn

Rev

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

Rev Author Line No. Line
514 s042372 1
/* ----------------------------------------------------------------------- *
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
* ----------------------------------------------------------------------- */
11
 
12
#include "flatten.h"
13
 
14
#include <string>
15
#include <fstream>
16
#include <vector>
17
#include <CGLA/Vec3f.h>
18
 
19
#include "Manifold.h"
20
#include "AttributeVector.h"
21
 
22
namespace HMesh
23
{
24
    using namespace std;
25
    using namespace CGLA;
26
 
27
    void flatten(Manifold& m, WeightScheme ws)
28
    {
519 s042372 29
        HalfEdgeAttributeVector<float> edge_weights(m.total_halfedges(), 0);
518 s042372 30
        for(HalfEdgeIDIterator h = m.halfedges_begin(); h != m.halfedges_end(); ++h){      
31
            if(boundary(m, *h))
32
                continue;
514 s042372 33
 
518 s042372 34
            HalfEdgeWalker wv = m.halfedgewalker(*h);
35
            Vec3f p0 = m.pos(wv.vertex());
36
            Vec3f p1 = m.pos(wv.next().vertex());
37
            Vec3f p2 = m.pos(wv.opp().vertex());
38
            Vec3f p3 = m.pos(wv.opp().next().vertex());
39
 
40
            if(ws == FLOATER_W){
41
                float d = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p0), normalize(p3-p0)))));
42
                float g = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p0), normalize(p1-p0)))));
43
                edge_weights[wv.opp().halfedge()]  = (tan(d/2) + tan(g/2)) / (p0-p2).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)))));
48
                edge_weights[*h]  = (tan(d/2) + tan(g/2)) / (p0-p2).length();
49
            }
50
            else if(ws == HARMONIC_W){
51
                float a = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p3), normalize(p2-p3)))));
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));
56
                edge_weights[*h]  = w;
57
                edge_weights[wv.opp().halfedge()]  = w;
58
            }
59
            else{
60
                edge_weights[*h]  = valency(m, wv.opp().vertex());
61
                edge_weights[wv.opp().halfedge()]  = valency(m, wv.vertex());
62
            }	
63
        }
64
 
65
        ofstream ofs("parametrized.obj");
66
 
67
        ofs << "mtllib parametrized.mtl\nusemtl mat\n" << endl;
68
 
69
        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;
71
        ofs << endl;
72
 
73
        VertexIDIterator v = m.vertices_begin();
74
        for(; v != m.vertices_end(); ++v){
75
            if(boundary(m, *v))
76
                break;
77
        }
78
        int n = 0;
79
        HalfEdgeWalker bv = m.halfedgewalker(*v);
80
        do{
81
            ++n;
82
            bv = bv.next();
83
        }
84
        while(bv.vertex() != *v);
85
 
86
        int i = 0;
87
        do{
88
            float a = 2.0*M_PI*float(i)/n;
89
            m.pos(bv.vertex()) = Vec3f(cos(a), sin(a), 0);
90
            ++i;
91
            bv = bv.next();
92
        }
93
        while(bv.vertex() != *v);
94
 
95
        for(v = m.vertices_begin(); v != m.vertices_end(); ++v)
96
            if(!boundary(m, *v))
97
                m.pos(*v) = Vec3f(0.0);
98
 
99
        for(int i = 0; i < 10000; ++i){
100
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v){
101
                if(!boundary(m, *v)){
102
                    Vec3f p_new(0);
103
                    float w_sum = 0;
104
                    for(HalfEdgeWalker wv = m.halfedgewalker(*v); !wv.full_circle(); wv = wv.circulate_vertex_cw()){
105
                        float w = edge_weights[wv.halfedge()];
106
                        p_new += m.pos(wv.vertex()) * w;
107
                        w_sum += w;
108
                    }
109
                    m.pos(*v) = p_new/w_sum;
110
                }
111
            }
112
        }
113
 
519 s042372 114
        VertexAttributeVector<int> vtouched(m.total_vertices(), 0);
518 s042372 115
        i = 0;
116
        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;
118
            vtouched[*v] = i;
119
        }
120
 
121
        ofs << endl;
122
 
123
        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
124
            ofs << "f ";
125
            for(HalfEdgeWalker w = m.halfedgewalker(*f); !w.full_circle(); w = w.circulate_face_cw()){
126
                int idx = vtouched[w.vertex()] + 1;
127
                ofs << idx << "/" << idx <<" ";
128
            }
129
            ofs << endl;
130
        }
131
 
514 s042372 132
    }
133
}