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