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.