1 // adjacency.cpp : Defines the entry point for the console application.
2 //
3 
4 /*
5  *	For convex hull processing
6  */
7 
8 #include "tokamak.h"
9 #include <stdio.h>
10 #include <windows.h>
11 
12 extern "C"
13 {
14 #include "qhull_a.h"
15 }
16 
17 const int INIT_ARRAY_SIZE = 100;
18 
19 struct ConvexFace
20 {
21 	int neighbourFaces;
22 	int neighbourVerts;
23 	int neighbourEdges;
24 };
25 struct ConvexVert
26 {
27 	int neighbourEdges;
28 };
29 struct ConvexEdge
30 {
31 	neByte f1;
32 	neByte f2;
33 	neByte v1;
34 	neByte v2;
35 };
36 
37 template <class T> class FArray
38 {
39 public:
FArray()40 	FArray() : nextFree(0), size(INIT_ARRAY_SIZE)
41 	{
42 		dataArray =  new T[INIT_ARRAY_SIZE];
43 
44 		keyArray = new u32[INIT_ARRAY_SIZE];
45 	}
46 
operator [](int i)47 	T & operator [] (int i)
48 	{
49 		assert(i < nextFree); return dataArray[i];
50 	}
51 
Add(u32 key,const T & item)52 	void Add(u32 key, const T & item)
53 	{
54 		for (int i = 0; i < nextFree; i++)
55 		{
56 			if (keyArray[i] == key)
57 			{
58 				return;
59 			}
60 		}
61 		if (nextFree == size)
62 			Grow();
63 
64 		keyArray[nextFree] = key;
65 
66 		dataArray[nextFree++] = item;
67 	}
GetIndex(u32 key)68 	int GetIndex(u32 key)
69 	{
70 		for (int i = 0; i < nextFree; i++)
71 		{
72 			if (keyArray[i] == key)
73 			{
74 				return i;
75 			}
76 		}
77 		return -1;
78 	}
79 
Get(u32 key,T & item)80 	int Get(u32 key, T & item)
81 	{
82 		for (int i = 0; i < nextFree; i++)
83 		{
84 			if (keyArray[i] == key)
85 			{
86 				item = dataArray[i];
87 
88 				return i;
89 			}
90 		}
91 		return -1;
92 	}
GetCount()93 	int GetCount() {
94 		return nextFree;
95 	}
96 
97 public:
98 	T * dataArray;
99 	u32 * keyArray;
100 	int nextFree;
101 	int size;
102 
103 private:
Grow()104 	void Grow() {
105 		T * newData = new T[size * 2];
106 
107 		u32 * newKey = new u32[size * 2];
108 
109 		for (int i = 0; i < nextFree; i++)
110 		{
111 			newData[i] = dataArray[i];
112 
113 			newKey[i] = keyArray[i];
114 		}
115 		size = size * 2;
116 
117 		delete dataArray;
118 
119 		delete keyArray;
120 
121 		dataArray = newData;
122 
123 		keyArray = newKey;
124 	}
125 };
126 
127 class neighbourItem
128 {
129 public:
130 	s32 neighbour;
131 	s32 nextNeighbour;
132 
neighbourItem()133 	neighbourItem() : neighbour (-1), nextNeighbour(-1) {}
134 };
135 
136 #define BUF_SIZE 1024
137 
MakeEdgeKey(neByte v1,neByte v2)138 u32 MakeEdgeKey(neByte v1, neByte v2)
139 {
140 	if (v1 < v2)
141 	{
142 		return (v1 << 16 | v2);
143 	}
144 	else
145 	{
146 		return (v2 << 16 | v1);
147 	}
148 }
149 
main(int argc,char * argv[])150 int main(int argc, char* argv[])
151 {
152 	if (argc < 3)
153 	{
154 		fprintf(stdout, "ADJACENCY input_file output_file [qhull_options]\n");
155 
156 		return 1;
157 	}
158 	FILE * ff = fopen(argv[1], "r");
159 
160 	fseek( ff, 0L, SEEK_SET );
161 
162 	if (ff == NULL)
163 	{
164 		fprintf(stdout, "cannot open file %s.\n", argv[1]);
165 
166 		return 1;
167 	}
168 
169 	int vertexCount = 0;
170 
171 	fscanf(ff, "%ld", &vertexCount);
172 
173 	if (vertexCount <= 0)
174 	{
175 		return 1;
176 	}
177 
178 	double * vertArray = new double[vertexCount * 3];
179 
180 	s32 i;
181 
182 	double * pdouble = vertArray;
183 
184 	for (i = 0; i < vertexCount; i++)
185 	{
186 		for (int j = 0; j < 3; j++)
187 		{
188 			double p;
189 
190 			if (fscanf(ff, "%Lf", &p))
191 			{
192 				*(pdouble++) = p;;
193 			}
194 			else
195 			{
196 				return 1;
197 			}
198 		}
199 	}
200 	qh_init_A (stdin, stdout, stderr, 0, NULL);
201 
202 	int exitcode= setjmp (qh errexit);
203 
204 	char options [200];
205 
206 	if (argc == 4)
207 		sprintf (options, "qhull %s", argv[3]);
208 	else
209 		sprintf (options, "qhull");
210 
211 	qh_initflags (options);
212 	qh_init_B (vertArray, vertexCount, 3, true);
213 	qh_qhull();
214 	qh_vertexneighbors();
215 	qh_check_output();
216 	qh_triangulate();
217 	qh_findgood_all (qh facet_list);
218 
219 	FArray<facetT *> faceRecord;
220 	FArray<ridgeT *> edgeRecord;
221 	FArray<ConvexEdge> edgeRecord2;
222 	FArray<vertexT *> vertexRecord;
223 {
224 	vertexT *vertex, **vertexp;
225 
226 	FORALLvertex_(qh vertex_list)
227 	{
228 		vertexRecord.Add(vertex->id, vertex);
229 	}
230 
231 	facetT *facet;
232 
233 	FORALLfacet_(qh facet_list)
234 	{
235 		faceRecord.Add(facet->id, facet);
236 	}
237 	FORALLfacet_(qh facet_list)
238 	{
239 		if (0)//facet->ridges)
240 		{
241 			ridgeT * ridge, ** ridgep;
242 
243 			FOREACHridge_(facet->ridges)
244 			{
245 				edgeRecord.Add(ridge->id, ridge);
246 			}
247 		}
248 		else
249 		{
250 			int vertexIndex[3], c = 0;
251 
252 			FOREACHvertex_(facet->vertices)
253 			{
254 				neByte h = vertexRecord.GetIndex(vertex->id);
255 
256 				ASSERT(h < qh num_vertices);
257 
258 				vertexIndex[c++] = h;
259 			}
260 			c = 0;
261 
262 			facetT * neighbor, ** neighborp;
263 
264 			FOREACHneighbor_(facet)
265 			{
266 				ConvexEdge e;
267 
268 				e.f1 = faceRecord.GetIndex(facet->id);
269 				e.f2 = faceRecord.GetIndex(neighbor->id);
270 
271 				ASSERT(e.f1 < qh num_facets);
272 				ASSERT(e.f2 < qh num_facets);
273 
274 				e.v1 = vertexIndex[(c+1)%3];
275 				e.v2 = vertexIndex[(c+2)%3];
276 
277 				u32 key = MakeEdgeKey(e.v1, e.v2);
278 
279 				edgeRecord2.Add(key, e);
280 
281 				c++;
282 			}
283 		}
284 	}
285 }
286 	if (faceRecord.GetCount() > 255)
287 	{
288 		fprintf(stderr, "Error: Object has more than 255 faces (Number of faces = %d).\n", faceRecord.GetCount());
289 		exit(0);
290 	}
291 	if (vertexRecord.GetCount() > 255)
292 	{
293 		fprintf(stderr, "Error: Object has more than 255 vertices (Number of vertices = %d).\n", vertexRecord.GetCount());
294 		exit(0);
295 	}
296 	if (edgeRecord2.GetCount() > 255)
297 	{
298 		fprintf(stderr, "Error: Object has more than 255 edges (Number of edges = %d).\n", edgeRecord2.GetCount());
299 		exit(0);
300 	}
301 {
302 	int edgeCount = edgeRecord2.GetCount();
303 	int zero = 0;
304 
305 	FILE * ff = fopen(argv[2], "wb+");
306 
307 	fwrite(&(qh num_facets), sizeof(int), 1, ff);
308 	fwrite(&(qh num_vertices), sizeof(int), 1, ff);
309 	fwrite(&edgeCount, sizeof(int), 1, ff);
310 	fwrite(&zero, sizeof(int), 1, ff);
311 
312 	TOKAMAK_OUTPUT_3("%d, %d, %d \n", qh num_facets, qh num_vertices, edgeCount);
313 
314 	int i;
315 	f32 f;
316 
317 	for (i = 0; i < faceRecord.GetCount(); i++)
318 	{
319 		facetT * facet = faceRecord[i];
320 
321 		for (int j = 0; j < 3; j++)
322 		{
323 			f = facet->normal[j];
324 
325 			fwrite(&f, sizeof(f), 1, ff);
326 
327 			TOKAMAK_OUTPUT_1("%f ", f);
328 		}
329 		f = facet->offset;
330 
331 		fwrite(&f, sizeof(f), 1, ff);
332 
333 		TOKAMAK_OUTPUT_1("%f \n", f);
334 	}
335 	for (i = 0; i < vertexRecord.GetCount(); i++)
336 	{
337 		vertexT *vertex	= vertexRecord[i];
338 
339 		for (int j = 0; j < 3; j++)
340 		{
341 			f = vertex->point[j];
342 
343 			fwrite(&f, sizeof(f), 1, ff);
344 
345 			TOKAMAK_OUTPUT_1("%f ", f);
346 		}
347 		fwrite(&zero, sizeof(f), 1, ff);
348 
349 		TOKAMAK_OUTPUT("\n");
350 	}
351 
352 	int offset = sizeof(int) * 4;
353 	offset += sizeof(float) * 4 * (faceRecord.GetCount() + qh num_vertices);
354 	offset += sizeof(ConvexFace) * faceRecord.GetCount();
355 	offset += sizeof(ConvexVert) * vertexRecord.GetCount();
356 
357 	if (edgeRecord.GetCount() != 0)
358 		offset += sizeof(ConvexEdge) * edgeRecord.GetCount();
359 	else
360 		offset += sizeof(ConvexEdge) * edgeRecord2.GetCount();
361 
362 	ConvexFace cface;
363 
364 	TOKAMAK_OUTPUT("Face Records \n");
365 
366 	for (i = 0; i < faceRecord.GetCount(); i++)
367 	{
368 		facetT * facet = faceRecord[i];
369 
370 		cface.neighbourFaces = offset;	offset += sizeof(neByte) * 3;//cface.numberFaceNeighbour;
371 		cface.neighbourVerts = offset;	offset += sizeof(neByte) * 3;//cface.numberVertNeighbour;
372 		cface.neighbourEdges = offset;	offset += sizeof(neByte) * 3;//cface.numberFaceNeighbour;
373 
374 		int ss = sizeof(cface);
375 
376 		fwrite(&cface, sizeof(cface), 1, ff);
377 
378 		TOKAMAK_OUTPUT_3("Face %d has %d face neighbour, %d vertics\n", i, 3, 3);
379 	}
380 
381 	TOKAMAK_OUTPUT("Vertex Records \n");
382 
383 	ConvexVert cvert;
384 
385 	for (i = 0; i < vertexRecord.GetCount(); i++)
386 	{
387 		vertexT * vertex = vertexRecord[i];
388 
389 		int numberEdgeNeighbour = 0;
390 
391 		facetT * neighbor, ** neighborp;
392 
393 		FOREACHneighbor_(vertex)
394 		{
395 			numberEdgeNeighbour++;
396 		}
397 		cvert.neighbourEdges = offset;	offset += sizeof(neByte) * (numberEdgeNeighbour + 1);
398 
399 		int ss = sizeof(cvert);
400 
401 		fwrite(&cvert, ss, 1, ff);
402 
403 		TOKAMAK_OUTPUT_2("Vertex %d has %d edges\n", i, numberEdgeNeighbour);
404 	}
405 	ConvexEdge cedge;
406 
407 	if (edgeRecord.GetCount() != 0)
408 	{
409 		for (i = 0; i < edgeRecord.GetCount(); i++)
410 		{
411 			ridgeT * ridge = edgeRecord[i];
412 
413 			cedge.f1 = faceRecord.GetIndex(ridge->top->id);
414 
415 			cedge.f2 = faceRecord.GetIndex(ridge->bottom->id);
416 
417 			vertexT * vertex, **vertexp;
418 			int v[2], c = 0;
419 			FOREACHvertex_(ridge->vertices)
420 			{
421 				ASSERT(c < 2);
422 
423 				v[c] = vertex->id;
424 
425 				c++;
426 			}
427 			cedge.v1 = vertexRecord.GetIndex(v[0]);
428 
429 			cedge.v2 = vertexRecord.GetIndex(v[1]);
430 
431 			fwrite(&cedge, sizeof(ConvexEdge), 1, ff);
432 
433 			TOKAMAK_OUTPUT_1("Edge %d = ", i);
434 
435 			TOKAMAK_OUTPUT_4(" faces %d, %d, verts %d, %d\n", cedge.f1, cedge.f2, cedge.v1, cedge.v2);
436 		}
437 	}
438 	else
439 	{
440 		for (i = 0; i < edgeRecord2.GetCount(); i++)
441 		{
442 			cedge = edgeRecord2[i];
443 
444 			fwrite(&cedge, sizeof(ConvexEdge), 1, ff);
445 
446 			TOKAMAK_OUTPUT_1("Edge %d = ", i);
447 
448 			TOKAMAK_OUTPUT_4(" faces %d, %d, verts %d, %d\n", cedge.f1, cedge.f2, cedge.v1, cedge.v2);
449 		}
450 	}
451 	for (i = 0; i < faceRecord.GetCount(); i++)
452 	{
453 		facetT * facet = faceRecord[i];
454 
455 		facetT * neighbor, ** neighborp;
456 
457 		TOKAMAK_OUTPUT_1("Face %d = {", i);
458 
459 		FOREACHneighbor_(facet)
460 		{
461 			neByte bb = faceRecord.GetIndex(neighbor->id);
462 
463 			fwrite(&bb, sizeof(neByte), 1, ff);
464 
465 			TOKAMAK_OUTPUT_1("%d,", bb);
466 		}
467 		TOKAMAK_OUTPUT("}, {");
468 
469 		vertexT * vertex, ** vertexp;
470 
471 		FOREACHvertex_(facet->vertices)
472 		{
473 			neByte bb = vertexRecord.GetIndex(vertex->id);
474 
475 			fwrite(&bb, sizeof(neByte), 1, ff);
476 
477 			TOKAMAK_OUTPUT_1("%d,", bb);
478 		}
479 		TOKAMAK_OUTPUT("}, {");
480 
481 		if (0)//facet->ridges)
482 		{
483 			ridgeT * ridge, ** ridgep;
484 
485 			FOREACHridge_(facet->ridges)
486 			{
487 				neByte bb = edgeRecord.GetIndex(ridge->id);
488 
489 				fwrite(&bb, sizeof(neByte), 1, ff);
490 
491 				TOKAMAK_OUTPUT_1("%d,", bb);
492 			}
493 		}
494 		else
495 		{
496 			int vertexIndex[3], c = 0;
497 
498 			FOREACHvertex_(facet->vertices)
499 			{
500 				vertexIndex[c++] = vertexRecord.GetIndex(vertex->id);
501 			}
502 			c = 0;
503 
504 			facetT * neighbor, ** neighborp;
505 
506 			FOREACHneighbor_(facet)
507 			{
508 				neByte v1 = vertexIndex[(c+1)%3];
509 				neByte v2 = vertexIndex[(c+2)%3];
510 				u32 key = MakeEdgeKey(v1, v2);
511 
512 				neByte bb = edgeRecord2.GetIndex(key);
513 
514 				fwrite(&bb, sizeof(neByte), 1, ff);
515 
516 				TOKAMAK_OUTPUT_1("%d,", bb);
517 				c++;
518 			}
519 		}
520 		TOKAMAK_OUTPUT("}\n");
521 	}
522 
523 	// vertex adjacent edges
524 
525 	for (i = 0; i < vertexRecord.GetCount(); i++)
526 	{
527 		neByte * ridgeNeigbour = new neByte[100];
528 
529 		vertexT * vert = vertexRecord[i];
530 
531 		facetT * neighbor, ** neighborp;
532 
533 		int numEdge = 0;
534 
535 		FOREACHneighbor_(vert)
536 		{
537 			if (0)//neighbor->ridges)
538 			{
539 				ridgeT * ridge, ** ridgep;
540 
541 				FOREACHridge_(neighbor->ridges)
542 				{
543 					vertexT * vertex, ** vertexp;
544 
545 					FOREACHvertex_(ridge->vertices)
546 					{
547 						if (vertexRecord.GetIndex(vertex->id) == i)
548 						{
549 							//add this ridge
550 							neByte eindex = edgeRecord.GetIndex(ridge->id);
551 
552 							bool found = false;
553 
554 							for (int k = 0; k < numEdge; k++)
555 							{
556 								if (ridgeNeigbour[k] == eindex)
557 								{
558 									found = true;
559 									break;
560 								}
561 							}
562 							if (!found)
563 							{
564 								ridgeNeigbour[numEdge++] = eindex;
565 							}
566 						}
567 					}
568 				}
569 			}
570 			else
571 			{
572 				vertexT * vertex, ** vertexp;
573 
574 				neByte vs[3]; int c = 0;
575 
576 				FOREACHvertex_(neighbor->vertices)
577 				{
578 					vs[c++] = vertexRecord.GetIndex(vertex->id);
579 				}
580 				for (int ii = 0; ii < 3; ii++)
581 				{
582 					neByte v1 = vs[(ii+1)%3];
583 
584 					neByte v2 = vs[(ii+2)%3];
585 
586 					if (v1 != i && v2 != i)
587 						continue;
588 
589 					u32 key = MakeEdgeKey(v1, v2);
590 
591 					neByte eindex = edgeRecord2.GetIndex(key);
592 
593 					bool found = false;
594 
595 					for (int k = 0; k < numEdge; k++)
596 					{
597 						if (ridgeNeigbour[k] == eindex)
598 						{
599 							found = true;
600 
601 							break;
602 						}
603 					}
604 					if (!found)
605 					{
606 						ridgeNeigbour[numEdge++] = eindex;
607 					}
608 				}
609 			}
610 		}
611 		TOKAMAK_OUTPUT_1("Vertex %d = {", i);
612 
613 		for (int j = 0; j < numEdge; j++)
614 		{
615 			neByte bb = ridgeNeigbour[j];
616 
617 			fwrite(&bb, sizeof(neByte), 1, ff);
618 
619 			TOKAMAK_OUTPUT_1("%d,", bb);
620 		}
621 		neByte f = 0xff;
622 
623 		fwrite(&f, sizeof(neByte), 1, ff);
624 
625 		TOKAMAK_OUTPUT("}\n");
626 
627 		delete ridgeNeigbour;
628 	}
629 	fclose(ff);
630 
631 	TOKAMAK_OUTPUT("\n");
632 }
633 	qh NOerrexit= True;
634 
635 	//qh_freeqhull (!qh_ALL);
636 
637 //	int curlong, totlong;
638 
639 	//qh_memfreeshort (&curlong, &totlong);
640 
641 	delete vertArray;
642 
643 	return 0;
644 }
645