Subversion Repositories gelsvn

Rev

Rev 514 | Rev 519 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/* ----------------------------------------------------------------------- *
* This file is part of GEL, www.imm.dtu.dk/GEL
* Copyright (C) the authors (see AUTHORS.txt) and DTU Informatics
*
* Principal authors:
*  Christian Thode Larsen (thode2d@gmail.com)
*  J. Andreas Baerentzen (jab@imm.dtu.dk)
*
* See LICENSE.txt for licensing information
* ----------------------------------------------------------------------- */

#include "flatten.h"

#include <string>
#include <fstream>
#include <vector>
#include <CGLA/Vec3f.h>

#include "Manifold.h"
#include "AttributeVector.h"

namespace HMesh
{
    using namespace std;
    using namespace CGLA;

    void flatten(Manifold& m, WeightScheme ws)
    {
        HalfEdgeAttributeVector<float> edge_weights(m, 0);
        for(HalfEdgeIDIterator h = m.halfedges_begin(); h != m.halfedges_end(); ++h){      
            if(boundary(m, *h))
                continue;

            HalfEdgeWalker wv = m.halfedgewalker(*h);
            Vec3f p0 = m.pos(wv.vertex());
            Vec3f p1 = m.pos(wv.next().vertex());
            Vec3f p2 = m.pos(wv.opp().vertex());
            Vec3f p3 = m.pos(wv.opp().next().vertex());

            if(ws == FLOATER_W){
                float d = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p0), normalize(p3-p0)))));
                float g = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p0), normalize(p1-p0)))));
                edge_weights[wv.opp().halfedge()]  = (tan(d/2) + tan(g/2)) / (p0-p2).length();


                d = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p2), normalize(p1-p2)))));
                g = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p2), normalize(p3-p2)))));
                edge_weights[*h]  = (tan(d/2) + tan(g/2)) / (p0-p2).length();
            }
            else if(ws == HARMONIC_W){
                float a = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p3), normalize(p2-p3)))));
                float b = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p1), normalize(p0-p1)))));
                float w=0;
                if(a+b < M_PI)
                    w = sin(a+b)/(sin(a)+sin(b));
                edge_weights[*h]  = w;
                edge_weights[wv.opp().halfedge()]  = w;
            }
            else{
                edge_weights[*h]  = valency(m, wv.opp().vertex());
                edge_weights[wv.opp().halfedge()]  = valency(m, wv.vertex());
            }   
        }

        ofstream ofs("parametrized.obj");

        ofs << "mtllib parametrized.mtl\nusemtl mat\n" << endl;

        for(VertexIDIterator v = m.vertices_begin(); v != m.vertices_end(); ++v)
            ofs << "v " << m.pos(*v)[0] << " " << m.pos(*v)[1] << " " << m.pos(*v)[2] << endl;
        ofs << endl;

        VertexIDIterator v = m.vertices_begin();
        for(; v != m.vertices_end(); ++v){
            if(boundary(m, *v))
                break;
        }
        int n = 0;
        HalfEdgeWalker bv = m.halfedgewalker(*v);
        do{
            ++n;
            bv = bv.next();
        }
        while(bv.vertex() != *v);

        int i = 0;
        do{
            float a = 2.0*M_PI*float(i)/n;
            m.pos(bv.vertex()) = Vec3f(cos(a), sin(a), 0);
            ++i;
            bv = bv.next();
        }
        while(bv.vertex() != *v);

        for(v = m.vertices_begin(); v != m.vertices_end(); ++v)
            if(!boundary(m, *v))
                m.pos(*v) = Vec3f(0.0);

        for(int i = 0; i < 10000; ++i){
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v){
                if(!boundary(m, *v)){
                    Vec3f p_new(0);
                    float w_sum = 0;
                    for(HalfEdgeWalker wv = m.halfedgewalker(*v); !wv.full_circle(); wv = wv.circulate_vertex_cw()){
                        float w = edge_weights[wv.halfedge()];
                        p_new += m.pos(wv.vertex()) * w;
                        w_sum += w;
                    }
                    m.pos(*v) = p_new/w_sum;
                }
            }
        }

        VertexAttributeVector<int> vtouched(m, 0);
        i = 0;
        for(v = m.vertices_begin(); v != m.vertices_end(); ++v, ++i){
            ofs << "vt " << (0.5*m.pos(*v)[0]+0.5) << " " << (0.5*m.pos(*v)[1]+0.5)  << endl;
            vtouched[*v] = i;
        }

        ofs << endl;

        for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f){
            ofs << "f ";
            for(HalfEdgeWalker w = m.halfedgewalker(*f); !w.full_circle(); w = w.circulate_face_cw()){
                int idx = vtouched[w.vertex()] + 1;
                ofs << idx << "/" << idx <<" ";
            }
            ofs << endl;
        }

    }
}

Generated by GNU Enscript 1.6.6.