Subversion Repositories gelsvn

Rev

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

Rev Author Line No. Line
362 jab 1
#include <map>
2
#include <algorithm>
3
#include <queue>
4
 
5
#include "Util/Grid2D.h"
6
#include "CGLA/Vec3f.h"
7
#include "CGLA/Vec2f.h"
8
 
9
#include "tessellate.h"
10
 
11
using namespace std;
12
using namespace CGLA;
13
using namespace Util;
14
 
15
namespace Geometry
16
{
17
 
18
	float MAX_ERR = 5;
19
	float MAX_DIST = 5;
20
	int  ADAPTIVE = false;
21
 
22
#define mymax(x,y) ((x)>(y)?(x):(y))
23
 
24
	// Test surfaces ---
25
 
26
 
27
	// ----------- CONSTANTS AND GLOBALS ------------
28
 
29
	namespace
30
	{
31
		float maximum_edge_error=0;
32
 
33
		IndexedFaceSet* face_set_ptr = 0;
34
		ParSurf* the_surf = 0;
35
 
36
		class TreeNode;
37
		typedef TreeNode* TreeNodePtr;
38
 
39
		vector<TreeNode*> root_nodes;
40
 
41
		class Point 
42
		{
43
			friend class Edge;
44
			friend float subdiv(int level, const Point&, const Point&, TreeNodePtr&);
45
			friend float compute_mid_pt_err(const Point&, const Point&, Point&);
46
 
47
 
48
			Vec2f ppos;
49
			Vec3f pos;
50
			mutable int vertex_idx;
51
 
52
public:
53
 
54
				Point(const Vec2f& _ppos, const Vec3f& _pos): 
55
				ppos(_ppos), pos(_pos), vertex_idx(-1)
56
			{
57
			}
58
 
59
			Point() {}
60
 
61
			void create_vertex() const
62
			{
63
				if(vertex_idx == -1) 
64
					vertex_idx = face_set_ptr->add_vertex(pos);
65
			}
66
		};
67
 
68
 
69
 
70
		inline const Point create_point(float u, float v)
71
		{
72
			Vec2f ppos(u,v);
73
			Vec3f pos = (*the_surf)(u,v);
74
			return Point(ppos, pos);
75
		}
76
 
77
		float subdiv(int level, const Point& lp, const Point& rp, TreeNodePtr& node);
78
 
79
		class TreeNode
80
		{
81
			friend class Edge;
82
			friend float subdiv(int level, const Point&, const Point&, TreeNodePtr&);
83
 
84
			const Point p;
85
			const float error;
86
 
87
			const TreeNodePtr left;
88
			const TreeNodePtr right;
89
 
90
public:
91
 
92
				TreeNode(const Point& _p, float _error,
93
						 TreeNodePtr _left, TreeNodePtr _right):
94
				p(_p), error(_error), left(_left), right(_right)  {}
95
 
96
			~TreeNode() 
97
			{
98
				if(left)
99
					delete left; 
100
 
101
				if(right)
102
					delete right;
103
			}
104
 
105
		};
106
 
107
		class Edge
108
		{
109
			friend Edge create_edge(const Point&, const Point&, bool);
110
 
111
			Edge(const Point& _left_point, 
112
				 const Point& _right_point, 
113
				 TreeNodePtr _root,
114
				 bool _cw): 
115
				left_point(_left_point), right_point(_right_point), root(_root), cw(_cw)
116
			{
117
			}
118
 
119
 
120
			Point left_point;
121
			Point right_point;
122
			TreeNodePtr root;
123
			bool cw;
124
 
125
public:
126
 
127
				Edge() {}
128
 
129
			float get_error() const
130
			{
131
				if(root)
132
					return root->error;
133
				return 0.0f;
134
			}
135
 
136
			float get_length() const
137
			{
138
				return (left_point.pos-right_point.pos).length();
139
			}
140
 
141
			bool is_simple() const 
142
			{
143
				if(root->left==0)
144
				{
145
					assert(root->left==0);
146
					assert(root->right==0);
147
					return true;
148
				}
149
				return false;
150
			}
151
 
152
			const Edge get_sub_edge(int edge_no) const
153
			{
154
				assert(edge_no == 0 || edge_no == 1);
155
				assert(!is_simple());
156
 
157
				if(!cw) edge_no = 1-edge_no;
158
 
159
				if(edge_no ==0)
160
					return Edge(left_point, root->p, root->left, cw);
161
				else
162
					return Edge(root->p, right_point, root->right, cw);
163
			}
164
 
165
			const Edge get_opp_edge() const
166
			{
167
				return Edge(left_point, right_point, root, !cw);
168
			}
169
 
170
 
171
			const Point& get_split_point() const
172
			{
173
				assert(!is_simple());
174
				return root->p;
175
			}
176
 
177
			const Point& get_point(int i) const
178
			{
179
				assert(i==0 || i==1);
180
				if(!cw) i=1-i;
181
				if(i == 0) 
182
					return left_point;
183
				return right_point;
184
			}
185
 
186
			int get_point_idx(int i) const
187
			{
188
				assert(i==0 || i==1);
189
				if(!cw) i=1-i;
190
				if(i == 0) 
191
					return left_point.vertex_idx;
192
				return right_point.vertex_idx;
193
			}
194
 
195
		};
196
 
197
 
198
		float compute_mid_pt_err(const Point&, const Point&, Point&);
199
 
200
		Edge create_edge(const Point& left_point, const Point& right_point, 
201
						 bool cw=true)
202
		{
203
			TreeNodePtr root=0;
204
			if(ADAPTIVE)
205
				subdiv(0, left_point,right_point,root);
206
			else
207
			{
208
				Point mid_point;
209
				float err = compute_mid_pt_err(left_point, right_point, mid_point);
210
				root = new TreeNode(mid_point,err,0,0);
211
			}
212
			if(root)
213
				root_nodes.push_back(root);
214
 
215
			return Edge(left_point, right_point, root, cw);
216
		}
217
 
218
		class Triangle
219
		{
220
			Edge a,b,c;
221
public:
222
			Triangle(const Edge& _a, const Edge& _b, const Edge& _c):
223
			a(_a),  b(_b), c(_c) {}
224
 
225
			const Edge& operator[](int i) const
226
		{
227
			switch(i)
228
			{
229
				case 0: return a;
230
				case 1: return b;
231
				case 2: return c;
232
			}
233
			return c;
234
		}
235
 
236
		};
237
 
238
		float compute_mid_pt_err(const Point& lp, const Point& rp, 
239
								 Point& mid_point)
240
		{
241
			Vec3f m = (lp.pos - rp.pos)/2.0f + rp.pos;
242
			Vec2f uvm = (lp.ppos -rp.ppos)/2.0f + rp.ppos;
243
 
244
			mid_point = create_point(uvm[0], uvm[1]);
245
			Vec3f diff = mid_point.pos - m;
246
			return diff.length();
247
		}
248
 
249
		float subdiv(int level, const Point& lp, const Point& rp, TreeNodePtr& node)
250
		{
251
			Point mid_point;
252
			float err = compute_mid_pt_err(lp,rp,mid_point);
253
 
254
			Vec3f dist = lp.pos-rp.pos;
255
			if (level>10) 
256
			{
257
				node = new TreeNode(mid_point,err,0,0);
258
				return err;
259
			}
260
 
261
			TreeNodePtr lnode;
262
			float lerr = subdiv(level+1,lp, mid_point, lnode);
263
 
264
			TreeNodePtr rnode;
265
			float rerr = subdiv(level+1,mid_point, rp, rnode);
266
 
267
			float max_err = mymax(err, mymax(lerr,rerr));
268
 
269
			if(max_err < MAX_ERR)
270
			{
271
				if(lnode) delete lnode;
272
				if(rnode) delete rnode;
273
 
274
				node = new TreeNode(mid_point, max_err, 0,0);
275
			}
276
			else
277
			{
278
				mid_point.create_vertex();
279
				node = new TreeNode(mid_point, max_err, lnode,rnode);
280
			}
281
 
282
			return max_err;
283
		}
284
 
285
 
286
 
287
		void split(const Triangle orig_tri)
288
		{
289
			queue<Triangle> tri_queue;
290
			tri_queue.push(orig_tri);
291
 
292
 
293
			while(!tri_queue.empty())
294
			{
295
				const Triangle tri = tri_queue.front();
296
				tri_queue.pop();
297
 
298
				int no_split_edges = 0;
299
 
300
				for(int i=0;i<3;++i)
301
					if(!tri[i].is_simple())
302
						++no_split_edges;
303
 
304
				if(no_split_edges==0 /* || level > 2000*/) 
305
				{
306
					int a = tri[0].get_point_idx(0);
307
					int b = tri[1].get_point_idx(0);
308
					int c = tri[2].get_point_idx(0);
309
					face_set_ptr->add_face(Vec3i(a,b,c));
310
					maximum_edge_error = mymax(mymax(tri[0].get_error(),
311
													 tri[1].get_error()),
312
											   tri[2].get_error());
313
				}
314
				else if(no_split_edges==3)
315
				{
316
					const Point& p0 = tri[0].get_point(0);
317
					const Point& p1 = tri[1].get_point(0);
318
					const Point& p2 = tri[2].get_point(0);
319
 
320
					const Point sp[3] = {tri[0].get_split_point(),
321
						tri[1].get_split_point(),
322
						tri[2].get_split_point()};
323
 
324
					Edge sp_edg[3] = {create_edge(sp[0],p2),
325
						create_edge(sp[1],p0),
326
						create_edge(sp[2],p1)};
327
 
328
					int i_min=0;
329
					float l_min = sp_edg[0].get_length();
330
					int i;
331
					for(i=1;i<3;++i)
332
					{
333
						float len = sp_edg[i].get_length();
334
						if(len<l_min) 
335
						{
336
							l_min = len;
337
							i_min = i;
338
						}
339
					}
340
 
341
					i = i_min;
342
					int j = (i+1)%3;
343
					int k = (i+2)%3;
344
 
345
					Edge spi_spj = create_edge(sp[i],sp[j]);
346
					Edge spi_spk = create_edge(sp[i],sp[k]);
347
 
348
					Triangle tri0(tri[i].get_sub_edge(1),
349
								  tri[j].get_sub_edge(0),
350
								  spi_spj.get_opp_edge());
351
					Triangle tri1(spi_spj,
352
								  tri[j].get_sub_edge(1),
353
								  sp_edg[i].get_opp_edge());
354
					Triangle tri2(sp_edg[i],
355
								  tri[k].get_sub_edge(0),
356
								  spi_spk.get_opp_edge());
357
					Triangle tri3(spi_spk,
358
								  tri[k].get_sub_edge(1),
359
								  tri[i].get_sub_edge(0));
360
 
361
					tri_queue.push(tri0);
362
					tri_queue.push(tri1);
363
					tri_queue.push(tri2);
364
					tri_queue.push(tri3);
365
				}
366
				else if(no_split_edges==2)
367
				{
368
					int i;
369
					if(tri[2].is_simple()) i = 0;
370
					else if(tri[1].is_simple()) i=2;
371
					else i = 1;
372
 
373
					int j = (i+1)%3;
374
					int k = (i+2)%3;
375
 
376
					const Point& spi = tri[i].get_split_point();
377
					const Point& spj = tri[j].get_split_point();
378
 
379
					const Point& pi = tri[i].get_point(0);
380
					const Point& pk = tri[k].get_point(0);
381
 
382
					Edge spi_spj = create_edge(spi, spj);
383
					Edge pi_spj = create_edge(pi, spj);
384
					Edge pk_spi = create_edge(pk, spi);
385
 
386
					Triangle tri0(tri[i].get_sub_edge(1),
387
								  tri[j].get_sub_edge(0),
388
								  spi_spj.get_opp_edge());
389
 
390
 
391
					if(pi_spj.get_length() < pk_spi.get_length())
392
					{
393
						Triangle tri1(spi_spj,
394
									  pi_spj.get_opp_edge(),
395
									  tri[i].get_sub_edge(0));
396
						Triangle tri2(pi_spj,
397
									  tri[j].get_sub_edge(1),
398
									  tri[k]);
399
						tri_queue.push(tri1);					
400
						tri_queue.push(tri2);	
401
					}
402
					else
403
					{
404
						Triangle tri1(tri[i].get_sub_edge(0),
405
									  pk_spi.get_opp_edge(),
406
									  tri[k]);
407
						Triangle tri2(spi_spj,
408
									  tri[j].get_sub_edge(1),
409
									  pk_spi);
410
						tri_queue.push(tri1);					
411
						tri_queue.push(tri2);
412
					}
413
					tri_queue.push(tri0);
414
				}
415
				else if(no_split_edges==1)
416
				{
417
					int i;
418
					if(!tri[0].is_simple()) i=0;
419
					else if(!tri[1].is_simple()) i=1;
420
					else i= 2;
421
 
422
					int j = (i+1)%3;
423
					int k = (i+2)%3;
424
 
425
					const Point& pk = tri[k].get_point(0);
426
					const Point& spi = tri[i].get_split_point();
427
 
428
					Edge spi_pk = create_edge(spi, pk);
429
 
430
					Triangle tri0(tri[i].get_sub_edge(1),
431
								  tri[j],
432
								  spi_pk.get_opp_edge());
433
 
434
					Triangle tri1(tri[i].get_sub_edge(0),
435
								  spi_pk,
436
								  tri[k]);
437
 
438
					tri_queue.push(tri0);
439
					tri_queue.push(tri1);
440
 
441
				}
442
			}
443
		}
444
	}
445
 
446
 
447
	void tessellate(IndexedFaceSet& face_set, ParSurf& s, Grid2D<Vec3f>& inigrid)
448
	{	
449
		face_set_ptr = &face_set;
450
		int i;
451
		int n=inigrid.get_xdim()-1;
452
		int m=inigrid.get_ydim()-1;
453
		the_surf = &s;
454
		Grid2D<Point> points(n+1,m+1);
455
		for(i=0;i<=n;++i)
456
			for(int j=0;j<=m;++j)
457
			{
458
				Vec3f p = inigrid(i,j);
459
				points(i,j) = create_point(p[0], p[1]);
460
				points(i,j).create_vertex();
461
			}
462
 
463
 
464
				Grid2D<Edge> h_edges(n,m+1);
465
		Grid2D<Edge> v_edges(n+1,m);
466
		for(i=0;i<=n;++i)
467
			for(int j=0;j<=m;++j)
468
			{
469
				if(i<n)
470
					h_edges(i,j) = create_edge(points(i,j), points(i+1,j));
471
				if(j<m)
472
					v_edges(i,j) = create_edge(points(i,j), points(i,j+1));
473
			}
474
 
475
				for(i=0;i<n;++i)
476
					for(int j=0;j<m;++j)
477
					{
478
						Edge diag = create_edge(points(i,j), points(i+1,j+1));
479
						Triangle tri0(h_edges(i,j), v_edges(i+1,j), diag.get_opp_edge());
480
						Triangle tri1(diag, h_edges(i,j+1).get_opp_edge(), 
481
									  v_edges(i,j).get_opp_edge());
482
						split(tri0);
483
						split(tri1);
484
					}
373 jrf 485
						for(i=0;i<static_cast<int>(root_nodes.size());++i)
362 jab 486
						{
487
							if(root_nodes[i])
488
							{
489
								delete root_nodes[i];
490
							}
491
						}
492
						root_nodes.clear();
493
		maximum_edge_error=0;
494
		the_surf = 0;
495
	}
496
 
497
 
498
	void tessellate(IndexedFaceSet& face_set, ParSurf& s,
499
					float u_min, float u_max, float v_min, float v_max, 
500
					int n, int m)
501
	{	
502
		face_set_ptr = &face_set;
503
		int i;
504
		the_surf = &s;
505
		Grid2D<Point> points(n+1,m+1);
506
		float step_x = (u_max-u_min)/float(n);
507
		float step_y = (v_max-v_min)/float(m);
508
		for(i=0;i<=n;++i)
509
			for(int j=0;j<=m;++j)
510
			{
511
				points(i,j) = create_point(u_min+i*step_x,v_min+j*step_y);
512
				points(i,j).create_vertex();
513
			}
514
 
515
 
516
				Grid2D<Edge> h_edges(n,m+1);
517
		Grid2D<Edge> v_edges(n+1,m);
518
		for(i=0;i<=n;++i)
519
			for(int j=0;j<=m;++j)
520
			{
521
				if(i<n)
522
					h_edges(i,j) = create_edge(points(i,j), points(i+1,j));
523
				if(j<m)
524
					v_edges(i,j) = create_edge(points(i,j), points(i,j+1));
525
			}
526
 
527
				for(i=0;i<n;++i)
528
					for(int j=0;j<m;++j)
529
					{
530
						Edge diag = create_edge(points(i,j), points(i+1,j+1));
531
						Triangle tri0(h_edges(i,j), v_edges(i+1,j), diag.get_opp_edge());
532
						Triangle tri1(diag, h_edges(i,j+1).get_opp_edge(), 
533
									  v_edges(i,j).get_opp_edge());
534
						split(tri0);
535
						split(tri1);
536
					}
373 jrf 537
						for(i=0;i<static_cast<int>(root_nodes.size());++i)
362 jab 538
						{
539
							if(root_nodes[i])
540
							{
541
								delete root_nodes[i];
542
							}
543
						}
544
						root_nodes.clear();
545
		maximum_edge_error=0;
546
		the_surf = 0;
547
	}
548
 
549
 
550
	/** The Edge2VertexMap is a simple database class.
551
		The database stores integer values referenced by keys formed by
552
		a pair of indices. The intended use is to let the key be a pair
553
		of vertices sharing an edge and the value be a new vertex inserted on
554
		that edge. */
555
	class EdgeMap
556
	{
557
		typedef pair<int,int>      VertPair;
558
		typedef map<VertPair, Edge> E2VMap;
559
		typedef E2VMap::iterator   E2VIter;
560
 
561
		E2VMap edge_to_vertex;
562
 
563
public:
564
 
565
			void set_edge(int ind0, int ind1, const Edge& new_edge)
566
		{
567
				edge_to_vertex[VertPair(ind0,ind1)] = new_edge;
568
		}
569
 
570
		bool find_edge(int ind0, int ind1, Edge& edg)
571
		{
572
			E2VIter iter = edge_to_vertex.find(VertPair(ind0,ind1));
573
 
574
			if(iter == edge_to_vertex.end())
575
				return false;
576
 
577
			edg = iter->second;
578
			return true;
579
		}
580
 
581
	};
582
 
583
	void tessellate(IndexedFaceSet& face_set, ParSurf& s, 
584
					std::vector<Vec2f> uv_points,
585
					std::vector<Vec3i> triangles)
586
	{		
587
		face_set_ptr = &face_set;
588
		int i;
589
		the_surf = &s;
590
		int N = uv_points.size();
591
		vector<Point> points(N);
592
		for(i=0;i<N;++i)
593
		{
594
			points[i] = create_point(uv_points[i][0], uv_points[i][1]);
595
			points[i].create_vertex();
596
		}
597
		EdgeMap edges;
598
		vector<Triangle> tris;
373 jrf 599
		for(size_t j=0;j<triangles.size();++j)
362 jab 600
		{
601
			Edge e[3];
602
			int v[3];
603
 
604
			v[0] = triangles[j][0];
605
			v[1] = triangles[j][1];
606
			v[2] = triangles[j][2];
607
 
608
			for(int i=0;i<3;++i)
609
			{
610
				int k = (i+1)%3;
611
				if(!edges.find_edge(v[i],v[k],e[i]))
612
				{
613
					e[i] = create_edge(points[v[i]], points[v[k]]);
614
					edges.set_edge(v[k],v[i],e[i].get_opp_edge());
615
				}
616
			}
617
			split(Triangle(e[0],e[1],e[2]));
618
 
619
		}
373 jrf 620
		for(i=0;i<static_cast<int>(root_nodes.size());++i)
362 jab 621
		{
622
			if(root_nodes[i])
623
			{
624
				delete root_nodes[i];
625
			}
626
		}
627
		root_nodes.clear();
628
		maximum_edge_error=0;
629
		the_surf = 0;
630
	}
631
 
632
}