Subversion Repositories gelsvn

Rev

Rev 630 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/* ----------------------------------------------------------------------- *
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
 * Copyright (C) the authors and DTU Informatics
 * For license and list of authors, see ../../doc/intro.pdf
 * ----------------------------------------------------------------------- */

#include "flatten.h"

#include <string>
#include <fstream>
#include <vector>
#include "../CGLA/Vec3d.h"

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

namespace HMesh
{
    using namespace std;
    using namespace CGLA;
        
    void flatten(Manifold& m, WeightScheme ws)
    {
        HalfEdgeAttributeVector<double> edge_weights(m.allocated_halfedges(), 0);
                for(FaceIDIterator f = m.faces_begin(); f != m.faces_end(); ++f)
                {
                        for(Walker wv = m.walker(*f); !wv.full_circle(); wv = wv.circulate_face_ccw())
                        {
                                HalfEdgeID h = wv.halfedge();
                                Vec3d p1(m.pos(wv.vertex()));
                                Vec3d p2(m.pos(wv.next().vertex()));
                                Vec3d p0(m.pos(wv.opp().vertex()));
                                
                                if(ws == FLOATER_W){
                                        double ang = acos(min(1.0, max(-1.0, dot(normalize(p1-p0), normalize(p2-p0)))));
                                        double ang_opp = acos(min(1.0, max(-1.0, dot(normalize(p2-p1), normalize(p0-p1)))));
                                        double l = (p1-p0).length();
                                        edge_weights[h]  += tan(ang/2) / l;
                                        edge_weights[wv.opp().halfedge()]  += tan(ang_opp/2) / l;
                                }
                                else if(ws == HARMONIC_W || ws == LSCM_W){
                                        double a = acos(min(1.0, max(-1.0, dot(normalize(p0-p2), normalize(p1-p2)))));
                                        double w = max(0.0000001,0.5/tan(a));
                                        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;
                
                VertexAttributeVector<double> touched(m.allocated_vertices(), 0);
        VertexIDIterator v = m.vertices_begin();
        for(; v != m.vertices_end(); ++v){
            if(boundary(m, *v))
                break;
        }
        int n = 0;
        Walker bv = m.walker(*v);
        do{
            ++n;
            bv = bv.next();
        }
        while(bv.vertex() != *v);
                
        int i = 0;
        do{
                        if(i==int(n*0.25) || i==int(n*0.75))
                                touched[bv.vertex()]=1;
            double a = 2.0*M_PI*double(i)/n;
            m.pos(bv.vertex()) = Vec3d(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) = Vec3d(0.0);
                
        VertexAttributeVector<Vec3d> new_pos(m.no_vertices());
        for(int i = 0; i < 15000; ++i){
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v){
                                if(boundary(m, *v))
                                {
                                        if(i>5000 && ws == LSCM_W && touched[*v] != 1)
                                        {
                                                Vec3d p_new(0);
                                                double w_sum = 1e-6;
                                                Vec3d grad_sum(0.0);
                                                Walker wv = m.walker(*v);
                                                for(;!wv.full_circle(); wv = wv.circulate_vertex_ccw())
                        {
                                                        if(wv.face() != InvalidFaceID)
                                                        {
                                                                Vec3d p1(m.pos(wv.next().vertex()));
                                                                Vec3d p0(m.pos(wv.vertex()));
                                                                Vec3d area_grad = 0.5*(p1 - p0); 
                                                                grad_sum[0] += -area_grad[1];
                                                                grad_sum[1] += area_grad[0];
                                                        }
                            double w = edge_weights[wv.halfedge()];
                            p_new += Vec3d(m.pos(wv.vertex()) * w);
                            w_sum += w;                            
                        }
                                                new_pos[*v] = ((p_new) - (grad_sum))/w_sum;     
                                        }
                    else
                        new_pos[*v] = m.pos(*v);
                                }
                                else
                                {
                                        Vec3d p_new(0);
                                        double w_sum = 1e-6;
                                        for(Walker wv = m.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_ccw()) 
                                        {
                                                double w = edge_weights[wv.halfedge()];
                                                p_new += Vec3d(m.pos(wv.vertex()) * w);
                                                w_sum += w;
                                        }
                    new_pos[*v] = p_new/w_sum;
                }
            }
            for(v = m.vertices_begin(); v != m.vertices_end(); ++v)
                m.pos(*v) = new_pos[*v];
        }
                
        VertexAttributeVector<int> vtouched(m.allocated_vertices(), 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(Walker w = m.walker(*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.