Subversion Repositories gelsvn

Rev

Rev 614 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 614 Rev 630
1
/*
1
/*
2
 *  harmonics.cpp
2
 *  harmonics.cpp
3
 *  GEL
3
 *  GEL
4
 *
4
 *
5
 *  Created by J. Andreas Bærentzen on 01/09/08.
5
 *  Created by J. Andreas Bærentzen on 01/09/08.
6
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
6
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
7
 *
7
 *
8
 */
8
 */
9
 
9
 
10
#include <iostream>
10
#include <iostream>
11
 
11
 
12
#include "harmonics.h"
12
#include "harmonics.h"
13
 
13
 
14
#if USE_SPARSE_MATRIX
14
#if USE_SPARSE_MATRIX
15
#include <arlgsym.h>
15
#include <arlgsym.h>
16
#endif
16
#endif
17
 
17
 
18
#include <CGLA/Vec3d.h>
18
#include <CGLA/Vec3d.h>
19
#include <CGLA/Mat2x2d.h>
19
#include <CGLA/Mat2x2d.h>
20
#include <LinAlg/Matrix.h>
20
#include <LinAlg/Matrix.h>
21
#include <LinAlg/Vector.h>
21
#include <LinAlg/Vector.h>
22
#include <LinAlg/LapackFunc.h>
22
#include <LinAlg/LapackFunc.h>
23
 
23
 
24
#include <GL/glew.h>
24
#include <GL/glew.h>
25
#include <GLGraphics/glsl_shader.h>
25
#include <GLGraphics/glsl_shader.h>
26
 
26
 
27
#include <HMesh/mesh_optimization.h>
27
#include <HMesh/mesh_optimization.h>
28
#include <HMesh/curvature.h>
28
#include <HMesh/curvature.h>
29
#include <HMesh/triangulate.h>
29
#include <HMesh/triangulate.h>
30
#include <HMesh/load.h>
30
#include <HMesh/load.h>
31
#include <HMesh/x3d_save.h>
31
#include <HMesh/x3d_save.h>
32
 
32
 
33
#include <GLGraphics/Console.h>
33
#include <GLGraphics/Console.h>
34
 
34
 
35
//#include "CSCMatrixBuilder.h"
35
//#include "CSCMatrixBuilder.h"
36
 
36
 
37
using namespace CGLA;
37
using namespace CGLA;
38
using namespace std;
38
using namespace std;
39
using namespace HMesh;
39
using namespace HMesh;
40
using namespace Geometry;
40
using namespace Geometry;
41
using namespace GLGraphics;
41
using namespace GLGraphics;
42
using namespace LinAlg;
42
using namespace LinAlg;
43
 
43
 
44
namespace
44
namespace
45
{
45
{
46
	
46
	
47
	string vss =
47
	string vss =
48
	"#version 120\n"
48
	"#version 120\n"
49
	"#extension GL_EXT_gpu_shader4 : enable\n"
49
	"#extension GL_EXT_gpu_shader4 : enable\n"
50
	"	\n"
50
	"	\n"
51
	"	\n"
51
	"	\n"
52
	"	attribute float eigenvalue;\n"
52
	"	attribute float eigenvalue;\n"
53
	"	attribute float eigenvalue2;\n"
53
	"	attribute float eigenvalue2;\n"
54
	"	varying vec3 normal;\n"
54
	"	varying vec3 normal;\n"
55
	"	varying float eig;\n"
55
	"	varying float eig;\n"
56
	"	varying float eig2;\n"
56
	"	varying float eig2;\n"
57
	"	\n"
57
	"	\n"
58
	"	void main(void)\n"
58
	"	void main(void)\n"
59
	"	{\n"
59
	"	{\n"
60
	"		gl_Position =  ftransform();\n"
60
	"		gl_Position =  ftransform();\n"
61
	"		normal = normalize(gl_NormalMatrix * gl_Normal);\n"
61
	"		normal = normalize(gl_NormalMatrix * gl_Normal);\n"
62
	"		eig = eigenvalue;\n"
62
	"		eig = eigenvalue;\n"
63
	"		eig2 = eigenvalue2;\n"
63
	"		eig2 = eigenvalue2;\n"
64
	"	}\n";
64
	"	}\n";
65
	
65
	
66
	string fss = 	
66
	string fss = 	
67
	"#version 120\n"
67
	"#version 120\n"
68
	"#extension GL_EXT_gpu_shader4 : enable\n"
68
	"#extension GL_EXT_gpu_shader4 : enable\n"
69
	"	\n"
69
	"	\n"
70
	"	varying vec3 normal;\n"
70
	"	varying vec3 normal;\n"
71
	"	varying float eig;\n"
71
	"	varying float eig;\n"
72
	"	varying float eig2;\n"
72
	"	varying float eig2;\n"
73
	"	uniform float eig_max;\n"
73
	"	uniform float eig_max;\n"
74
	"	uniform float eig_max2;\n"
74
	"	uniform float eig_max2;\n"
75
	"	uniform bool do_highlight;\n"
75
	"	uniform bool do_highlight;\n"
76
	"	uniform bool do_diffuse;\n"
76
	"	uniform bool do_diffuse;\n"
77
	"	const vec3 light_dir = vec3(0,0,1);\n"
77
	"	const vec3 light_dir = vec3(0,0,1);\n"
78
	"	\n"
78
	"	\n"
79
	" float basef(float x) {return max(0.0,min(1.0,2.0-4.0*abs(x)));\n}" 
79
	" float basef(float x) {return max(0.0,min(1.0,2.0-4.0*abs(x)));\n}" 
80
	"	void main()\n"
80
	"	void main()\n"
81
	"	{\n"
81
	"	{\n"
82
	"		float dot_ln = max(0.0,dot(light_dir, normal));\n"
82
	"		float dot_ln = max(0.0,dot(light_dir, normal));\n"
83
	"		\n"
83
	"		\n"
84
	"		float eig_norm = eig/eig_max;\n"
84
	"		float eig_norm = eig/eig_max;\n"
85
	"		float stripe_signal = 250 * eig_norm;\n"
85
	"		float stripe_signal = 250 * eig_norm;\n"
86
	//"		vec4 stripe_col = abs(stripe_signal) < 3.14 ? vec4(1,1,0,0) : vec4(.4,.4,.4,0);\n"
86
	//"		vec4 stripe_col = abs(stripe_signal) < 3.14 ? vec4(1,1,0,0) : vec4(.4,.4,.4,0);\n"
87
	"		vec4 stripe_col = -vec4(.4,.4,.4,0);\n"
87
	"		vec4 stripe_col = -vec4(.4,.4,.4,0);\n"
88
	"		\n"
88
	"		\n"
89
	"       float alpha = (1.0-eig_norm) * 2.0 * 3.1415926;\n"
89
	"       float alpha = (1.0-eig_norm) * 2.0 * 3.1415926;\n"
90
	"       float offs = 2.0*3.1415/3.0;\n"
90
	"       float offs = 2.0*3.1415/3.0;\n"
91
	"		gl_FragColor = vec4(0,0,1,0)*basef(eig_norm)+vec4(0,1,0,0)*basef(eig_norm-0.5)+vec4(1,0,0,0)* basef(eig_norm-1.0);\n"
91
	"		gl_FragColor = vec4(0,0,1,0)*basef(eig_norm)+vec4(0,1,0,0)*basef(eig_norm-0.5)+vec4(1,0,0,0)* basef(eig_norm-1.0);\n"
92
	"		if(do_diffuse)   gl_FragColor *= dot_ln;\n"
92
	"		if(do_diffuse)   gl_FragColor *= dot_ln;\n"
93
	"		if(do_highlight) gl_FragColor += dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*vec4(.5,.5,.5,0);\n"
93
	"		if(do_highlight) gl_FragColor += dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*dot_ln*vec4(.5,.5,.5,0);\n"
94
	"		gl_FragColor -= vec4(.4,.4,.4,.4)*smoothstep(0.2,0.6,cos(stripe_signal));\n"
94
	"		gl_FragColor -= vec4(.4,.4,.4,.4)*smoothstep(0.2,0.6,cos(stripe_signal));\n"
95
	"	}\n";
95
	"	}\n";
96
}
96
}
97
 
97
 
98
 
98
 
99
 
99
 
100
#if USE_SPARSE_MATRIX
100
#if USE_SPARSE_MATRIX
101
 
101
 
102
double calculate_laplace_entry(VertexCirculator vc,Vec3d vertex)
102
double calculate_laplace_entry(VertexCirculator vc,Vec3d vertex)
103
{
103
{
104
	//* this piece of code is taken from the orginal make_laplace_operator...
104
	//* this piece of code is taken from the orginal make_laplace_operator...
105
	HalfEdgeIter h = vc.get_halfedge();
105
	HalfEdgeIter h = vc.get_halfedge();
106
	Vec3d nbr(h->vert->pos);
106
	Vec3d nbr(h->vert->pos);
107
	Vec3d left(h->next->vert->pos);
107
	Vec3d left(h->next->vert->pos);
108
	Vec3d right(h->opp->prev->opp->vert->pos);
108
	Vec3d right(h->opp->prev->opp->vert->pos);
109
	
109
	
110
	double d_left = dot(normalize(nbr-left),normalize(vertex-left));
110
	double d_left = dot(normalize(nbr-left),normalize(vertex-left));
111
	double d_right = dot(normalize(nbr-right),normalize(vertex-right));
111
	double d_right = dot(normalize(nbr-right),normalize(vertex-right));
112
	double a_left  = acos(min(1.0, max(-1.0, d_left))); // w positive...?
112
	double a_left  = acos(min(1.0, max(-1.0, d_left))); // w positive...?
113
	double a_right = acos(min(1.0, max(-1.0, d_right)));
113
	double a_right = acos(min(1.0, max(-1.0, d_right)));
114
	
114
	
115
	double w = 1.0/tan(a_left) + 1.0/tan(a_right);
115
	double w = 1.0/tan(a_left) + 1.0/tan(a_right);
116
	return -w;
116
	return -w;
117
}
117
}
118
 
118
 
119
void Harmonics::make_laplace_operator_sparse()
119
void Harmonics::make_laplace_operator_sparse()
120
{
120
{
121
	bool is_generalized=true;
121
	bool is_generalized=true;
122
	CSCMatrixBuilder<double> mb_M;
122
	CSCMatrixBuilder<double> mb_M;
123
	//+GENERALIZED
123
	//+GENERALIZED
124
	CSCMatrixBuilder<double> mb_S;
124
	CSCMatrixBuilder<double> mb_S;
125
	// S has the same type as V
125
	// S has the same type as V
126
	S.Resize(mani.no_vertices());
126
	S.Resize(mani.no_vertices());
127
	
127
	
128
	for(VertexIter v = mani.vhandles_begin(); v != mani.vhandles_end(); ++v)
128
	for(VertexIter v = mani.vhandles_begin(); v != mani.vhandles_end(); ++v)
129
		if(!is_boundary(v))
129
		if(!is_boundary(v))
130
		{
130
		{
131
			int i = v->touched;
131
			int i = v->touched;
132
			double area_i = voronoi_area(v);
132
			double area_i = voronoi_area(v);
133
			Vec3d vertex(v->pos);
133
			Vec3d vertex(v->pos);
134
			double a_sum = 0;
134
			double a_sum = 0;
135
			for(VertexCirculator vc(v); !vc.end(); ++vc)
135
			for(VertexCirculator vc(v); !vc.end(); ++vc)
136
			{
136
			{
137
				int j = vc.get_vertex()->touched;
137
				int j = vc.get_vertex()->touched;
138
				double entry = calculate_laplace_entry(vc,vertex);
138
				double entry = calculate_laplace_entry(vc,vertex);
139
				if(!is_generalized)
139
				if(!is_generalized)
140
				{
140
				{
141
					double area_j = voronoi_area(vc.get_vertex());
141
					double area_j = voronoi_area(vc.get_vertex());
142
					entry /= sqrt(area_i*area_j);
142
					entry /= sqrt(area_i*area_j);
143
				}
143
				}
144
				if(j > i)
144
				if(j > i)
145
					mb_M.insert_entry(j,entry);
145
					mb_M.insert_entry(j,entry);
146
				a_sum += entry;
146
				a_sum += entry;
147
			}
147
			}
148
			//cout << a_sum << " ";
148
			//cout << a_sum << " ";
149
			mb_M.insert_entry(i,-a_sum);
149
			mb_M.insert_entry(i,-a_sum);
150
			mb_M.next_column();
150
			mb_M.next_column();
151
			
151
			
152
			if(!is_generalized)
152
			if(!is_generalized)
153
				area_i = 1; // if standard S is an identity matrix;
153
				area_i = 1; // if standard S is an identity matrix;
154
			mb_S.insert_entry(i,area_i);
154
			mb_S.insert_entry(i,area_i);
155
			mb_S.next_column_nonsort();
155
			mb_S.next_column_nonsort();
156
			S[i] = area_i;
156
			S[i] = area_i;
157
		}     
157
		}     
158
	
158
	
159
	cout << "solving generalized problem... i = " << mani.no_vertices()<< endl;
159
	cout << "solving generalized problem... i = " << mani.no_vertices()<< endl;
160
	
160
	
161
	
161
	
162
	//+STANDARD
162
	//+STANDARD
163
	//ArpackPP::ARluSymStdEig<double> dprob(50L, mb_M.get_Matrix(), "SA");
163
	//ArpackPP::ARluSymStdEig<double> dprob(50L, mb_M.get_Matrix(), "SA");
164
	//+GENERALIZED (shifted inv mode)
164
	//+GENERALIZED (shifted inv mode)
165
	ARluSymGenEig<double> dprob('S',maximum_eigenvalue, mb_M.get_Matrix(), mb_S.get_Matrix(), 0.0);
165
	ARluSymGenEig<double> dprob('S',maximum_eigenvalue, mb_M.get_Matrix(), mb_S.get_Matrix(), 0.0);
166
	//ArpackPP::ARluSymGenEig<double> dprob(number_of_eigenvalues, mb_M.get_Matrix(), mb_S.get_Matrix());
166
	//ArpackPP::ARluSymGenEig<double> dprob(number_of_eigenvalues, mb_M.get_Matrix(), mb_S.get_Matrix());
167
	
167
	
168
	dprob.FindEigenvectors();
168
	dprob.FindEigenvectors();
169
	int conv = dprob.ConvergedEigenvalues();
169
	int conv = dprob.ConvergedEigenvalues();
170
	cout << conv << " eigenvectors found" << endl;
170
	cout << conv << " eigenvectors found" << endl;
171
	Q.Resize(conv, dprob.GetN());
171
	Q.Resize(conv, dprob.GetN());
172
	V.Resize(conv);
172
	V.Resize(conv);
173
	
173
	
174
	qnorm.Resize(conv);
174
	qnorm.Resize(conv);
175
	for(int i = 0; i < conv; i++)
175
	for(int i = 0; i < conv; i++)
176
	{
176
	{
177
		V[i] = dprob.Eigenvalue(i);
177
		V[i] = dprob.Eigenvalue(i);
178
		qnorm[i] = 0;
178
		qnorm[i] = 0;
179
		for(int j = 0; j < dprob.GetN(); j++)
179
		for(int j = 0; j < dprob.GetN(); j++)
180
		{
180
		{
181
			Q[i][j] = dprob.Eigenvector(i,j);
181
			Q[i][j] = dprob.Eigenvector(i,j);
182
			qnorm[i] += Q[i][j]*Q[i][j];
182
			qnorm[i] += Q[i][j]*Q[i][j];
183
		}
183
		}
184
		
184
		
185
		cout << "(" << i << ":" << sqrt(V[i]/V[1]
185
		cout << "(" << i << ":" << sqrt(V[i]/V[1]
186
										) << ")" << V[i]/V[1] << "V= "<< V[i] << " exp " << exp(-0.01*V[i]/V[1]) << " Qnorm " << qnorm[i]<< endl;
186
										) << ")" << V[i]/V[1] << "V= "<< V[i] << " exp " << exp(-0.01*V[i]/V[1]) << " Qnorm " << qnorm[i]<< endl;
187
	}
187
	}
188
	
188
	
189
	cout  << endl;
189
	cout  << endl;
190
}
190
}
191
 
191
 
192
Harmonics::Harmonics(Manifold& _mani):mani(_mani)
192
Harmonics::Harmonics(Manifold& _mani):mani(_mani)
193
{
193
{
194
	assert(is_initialized);
194
	assert(is_initialized);
195
	
195
	
196
	maximum_eigenvalue = min(size_t(500),mani.no_vertices());
196
	maximum_eigenvalue = min(size_t(500),mani.no_vertices());
197
	
197
	
198
	triangulate(mani);
198
	triangulate(mani);
199
	mani.enumerate_vertices();
199
	mani.enumerate_vertices();
200
	make_laplace_operator_sparse();
200
	make_laplace_operator_sparse();
201
	
201
	
202
	if(maximum_eigenvalue == -1)
202
	if(maximum_eigenvalue == -1)
203
	{
203
	{
204
		cout << "not found" << endl;
204
		cout << "not found" << endl;
205
		return;
205
		return;
206
	}
206
	}
207
	
207
	
208
	proj.resize(maximum_eigenvalue);
208
	proj.resize(maximum_eigenvalue);
209
	
209
	
210
	max_eig_values.resize(maximum_eigenvalue, 1e-10f);
210
	max_eig_values.resize(maximum_eigenvalue, 1e-10f);
211
	
211
	
212
	cout << endl << "Proj" << endl;
212
	cout << endl << "Proj" << endl;
213
	for(int es=0; es<maximum_eigenvalue; ++es)  //o(n^2)
213
	for(int es=0; es<maximum_eigenvalue; ++es)  //o(n^2)
214
	{
214
	{
215
		proj[es] = Vec3d(0.0);
215
		proj[es] = Vec3d(0.0);
216
		for(VertexIter v=mani.vhandles_begin(); v != mani.vhandles_end(); ++v)
216
		for(VertexIter v=mani.vhandles_begin(); v != mani.vhandles_end(); ++v)
217
		{
217
		{
218
			proj[es] +=  Vec3d(v->pos) * Q[es][v->touched] * S[v->touched];
218
			proj[es] +=  Vec3d(v->pos) * Q[es][v->touched] * S[v->touched];
219
			max_eig_values[es] = max(max_eig_values[es], static_cast<float>(abs(Q[es][v->touched])));     
219
			max_eig_values[es] = max(max_eig_values[es], static_cast<float>(abs(Q[es][v->touched])));     
220
		}     
220
		}     
221
	}
221
	}
222
	cout << endl;
222
	cout << endl;
223
}
223
}
224
 
224
 
225
#else
225
#else
226
void Harmonics::make_laplace_operator()
226
void Harmonics::make_laplace_operator()
227
{
227
{
228
	Q.Resize(mani.no_vertices(), mani.no_vertices());
228
	Q.Resize(mani.no_vertices(), mani.no_vertices());
229
	
229
	
230
	for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v)
230
	for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v)
231
		if(!boundary(mani, *v)){
231
		if(!boundary(mani, *v)){
232
			int i = vtouched[*v];
232
			int i = vtouched[*v];
233
			double area_i = voronoi_area(mani, *v);
233
			double area_i = voronoi_area(mani, *v);
234
			Vec3d vertex(mani.pos(*v));
234
			Vec3d vertex(mani.pos(*v));
235
			Vec3d curv_normal(0);
235
			Vec3d curv_normal(0);
236
			double a_sum = 0;
236
			double a_sum = 0;
237
            for(Walker wv = mani.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_cw())
237
            for(Walker wv = mani.walker(*v); !wv.full_circle(); wv = wv.circulate_vertex_cw())
238
			{
238
			{
239
				int j = vtouched[wv.vertex()];
239
				int j = vtouched[wv.vertex()];
240
				double area_j = voronoi_area(mani, wv.vertex());
240
				double area_j = voronoi_area(mani, wv.vertex());
241
				
241
				
242
				Vec3d nbr(mani.pos(wv.vertex()));
242
				Vec3d nbr(mani.pos(wv.vertex()));
243
				Vec3d left(mani.pos(wv.next().vertex()));
243
				Vec3d left(mani.pos(wv.next().vertex()));
244
				Vec3d right(mani.pos(wv.opp().prev().opp().vertex()));
244
				Vec3d right(mani.pos(wv.opp().prev().opp().vertex()));
245
				
245
				
246
				double d_left = dot(normalize(nbr-left),
246
				double d_left = dot(normalize(nbr-left),
247
									normalize(vertex-left));
247
									normalize(vertex-left));
248
				double d_right = dot(normalize(nbr-right),
248
				double d_right = dot(normalize(nbr-right),
249
									 normalize(vertex-right));
249
									 normalize(vertex-right));
250
				double a_left  = acos(min(1.0, max(-1.0, d_left)));
250
				double a_left  = acos(min(1.0, max(-1.0, d_left)));
251
				double a_right = acos(min(1.0, max(-1.0, d_right)));
251
				double a_right = acos(min(1.0, max(-1.0, d_right)));
252
				
252
				
253
				double w = 1.0/tan(a_left) + 1.0/tan(a_right);
253
				double w = 1.0/tan(a_left) + 1.0/tan(a_right);
254
				
254
				
255
				Q[i][j] = -w/sqrt(area_i*area_j);						
255
				Q[i][j] = -w/sqrt(area_i*area_j);						
256
				//Q[i][j] = -1;						
256
				//Q[i][j] = -1;						
257
				a_sum += Q[i][j];
257
				a_sum += Q[i][j];
258
			}
258
			}
259
			Q[i][i] = -a_sum;
259
			Q[i][i] = -a_sum;
260
		}
260
		}
261
	EigenSolutionsSym(Q,V);
261
	EigenSolutionsSym(Q,V);
262
}
262
}
263
 
263
 
264
Harmonics::Harmonics(HMesh::Manifold& _mani, GLGraphics::Console& cs):mani(_mani), vtouched(_mani.allocated_vertices(), 0)
264
Harmonics::Harmonics(HMesh::Manifold& _mani, GLGraphics::Console& cs):mani(_mani), vtouched(_mani.allocated_vertices(), 0)
265
{
265
{
266
    string shader_path = "/Users/jab/GEL/apps/MeshEdit/";
266
    string shader_path = "/Users/jab/GEL/apps/MeshEdit/";
267
	GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, vss);
267
	GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, vss);
268
	GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, fss);
268
	GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, fss);
269
	
269
	
270
	// Create the program
270
	// Create the program
271
	prog_P0 = glCreateProgram();
271
	prog_P0 = glCreateProgram();
272
	
272
	
273
	// Attach all shaders
273
	// Attach all shaders
274
	if(vs) glAttachShader(prog_P0, vs);
274
	if(vs) glAttachShader(prog_P0, vs);
275
	if(fs) glAttachShader(prog_P0, fs);
275
	if(fs) glAttachShader(prog_P0, fs);
276
	
276
	
277
	// Link the program object and print out the info log
277
	// Link the program object and print out the info log
278
	glLinkProgram(prog_P0);
278
	glLinkProgram(prog_P0);
279
	print_glsl_program_log(prog_P0);
279
	print_glsl_program_log(prog_P0);
280
	
280
	
281
	// Install program object as part of current state
281
	// Install program object as part of current state
282
	glUseProgram(0);
282
	glUseProgram(0);
283
	
283
	
284
    display_harmonics_diffuse.reg(cs, "display.harmonics.diffuse", "");
284
    display_harmonics_diffuse.reg(cs, "display.harmonics.diffuse", "");
285
    display_harmonics_time.reg(cs, "display.harmonics.time", "");
285
    display_harmonics_time.reg(cs, "display.harmonics.time", "");
286
    display_harmonics_highlight.reg(cs, "display.harmonics.highlight", "");
286
    display_harmonics_highlight.reg(cs, "display.harmonics.highlight", "");
287
	
287
	
288
	triangulate_by_edge_face_split(mani);
288
	triangulate_by_edge_face_split(mani);
289
 
289
 
290
    int i = 0;
290
    int i = 0;
291
    for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v, ++i)
291
    for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v, ++i)
292
        vtouched[*v] = i;
292
        vtouched[*v] = i;
293
	maximum_eigenvalue = mani.no_vertices()-1;
293
	maximum_eigenvalue = mani.no_vertices()-1;
294
	make_laplace_operator();
294
	make_laplace_operator();
295
	
295
	
296
	proj.resize(maximum_eigenvalue);
296
	proj.resize(maximum_eigenvalue);
297
	max_eig_values.resize(maximum_eigenvalue, 1e-10f);
297
	max_eig_values.resize(maximum_eigenvalue, 1e-10f);
298
	
298
	
299
	cout << "Projection magnitude" << endl;
299
	cout << "Projection magnitude" << endl;
300
	for(int es=0; es<maximum_eigenvalue; ++es)
300
	for(int es=0; es<maximum_eigenvalue; ++es)
301
	{
301
	{
302
		proj[es] = Vec3d(0.0);
302
		proj[es] = Vec3d(0.0);
303
		for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v)
303
		for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v)
304
		{
304
		{
305
			proj[es] +=  Vec3d(mani.pos(*v)) * Q[es][vtouched[*v]];
305
			proj[es] +=  Vec3d(mani.pos(*v)) * Q[es][vtouched[*v]];
306
			max_eig_values[es] = max(max_eig_values[es], static_cast<float>(abs(Q[es][vtouched[*v]])));
306
			max_eig_values[es] = max(max_eig_values[es], static_cast<float>(abs(Q[es][vtouched[*v]])));
307
		}
307
		}
308
	}
308
	}
309
}
309
}
310
 
310
 
311
#endif
311
#endif
312
 
312
 
313
void Harmonics::add_frequency(int es, float scale)
313
void Harmonics::add_frequency(int es, float scale)
314
{
314
{
315
	if(es<maximum_eigenvalue)
315
	if(es<maximum_eigenvalue)
316
		for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v){
316
		for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v){
317
			Vec3d p = Vec3d(proj[es]);
317
			Vec3d p = Vec3d(proj[es]);
318
			double Qval = Q[es][vtouched[*v]];
318
			double Qval = Q[es][vtouched[*v]];
319
			
319
			
320
			mani.pos(*v) += p * Qval * scale; 	
320
			mani.pos(*v) += p * Qval * scale; 	
321
		}
321
		}
322
}
322
}
323
 
323
 
324
void Harmonics::reset_shape()
324
void Harmonics::reset_shape()
325
{
325
{
326
	for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v)
326
	for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v)
327
		mani.pos(*v) = Vec3d(0);	
327
		mani.pos(*v) = Vec3d(0);	
328
}
328
}
329
void Harmonics::partial_reconstruct(int E0, int E1, float scale)
329
void Harmonics::partial_reconstruct(int E0, int E1, float scale)
330
{
330
{
331
	for(int es=E0;es<=E1;++es)
331
	for(int es=E0;es<=E1;++es)
332
		add_frequency(es, scale);
332
		add_frequency(es, scale);
333
}
333
}
334
 
334
 
335
void Harmonics::parse_key(unsigned char key)
335
void Harmonics::parse_key(unsigned char key)
336
{
336
{
337
	switch(key) {
337
	switch(key) {
338
		case '+': 
338
		case '+': 
339
			display_harmonics_time = display_harmonics_time+0.001; 
339
			display_harmonics_time = display_harmonics_time+0.001; 
340
			break;
340
			break;
341
		case '-': 
341
		case '-': 
342
			display_harmonics_time = display_harmonics_time-0.001; 
342
			display_harmonics_time = display_harmonics_time-0.001; 
343
			break;
343
			break;
344
		case 'd':	
344
		case 'd':	
345
			display_harmonics_diffuse = !display_harmonics_diffuse; 
345
			display_harmonics_diffuse = !display_harmonics_diffuse; 
346
			break;
346
			break;
347
		case 'h':
347
		case 'h':
348
			display_harmonics_highlight = !display_harmonics_highlight;
348
			display_harmonics_highlight = !display_harmonics_highlight;
349
			break;			
349
			break;			
350
	}
350
	}
351
	
351
	
352
}
352
}
353
 
353
 
354
 
354
 
355
void Harmonics::draw_adf()
355
void Harmonics::draw_adf()
356
{
356
{
357
	vector<double> F(mani.no_vertices(),0);
357
	vector<double> F(mani.no_vertices(),0);
358
	double F_max = 0;
358
	double F_max = 0;
359
	for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v){
359
	for(VertexIDIterator v = mani.vertices_begin(); v != mani.vertices_end(); ++v){
360
		int v_idx = vtouched[*v];
360
		int v_idx = vtouched[*v];
361
		for(int e = 1; e < V.Length(); ++e)
361
		for(int e = 1; e < V.Length(); ++e)
362
			F[v_idx] += sqr(Q[e][v_idx]) * exp(-(display_harmonics_time)*V[e]/V[1]);
362
			F[v_idx] += sqr(Q[e][v_idx]) * exp(-(display_harmonics_time)*V[e]/V[1]);
363
		F_max = max(F[v_idx], F_max);
363
		F_max = max(F[v_idx], F_max);
364
	}
364
	}
365
	cout << "F max" <<  F_max << endl;
365
	cout << "F max" <<  F_max << endl;
366
	glUseProgram(prog_P0);
366
	glUseProgram(prog_P0);
367
	glUniform1f(glGetUniformLocation(prog_P0,"eig_max"),F_max);//2*M_PI);
367
	glUniform1f(glGetUniformLocation(prog_P0,"eig_max"),F_max);//2*M_PI);
368
	glUniform1i(glGetUniformLocation(prog_P0,"do_diffuse"),display_harmonics_diffuse);
368
	glUniform1i(glGetUniformLocation(prog_P0,"do_diffuse"),display_harmonics_diffuse);
369
   	glUniform1i(glGetUniformLocation(prog_P0,"do_highlight"),display_harmonics_highlight);
369
   	glUniform1i(glGetUniformLocation(prog_P0,"do_highlight"),display_harmonics_highlight);
370
	GLuint attrib = glGetAttribLocationARB(prog_P0, "eigenvalue");
370
	GLuint attrib = glGetAttribLocationARB(prog_P0, "eigenvalue");
371
	
371
	
372
	glFrontFace(GL_CW);
372
	glFrontFace(GL_CW);
373
	for(FaceIDIterator f = mani.faces_begin(); f != mani.faces_end(); ++f){
373
	for(FaceIDIterator f = mani.faces_begin(); f != mani.faces_end(); ++f){
374
		glBegin(GL_TRIANGLES);
374
		glBegin(GL_TRIANGLES);
375
        for(Walker w = mani.walker(*f); !w.full_circle(); w = w.circulate_face_cw()){
375
        for(Walker w = mani.walker(*f); !w.full_circle(); w = w.circulate_face_cw()){
376
			int i = vtouched[w.vertex()];
376
			int i = vtouched[w.vertex()];
377
			glVertexAttrib1f(attrib,F[i]);
377
			glVertexAttrib1f(attrib,F[i]);
378
			glNormal3dv(normal(mani, w.vertex()).get());
378
			glNormal3dv(normal(mani, w.vertex()).get());
379
			glVertex3dv(mani.pos(w.vertex()).get());
379
			glVertex3dv(mani.pos(w.vertex()).get());
380
		}
380
		}
381
		glEnd();
381
		glEnd();
382
	}
382
	}
383
	glFrontFace(GL_CCW);
383
	glFrontFace(GL_CCW);
384
	glUseProgram(0);
384
	glUseProgram(0);
385
}
385
}
386
 
386
 
387
 
387