Subversion Repositories gelsvn

Rev

Rev 417 | Rev 601 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 417 Rev 595
1
/**********************************************************************
1
/**********************************************************************
2
 
2
 
3
polygonizer.h
3
polygonizer.h
4
 
4
 
5
This is Jules Bloomenthal's implicit surface polygonizer from GRAPHICS 
5
This is Jules Bloomenthal's implicit surface polygonizer from GRAPHICS 
6
GEMS IV. Bloomenthal's polygonizer is still used and the present code
6
GEMS IV. Bloomenthal's polygonizer is still used and the present code
7
is simply the original code morphed into C++.
7
is simply the original code morphed into C++.
8
 
8
 
9
J. Andreas Bærentzen 2003.
9
J. Andreas Bærentzen 2003.
10
 
10
 
11
**********************************************************************/
11
**********************************************************************/
12
 
12
 
-
 
13
/* Original Comment
-
 
14
 
-
 
15
 * C code from the article
-
 
16
 * "An Implicit Surface Polygonizer"
-
 
17
 * http::www.unchainedgeometry.com/jbloom/papers/polygonizer.pdf
-
 
18
 * by Jules Bloomenthal, jules@bloomenthal.com
-
 
19
 * in "Graphics Gems IV", Academic Press, 1994 */
-
 
20
 
-
 
21
/* polygonizer.c - implicit surface polygonizer, translated from Mesa
-
 
22
 *
-
 
23
 * Authored by Jules Bloomenthal, Xerox PARC.
-
 
24
 * Copyright (c) Xerox Corporation, 1991.  All rights reserved.
-
 
25
 * Permission is granted to reproduce, use and distribute this code for
-
 
26
 * any and all purposes, provided that this notice appears in all copies.  */
-
 
27
 
13
#include <string>
28
#include <string>
14
#include <stdlib.h>
29
#include <stdlib.h>
15
#include <math.h>
30
#include <math.h>
16
#include <iostream>
31
#include <iostream>
17
#include <vector>
32
#include <vector>
18
#include <list>
33
#include <list>
19
#include <sys/types.h>
34
#include <sys/types.h>
20
#include "CGLA/CGLA.h"
35
#include "CGLA/CGLA.h"
21
#include "Polygonizer.h"
36
#include "Polygonizer.h"
22
 
37
 
23
using namespace std;
38
using namespace std;
24
using namespace CGLA;
39
using namespace CGLA;
25
 
40
 
26
namespace Geometry
41
namespace Geometry
27
{
42
{
28
 
43
 
29
	namespace
44
	namespace
30
	{
45
	{
31
		const int RES =	10; /* # converge iterations    */
46
		const int RES =	10; /* # converge iterations    */
32
 
47
 
33
		const int L =	0;  /* left direction:	-x, -i */
48
		const int L =	0;  /* left direction:	-x, -i */
34
		const int R =	1;  /* right direction:	+x, +i */
49
		const int R =	1;  /* right direction:	+x, +i */
35
		const int B =	2;  /* bottom direction: -y, -j */
50
		const int B =	2;  /* bottom direction: -y, -j */
36
		const int T =	3;  /* top direction:	+y, +j */
51
		const int T =	3;  /* top direction:	+y, +j */
37
		const int N =	4;  /* near direction:	-z, -k */
52
		const int N =	4;  /* near direction:	-z, -k */
38
		const int F =	5;  /* far direction:	+z, +k */
53
		const int F =	5;  /* far direction:	+z, +k */
39
		const int LBN =	0;  /* left bottom near corner  */
54
		const int LBN =	0;  /* left bottom near corner  */
40
		const int LBF =	1;  /* left bottom far corner   */
55
		const int LBF =	1;  /* left bottom far corner   */
41
		const int LTN =	2;  /* left top near corner     */
56
		const int LTN =	2;  /* left top near corner     */
42
		const int LTF =	3;  /* left top far corner      */
57
		const int LTF =	3;  /* left top far corner      */
43
		const int RBN =	4;  /* right bottom near corner */
58
		const int RBN =	4;  /* right bottom near corner */
44
		const int RBF =	5;  /* right bottom far corner  */
59
		const int RBF =	5;  /* right bottom far corner  */
45
		const int RTN =	6;  /* right top near corner    */
60
		const int RTN =	6;  /* right top near corner    */
46
		const int RTF =	7;  /* right top far corner     */
61
		const int RTF =	7;  /* right top far corner     */
47
 
62
 
48
 
63
 
49
		/* the LBN corner of cube (i, j, k), corresponds with location
64
		/* the LBN corner of cube (i, j, k), corresponds with location
50
		 * (start.x+(i-.5)*size, start.y+(j-.5)*size, start.z+(k-.5)*size) */
65
		 * (start.x+(i-.5)*size, start.y+(j-.5)*size, start.z+(k-.5)*size) */
51
 
66
 
52
		inline float RAND() 
67
		inline float RAND() 
53
		{
68
		{
54
			return (gel_rand()&GEL_RAND_MAX)/static_cast<float>(GEL_RAND_MAX);
69
			return (gel_rand()&GEL_RAND_MAX)/static_cast<float>(GEL_RAND_MAX);
55
		}
70
		}
56
 
71
 
57
		const int HASHBIT = 5;
72
		const int HASHBIT = 5;
58
 
73
 
59
		const int HASHSIZE = (size_t)(1<<(3*HASHBIT));   
74
		const int HASHSIZE = (size_t)(1<<(3*HASHBIT));   
60
 
75
 
61
		const int MASK = ((1<<HASHBIT)-1);
76
		const int MASK = ((1<<HASHBIT)-1);
62
 
77
 
63
		inline int HASH( int i, int j,int k) 
78
		inline int HASH( int i, int j,int k) 
64
		{ 
79
		{ 
65
			return (((((i&MASK)<<HASHBIT)|j&MASK)<<HASHBIT)|k&MASK);
80
			return (((((i&MASK)<<HASHBIT)|(j&MASK))<<HASHBIT)|(k&MASK));
66
		} 
81
		} 
67
 
82
 
68
		inline int BIT(int i, int bit) 
83
		inline int BIT(int i, int bit) 
69
		{ 
84
		{ 
70
			return (i>>bit)&1; 
85
			return (i>>bit)&1; 
71
		}
86
		}
72
 
87
 
73
		// flip the given bit of i 
88
		// flip the given bit of i 
74
		inline int FLIP(int i, int bit) 
89
		inline int FLIP(int i, int bit) 
75
		{
90
		{
76
			return i^1<<bit;
91
			return i^1<<bit;
77
		}
92
		}
78
 
93
 
79
		struct TEST {		   /* test the function for a signed value */
94
		struct TEST {		   /* test the function for a signed value */
80
			POINT p;			   /* location of test */
95
			POINT p;			   /* location of test */
81
			float value;		   /* function value at p */
96
			float value;		   /* function value at p */
82
			int ok;			   /* if value is of correct sign */
97
			int ok;			   /* if value is of correct sign */
83
		};
98
		};
84
 
99
 
85
		struct CORNER {		   /* corner of a cube */
100
		struct CORNER {		   /* corner of a cube */
86
			int i, j, k;		   /* (i, j, k) is index within lattice */
101
			int i, j, k;		   /* (i, j, k) is index within lattice */
87
			float x, y, z, value;	   /* location and function value */
102
			float x, y, z, value;	   /* location and function value */
88
		};
103
		};
89
 
104
 
90
		struct CUBE {		   /* partitioning cell (cube) */
105
		struct CUBE {		   /* partitioning cell (cube) */
91
			int i, j, k;		   /* lattice location of cube */
106
			int i, j, k;		   /* lattice location of cube */
92
			CORNER *corners[8];		   /* eight corners */
107
			CORNER *corners[8];		   /* eight corners */
93
		};
108
		};
94
 
109
 
95
		struct CENTERELEMENT {	   /* list of cube locations */
110
		struct CENTERELEMENT {	   /* list of cube locations */
96
			int i, j, k;		   /* cube location */
111
			int i, j, k;		   /* cube location */
97
			CENTERELEMENT(int _i, int _j, int _k): i(_i), j(_j), k(_k) {}
112
			CENTERELEMENT(int _i, int _j, int _k): i(_i), j(_j), k(_k) {}
98
		};
113
		};
99
		typedef list<CENTERELEMENT> CENTERLIST;
114
		typedef list<CENTERELEMENT> CENTERLIST;
100
 
115
 
101
		struct CORNERELEMENT {	   /* list of corners */
116
		struct CORNERELEMENT {	   /* list of corners */
102
			int i, j, k;		   /* corner id */
117
			int i, j, k;		   /* corner id */
103
			float value;		   /* corner value */
118
			float value;		   /* corner value */
104
			CORNERELEMENT(int _i, int _j, int _k, float _value):
119
			CORNERELEMENT(int _i, int _j, int _k, float _value):
105
				i(_i), j(_j), k(_k), value(_value) {}
120
				i(_i), j(_j), k(_k), value(_value) {}
106
		};
121
		};
107
		typedef list<CORNERELEMENT> CORNERLIST;
122
		typedef list<CORNERELEMENT> CORNERLIST;
108
 
123
 
109
		struct EDGEELEMENT {	   /* list of edges */
124
		struct EDGEELEMENT {	   /* list of edges */
110
			int i1, j1, k1, i2, j2, k2;	   /* edge corner ids */
125
			int i1, j1, k1, i2, j2, k2;	   /* edge corner ids */
111
			int vid;			   /* vertex id */
126
			int vid;			   /* vertex id */
112
		};
127
		};
113
 
128
 
114
		typedef list<EDGEELEMENT> EDGELIST;
129
		typedef list<EDGEELEMENT> EDGELIST;
115
		typedef list<int> INTLIST;
130
		typedef list<int> INTLIST;
116
		typedef list<INTLIST> INTLISTS;
131
		typedef list<INTLIST> INTLISTS;
117
 
132
 
118
 
133
 
119
		//----------------------------------------------------------------------
134
		//----------------------------------------------------------------------
120
		// Implicit surface evaluation functions
135
		// Implicit surface evaluation functions
121
		//----------------------------------------------------------------------
136
		//----------------------------------------------------------------------
122
 
137
 
123
		/* converge: from two points of differing sign, converge to zero crossing */
138
		/* converge: from two points of differing sign, converge to zero crossing */
124
 
139
 
125
		void converge (POINT* p1, POINT* p2, float v, 
140
		void converge (POINT* p1, POINT* p2, float v, 
126
									 ImplicitFunction* function, POINT* p)
141
									 ImplicitFunction* function, POINT* p)
127
		{
142
		{
128
			int i = 0;
143
			int i = 0;
129
			POINT pos, neg;
144
			POINT pos, neg;
130
			if (v < 0) {
145
			if (v < 0) {
131
				pos.x = p2->x; pos.y = p2->y; pos.z = p2->z;
146
				pos.x = p2->x; pos.y = p2->y; pos.z = p2->z;
132
				neg.x = p1->x; neg.y = p1->y; neg.z = p1->z;
147
				neg.x = p1->x; neg.y = p1->y; neg.z = p1->z;
133
			}
148
			}
134
			else {
149
			else {
135
				pos.x = p1->x; pos.y = p1->y; pos.z = p1->z;
150
				pos.x = p1->x; pos.y = p1->y; pos.z = p1->z;
136
				neg.x = p2->x; neg.y = p2->y; neg.z = p2->z;
151
				neg.x = p2->x; neg.y = p2->y; neg.z = p2->z;
137
			}
152
			}
138
			while (1) {
153
			while (1) {
139
				p->x = 0.5f*(pos.x + neg.x);
154
				p->x = 0.5f*(pos.x + neg.x);
140
				p->y = 0.5f*(pos.y + neg.y);
155
				p->y = 0.5f*(pos.y + neg.y);
141
				p->z = 0.5f*(pos.z + neg.z);
156
				p->z = 0.5f*(pos.z + neg.z);
142
				if (i++ == RES) return;
157
				if (i++ == RES) return;
143
				if ((function->eval(p->x, p->y, p->z)) > 0.0)
158
				if ((function->eval(p->x, p->y, p->z)) > 0.0)
144
					{pos.x = p->x; pos.y = p->y; pos.z = p->z;}
159
					{pos.x = p->x; pos.y = p->y; pos.z = p->z;}
145
				else {neg.x = p->x; neg.y = p->y; neg.z = p->z;}
160
				else {neg.x = p->x; neg.y = p->y; neg.z = p->z;}
146
			}
161
			}
147
		}
162
		}
148
 
163
 
149
 
164
 
150
		/* vnormal: compute unit length surface normal at point */
165
		/* vnormal: compute unit length surface normal at point */
151
 
166
 
152
		inline void vnormal (ImplicitFunction* function, POINT* point, POINT* n, float delta)
167
		inline void vnormal (ImplicitFunction* function, POINT* point, POINT* n, float delta)
153
		{
168
		{
154
			float f = function->eval(point->x, point->y, point->z);
169
			float f = function->eval(point->x, point->y, point->z);
155
			n->x = function->eval(point->x+delta, point->y, point->z)-f;
170
			n->x = function->eval(point->x+delta, point->y, point->z)-f;
156
			n->y = function->eval(point->x, point->y+delta, point->z)-f;
171
			n->y = function->eval(point->x, point->y+delta, point->z)-f;
157
			n->z = function->eval(point->x, point->y, point->z+delta)-f;
172
			n->z = function->eval(point->x, point->y, point->z+delta)-f;
158
			f = sqrt(n->x*n->x + n->y*n->y + n->z*n->z);
173
			f = sqrt(n->x*n->x + n->y*n->y + n->z*n->z);
159
			if (f != 0.0) {n->x /= f; n->y /= f; n->z /= f;}
174
			if (f != 0.0) {n->x /= f; n->y /= f; n->z /= f;}
160
		}
175
		}
161
 
176
 
162
 
177
 
163
 
178
 
164
		// ----------------------------------------------------------------------
179
		// ----------------------------------------------------------------------
165
 
180
 
166
		class EDGETABLE
181
		class EDGETABLE
167
		{
182
		{
168
			vector<EDGELIST> table;		   /* edge and vertex id hash table */
183
			vector<EDGELIST> table;		   /* edge and vertex id hash table */
169
		
184
		
170
		public:
185
		public:
171
		
186
		
172
			EDGETABLE(): table(2*HASHSIZE) {}
187
			EDGETABLE(): table(2*HASHSIZE) {}
173
 
188
 
174
			void setedge (int i1, int j1, int k1, 
189
			void setedge (int i1, int j1, int k1, 
175
										int i2, int j2, int k2, int vid);
190
										int i2, int j2, int k2, int vid);
176
			int getedge (int i1, int j1, int k1, 
191
			int getedge (int i1, int j1, int k1, 
177
									 int i2, int j2, int k2);
192
									 int i2, int j2, int k2);
178
		
193
		
179
 
194
 
180
		};
195
		};
181
 
196
 
182
		/* setedge: set vertex id for edge */
197
		/* setedge: set vertex id for edge */
183
		void EDGETABLE::setedge (int i1, int j1, int k1, 
198
		void EDGETABLE::setedge (int i1, int j1, int k1, 
184
														 int i2, int j2, int k2, int vid)
199
														 int i2, int j2, int k2, int vid)
185
		{
200
		{
186
			unsigned int index;
201
			unsigned int index;
187
 
202
 
188
			if (i1>i2 || (i1==i2 && (j1>j2 || (j1==j2 && k1>k2)))) {
203
			if (i1>i2 || (i1==i2 && (j1>j2 || (j1==j2 && k1>k2)))) {
189
				int t=i1; i1=i2; i2=t; t=j1; j1=j2; j2=t; t=k1; k1=k2; k2=t;
204
				int t=i1; i1=i2; i2=t; t=j1; j1=j2; j2=t; t=k1; k1=k2; k2=t;
190
			}
205
			}
191
			index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
206
			index = HASH(i1, j1, k1) + HASH(i2, j2, k2);
192
 
207
 
193
			EDGEELEMENT new_obj;
208
			EDGEELEMENT new_obj;
194
			new_obj.i1 = i1; 
209
			new_obj.i1 = i1; 
195
			new_obj.j1 = j1; 
210
			new_obj.j1 = j1; 
196
			new_obj.k1 = k1;
211
			new_obj.k1 = k1;
197
			new_obj.i2 = i2; 
212
			new_obj.i2 = i2; 
198
			new_obj.j2 = j2; 
213
			new_obj.j2 = j2; 
199
			new_obj.k2 = k2;
214
			new_obj.k2 = k2;
200
			new_obj.vid = vid;
215
			new_obj.vid = vid;
201
			table[index].push_front(new_obj);
216
			table[index].push_front(new_obj);
202
		}
217
		}
203
 
218
 
204
 
219
 
205
		/* getedge: return vertex id for edge; return -1 if not set */
220
		/* getedge: return vertex id for edge; return -1 if not set */
206
 
221
 
207
		int EDGETABLE::getedge (int i1, int j1, int k1, int i2, int j2, int k2)
222
		int EDGETABLE::getedge (int i1, int j1, int k1, int i2, int j2, int k2)
208
		{
223
		{
209
 
224
 
210
			if (i1>i2 || (i1==i2 && (j1>j2 || (j1==j2 && k1>k2)))) {
225
			if (i1>i2 || (i1==i2 && (j1>j2 || (j1==j2 && k1>k2)))) {
211
				int t=i1; i1=i2; i2=t; t=j1; j1=j2; j2=t; t=k1; k1=k2; k2=t;
226
				int t=i1; i1=i2; i2=t; t=j1; j1=j2; j2=t; t=k1; k1=k2; k2=t;
212
			};
227
			};
213
			int hashval = HASH(i1, j1, k1)+HASH(i2, j2, k2);
228
			int hashval = HASH(i1, j1, k1)+HASH(i2, j2, k2);
214
			EDGELIST::const_iterator q = table[hashval].begin();
229
			EDGELIST::const_iterator q = table[hashval].begin();
215
			for (; q != table[hashval].end(); ++q)
230
			for (; q != table[hashval].end(); ++q)
216
				if (q->i1 == i1 && q->j1 == j1 && q->k1 == k1 &&
231
				if (q->i1 == i1 && q->j1 == j1 && q->k1 == k1 &&
217
						q->i2 == i2 && q->j2 == j2 && q->k2 == k2)
232
						q->i2 == i2 && q->j2 == j2 && q->k2 == k2)
218
					return q->vid;
233
					return q->vid;
219
			return -1;
234
			return -1;
220
		}
235
		}
221
 
236
 
222
 
237
 
223
		// ----------------------------------------------------------------------
238
		// ----------------------------------------------------------------------
224
		class PROCESS
239
		class PROCESS
225
		{	   /* parameters, function, storage */
240
		{	   /* parameters, function, storage */
226
 
241
 
227
			std::vector<NORMAL>* gnormals;  
242
			std::vector<NORMAL>* gnormals;  
228
			std::vector<VERTEX>* gvertices;  
243
			std::vector<VERTEX>* gvertices;  
229
			std::vector<TRIANGLE> *gtriangles;
244
			std::vector<TRIANGLE> *gtriangles;
230
  
245
  
231
			ImplicitFunction* function;	   /* implicit surface function */
246
			ImplicitFunction* function;	   /* implicit surface function */
232
 
247
 
233
			float size, delta;		   /* cube size, normal delta */
248
			float size, delta;		   /* cube size, normal delta */
234
			int bounds;			   /* cube range within lattice */
249
			int bounds;			   /* cube range within lattice */
235
			POINT start;		   /* start point on surface */
250
			POINT start;		   /* start point on surface */
236
			bool use_normals;
251
			bool use_normals;
237
 
252
 
238
			// Global list of corners (keeps track of memory)
253
			// Global list of corners (keeps track of memory)
239
			list<CORNER> corner_lst;
254
			list<CORNER> corner_lst;
240
			list<CUBE> cubes;		   /* active cubes */
255
			list<CUBE> cubes;		   /* active cubes */
241
			vector<CENTERLIST> centers;	   /* cube center hash table */
256
			vector<CENTERLIST> centers;	   /* cube center hash table */
242
			vector<CORNERLIST> corners;	   /* corner value hash table */
257
			vector<CORNERLIST> corners;	   /* corner value hash table */
243
			EDGETABLE edges;
258
			EDGETABLE edges;
244
 
259
 
245
			CORNER *setcorner (int i, int j, int k);
260
			CORNER *setcorner (int i, int j, int k);
246
 
261
 
247
			void testface (int i, int j, int k, CUBE* old, 
262
			void testface (int i, int j, int k, CUBE* old, 
248
										 int face, int c1, int c2, int c3, int c4); 
263
										 int face, int c1, int c2, int c3, int c4); 
249
 
264
 
250
			TEST find (int sign, float x, float y, float z);
265
			TEST find (int sign, float x, float y, float z);
251
    
266
    
252
			int vertid (CORNER* c1, CORNER* c2);
267
			int vertid (CORNER* c1, CORNER* c2);
253
    
268
    
254
			int dotet (CUBE* cube, int c1, int c2, int c3, int c4);
269
			int dotet (CUBE* cube, int c1, int c2, int c3, int c4);
255
    
270
    
256
			int docube (CUBE* cube);
271
			int docube (CUBE* cube);
257
 
272
 
258
			int triangle (int i1, int i2, int i3)
273
			int triangle (int i1, int i2, int i3)
259
			{
274
			{
260
				TRIANGLE t;
275
				TRIANGLE t;
261
				t.v0 = i1;
276
				t.v0 = i1;
262
				t.v1 = i2;
277
				t.v1 = i2;
263
				t.v2 = i3;
278
				t.v2 = i3;
264
				(*gtriangles).push_back(t);
279
				(*gtriangles).push_back(t);
265
				return 1;
280
				return 1;
266
			}
281
			}
267
 
282
 
268
		public:
283
		public:
269
			PROCESS(ImplicitFunction* _function,
284
			PROCESS(ImplicitFunction* _function,
270
							float _size, float _delta, 
285
							float _size, float _delta, 
271
							int _bounds,
286
							int _bounds,
272
							vector<VERTEX>& _gvertices,
287
							vector<VERTEX>& _gvertices,
273
							vector<NORMAL>& _gnormals,
288
							vector<NORMAL>& _gnormals,
274
							vector<TRIANGLE>& _gtriangles,
289
							vector<TRIANGLE>& _gtriangles,
275
							bool _compute_normals=false);
290
							bool _compute_normals=false);
276
	  
291
	  
277
 
292
 
278
			~PROCESS() {}
293
			~PROCESS() {}
279
		
294
		
280
			void march(int mode, float x, float y, float z);
295
			void march(int mode, float x, float y, float z);
281
 
296
 
282
		};
297
		};
283
 
298
 
284
 
299
 
285
		/* setcenter: set (i,j,k) entry of table[]
300
		/* setcenter: set (i,j,k) entry of table[]
286
			 return 1 if already set; otherwise, set and return 0 */
301
			 return 1 if already set; otherwise, set and return 0 */
287
		int setcenter(vector<CENTERLIST>& table,
302
		int setcenter(vector<CENTERLIST>& table,
288
									int i, int j, int k)
303
									int i, int j, int k)
289
		{
304
		{
290
			int index = HASH(i,j,k);
305
			int index = HASH(i,j,k);
291
			CENTERLIST::const_iterator q = table[index].begin();
306
			CENTERLIST::const_iterator q = table[index].begin();
292
			for(; q != table[index].end(); ++q)
307
			for(; q != table[index].end(); ++q)
293
				if(q->i == i && q->j==j && q->k == k) return 1;
308
				if(q->i == i && q->j==j && q->k == k) return 1;
294
  
309
  
295
			CENTERELEMENT elem(i,j,k);
310
			CENTERELEMENT elem(i,j,k);
296
			table[index].push_front(elem);
311
			table[index].push_front(elem);
297
			return 0;
312
			return 0;
298
		}
313
		}
299
 
314
 
300
		/* setcorner: return corner with the given lattice location
315
		/* setcorner: return corner with the given lattice location
301
			 set (and cache) its function value */
316
			 set (and cache) its function value */
302
		CORNER* PROCESS::setcorner (int i, int j, int k)
317
		CORNER* PROCESS::setcorner (int i, int j, int k)
303
		{
318
		{
304
			/* for speed, do corner value caching here */
319
			/* for speed, do corner value caching here */
305
			corner_lst.push_back(CORNER());
320
			corner_lst.push_back(CORNER());
306
			CORNER *c = &corner_lst.back();
321
			CORNER *c = &corner_lst.back();
307
			int index = HASH(i, j, k);
322
			int index = HASH(i, j, k);
308
 
323
 
309
			c->i = i; c->x = start.x+((float)i-.5f)*size;
324
			c->i = i; c->x = start.x+((float)i-.5f)*size;
310
			c->j = j; c->y = start.y+((float)j-.5f)*size;
325
			c->j = j; c->y = start.y+((float)j-.5f)*size;
311
			c->k = k; c->z = start.z+((float)k-.5f)*size;
326
			c->k = k; c->z = start.z+((float)k-.5f)*size;
312
 
327
 
313
			CORNERLIST::const_iterator l = corners[index].begin();
328
			CORNERLIST::const_iterator l = corners[index].begin();
314
			for (; l != corners[index].end(); ++l)
329
			for (; l != corners[index].end(); ++l)
315
				if (l->i == i && l->j == j && l->k == k) {
330
				if (l->i == i && l->j == j && l->k == k) {
316
					c->value = l->value;
331
					c->value = l->value;
317
					return c;
332
					return c;
318
				}
333
				}
319
 
334
 
320
			c->value = function->eval(c->x, c->y, c->z);
335
			c->value = function->eval(c->x, c->y, c->z);
321
			CORNERELEMENT elem(i,j,k,c->value);
336
			CORNERELEMENT elem(i,j,k,c->value);
322
			corners[index].push_front(elem);
337
			corners[index].push_front(elem);
323
			return c;
338
			return c;
324
		}
339
		}
325
 
340
 
326
 
341
 
327
 
342
 
328
		/* testface: given cube at lattice (i, j, k), and four corners of face,
343
		/* testface: given cube at lattice (i, j, k), and four corners of face,
329
		 * if surface crosses face, compute other four corners of adjacent cube
344
		 * if surface crosses face, compute other four corners of adjacent cube
330
		 * and add new cube to cube stack */
345
		 * and add new cube to cube stack */
331
 
346
 
332
		inline void PROCESS::testface (int i, int j, int k, CUBE* old, 
347
		inline void PROCESS::testface (int i, int j, int k, CUBE* old, 
333
														int face, int c1, int c2, int c3, int c4) 
348
														int face, int c1, int c2, int c3, int c4) 
334
		{
349
		{
335
			CUBE new_obj;
350
			CUBE new_obj;
336
 
351
 
337
			static int facebit[6] = {2, 2, 1, 1, 0, 0};
352
			static int facebit[6] = {2, 2, 1, 1, 0, 0};
338
			int n, pos = old->corners[c1]->value > 0.0 ? 1 : 0, bit = facebit[face];
353
			int n, pos = old->corners[c1]->value > 0.0 ? 1 : 0, bit = facebit[face];
339
 
354
 
340
			/* test if no surface crossing, cube out of bounds, or already visited: */
355
			/* test if no surface crossing, cube out of bounds, or already visited: */
341
			if ((old->corners[c2]->value > 0) == pos &&
356
			if ((old->corners[c2]->value > 0) == pos &&
342
					(old->corners[c3]->value > 0) == pos &&
357
					(old->corners[c3]->value > 0) == pos &&
343
					(old->corners[c4]->value > 0) == pos) return;
358
					(old->corners[c4]->value > 0) == pos) return;
344
			if (abs(i) > bounds || abs(j) > bounds || abs(k) > bounds) return;
359
			if (abs(i) > bounds || abs(j) > bounds || abs(k) > bounds) return;
345
			if (setcenter(centers, i, j, k)) return;
360
			if (setcenter(centers, i, j, k)) return;
346
 
361
 
347
			/* create new_obj cube: */
362
			/* create new_obj cube: */
348
			new_obj.i = i;
363
			new_obj.i = i;
349
			new_obj.j = j;
364
			new_obj.j = j;
350
			new_obj.k = k;
365
			new_obj.k = k;
351
			for (n = 0; n < 8; n++) new_obj.corners[n] = 0;
366
			for (n = 0; n < 8; n++) new_obj.corners[n] = 0;
352
			new_obj.corners[FLIP(c1, bit)] = old->corners[c1];
367
			new_obj.corners[FLIP(c1, bit)] = old->corners[c1];
353
			new_obj.corners[FLIP(c2, bit)] = old->corners[c2];
368
			new_obj.corners[FLIP(c2, bit)] = old->corners[c2];
354
			new_obj.corners[FLIP(c3, bit)] = old->corners[c3];
369
			new_obj.corners[FLIP(c3, bit)] = old->corners[c3];
355
			new_obj.corners[FLIP(c4, bit)] = old->corners[c4];
370
			new_obj.corners[FLIP(c4, bit)] = old->corners[c4];
356
			for (n = 0; n < 8; n++)
371
			for (n = 0; n < 8; n++)
357
				if (new_obj.corners[n] == 0)
372
				if (new_obj.corners[n] == 0)
358
					new_obj.corners[n] = setcorner(i+BIT(n,2), j+BIT(n,1), k+BIT(n,0));
373
					new_obj.corners[n] = setcorner(i+BIT(n,2), j+BIT(n,1), k+BIT(n,0));
359
 
374
 
360
			// Add new cube to top of stack
375
			// Add new cube to top of stack
361
			cubes.push_front(new_obj);
376
			cubes.push_front(new_obj);
362
		}
377
		}
363
 
378
 
364
		/* find: search for point with value of given sign (0: neg, 1: pos) */
379
		/* find: search for point with value of given sign (0: neg, 1: pos) */
365
 
380
 
366
		TEST PROCESS::find (int sign, float x, float y, float z)
381
		TEST PROCESS::find (int sign, float x, float y, float z)
367
		{
382
		{
368
			int i;
383
			int i;
369
			TEST test;
384
			TEST test;
370
			float range = size;
385
			float range = size;
371
			test.ok = 1;
386
			test.ok = 1;
372
			for (i = 0; i < 10000; i++) {
387
			for (i = 0; i < 10000; i++) {
373
				test.p.x = x+range*(RAND()-0.5f);
388
				test.p.x = x+range*(RAND()-0.5f);
374
				test.p.y = y+range*(RAND()-0.5f);
389
				test.p.y = y+range*(RAND()-0.5f);
375
				test.p.z = z+range*(RAND()-0.5f);
390
				test.p.z = z+range*(RAND()-0.5f);
376
				test.value = function->eval(test.p.x, test.p.y, test.p.z);
391
				test.value = function->eval(test.p.x, test.p.y, test.p.z);
377
				if (sign == (test.value > 0.0)) return test;
392
				if (sign == (test.value > 0.0)) return test;
378
				range = range*1.0005f; /* slowly expand search outwards */
393
				range = range*1.0005f; /* slowly expand search outwards */
379
			}
394
			}
380
			test.ok = 0;
395
			test.ok = 0;
381
			return test;
396
			return test;
382
		}
397
		}
383
 
398
 
384
 
399
 
385
		/* vertid: return index for vertex on edge:
400
		/* vertid: return index for vertex on edge:
386
		 * c1->value and c2->value are presumed of different sign
401
		 * c1->value and c2->value are presumed of different sign
387
		 * return saved index if any; else compute vertex and save */
402
		 * return saved index if any; else compute vertex and save */
388
 
403
 
389
		int PROCESS::vertid (CORNER* c1, CORNER* c2)
404
		int PROCESS::vertid (CORNER* c1, CORNER* c2)
390
		{
405
		{
391
			VERTEX v;
406
			VERTEX v;
392
			NORMAL n;
407
			NORMAL n;
393
			POINT a, b;
408
			POINT a, b;
394
			int vid = edges.getedge(c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
409
			int vid = edges.getedge(c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);
395
			if (vid != -1) return vid;			     /* previously computed */
410
			if (vid != -1) return vid;			     /* previously computed */
396
			a.x = c1->x; a.y = c1->y; a.z = c1->z;
411
			a.x = c1->x; a.y = c1->y; a.z = c1->z;
397
			b.x = c2->x; b.y = c2->y; b.z = c2->z;
412
			b.x = c2->x; b.y = c2->y; b.z = c2->z;
398
			converge(&a, &b, c1->value, function, &v); /* position */
413
			converge(&a, &b, c1->value, function, &v); /* position */
399
			(*gvertices).push_back(v);			   /* save vertex */
414
			(*gvertices).push_back(v);			   /* save vertex */
400
			if(use_normals)
415
			if(use_normals)
401
				{
416
				{
402
					vnormal(function, &v, &n, delta);			   /* normal */
417
					vnormal(function, &v, &n, delta);			   /* normal */
403
					(*gnormals).push_back(n);			   /* save vertex */
418
					(*gnormals).push_back(n);			   /* save vertex */
404
				}
419
				}
405
			vid = gvertices->size()-1;
420
			vid = gvertices->size()-1;
406
			edges.setedge(c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
421
			edges.setedge(c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);
407
			return vid;
422
			return vid;
408
		}
423
		}
409
 
424
 
410
 
425
 
411
 
426
 
412
 
427
 
413
		/**** Tetrahedral Polygonization ****/
428
		/**** Tetrahedral Polygonization ****/
414
 
429
 
415
 
430
 
416
		/* dotet: triangulate the tetrahedron
431
		/* dotet: triangulate the tetrahedron
417
		 * b, c, d should appear clockwise when viewed from a
432
		 * b, c, d should appear clockwise when viewed from a
418
		 * return 0 if client aborts, 1 otherwise */
433
		 * return 0 if client aborts, 1 otherwise */
419
 
434
 
420
		int PROCESS::dotet (CUBE* cube, int c1, int c2, int c3, int c4)
435
		int PROCESS::dotet (CUBE* cube, int c1, int c2, int c3, int c4)
421
		{
436
		{
422
			CORNER *a = cube->corners[c1];
437
			CORNER *a = cube->corners[c1];
423
			CORNER *b = cube->corners[c2];
438
			CORNER *b = cube->corners[c2];
424
			CORNER *c = cube->corners[c3];
439
			CORNER *c = cube->corners[c3];
425
			CORNER *d = cube->corners[c4];
440
			CORNER *d = cube->corners[c4];
426
			int index = 0, apos, bpos, cpos, dpos, e1, e2, e3, e4, e5, e6;
441
			int index = 0, apos, bpos, cpos, dpos, e1, e2, e3, e4, e5, e6;
427
			if ((apos = (a->value > 0.0))) index += 8;
442
			if ((apos = (a->value > 0.0))) index += 8;
428
			if ((bpos = (b->value > 0.0))) index += 4;
443
			if ((bpos = (b->value > 0.0))) index += 4;
429
			if ((cpos = (c->value > 0.0))) index += 2;
444
			if ((cpos = (c->value > 0.0))) index += 2;
430
			if ((dpos = (d->value > 0.0))) index += 1;
445
			if ((dpos = (d->value > 0.0))) index += 1;
431
			/* index is now 4-bit number representing one of the 16 possible cases */
446
			/* index is now 4-bit number representing one of the 16 possible cases */
432
			if (apos != bpos) e1 = vertid(a, b);
447
			if (apos != bpos) e1 = vertid(a, b);
433
			if (apos != cpos) e2 = vertid(a, c);
448
			if (apos != cpos) e2 = vertid(a, c);
434
			if (apos != dpos) e3 = vertid(a, d);
449
			if (apos != dpos) e3 = vertid(a, d);
435
			if (bpos != cpos) e4 = vertid(b, c);
450
			if (bpos != cpos) e4 = vertid(b, c);
436
			if (bpos != dpos) e5 = vertid(b, d);
451
			if (bpos != dpos) e5 = vertid(b, d);
437
			if (cpos != dpos) e6 = vertid(c, d);
452
			if (cpos != dpos) e6 = vertid(c, d);
438
			/* 14 productive tetrahedral cases (0000 and 1111 do not yield polygons */
453
			/* 14 productive tetrahedral cases (0000 and 1111 do not yield polygons */
439
			switch (index) {
454
			switch (index) {
440
			case 1:	 return triangle(e5, e6, e3);
455
			case 1:	 return triangle(e5, e6, e3);
441
			case 2:	 return triangle(e2, e6, e4);
456
			case 2:	 return triangle(e2, e6, e4);
442
			case 3:	 return triangle(e3, e5, e4) &&
457
			case 3:	 return triangle(e3, e5, e4) &&
443
								 triangle(e3, e4, e2);
458
								 triangle(e3, e4, e2);
444
			case 4:	 return triangle(e1, e4, e5);
459
			case 4:	 return triangle(e1, e4, e5);
445
			case 5:	 return triangle(e3, e1, e4) &&
460
			case 5:	 return triangle(e3, e1, e4) &&
446
								 triangle(e3, e4, e6);
461
								 triangle(e3, e4, e6);
447
			case 6:	 return triangle(e1, e2, e6) &&
462
			case 6:	 return triangle(e1, e2, e6) &&
448
								 triangle(e1, e6, e5);
463
								 triangle(e1, e6, e5);
449
			case 7:	 return triangle(e1, e2, e3);
464
			case 7:	 return triangle(e1, e2, e3);
450
			case 8:	 return triangle(e1, e3, e2);
465
			case 8:	 return triangle(e1, e3, e2);
451
			case 9:	 return triangle(e1, e5, e6) &&
466
			case 9:	 return triangle(e1, e5, e6) &&
452
								 triangle(e1, e6, e2);
467
								 triangle(e1, e6, e2);
453
			case 10: return triangle(e1, e3, e6) &&
468
			case 10: return triangle(e1, e3, e6) &&
454
								 triangle(e1, e6, e4);
469
								 triangle(e1, e6, e4);
455
			case 11: return triangle(e1, e5, e4);
470
			case 11: return triangle(e1, e5, e4);
456
			case 12: return triangle(e3, e2, e4) &&
471
			case 12: return triangle(e3, e2, e4) &&
457
								 triangle(e3, e4, e5);
472
								 triangle(e3, e4, e5);
458
			case 13: return triangle(e6, e2, e4);
473
			case 13: return triangle(e6, e2, e4);
459
			case 14: return triangle(e5, e3, e6);
474
			case 14: return triangle(e5, e3, e6);
460
			}
475
			}
461
			return 1;
476
			return 1;
462
		}
477
		}
463
 
478
 
464
 
479
 
465
		/**** Cubical Polygonization (optional) ****/
480
		/**** Cubical Polygonization (optional) ****/
466
 
481
 
467
 
482
 
468
		const int LB =	0;  /* left bottom edge	*/
483
		const int LB =	0;  /* left bottom edge	*/
469
		const int LT =	1;  /* left top edge	*/
484
		const int LT =	1;  /* left top edge	*/
470
		const int LN =	2;  /* left near edge	*/
485
		const int LN =	2;  /* left near edge	*/
471
		const int LF =	3;  /* left far edge	*/
486
		const int LF =	3;  /* left far edge	*/
472
		const int RB =	4;  /* right bottom edge */
487
		const int RB =	4;  /* right bottom edge */
473
		const int RT =	5;  /* right top edge	*/
488
		const int RT =	5;  /* right top edge	*/
474
		const int RN =	6;  /* right near edge	*/
489
		const int RN =	6;  /* right near edge	*/
475
		const int RF =	7;  /* right far edge	*/
490
		const int RF =	7;  /* right far edge	*/
476
		const int BN =	8;  /* bottom near edge	*/
491
		const int BN =	8;  /* bottom near edge	*/
477
		const int BF =	9;  /* bottom far edge	*/
492
		const int BF =	9;  /* bottom far edge	*/
478
		const int TN =	10; /* top near edge	*/
493
		const int TN =	10; /* top near edge	*/
479
		const int TF =	11; /* top far edge	*/
494
		const int TF =	11; /* top far edge	*/
480
 
495
 
481
 
496
 
482
		class CUBETABLE
497
		class CUBETABLE
483
		{
498
		{
484
			vector<INTLISTS> ctable;
499
			vector<INTLISTS> ctable;
485
			int nextcwedge (int edge, int face);
500
			int nextcwedge (int edge, int face);
486
			int otherface (int edge, int face);
501
			int otherface (int edge, int face);
487
 
502
 
488
		public:
503
		public:
489
 
504
 
490
			CUBETABLE();
505
			CUBETABLE();
491
		
506
		
492
			const INTLISTS& get_lists(int i) const
507
			const INTLISTS& get_lists(int i) const
493
			{
508
			{
494
				return ctable[i];
509
				return ctable[i];
495
			}
510
			}
496
		};
511
		};
497
 
512
 
498
		/*			edge: LB, LT, LN, LF, RB, RT, RN, RF, BN, BF, TN, TF */
513
		/*			edge: LB, LT, LN, LF, RB, RT, RN, RF, BN, BF, TN, TF */
499
		const int corner1[12]	   = {LBN,LTN,LBN,LBF,RBN,RTN,RBN,RBF,LBN,LBF,LTN,LTF};
514
		const int corner1[12]	   = {LBN,LTN,LBN,LBF,RBN,RTN,RBN,RBF,LBN,LBF,LTN,LTF};
500
		const int corner2[12]	   = {LBF,LTF,LTN,LTF,RBF,RTF,RTN,RTF,RBN,RBF,RTN,RTF};
515
		const int corner2[12]	   = {LBF,LTF,LTN,LTF,RBF,RTF,RTN,RTF,RBN,RBF,RTN,RTF};
501
		const int leftface[12]	   = {B,  L,  L,  F,  R,  T,  N,  R,  N,  B,  T,  F};
516
		const int leftface[12]	   = {B,  L,  L,  F,  R,  T,  N,  R,  N,  B,  T,  F};
502
		/* face on left when going corner1 to corner2 */
517
		/* face on left when going corner1 to corner2 */
503
		const int rightface[12]   = {L,  T,  N,  L,  B,  R,  R,  F,  B,  F,  N,  T};
518
		const int rightface[12]   = {L,  T,  N,  L,  B,  R,  R,  F,  B,  F,  N,  T};
504
		/* face on right when going corner1 to corner2 */
519
		/* face on right when going corner1 to corner2 */
505
 
520
 
506
 
521
 
507
		/* nextcwedge: return next clockwise edge from given edge around given face */
522
		/* nextcwedge: return next clockwise edge from given edge around given face */
508
 
523
 
509
		inline int CUBETABLE::nextcwedge (int edge, int face)
524
		inline int CUBETABLE::nextcwedge (int edge, int face)
510
		{
525
		{
511
			switch (edge) {
526
			switch (edge) {
512
			case LB: return (face == L)? LF : BN;
527
			case LB: return (face == L)? LF : BN;
513
			case LT: return (face == L)? LN : TF;
528
			case LT: return (face == L)? LN : TF;
514
			case LN: return (face == L)? LB : TN;
529
			case LN: return (face == L)? LB : TN;
515
			case LF: return (face == L)? LT : BF;
530
			case LF: return (face == L)? LT : BF;
516
			case RB: return (face == R)? RN : BF;
531
			case RB: return (face == R)? RN : BF;
517
			case RT: return (face == R)? RF : TN;
532
			case RT: return (face == R)? RF : TN;
518
			case RN: return (face == R)? RT : BN;
533
			case RN: return (face == R)? RT : BN;
519
			case RF: return (face == R)? RB : TF;
534
			case RF: return (face == R)? RB : TF;
520
			case BN: return (face == B)? RB : LN;
535
			case BN: return (face == B)? RB : LN;
521
			case BF: return (face == B)? LB : RF;
536
			case BF: return (face == B)? LB : RF;
522
			case TN: return (face == T)? LT : RN;
537
			case TN: return (face == T)? LT : RN;
523
			case TF: return (face == T)? RT : LF;
538
			case TF: return (face == T)? RT : LF;
524
			}
539
			}
525
			return -1;
540
			return -1;
526
		}
541
		}
527
 
542
 
528
		/* otherface: return face adjoining edge that is not the given face */
543
		/* otherface: return face adjoining edge that is not the given face */
529
 
544
 
530
		inline int CUBETABLE::otherface (int edge, int face)
545
		inline int CUBETABLE::otherface (int edge, int face)
531
		{
546
		{
532
			int other = leftface[edge];
547
			int other = leftface[edge];
533
			return face == other? rightface[edge] : other;
548
			return face == other? rightface[edge] : other;
534
		}
549
		}
535
 
550
 
536
 
551
 
537
		CUBETABLE::CUBETABLE(): ctable(256)
552
		CUBETABLE::CUBETABLE(): ctable(256)
538
		{
553
		{
539
			int i, e, c, done[12], pos[8];
554
			int i, e, c, done[12], pos[8];
540
			for (i = 0; i < 256; i++) 
555
			for (i = 0; i < 256; i++) 
541
				{
556
				{
542
					for (e = 0; e < 12; e++) 
557
					for (e = 0; e < 12; e++) 
543
						done[e] = 0;
558
						done[e] = 0;
544
					for (c = 0; c < 8; c++) 
559
					for (c = 0; c < 8; c++) 
545
						pos[c] = BIT(i, c);
560
						pos[c] = BIT(i, c);
546
					for (e = 0; e < 12; e++)
561
					for (e = 0; e < 12; e++)
547
						if (!done[e] && (pos[corner1[e]] != pos[corner2[e]])) 
562
						if (!done[e] && (pos[corner1[e]] != pos[corner2[e]])) 
548
							{
563
							{
549
								INTLIST ints;
564
								INTLIST ints;
550
								int start = e, edge = e;
565
								int start = e, edge = e;
551
							
566
							
552
								/* get face that is to right of edge from pos to neg corner: */
567
								/* get face that is to right of edge from pos to neg corner: */
553
								int face = pos[corner1[e]]? rightface[e] : leftface[e];
568
								int face = pos[corner1[e]]? rightface[e] : leftface[e];
554
								while (1) 
569
								while (1) 
555
									{
570
									{
556
										edge = nextcwedge(edge, face);
571
										edge = nextcwedge(edge, face);
557
										done[edge] = 1;
572
										done[edge] = 1;
558
										if (pos[corner1[edge]] != pos[corner2[edge]]) 
573
										if (pos[corner1[edge]] != pos[corner2[edge]]) 
559
											{
574
											{
560
												ints.push_front(edge);
575
												ints.push_front(edge);
561
												if (edge == start) 
576
												if (edge == start) 
562
													break;
577
													break;
563
												face = otherface(edge, face);
578
												face = otherface(edge, face);
564
											}
579
											}
565
									}
580
									}
566
								ctable[i].push_front(ints);
581
								ctable[i].push_front(ints);
567
							}
582
							}
568
				}
583
				}
569
		}
584
		}
570
 
585
 
571
		inline const INTLISTS& get_cubetable_entry(int i) 
586
		inline const INTLISTS& get_cubetable_entry(int i) 
572
		{
587
		{
573
			static CUBETABLE c;
588
			static CUBETABLE c;
574
			return c.get_lists(i);
589
			return c.get_lists(i);
575
		}
590
		}
576
 
591
 
577
 
592
 
578
		/* docube: triangulate the cube directly, without decomposition */
593
		/* docube: triangulate the cube directly, without decomposition */
579
 
594
 
580
		int PROCESS::docube (CUBE* cube)
595
		int PROCESS::docube (CUBE* cube)
581
		{
596
		{
582
			int index = 0;
597
			int index = 0;
583
			for (int i = 0; i < 8; i++) 
598
			for (int i = 0; i < 8; i++) 
584
				if (cube->corners[i]->value > 0.0) 
599
				if (cube->corners[i]->value > 0.0) 
585
					index += (1<<i);
600
					index += (1<<i);
586
 
601
 
587
			INTLISTS intlists = get_cubetable_entry(index);
602
			INTLISTS intlists = get_cubetable_entry(index);
588
			INTLISTS::const_iterator polys = intlists.begin();
603
			INTLISTS::const_iterator polys = intlists.begin();
589
			for (; polys != intlists.end(); ++polys) 
604
			for (; polys != intlists.end(); ++polys) 
590
				{
605
				{
591
					INTLIST::const_iterator edges = polys->begin();
606
					INTLIST::const_iterator edges = polys->begin();
592
					int a = -1, b = -1, count = 0;
607
					int a = -1, b = -1, count = 0;
593
					for (; edges != polys->end(); ++edges) 
608
					for (; edges != polys->end(); ++edges) 
594
						{
609
						{
595
							CORNER *c1 = cube->corners[corner1[(*edges)]];
610
							CORNER *c1 = cube->corners[corner1[(*edges)]];
596
							CORNER *c2 = cube->corners[corner2[(*edges)]];
611
							CORNER *c2 = cube->corners[corner2[(*edges)]];
597
							int c = vertid(c1, c2);
612
							int c = vertid(c1, c2);
598
							if (++count > 2 && ! triangle(a, b, c)) 
613
							if (++count > 2 && ! triangle(a, b, c)) 
599
								return 0;
614
								return 0;
600
							if (count < 3) 
615
							if (count < 3) 
601
								a = b;
616
								a = b;
602
							b = c;
617
							b = c;
603
						}
618
						}
604
				}
619
				}
605
			return 1;
620
			return 1;
606
		}
621
		}
607
 
622
 
608
 
623
 
609
 
624
 
610
 
625
 
611
 
626
 
612
 
627
 
613
 
628
 
614
		/**** An Implicit Surface Polygonizer ****/
629
		/**** An Implicit Surface Polygonizer ****/
615
 
630
 
616
 
631
 
617
		/* polygonize: polygonize the implicit surface function
632
		/* polygonize: polygonize the implicit surface function
618
		 *   arguments are:
633
		 *   arguments are:
619
		 *	 ImplicitFunction
634
		 *	 ImplicitFunction
620
		 *	     the implicit surface function
635
		 *	     the implicit surface function
621
		 *	     return negative for inside, positive for outside
636
		 *	     return negative for inside, positive for outside
622
		 *	 float size
637
		 *	 float size
623
		 *	     width of the partitioning cube
638
		 *	     width of the partitioning cube
624
		 *   float delta 
639
		 *   float delta 
625
		 *       a small step - used for gradient computation
640
		 *       a small step - used for gradient computation
626
		 *	 int bounds
641
		 *	 int bounds
627
		 *	     max. range of cubes (+/- on the three axes) from first cube
642
		 *	     max. range of cubes (+/- on the three axes) from first cube
628
		 *   _gvertices, _gnormals, _gtriangles
643
		 *   _gvertices, _gnormals, _gtriangles
629
		 *       the data structures into which information is put.
644
		 *       the data structures into which information is put.
630
		 */
645
		 */
631
 
646
 
632
		PROCESS::PROCESS(ImplicitFunction* _function,
647
		PROCESS::PROCESS(ImplicitFunction* _function,
633
										 float _size, float _delta, 
648
										 float _size, float _delta, 
634
										 int _bounds, 
649
										 int _bounds, 
635
										 vector<VERTEX>& _gvertices,
650
										 vector<VERTEX>& _gvertices,
636
										 vector<NORMAL>& _gnormals,
651
										 vector<NORMAL>& _gnormals,
637
										 vector<TRIANGLE>& _gtriangles,
652
										 vector<TRIANGLE>& _gtriangles,
638
										 bool _use_normals):
653
										 bool _use_normals):
639
			function(_function), size(_size), delta(_delta), bounds(_bounds),
654
			function(_function), size(_size), delta(_delta), bounds(_bounds),
640
			centers(HASHSIZE), corners(HASHSIZE), 
655
			centers(HASHSIZE), corners(HASHSIZE), 
641
			gvertices(&_gvertices),
656
			gvertices(&_gvertices),
642
			gnormals(&_gnormals),
657
			gnormals(&_gnormals),
643
			gtriangles(&_gtriangles),
658
			gtriangles(&_gtriangles),
644
			use_normals(_use_normals)
659
			use_normals(_use_normals)
645
		{}
660
		{}
646
 
661
 
647
		void PROCESS::march(int mode, float x, float y, float z)
662
		void PROCESS::march(int mode, float x, float y, float z)
648
		{
663
		{
649
			int noabort;
664
			int noabort;
650
			TEST in, out;
665
			TEST in, out;
651
  
666
  
652
			/* find point on surface, beginning search at (x, y, z): */
667
			/* find point on surface, beginning search at (x, y, z): */
653
			gel_srand(1);
668
			gel_srand(1);
654
			in = find(1, x, y, z);
669
			in = find(1, x, y, z);
655
			out = find(0, x, y, z);
670
			out = find(0, x, y, z);
656
			if (!in.ok || !out.ok) 
671
			if (!in.ok || !out.ok) 
657
            {
672
            {
658
                exit(1);
673
                exit(1);
659
            }
674
            }
660
			converge(&in.p, &out.p, in.value, function, &start);
675
			converge(&in.p, &out.p, in.value, function, &start);
661
  
676
  
662
			/* push initial cube on stack: */
677
			/* push initial cube on stack: */
663
			CUBE cube;
678
			CUBE cube;
664
			cube.i = cube.j = cube.k = 0;
679
			cube.i = cube.j = cube.k = 0;
665
			cubes.push_front(cube);
680
			cubes.push_front(cube);
666
 
681
 
667
			/* set corners of initial cube: */
682
			/* set corners of initial cube: */
668
			for (int n = 0; n < 8; n++)
683
			for (int n = 0; n < 8; n++)
669
				cubes.front().corners[n] = setcorner(BIT(n,2), BIT(n,1), BIT(n,0));
684
				cubes.front().corners[n] = setcorner(BIT(n,2), BIT(n,1), BIT(n,0));
670
    
685
    
671
			setcenter(centers, 0, 0, 0);
686
			setcenter(centers, 0, 0, 0);
672
    
687
    
673
			while (cubes.size() != 0) 
688
			while (cubes.size() != 0) 
674
				{
689
				{
675
					/* process active cubes till none left */
690
					/* process active cubes till none left */
676
					CUBE c = cubes.front();
691
					CUBE c = cubes.front();
677
      
692
      
678
					noabort = mode == TET?
693
					noabort = mode == TET?
679
						/* either decompose into tetrahedra and polygonize: */
694
						/* either decompose into tetrahedra and polygonize: */
680
						dotet(&c, LBN, LTN, RBN, LBF) &&
695
						dotet(&c, LBN, LTN, RBN, LBF) &&
681
						dotet(&c, RTN, LTN, LBF, RBN) &&
696
						dotet(&c, RTN, LTN, LBF, RBN) &&
682
						dotet(&c, RTN, LTN, LTF, LBF) &&
697
						dotet(&c, RTN, LTN, LTF, LBF) &&
683
						dotet(&c, RTN, RBN, LBF, RBF) &&
698
						dotet(&c, RTN, RBN, LBF, RBF) &&
684
						dotet(&c, RTN, LBF, LTF, RBF) &&
699
						dotet(&c, RTN, LBF, LTF, RBF) &&
685
						dotet(&c, RTN, LTF, RTF, RBF)
700
						dotet(&c, RTN, LTF, RTF, RBF)
686
						:
701
						:
687
						/* or polygonize the cube directly: */
702
						/* or polygonize the cube directly: */
688
						docube(&c);
703
						docube(&c);
689
                        if (! noabort) {
704
                        if (! noabort) {
690
                           exit(1);
705
                           exit(1);
691
                        }
706
                        }
692
      
707
      
693
					/* pop current cube from stack */
708
					/* pop current cube from stack */
694
					cubes.pop_front();
709
					cubes.pop_front();
695
      
710
      
696
					/* test six face directions, maybe add to stack: */
711
					/* test six face directions, maybe add to stack: */
697
					testface(c.i-1, c.j, c.k, &c, L, LBN, LBF, LTN, LTF);
712
					testface(c.i-1, c.j, c.k, &c, L, LBN, LBF, LTN, LTF);
698
					testface(c.i+1, c.j, c.k, &c, R, RBN, RBF, RTN, RTF);
713
					testface(c.i+1, c.j, c.k, &c, R, RBN, RBF, RTN, RTF);
699
					testface(c.i, c.j-1, c.k, &c, B, LBN, LBF, RBN, RBF);
714
					testface(c.i, c.j-1, c.k, &c, B, LBN, LBF, RBN, RBF);
700
					testface(c.i, c.j+1, c.k, &c, T, LTN, LTF, RTN, RTF);
715
					testface(c.i, c.j+1, c.k, &c, T, LTN, LTF, RTN, RTF);
701
					testface(c.i, c.j, c.k-1, &c, N, LBN, LTN, RBN, RTN);
716
					testface(c.i, c.j, c.k-1, &c, N, LBN, LTN, RBN, RTN);
702
					testface(c.i, c.j, c.k+1, &c, F, LBF, LTF, RBF, RTF);
717
					testface(c.i, c.j, c.k+1, &c, F, LBF, LTF, RBF, RTF);
703
				}
718
				}
704
		}
719
		}
705
	}
720
	}
706
 
721
 
707
	void Polygonizer::march(float x, float y, float z)
722
	void Polygonizer::march(float x, float y, float z)
708
		{
723
		{
709
			gvertices.clear();
724
			gvertices.clear();
710
			gnormals.clear();
725
			gnormals.clear();
711
			gtriangles.clear();
726
			gtriangles.clear();
712
			PROCESS p(func, size, size/(float)(RES*RES), bounds, 
727
			PROCESS p(func, size, size/(float)(RES*RES), bounds, 
713
								gvertices, gnormals, gtriangles, use_normals);
728
								gvertices, gnormals, gtriangles, use_normals);
714
			p.march(use_tetra?TET:NOTET,x,y,z);
729
			p.march(use_tetra?TET:NOTET,x,y,z);
715
		}
730
		}
716
 
731
 
717
}	
732
}	
718
 
733