595 |
jab |
1 |
/* ----------------------------------------------------------------------- *
|
|
|
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
|
|
|
5 |
* ----------------------------------------------------------------------- */
|
|
|
6 |
|
|
|
7 |
#include "subdivision.h"
|
|
|
8 |
|
|
|
9 |
#include <vector>
|
|
|
10 |
#include <CGLA/Vec3d.h>
|
|
|
11 |
|
|
|
12 |
#include "Manifold.h"
|
|
|
13 |
#include "AttributeVector.h"
|
|
|
14 |
|
|
|
15 |
namespace HMesh
|
|
|
16 |
{
|
|
|
17 |
using namespace std;
|
|
|
18 |
using namespace CGLA;
|
|
|
19 |
|
|
|
20 |
void cc_split(Manifold& m_in, Manifold& m_out)
|
|
|
21 |
{
|
|
|
22 |
const int Invalid = -1;
|
|
|
23 |
|
|
|
24 |
vector<Vec3d> new_points;
|
|
|
25 |
new_points.reserve(m_in.no_vertices());
|
|
|
26 |
|
|
|
27 |
VertexAttributeVector<int> vtouched(m_in.allocated_vertices(), Invalid);
|
|
|
28 |
HalfEdgeAttributeVector<int> htouched(m_in.allocated_halfedges(), Invalid);
|
|
|
29 |
|
|
|
30 |
int npsize = 0;
|
|
|
31 |
for(VertexIDIterator v = m_in.vertices_begin(); v != m_in.vertices_end(); ++v){
|
|
|
32 |
vtouched[*v] = npsize;
|
|
|
33 |
new_points.push_back(m_in.pos(*v));
|
|
|
34 |
++npsize;
|
|
|
35 |
}
|
|
|
36 |
|
|
|
37 |
for(HalfEdgeIDIterator h = m_in.halfedges_begin(); h != m_in.halfedges_end(); ++h){
|
|
|
38 |
if(htouched[*h] != Invalid)
|
|
|
39 |
continue;
|
|
|
40 |
|
|
|
41 |
Walker w = m_in.walker(*h);
|
|
|
42 |
htouched[*h] = htouched[w.opp().halfedge()] = npsize;
|
|
|
43 |
new_points.push_back((m_in.pos(w.vertex()) + m_in.pos(w.opp().vertex())) * 0.5f);
|
|
|
44 |
++npsize;
|
|
|
45 |
|
|
|
46 |
}
|
|
|
47 |
vector<int> indices;
|
|
|
48 |
vector<int> faces;
|
|
|
49 |
|
|
|
50 |
for(FaceIDIterator f = m_in.faces_begin(); f != m_in.faces_end(); ++f){
|
|
|
51 |
for(Walker w = m_in.walker(*f); !w.full_circle(); w = w.circulate_face_cw()){
|
|
|
52 |
indices.push_back(npsize);
|
|
|
53 |
indices.push_back(htouched[w.halfedge()]);
|
|
|
54 |
indices.push_back(vtouched[w.vertex()]);
|
|
|
55 |
indices.push_back(htouched[w.next().halfedge()]);
|
|
|
56 |
faces.push_back(4);
|
|
|
57 |
}
|
|
|
58 |
new_points.push_back(centre(m_in, *f));
|
|
|
59 |
++npsize;
|
|
|
60 |
}
|
|
|
61 |
|
|
|
62 |
m_out.clear();
|
|
|
63 |
m_out.build(npsize, reinterpret_cast<double*>(&new_points[0]), faces.size(), &faces[0], &indices[0]);
|
|
|
64 |
}
|
|
|
65 |
|
|
|
66 |
void cc_smooth(Manifold& m)
|
|
|
67 |
{
|
|
|
68 |
VertexAttributeVector<Vec3d> new_vertices(m.no_vertices(), Vec3d(0));
|
|
|
69 |
for(FaceIDIterator fi = m.faces_begin(); fi != m.faces_end(); ++fi)
|
|
|
70 |
{
|
|
|
71 |
FaceID f = *fi;
|
|
|
72 |
Walker w = m.walker(f);
|
|
|
73 |
for(; !w.full_circle(); w = w.next())
|
|
|
74 |
{
|
|
|
75 |
VertexID v = w.vertex();
|
|
|
76 |
float val = valency(m, v);
|
|
|
77 |
float A = (1.0f-3.0f/val) * (1.0f/val);
|
|
|
78 |
float B = sqr(1.0f/val);
|
|
|
79 |
Walker w2 = m.walker(f);
|
|
|
80 |
for(; !w2.full_circle(); w2 = w2.next())
|
|
|
81 |
{
|
|
|
82 |
VertexID v2 = w2.vertex();
|
|
|
83 |
if(v==v2)
|
|
|
84 |
new_vertices[v] += A * m.pos(v2);
|
|
|
85 |
else
|
|
|
86 |
new_vertices[v] += B * m.pos(v2);
|
|
|
87 |
}
|
|
|
88 |
|
|
|
89 |
}
|
|
|
90 |
}
|
|
|
91 |
for(VertexIDIterator vi = m.vertices_begin(); vi != m.vertices_end(); ++vi)
|
|
|
92 |
m.pos(*vi) = new_vertices[*vi];
|
|
|
93 |
}
|
|
|
94 |
|
|
|
95 |
|
|
|
96 |
}
|