Subversion Repositories gelsvn

Rev

Rev 417 | Rev 456 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 417 Rev 434
Line 37... Line 37...
37
#include <HMesh/load.h>
37
#include <HMesh/load.h>
38
#include <HMesh/quadric_simplify.h>
38
#include <HMesh/quadric_simplify.h>
39
#include <HMesh/smooth.h>
39
#include <HMesh/smooth.h>
40
#include <HMesh/x3d_save.h>
40
#include <HMesh/x3d_save.h>
41
#include <HMesh/obj_save.h>
41
#include <HMesh/obj_save.h>
-
 
42
#include <HMesh/off_save.h>
42
#include <HMesh/mesh_optimization.h>
43
#include <HMesh/mesh_optimization.h>
43
#include <HMesh/triangulate.h>
44
#include <HMesh/triangulate.h>
44
#include <HMesh/close_holes.h>
45
#include <HMesh/close_holes.h>
45
#include <HMesh/caps_and_needles.h>
46
#include <HMesh/caps_and_needles.h>
46
#include <HMesh/refine_edges.h>
47
#include <HMesh/refine_edges.h>
Line 168... Line 169...
168
	get_vis_obj(dest).view_control() = get_vis_obj(src).view_control();
169
	get_vis_obj(dest).view_control() = get_vis_obj(src).view_control();
169
	
170
	
170
	return "";
171
	return "";
171
}
172
}
172
 
173
 
-
 
174
char* console_flatten(std::vector<std::string> &args)
-
 
175
{
-
 
176
	if(wantshelp(args)) 
-
 
177
	{
-
 
178
		theConsole.Printf("usage: flatten <floater|harmonic|barycentric>");
-
 
179
		theConsole.Printf("This function flattens a meshs with a simple boundary. It is mostly for showing mesh");
-
 
180
		theConsole.Printf("parametrization methods. The current mesh MUST have a SINGLE boundary loop");
-
 
181
		theConsole.Printf("This loop is mapped to the unit circle in a regular fashion (equal angle intervals).");
-
 
182
		theConsole.Printf("All non boundary vertices are placed at the origin. Then the system is relaxed iteratively");
-
 
183
		theConsole.Printf("using the weight scheme given as argument.");
-
 
184
		return "";
-
 
185
	}
-
 
186
	enum WeightScheme {FLOATER_W, HARMONIC_W, BARYCENTRIC_W};
-
 
187
	WeightScheme ws = BARYCENTRIC_W;
-
 
188
	if(args.size()>0)
-
 
189
	{
-
 
190
		if(args[0] == "floater")
-
 
191
			ws = FLOATER_W;
-
 
192
		else if(args[0] == "harmonic")
-
 
193
			ws = HARMONIC_W;
-
 
194
	}
-
 
195
	else
-
 
196
		return "";
-
 
197
	
-
 
198
	active_mesh().enumerate_vertices();
-
 
199
	active_mesh().enumerate_halfedges();
-
 
200
	
-
 
201
	vector<float> edge_weights(active_mesh().no_halfedges());
-
 
202
	for(HalfEdgeIter h=active_mesh().halfedges_begin(); h != active_mesh().halfedges_end(); ++h)
-
 
203
		if(!is_boundary(h))
-
 
204
		{
-
 
205
			Vec3f p0 = h->vert->pos;
-
 
206
			Vec3f p1 = h->next->vert->pos;
-
 
207
			Vec3f p2 = h->opp->vert->pos;
-
 
208
			Vec3f p3 = h->opp->next->vert->pos;
-
 
209
			
-
 
210
			if(ws == FLOATER_W)
-
 
211
			{
-
 
212
				float d = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p0), normalize(p3-p0)))));
-
 
213
				float g = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p0), normalize(p1-p0)))));
-
 
214
				edge_weights[h->opp->touched]  = (tan(d/2) + tan(g/2)) / (p0-p2).length();
-
 
215
				
-
 
216
				
-
 
217
				d = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p2), normalize(p1-p2)))));
-
 
218
				g = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p2), normalize(p3-p2)))));
-
 
219
				edge_weights[h->touched]  = (tan(d/2) + tan(g/2)) / (p0-p2).length();
-
 
220
			}
-
 
221
			else if(ws == HARMONIC_W)
-
 
222
			{
-
 
223
				
-
 
224
				float a = acos(min(1.0f, max(-1.0f, dot(normalize(p0-p3), normalize(p2-p3)))));
-
 
225
				float b = acos(min(1.0f, max(-1.0f, dot(normalize(p2-p1), normalize(p0-p1)))));
-
 
226
				float w=0;
-
 
227
				if(a+b < M_PI)
-
 
228
					w = sin(a+b)/(sin(a)+sin(b));
-
 
229
				edge_weights[h->touched]  = w;
-
 
230
				edge_weights[h->opp->touched]  = w;
-
 
231
			}
-
 
232
			else
-
 
233
			{
-
 
234
				edge_weights[h->touched]  = valency(h->opp->vert);
-
 
235
				edge_weights[h->opp->touched]  = valency(h->vert);
-
 
236
			}	
-
 
237
		}
-
 
238
	
-
 
239
	ofstream ofs("parametrized.obj");
-
 
240
	
-
 
241
	ofs << "mtllib parametrized.mtl\nusemtl mat\n" << endl;
-
 
242
	
-
 
243
	VertexIter v;
-
 
244
	for(v=active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v)
-
 
245
		ofs << "v " << v->pos[0] << " " << v->pos[1] << " " << v->pos[2] << endl;
-
 
246
	ofs << endl;
-
 
247
	
-
 
248
	
-
 
249
	for(v=active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v)
-
 
250
	{
-
 
251
		if(is_boundary(v))
-
 
252
			break;
-
 
253
	}
-
 
254
	int n=0;
-
 
255
	VertexIter bv = v;
-
 
256
	do{
-
 
257
		++n;
-
 
258
		bv = bv->he->vert;
-
 
259
	}
-
 
260
	while(bv != v);
-
 
261
	
-
 
262
	int i=0;
-
 
263
	do{
-
 
264
		float a = 2.0*M_PI*float(i)/n;
-
 
265
		bv->pos = Vec3f(cos(a), sin(a), 0);
-
 
266
		++i;
-
 
267
		bv = bv->he->vert;
-
 
268
	}
-
 
269
	while(bv != v);
-
 
270
	
-
 
271
	for(v=active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v)
-
 
272
		if(!is_boundary(v))
-
 
273
			v->pos = Vec3f(0.0);
-
 
274
	
-
 
275
	for(int i=0;i<10000;++i)
-
 
276
		for(v=active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v)
-
 
277
			if(!is_boundary(v))
-
 
278
			{
-
 
279
				Vec3f p_new(0);
-
 
280
				float w_sum = 0;
-
 
281
				for(VertexCirculator vc(v); !vc.end(); ++vc)
-
 
282
				{
-
 
283
					float w = edge_weights[vc.get_halfedge()->touched];
-
 
284
					p_new += vc.get_vertex()->pos * w;
-
 
285
					w_sum += w;
-
 
286
				}
-
 
287
				v->pos = p_new/w_sum;
-
 
288
			}
-
 
289
	
-
 
290
	for(v=active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v)
-
 
291
		ofs << "vt " << (0.5*v->pos[0]+0.5) << " " << (0.5*v->pos[1]+0.5)  << endl;
-
 
292
	
-
 
293
	ofs << endl;
-
 
294
	
-
 
295
	for(FaceIter f = active_mesh().faces_begin(); f != active_mesh().faces_end(); ++f)
-
 
296
	{
-
 
297
		ofs << "f ";
-
 
298
		for(FaceCirculator fc(f); !fc.end(); ++fc)
-
 
299
		{
-
 
300
			int idx = fc.get_vertex()->touched + 1;
-
 
301
			ofs << idx << "/" << idx <<" ";
-
 
302
		}
-
 
303
		ofs << endl;
-
 
304
	}
-
 
305
	
-
 
306
	return "";
-
 
307
}
173
 
308
 
174
char* console_save(std::vector<std::string> &args)
309
char* console_save(std::vector<std::string> &args)
175
{
310
{
176
	if(wantshelp(args)) 
311
	if(wantshelp(args)) 
177
	{
312
	{
Line 184... Line 319...
184
		if(file_name.substr(file_name.length()-4,file_name.length())==".obj")
319
		if(file_name.substr(file_name.length()-4,file_name.length())==".obj")
185
		{
320
		{
186
			obj_save(file_name, active_mesh());
321
			obj_save(file_name, active_mesh());
187
			return "";
322
			return "";
188
		}
323
		}
-
 
324
		else if(file_name.substr(file_name.length()-4,file_name.length())==".off")
-
 
325
		{
-
 
326
			off_save(file_name, active_mesh());
-
 
327
			return "";
-
 
328
		}
189
		else if(file_name.substr(file_name.length()-4,file_name.length())==".x3d")
329
		else if(file_name.substr(file_name.length()-4,file_name.length())==".x3d")
190
		{
330
		{
191
			x3d_save(file_name, active_mesh());
331
			x3d_save(file_name, active_mesh());
192
			return "";
332
			return "";
193
		}
333
		}
Line 550... Line 690...
550
}
690
}
551
 
691
 
552
 
692
 
553
char* console_partial_reconstruct(std::vector<std::string> &args)
693
char* console_partial_reconstruct(std::vector<std::string> &args)
554
{
694
{
555
  if(args.size() != 3)
695
	if(args.size() != 3)
556
		theConsole.Printf("usage: haramonics.partial_reconstruct <e0> <e1> <s>");
696
		theConsole.Printf("usage: haramonics.partial_reconstruct <e0> <e1> <s>");
557
 
697
	
558
  if(wantshelp(args)) 
698
	if(wantshelp(args)) 
559
	{
699
	{
560
		theConsole.Printf("Reconstruct from projections onto eigenvectors. The two first arguments indicate");
700
		theConsole.Printf("Reconstruct from projections onto eigenvectors. The two first arguments indicate");
561
		theConsole.Printf("the eigenvector interval that we reconstruct from. The last argument is the ");
701
		theConsole.Printf("the eigenvector interval that we reconstruct from. The last argument is the ");
562
		theConsole.Printf("scaling factor. Thus, for a vertex, v, the formula for computing the position, p, is:");
702
		theConsole.Printf("scaling factor. Thus, for a vertex, v, the formula for computing the position, p, is:");
563
		theConsole.Printf("for (i=e0; i<=e1;++i) p += proj[i] * Q[i][v] * s;");
703
		theConsole.Printf("for (i=e0; i<=e1;++i) p += proj[i] * Q[i][v] * s;");
564
		theConsole.Printf("where proj[i] is the 3D vector containing the x, y, and z projections of the mesh onto");
704
		theConsole.Printf("where proj[i] is the 3D vector containing the x, y, and z projections of the mesh onto");
565
		theConsole.Printf("eigenvector i. Q[i][v] is the v'th coordinate of the i'th eigenvector.");
705
		theConsole.Printf("eigenvector i. Q[i][v] is the v'th coordinate of the i'th eigenvector.");
566
		theConsole.Printf("Note that if vertex coordinates are not first reset, the result is probably unexpected.");
706
		theConsole.Printf("Note that if vertex coordinates are not first reset, the result is probably unexpected.");
567
	}
707
	}
568
 
708
	
569
  if(args.size() != 3)
709
	if(args.size() != 3)
570
		return "";
710
		return "";
571
 
711
	
572
  int E0,E1;
712
	int E0,E1;
573
	float scale;
713
	float scale;
574
	istringstream a0(args[0]);
714
	istringstream a0(args[0]);
575
	a0 >> E0;
715
	a0 >> E0;
576
	istringstream a1(args[1]);
716
	istringstream a1(args[1]);
577
	a1 >> E1;
717
	a1 >> E1;
Line 804... Line 944...
804
			v->pos = Vec3f(new_pos[i]);
944
			v->pos = Vec3f(new_pos[i]);
805
	}
945
	}
806
	return "";
946
	return "";
807
}
947
}
808
 
948
 
-
 
949
const double angle_defect(VertexIter v)
-
 
950
{
-
 
951
	if(!is_boundary(v))
-
 
952
	{
-
 
953
		Vec3f vertex(v->pos);
-
 
954
		vector<Vec3d> edges;
-
 
955
		for(VertexCirculator vc(v); !vc.end(); ++vc)
-
 
956
		{
-
 
957
			Vec3d e(normalize(vc.get_vertex()->pos-vertex));
-
 
958
			edges.push_back(e);
-
 
959
		}
-
 
960
		int N=edges.size();
-
 
961
		double angle_sum = 0;
-
 
962
		for(int i=0;i<N;++i)
-
 
963
		{
-
 
964
			double dot_prod = 
-
 
965
			s_max(-1.0, s_min(1.0, dot(edges[i],edges[(i+1)%N])));
-
 
966
			angle_sum += acos(dot_prod);
-
 
967
		}
-
 
968
		return fabs(2*M_PI - angle_sum);
-
 
969
	}
-
 
970
	return 1000;
-
 
971
}
-
 
972
 
-
 
973
char* console_experimental_smooth(std::vector<std::string> &args)
-
 
974
{
-
 
975
	if(wantshelp(args)) 
-
 
976
	{
-
 
977
		theConsole.Printf("usage:  smooth.experimental <weight> <iter>");
-
 
978
		theConsole.Printf("Perform experimental smoothing. weight is the scaling factor for the");
-
 
979
		theConsole.Printf("experimetnal vector which has been normalized by dividing by edge lengths");
-
 
980
		theConsole.Printf("this allows for larger steps as suggested by Desbrun et al.");
-
 
981
		theConsole.Printf("default weight = 1.0. Default number of iterations = 1");
-
 
982
		return "";
-
 
983
	}
-
 
984
	float t=1.0;
-
 
985
	if(args.size()>0)
-
 
986
	{
-
 
987
		istringstream a0(args[0]);
-
 
988
		a0 >> t;
-
 
989
	}
-
 
990
	int iter=1;
-
 
991
	if(args.size()>1)
-
 
992
	{
-
 
993
		istringstream a0(args[1]);
-
 
994
		a0 >> iter;
-
 
995
	}	
-
 
996
	
-
 
997
	Vec3f p0_before, p7_before;
-
 
998
	active_mesh().get_bbox(p0_before, p7_before);
-
 
999
 
-
 
1000
	double avg_area=0.0;
-
 
1001
	for(FaceIter f=active_mesh().faces_begin(); f != active_mesh().faces_end(); ++f)
-
 
1002
		avg_area += area(f);
-
 
1003
	avg_area /= active_mesh().no_faces();
-
 
1004
		
-
 
1005
	for(int j=0;j<iter;++j)
-
 
1006
	{
-
 
1007
		
-
 
1008
		vector<Vec3d> new_pos(active_mesh().no_vertices());
-
 
1009
 
-
 
1010
		int i=0;
-
 
1011
		for(VertexIter v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v,++i) 
-
 
1012
			{
-
 
1013
				double w_sum=0;
-
 
1014
				Vec3d m(0);
-
 
1015
				VertexCirculator vc(v);
-
 
1016
				for(; !vc.end(); ++vc)
-
 
1017
				{
-
 
1018
					HalfEdgeIter h = vc.get_halfedge();
-
 
1019
					double area_left  = area(h->face);
-
 
1020
					double area_right = area(h->opp->face);
-
 
1021
					
-
 
1022
					double w = 0.5 * (area_left + area_right);
-
 
1023
					m += w * Vec3d(vc.get_vertex()->pos-v->pos);
-
 
1024
					w_sum += w;
-
 
1025
				}
-
 
1026
				double t2 = pow((w_sum/vc.no_steps())/avg_area,.25);
-
 
1027
				if(t2 > 1e-10)
-
 
1028
					new_pos[i] = Vec3d(v->pos)  + (t * t2 * m/w_sum);
-
 
1029
			}
-
 
1030
		i=0;
-
 
1031
		for(VertexIter v = active_mesh().vertices_begin(); v != active_mesh().vertices_end(); ++v,++i)
-
 
1032
			v->pos = Vec3f(new_pos[i]);
-
 
1033
		
-
 
1034
		active_mesh().delayed_erase();
-
 
1035
		for(HalfEdgeIter h=active_mesh().halfedges_begin(); h!=active_mesh().halfedges_end(); ++h)
-
 
1036
			if(active_mesh().is_used(h))
-
 
1037
		{
-
 
1038
			Vec3d mcna,mcnb;
-
 
1039
			double ws;
-
 
1040
			
-
 
1041
			unnormalized_mean_curvature_normal(h->vert, mcna, ws);
-
 
1042
			unnormalized_mean_curvature_normal(h->opp->vert, mcnb, ws);
-
 
1043
			if(sqr_length(mcna) < 1 && sqr_length(mcnb) < 1)
-
 
1044
				if(active_mesh().collapse_precond(h))
-
 
1045
				{
-
 
1046
					active_mesh().collapse_halfedge(h, false);
-
 
1047
				}
-
 
1048
		}
-
 
1049
		active_mesh().immediate_erase();
-
 
1050
		maximize_min_angle(active_mesh(), 0.95, false);
-
 
1051
	}
-
 
1052
	
-
 
1053
	Vec3f p0, p7;
-
 
1054
	active_mesh().get_bbox(p0, p7);
-
 
1055
	for(VertexIter vi = active_mesh().vertices_begin(); vi != active_mesh().vertices_end(); ++vi)
-
 
1056
		vi->pos = (p7_before-p0_before)*(vi->pos - p0)/(p7-p0)+p0_before;
-
 
1057
	
-
 
1058
	return "";
-
 
1059
}
-
 
1060
 
809
 
1061
 
810
char* console_taubin_smooth(std::vector<std::string> &args)
1062
char* console_taubin_smooth(std::vector<std::string> &args)
811
{
1063
{
812
	if(wantshelp(args)) 
1064
	if(wantshelp(args)) 
813
	{
1065
	{
Line 985... Line 1237...
985
		switch(key) {
1237
		switch(key) {
986
			case '\033': 
1238
			case '\033': 
987
				theConsole.ToggleConsole();
1239
				theConsole.ToggleConsole();
988
			default:
1240
			default:
989
				theConsole.EnterCommandCharacter(key);
1241
				theConsole.EnterCommandCharacter(key);
990
			break;
1242
				break;
991
		}
1243
		}
992
		if(key == 13)	avo().post_create_display_list();
1244
		if(key == 13)	avo().post_create_display_list();
993
		
1245
		
994
	}	
1246
	}	
995
	else {
1247
	else {
Line 1084... Line 1336...
1084
	CreateCVar("harmonics.reset_shape", console_reset_shape);
1336
	CreateCVar("harmonics.reset_shape", console_reset_shape);
1085
	CreateCVar("harmonics.analyze", console_analyze);
1337
	CreateCVar("harmonics.analyze", console_analyze);
1086
	CreateCVar("harmonics.partial_reconstruct", console_partial_reconstruct);
1338
	CreateCVar("harmonics.partial_reconstruct", console_partial_reconstruct);
1087
	CreateCVar("simplify", console_simplify);
1339
	CreateCVar("simplify", console_simplify);
1088
	CreateCVar("smooth.mean_curvature", console_mean_curvature_smooth);
1340
	CreateCVar("smooth.mean_curvature", console_mean_curvature_smooth);
-
 
1341
	CreateCVar("smooth.experimental", console_experimental_smooth);
1089
	CreateCVar("smooth.laplacian", console_laplacian_smooth);
1342
	CreateCVar("smooth.laplacian", console_laplacian_smooth);
1090
	CreateCVar("smooth.taubin", console_taubin_smooth);
1343
	CreateCVar("smooth.taubin", console_taubin_smooth);
1091
	CreateCVar("smooth.fuzzy_vector_median", console_fvm_smooth);
1344
	CreateCVar("smooth.fuzzy_vector_median", console_fvm_smooth);
1092
	
1345
	
1093
	CreateCVar("optimize.valency", console_optimize_valency);
1346
	CreateCVar("optimize.valency", console_optimize_valency);
Line 1107... Line 1360...
1107
	CreateCVar("noise.perturb_vertices", console_vertex_noise);
1360
	CreateCVar("noise.perturb_vertices", console_vertex_noise);
1108
	CreateCVar("noise.perturb_vertices_perpendicular", console_perpendicular_vertex_noise);
1361
	CreateCVar("noise.perturb_vertices_perpendicular", console_perpendicular_vertex_noise);
1109
	CreateCVar("noise.perturb_topology", console_noisy_flips);
1362
	CreateCVar("noise.perturb_topology", console_noisy_flips);
1110
	
1363
	
1111
	CreateCVar("dual", console_dual);
1364
	CreateCVar("dual", console_dual);
-
 
1365
	CreateCVar("flatten", console_flatten);
1112
	
1366
	
1113
	CreateCVar("align", console_align);
1367
	CreateCVar("align", console_align);
1114
	
1368
	
1115
	CVarUtils::CreateCVar( "history.load", ConsoleLoadHistory );
1369
	CVarUtils::CreateCVar( "history.load", ConsoleLoadHistory );
1116
    CVarUtils::CreateCVar( "history.save", ConsoleSaveHistory );
1370
    CVarUtils::CreateCVar( "history.save", ConsoleSaveHistory );