Subversion Repositories gelsvn

Rev

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

Rev Author Line No. Line
149 jab 1
#include <queue>
2
#include "HMesh/FaceCirculator.h"
3
#include "HMesh/VertexCirculator.h"
4
#include "caps_and_needles.h"
5
#include "Geometry/QEM.h"
6
 
7
using namespace std;
8
using namespace CGLA;
9
using namespace GEO;
10
using namespace HMesh;
11
 
12
 
150 jab 13
namespace HMesh
149 jab 14
{
15
	namespace
16
	{
17
		float min_angle(const Vec3f& v0,const Vec3f& v1,const Vec3f& v2)
18
		{
19
			Vec3f a = normalize(v1-v0);
20
			Vec3f b = normalize(v2-v1);
21
			Vec3f c = normalize(v0-v2);
22
 
23
			return min(dot(a,-c), min(dot(b,-a), dot(c,-b)));
24
		}
25
 
26
		float edge_error(HalfEdgeIter h, 
27
										 const Vec3f& pa,
28
										 const Vec3f& pb)
29
		{
30
			QEM q;
31
			if(h->face != NULL_FACE_ITER)
32
				q += QEM(Vec3d(0), Vec3d(normal(h->face)));
33
			if(h->opp->face != NULL_FACE_ITER)
34
				q += QEM(Vec3d(0), Vec3d(normal(h->opp->face)));
35
			return q.error(pb-pa);
36
		}
37
 
38
 
39
		float vertex_error(VertexIter va, const Vec3f& pb)
40
		{
41
			QEM q;
42
			Vec3f pa = va->pos;
43
			for(VertexCirculator vc(va); !vc.end(); ++vc)
44
				{
45
					FaceIter f = vc.get_face();
46
					if(f != NULL_FACE_ITER)
47
						{
48
							Vec3f n = normal(f);
49
							q += QEM(Vec3d(0), Vec3d(n));
50
						}
51
				}
52
			return q.error(pb-pa);
53
		}
54
 
55
	}
56
 
57
	void remove_caps_from_trimesh(Manifold& mani, float ang_thresh)
58
	{
59
		for(FaceIter fi=mani.faces_begin(); fi != mani.faces_end(); ++fi)
60
			{
61
				Vec3f p[3];
62
				HalfEdgeIter he[3];
63
				VertexIter vi[3];
64
 
65
				int n=0;
66
				for(FaceCirculator fc(fi); !fc.end(); ++fc,++n)
67
					{
68
						vi[n] = fc.get_vertex();
69
						p[n]  = fc.get_vertex()->pos;
70
						he[n]= fc.get_halfedge();
71
					}
72
				assert(n=3);
73
 
74
				bool is_collapsed = false;
75
				Vec3f edges[3];
76
				for(int i=0;i<3;++i)
77
					{
78
						edges[i] = p[(i+1)%3]-p[i];
79
						float l = length(edges[i]);
80
						if(l<1e-20)
81
							is_collapsed = true;
82
						else
83
							edges[i] /= l;
84
					}
85
				if(is_collapsed) continue;
86
 
87
				for(int i=0;i<3;++i)
88
					{
89
						float d = max(-1.0f,min(1.0f,dot(-edges[(i+2)%3],edges[i])));
90
						float ang = acos(d);
91
						if(ang > ang_thresh)
92
							{
93
								int iplus1 = (i+1)%3;
94
								Vec3f edge_dir = edges[iplus1];
95
								Vec3f pprj =  
96
									edge_dir * dot(edge_dir,p[i]-p[iplus1])+p[iplus1];
97
 
98
								HalfEdgeIter h = he[iplus1];
99
								Vec3f v0 = h->vert->pos;
100
								Vec3f v1 = h->next->vert->pos;
101
								Vec3f v2 = h->opp->vert->pos;
102
								Vec3f v3 = h->opp->next->vert->pos;
103
 
104
								float m1 = min(min_angle(v0,v1,v2), min_angle(v0,v2,v3));
105
								float m2 = min(min_angle(v0,pprj,v3), min_angle(pprj,v2,v3));
106
								if(m1 < m2)
107
									{
108
											if(edge_error(he[iplus1], pprj, vi[i]->pos) >
109
											 vertex_error(vi[i], pprj))
110
												vi[i]->pos = pprj;
111
 
112
										mani.flip(he[iplus1]);
113
										break;
114
									}
115
							}
116
					}
117
 
118
			}
119
	}
120
 
121
 
122
 
123
	void remove_needles_from_trimesh(Manifold& mani, 
124
																	 float thresh)
125
	{
126
		bool did_work;
127
		do
128
			{
129
				did_work = false;
130
				for(VertexIter vi=mani.vertices_begin(); 
131
						vi != mani.vertices_end(); ++vi)
132
					{
133
							if(is_boundary(vi)) continue;
134
						for(VertexCirculator vc(vi);!vc.end();++vc)
135
							{
136
								if(is_boundary(vc.get_halfedge()->vert)) continue;
137
								HalfEdgeIter he = vc.get_halfedge()->opp;
138
 
139
								VertexIter n = vc.get_vertex();
140
								float dist = length(he);
141
								if((dist<thresh) && mani.collapse_precond(n,he))
142
									{
143
											if(vertex_error(vi,n->pos) < 
144
											 vertex_error(n,vi->pos))
145
													vi->pos = n->pos;
146
 
147
										mani.collapse_halfedge(n,he);
148
										did_work = true;
149
										break;
150
									}
151
							}
152
					}
153
			}
154
		while(did_work);
155
	}
156
}