001: #include <stdio.h>
002: #include <string.h>
003: #include <math.h>
004: #include <stdlib.h>
005: #ifdef __BORLANDC__
006: #define MINRECSZ 1
007: #else
008: #define MINRECSZ 0
009: #endif
010: #ifdef _WIN32
011: #include <windows.h>
012: #include <process.h>
013: #endif
014:
015: #ifdef _PA_RISC1_1
016: #include <unistd.h>
017: #define wchar_t unsigned short
018: #define __int64 long long
019: #define MAX_PATH 256
020: #endif
021:
022: #define MAX_COORDS 12000
023: #define HASHSIZE 256
024:
025: #define SLP_STL_ASCII_HEAD "solid "
026:
027: void Pause(void)
028: { char Zeile[100];
029: fprintf(stderr, ">>> RETURN bitte >>> RETURN please >>>");
030: fgets(Zeile, 100, stdin);
031: }
032:
033: struct HEAD {
034: unsigned char c[30];
035: unsigned short us;
036: unsigned long ul;
037: float f;
038: double d;
039: } head = { "triangulara dosiero (.vtf)\r\n\32", 1, 987654321L,
040: 7654321.0, 9876543210123456.0 };
041:
042: FILE *aus = NULL, *aus2 = NULL;
043:
044: void swap2(unsigned short *p)
045: { unsigned char uc;
046: union tausch2 {
047: unsigned short h;
048: unsigned char c[2];
049: } *u;
050: uc = ((union tausch2 *)p)->c[0];
051: ((union tausch2 *)p)->c[0] = ((union tausch2 *)p)->c[1];
052: ((union tausch2 *)p)->c[1] = uc;
053: }
054:
055: void swap4(unsigned long *p)
056: { unsigned char uc;
057: union tausch4 {
058: unsigned long h;
059: unsigned char c[4];
060: } *u;
061: uc = ((union tausch4 *)p)->c[0];
062: ((union tausch4 *)p)->c[0] = ((union tausch4 *)p)->c[3];
063: ((union tausch4 *)p)->c[3] = uc;
064: uc = ((union tausch4 *)p)->c[1];
065: ((union tausch4 *)p)->c[1] = ((union tausch4 *)p)->c[2];
066: ((union tausch4 *)p)->c[2] = uc;
067: }
068:
069: void swap8(unsigned __int64 *p)
070: { unsigned char uc;
071: union tausch8 {
072: unsigned __int64 h;
073: unsigned char c[8];
074: } *u;
075: uc = ((union tausch8 *)p)->c[0];
076: ((union tausch8 *)p)->c[0] = ((union tausch8 *)p)->c[7];
077: ((union tausch8 *)p)->c[7] = uc;
078: uc = ((union tausch8 *)p)->c[1];
079: ((union tausch8 *)p)->c[1] = ((union tausch8 *)p)->c[6];
080: ((union tausch8 *)p)->c[6] = uc;
081: uc = ((union tausch8 *)p)->c[2];
082: ((union tausch8 *)p)->c[2] = ((union tausch8 *)p)->c[5];
083: ((union tausch8 *)p)->c[5] = uc;
084: uc = ((union tausch8 *)p)->c[3];
085: ((union tausch8 *)p)->c[3] = ((union tausch8 *)p)->c[4];
086: ((union tausch8 *)p)->c[4] = uc;
087: }
088:
089: void swap2x4(unsigned __int64 *p)
090: { unsigned char uc;
091: union tausch8 {
092: unsigned __int64 h;
093: unsigned char c[8];
094: } *u;
095: uc = ((union tausch8 *)p)->c[0];
096: ((union tausch8 *)p)->c[0] = ((union tausch8 *)p)->c[3];
097: ((union tausch8 *)p)->c[3] = uc;
098: uc = ((union tausch8 *)p)->c[1];
099: ((union tausch8 *)p)->c[1] = ((union tausch8 *)p)->c[2];
100: ((union tausch8 *)p)->c[2] = uc;
101: uc = ((union tausch8 *)p)->c[4];
102: ((union tausch8 *)p)->c[4] = ((union tausch8 *)p)->c[7];
103: ((union tausch8 *)p)->c[7] = uc;
104: uc = ((union tausch8 *)p)->c[5];
105: ((union tausch8 *)p)->c[5] = ((union tausch8 *)p)->c[6];
106: ((union tausch8 *)p)->c[6] = uc;
107: }
108:
109: struct {
110: float hx, hy, hz;
111: unsigned long ret_val, count;
112: } Hash[HASHSIZE];
113: int in_hash_cnt = 0, hashpos_to_replace;
114: unsigned long hash_hit = 0, no_hash_hit =0;
115: unsigned long FileSize;
116:
117:
118: float xmin, xmax, ymin, ymax, zmin, zmax;
119: unsigned long total_facet_count;
120:
121: int indexed = 0, colorindexed = 0, silent = 0, swaped = 0, swap_still_allowed = 1;
122:
123: struct Coords_accel {
124: struct Coords_accel *X, *Y, *Z;
125: int this_pos;
126: float *values;
127: } *BaseAccel = NULL;
128:
129: unsigned long stored_coordinates = 0;
130: struct CoordsField {
131: struct CoordsField *next;
132: float coords[MAX_COORDS];
133: struct Coords_accel accel[MAX_COORDS / 3];
134: } *CArr = NULL, *CArrLast = NULL;
135:
136: union NomoX {
137: struct NomoL {
138: unsigned long size_n_flags;
139: wchar_t ObjectName[MAX_PATH + 10];
140: } n;
141: __int64 Data[1];
142: } nomo;
143:
144: struct Nomo {
145: unsigned long size_n_flags;
146: wchar_t ObjectName[MINRECSZ];
147: };
148:
149: struct Coloratoro {
150: unsigned long size_n_flags;
151: unsigned long index;
152: } coloratoro;
153:
154: struct Dauxrigo {
155: unsigned long size_n_flags;
156: void * There;
157: } dauxrigo;
158:
159: struct Triangulo {
160: unsigned long size_n_flags;
161: unsigned long repeated;
162: double coordinates[MINRECSZ];
163: };
164:
165: struct TrianguletoL {
166: unsigned long size_n_flags;
167: unsigned long repeated;
168: union { float coordinates[MAX_COORDS];
169: unsigned long index[MAX_COORDS];
170: } d;
171: } trianguleto;
172:
173: struct Trianguleto {
174: unsigned long size_n_flags;
175: unsigned long repeated;
176: float coordinates[MINRECSZ];
177: };
178:
179: struct Coloro {
180: unsigned long size_n_flags;
181: float r, g, b;
182: } coloro;
183:
184: union Unu {
185: struct Coloro coloro;
186: struct Coloratoro coloratoro;
187: struct Triangulo triangulo;
188: struct Trianguleto trianguleto;
189: struct Dauxrigo dauxrigo;
190: struct Nomo nomo;
191: unsigned __int64 Data[1];
192: };
193:
194: struct Memorilo {
195: struct Memorilo *next_block;
196: unsigned long capacity;
197: unsigned long next_free;
198: void * next_free_p;
199: unsigned __int64 Data[MINRECSZ];
200: } *TDate = NULL, *TDate_Current = NULL;
201:
202: void free_coordinates(void)
203: { struct CoordsField *arr, *nxt;
204: for (arr = CArr; arr != NULL; arr = nxt) {
205: nxt = arr->next;
206: free(arr);
207: }
208: CArr = CArrLast = NULL; BaseAccel = NULL;
209: in_hash_cnt = 0;
210: stored_coordinates = 0;
211: }
212:
213: struct CoordsField *alloc_CoordsField(void)
214: { struct CoordsField *neu;
215: if ((neu = malloc(sizeof(struct CoordsField))) == NULL) return NULL;
216: neu->next = NULL;
217: return neu;
218: }
219:
220: unsigned long new_index(float wx, float wy, float wz, int e, struct Coords_accel *ca)
221: { unsigned long erg, idx, aidx;
222: if ((CArr == NULL) || (stored_coordinates == 0)) {
223: if ((CArr = alloc_CoordsField()) == NULL) return 0xffffffffL;
224: CArrLast = CArr;
225: }
226: idx = stored_coordinates % MAX_COORDS;
227: aidx = idx / 3;
228: if ((idx == 0) && stored_coordinates) {
229: if ((CArrLast->next = alloc_CoordsField()) == NULL) return 0xffffffffL;
230: CArrLast = CArrLast->next;
231: }
232: CArrLast->coords[idx] = wx;
233: CArrLast->coords[idx + 1] = wy;
234: CArrLast->coords[idx + 2] = wz;
235: CArrLast->accel[aidx].X = NULL;
236: CArrLast->accel[aidx].Y = NULL;
237: CArrLast->accel[aidx].Z = NULL;
238: CArrLast->accel[aidx].this_pos = stored_coordinates;
239: CArrLast->accel[aidx].values = &(CArrLast->coords[idx]);
240: switch (e) {
241: case 0: BaseAccel = &(CArrLast->accel[aidx]); break;
242: case 1: ca->X = &(CArrLast->accel[aidx]); break;
243: case 2: ca->Y = &(CArrLast->accel[aidx]); break;
244: case 3: ca->Z = &(CArrLast->accel[aidx]); break;
245: }
246: erg = stored_coordinates;
247: stored_coordinates += 3;
248: Hash[hashpos_to_replace].hx = wx;
249: Hash[hashpos_to_replace].hy = wy;
250: Hash[hashpos_to_replace].hz = wz;
251: Hash[hashpos_to_replace].ret_val = erg;
252: Hash[hashpos_to_replace].count = 0;
253: if (in_hash_cnt <= hashpos_to_replace) in_hash_cnt = hashpos_to_replace + 1;
254: return erg;
255: }
256:
257: unsigned long coordinate_index(float wx, float wy, float wz)
258: { struct Coords_accel *p;
259: unsigned long hmv;
260: int ct, i;
261: hmv = 0; hashpos_to_replace = 0;
262: if ((CArr == NULL) || (stored_coordinates == 0) || (BaseAccel == NULL))
263: return(new_index(wx, wy, wz, 0, NULL));
264:
265: for (ct = 0; ct < in_hash_cnt; ct++) {
266: if ((Hash[ct].hx == wx) && (Hash[ct].hy == wy) && (Hash[ct].hz == wz)) {
267: for (i = ct; i < in_hash_cnt; i++) Hash[i].count++;
268: Hash[ct].count = 0;
269: hash_hit++;
270: return(Hash[ct].ret_val);
271: }
272: if (Hash[ct].count >= hmv) {
273: hashpos_to_replace = ct;
274: hmv = Hash[ct].count;
275: }
276: Hash[ct].count++;
277: }
278: if (in_hash_cnt < HASHSIZE) hashpos_to_replace = in_hash_cnt;
279:
280: p = BaseAccel;
281: while (1) {
282: if (wx == p->values[0]) {
283: while (1) {
284: if (wy == p->values[1]) {
285: while (1) {
286: if (wz == p->values[2]) {
287: Hash[hashpos_to_replace].hx = wx;
288: Hash[hashpos_to_replace].hy = wy;
289: Hash[hashpos_to_replace].hz = wz;
290: Hash[hashpos_to_replace].ret_val = p->this_pos;
291: Hash[hashpos_to_replace].count = 0;
292:
293:
294:
295:
296: no_hash_hit++;
297: return p->this_pos;
298: } else {
299: if (p->Z == NULL) return(new_index(wx, wy, wz, 3, p));
300: p = p->Z;
301: }
302: }
303: } else {
304: if (p->Y == NULL) return(new_index(wx, wy, wz, 2, p));
305: p = p->Y;
306: }
307: }
308: } else {
309: if (p->X == NULL) return(new_index(wx, wy, wz, 1, p));
310: p = p->X;
311: }
312: }
313: }
314:
315: void flush_facets(FILE *aus)
316: { unsigned long QWordsToStore;
317: unsigned long ct, swaplimit;
318: if (!trianguleto.repeated) return;
319: if (indexed) {
320: QWordsToStore = 1L + 2L * trianguleto.repeated;
321: swaplimit = 4L * trianguleto.repeated;
322: trianguleto.size_n_flags = 0x10000000L + QWordsToStore;
323: } else {
324: QWordsToStore = 1L + 6L * trianguleto.repeated;
325: swaplimit = 12L * trianguleto.repeated;
326: trianguleto.size_n_flags = 0x20000000L + QWordsToStore;
327: }
328: if (swaped) {
329: swap4(&(trianguleto.size_n_flags)); swap4(&(trianguleto.repeated));
330: for (ct = 0; ct < swaplimit; ct++) swap4(&(trianguleto.d.index[ct]));
331: }
332: fwrite(&trianguleto, 8, QWordsToStore, aus);
333: trianguleto.repeated = 0;
334: }
335:
336: void store_endsolid(FILE *aus)
337: { unsigned long QWords_to_store;
338: flush_facets(aus);
339: QWords_to_store = 1;
340: dauxrigo.size_n_flags = 0x90000001;
341: dauxrigo.There = NULL;
342: if (swaped) {
343: swap4(&(dauxrigo.size_n_flags));
344: swap4((unsigned long*)&(dauxrigo.There));
345: }
346: fwrite(&dauxrigo, 1, sizeof(struct Dauxrigo), aus);
347: }
348:
349: void store_beginsolid(FILE *aus2, char *Name)
350: { unsigned long QWords_to_store;
351: unsigned int Strlg;
352: if (!silent) fprintf(stderr, " Solid %s ...\n", Name);
353: flush_facets(aus);
354: Strlg = strlen(Name) + 3;
355: while (Strlg & 3) Strlg++;
356: QWords_to_store = Strlg / 4;
357: nomo.Data[QWords_to_store - 1] = 0;
358: nomo.n.size_n_flags = 0x80000000 + QWords_to_store;
359: for (Strlg = 0; Name[Strlg]; Strlg++) {
360: nomo.n.ObjectName[Strlg] = (wchar_t) ((unsigned char) Name[Strlg]);
361: if (swaped) swap2(&(nomo.n.ObjectName[Strlg]));
362: }
363: if (swaped) swap4(&(nomo.n.size_n_flags));
364: fwrite(&nomo, 8, QWords_to_store, aus2);
365: }
366:
367: void store_set_color(FILE *aus, float r, float g, float b)
368: { unsigned long QWords_to_store;
369: flush_facets(aus);
370: QWords_to_store = 2;
371: coloro.size_n_flags = 0x40000000L + QWords_to_store;
372: coloro.r = r;
373: coloro.g = g;
374: coloro.b = b;
375: if (swaped) {
376: swap4(&(coloro.size_n_flags));
377: swap4((unsigned long *)&(coloro.r)); swap4((unsigned long *)&(coloro.g)); swap4((unsigned long *)&(coloro.b));
378: }
379: fwrite(&coloro, 1, sizeof(struct Coloro), aus);
380: }
381:
382:
383: void store_color_indexed(FILE *aus, unsigned long p)
384: { unsigned long Words_pos;
385: unsigned long QWords_to_store;
386: flush_facets(aus);
387: QWords_to_store = 1;
388: coloratoro.size_n_flags = 1;
389: coloratoro.index = p;
390: if (swaped) {
391: swap4(&(coloratoro.size_n_flags));
392: swap4(&(coloratoro.index));
393: }
394: fwrite(&coloratoro, 1, sizeof(struct Coloratoro), aus);
395: }
396:
397:
398: void store_facet_indexed(FILE *aus, unsigned long pn, unsigned long p1, unsigned long p2, unsigned long p3)
399: { unsigned long Words_pos;
400: if (trianguleto.repeated >= MAX_COORDS / 4) flush_facets(aus);
401: Words_pos = 4L * trianguleto.repeated;
402: trianguleto.d.index[Words_pos + 0] = pn;
403: trianguleto.d.index[Words_pos + 1] = p1;
404: trianguleto.d.index[Words_pos + 2] = p2;
405: trianguleto.d.index[Words_pos + 3] = p3;
406: trianguleto.repeated++;
407: total_facet_count++;
408: }
409:
410:
411: void store_facet_short(FILE* aus, float Nx, float Ny, float Nz, float *vx, float *vy, float *vz)
412: { unsigned long Words_pos;
413: int ct;
414: if (trianguleto.repeated >= MAX_COORDS / 12) flush_facets(aus);
415: Words_pos = 12L * trianguleto.repeated;
416: if (!total_facet_count) {
417: xmin = xmax = vx[0]; ymin = ymax = vy[0]; zmin = zmax = vz[0];
418: }
419: for (ct = 0; ct < 3; ct++) {
420: if (vx[ct] < xmin) xmin = vx[ct]; else if (vx[ct] > xmax) xmax = vx[ct];
421: if (vy[ct] < ymin) ymin = vy[ct]; else if (vy[ct] > ymax) ymax = vy[ct];
422: if (vz[ct] < zmin) zmin = vz[ct]; else if (vz[ct] > zmax) zmax = vz[ct];
423: }
424: trianguleto.d.coordinates[Words_pos + 0] = Nx;
425: trianguleto.d.coordinates[Words_pos + 1] = Ny;
426: trianguleto.d.coordinates[Words_pos + 2] = Nz;
427: trianguleto.d.coordinates[Words_pos + 3] = vx[0];
428: trianguleto.d.coordinates[Words_pos + 4] = vy[0];
429: trianguleto.d.coordinates[Words_pos + 5] = vz[0];
430: trianguleto.d.coordinates[Words_pos + 6] = vx[1];
431: trianguleto.d.coordinates[Words_pos + 7] = vy[1];
432: trianguleto.d.coordinates[Words_pos + 8] = vz[1];
433: trianguleto.d.coordinates[Words_pos + 9] = vx[2];
434: trianguleto.d.coordinates[Words_pos + 10] = vy[2];
435: trianguleto.d.coordinates[Words_pos + 11] = vz[2];
436: trianguleto.repeated++;
437: total_facet_count++;
438: }
439:
440:
441: void FlushFileIndexedSLP(FILE *ein, FILE *aus2)
442: { char Data[8192];
443: int sz, ct;
444: unsigned long QWords_to_store;
445: struct Trianguleto KK;
446: struct CoordsField *p;
447: KK.repeated = stored_coordinates / 3;
448: if (!silent) fprintf(stderr, "%lu Koordinaten = %lu Zahlen = 0x%lx Byte\n",
449: (unsigned long) KK.repeated,
450: (unsigned long) stored_coordinates,
451: (unsigned long) stored_coordinates * sizeof(float));
452: if (!silent) fprintf(stderr, "%lu : %lu Hashtreffer in Feldgroesse %d\n",
453: hash_hit, no_hash_hit, HASHSIZE);
454: QWords_to_store = (stored_coordinates + 1) / 2;
455: KK.size_n_flags = 0x60000001 + QWords_to_store;
456: if (swaped) { swap4(&(KK.size_n_flags)); swap4(&(KK.repeated)); }
457: fwrite(&KK, 1, sizeof(KK), aus2);
458: p = CArr;
459: while (QWords_to_store) {
460: if (p != NULL) {
461: if (swaped) {
462: for (ct = 0; ct < MAX_COORDS; ct++) swap4((unsigned long *)&(p->coords[ct]));
463: }
464: fwrite(&(p->coords[0]), 8,
465: (QWords_to_store > MAX_COORDS / 2) ? MAX_COORDS / 2 : QWords_to_store,
466: aus2);
467: p = p->next;
468: }
469: if (QWords_to_store > MAX_COORDS / 2)
470: QWords_to_store -= (MAX_COORDS / 2);
471: else
472: QWords_to_store = 0;
473: }
474: rewind(ein);
475: while ((sz = fread(Data, 1, 8192, ein)) > 0)
476: fwrite(Data, 1, sz, aus2);
477:
478: free_coordinates();
479: }
480:
481: int ReadFileIndexedSLP(FILE *ein, FILE *aus2)
482: { char Zeile[MAX_PATH + 50], Kennwort[MAX_PATH + 50], Kennwort2[MAX_PATH + 50];
483: unsigned long ZNR, pn, p1, p2, p3;
484: int sw, stp = -1, STATE = -1, cv, cn, data_in_temp = 0;
485: float d1, d2, d3, nx[3], ny[3], nz[3], vx[6], vy[6], vz[6], Nx, Ny, Nz, NNx, NNy, NNz; double NL;
486: FILE *temp; char LTemp[MAX_PATH];
487: sprintf(LTemp, "_vtf_%u.tmp", getpid());
488: if ((temp = fopen(LTemp, "w+b"))== NULL) {
489: fprintf(stderr, "Temporaerdatei '%s' nicht schreibbar!\n", LTemp);
490: fclose(ein); Pause(); return 0;
491: }
492: trianguleto.repeated = 0;
493: ZNR = 0;
494: while (fgets(Zeile, MAX_PATH + 50, ein) != NULL) {
495: if (!silent) if (!(ZNR & 0xfff)) {
496: fprintf(stderr, " %5.1f %%\r", (float) ((100.0 * ftell(ein)) / ((float) FileSize)));
497: }
498: Kennwort[0] = '\0'; ZNR++;
499: sw = sscanf(Zeile, "%s %f %f %f", Kennwort, &d1, &d2, &d3);
500: if (!strcmp(Kennwort, "solid")) {
501: STATE = 1;
502: Kennwort2[0] = '\0';
503: sscanf(Zeile, "%s %s", Kennwort, Kennwort2);
504: if (data_in_temp) {
505: if (!silent) fprintf(stderr, " Pass 1 ready\r");
506: FlushFileIndexedSLP(temp, aus2);
507: data_in_temp = 0;
508: fclose(temp); unlink(LTemp);
509: if ((temp = fopen(LTemp, "w+b"))== NULL) {
510: fprintf(stderr, "Temporaerdatei '%s' nicht schreibbar!\n", LTemp);
511: fclose(ein); Pause(); return 0;
512: }
513: if (!silent) fprintf(stderr, " Pass 2 ready \n");
514: }
515: store_beginsolid(aus2, Kennwort2);
516: } else
517: if (!strcmp(Kennwort, "endsolid")) {
518: STATE = 0;
519: if (data_in_temp) {
520: if (!silent) fprintf(stderr, " Pass 1 ready\r");
521: FlushFileIndexedSLP(temp, aus2);
522: data_in_temp = 0;
523: fclose(temp); unlink(LTemp);
524: if ((temp = fopen(LTemp, "w+b"))== NULL) {
525: fprintf(stderr, "Temporaerdatei '%s' nicht schreibbar!\n", LTemp);
526: fclose(ein); Pause(); return 0;
527: }
528: if (!silent) fprintf(stderr, " Pass 2 ready \n");
529: }
530: store_endsolid(aus2);
531: } else
532: if (!strcmp(Kennwort, "color")) {
533: if ((STATE == 1) && (sw == 4))
534: if (colorindexed) {
535: pn = coordinate_index(d1, d2, d3);
536: store_color_indexed(temp, pn);
537: } else
538: store_set_color(temp, (float) d1, (float) d2, (float) d3);
539: data_in_temp = 1;
540: } else
541: if (!strcmp(Kennwort, "facet")) {
542: if (STATE == 1) {
543: cn = cv = 0;
544: STATE = 2;
545: sw = sscanf(Zeile, "%s %s %f %f %f", Kennwort, Kennwort2, &d1, &d2, &d3);
546: if ((sw == 5) && !strcmp(Kennwort2, "normal") && (cn < 3)) {
547: nx[cn] = d1; ny[cn] = d2; nz[cn] = d3; cn++;
548: }
549: }
550: } else
551: if (!strcmp(Kennwort, "endfacet")) {
552: if (STATE > 1) {
553: if ((cv == 3) && (cn > 0)) {
554: NNx = nx[0]; NNy = ny[0]; NNz = nz[0];
555: for (sw = 1; sw < cn; sw++) {
556: NNx += nx[sw]; NNy += ny[sw]; NNz += nz[sw];
557: }
558: vx[3] = vx[1] - vx[0]; vx[4] = vx[2] - vx[1]; vx[5] = vx[0] - vx[2];
559: vy[3] = vy[1] - vy[0]; vy[4] = vy[2] - vy[1]; vy[5] = vy[0] - vy[2];
560: vz[3] = vz[1] - vz[0]; vz[4] = vz[2] - vz[1]; vz[5] = vz[0] - vz[2];
561: Nx = (vy[3] * vz[4] - vz[3] * vy[4]) + (vy[4] * vz[5] - vz[4] * vy[5]) + (vy[5] * vz[3] - vz[5] * vy[3]);
562: Ny = (vz[3] * vx[4] - vx[3] * vz[4]) + (vz[4] * vx[5] - vx[4] * vz[5]) + (vz[5] * vx[3] - vx[5] * vz[3]);
563: Nz = (vx[3] * vy[4] - vy[3] * vx[4]) + (vx[4] * vy[5] - vy[4] * vx[5]) + (vx[5] * vy[3] - vy[5] * vx[3]);
564: NL = sqrt(Nx*Nx + Ny*Ny + Nz*Nz);
565: if (NL >= 1.0e-100L) {
566: if ((d1 = Nx * NNx + Ny * NNy + Nz * NNz) > 0.0) {
567: } else if (d1 < 0.0) {
568: NL *= -1.0;
569: vx[4] = vx[1]; vx[1] = vx[2]; vx[2] = vx[4];
570: vy[4] = vy[1]; vy[1] = vy[2]; vy[2] = vy[4];
571: vz[4] = vz[1]; vz[1] = vz[2]; vz[2] = vz[4];
572: }
573: Nx /= NL; Ny /= NL; Nz /= NL;
574: }
575: pn = coordinate_index(Nx, Ny, Nz);
576: p1 = coordinate_index(vx[0], vy[0], vz[0]);
577: p2 = coordinate_index(vx[1], vy[1], vz[1]);
578: p3 = coordinate_index(vx[2], vy[2], vz[2]);
579: store_facet_indexed(temp, pn, p1, p2, p3);
580: data_in_temp = 1;
581: }
582: STATE = 1;
583: }
584: } else
585: if (!strcmp(Kennwort, "outer")) {
586: if (STATE == 2) STATE = 3;
587: } else
588: if (!strcmp(Kennwort, "endloop")) {
589: if (STATE == 3) STATE = 2;
590: } else
591: if (!strcmp(Kennwort, "normal")) {
592: if ((STATE == 2) && (sw == 4) && (cn < 3)) {
593: nx[cn] = d1; ny[cn] = d2; nz[cn] = d3; cn++;
594: }
595: } else
596: if (!strcmp(Kennwort, "vertex")) {
597: if ((STATE == 3) && (sw == 4) && (cv < 3)) {
598: vx[cv] = d1; vy[cv] = d2; vz[cv] = d3; cv++;
599: }
600: }
601: }
602: flush_facets(temp);
603: if (data_in_temp) {
604: if (!silent) fprintf(stderr, " Pass 1 ready\r");
605: FlushFileIndexedSLP(temp, aus2);
606: data_in_temp = 0;
607: if (!silent) fprintf(stderr, " Pass 2 ready \n");
608: }
609: fclose(temp); unlink(LTemp);
610: return 1;
611: }
612:
613:
614: int ReadFileSLP(FILE *ein, FILE *aus)
615: { char Zeile[MAX_PATH + 50], Kennwort[MAX_PATH + 50], Kennwort2[MAX_PATH + 50];
616: unsigned long ZNR;
617: int sw, stp = -1, STATE = -1, cv, cn;
618: float d1, d2, d3, nx[3], ny[3], nz[3], vx[6], vy[6], vz[6], Nx, Ny, Nz, NNx, NNy, NNz; double NL;
619: trianguleto.repeated = 0;
620: ZNR = 0;
621: while (fgets(Zeile, MAX_PATH + 50, ein) != NULL) {
622: Kennwort[0] = '\0'; ZNR++;
623: sw = sscanf(Zeile, "%s %f %f %f", Kennwort, &d1, &d2, &d3);
624: if (!strcmp(Kennwort, "solid")) {
625: STATE = 1;
626: Kennwort2[0] = '\0';
627: sscanf(Zeile, "%s %s", Kennwort, Kennwort2);
628: store_beginsolid(aus, Kennwort2);
629: } else
630: if (!strcmp(Kennwort, "endsolid")) {
631: STATE = 0;
632: store_endsolid(aus);
633: } else
634: if (!strcmp(Kennwort, "color")) {
635: if ((STATE == 1) && (sw == 4))
636: store_set_color(aus, (float) d1, (float) d2, (float) d3);
637: } else
638: if (!strcmp(Kennwort, "facet")) {
639: if (STATE == 1) {
640: cn = cv = 0;
641: STATE = 2;
642: sw = sscanf(Zeile, "%s %s %f %f %f", Kennwort, Kennwort2, &d1, &d2, &d3);
643: if ((sw == 5) && !strcmp(Kennwort2, "normal") && (cn < 3)) {
644: nx[cn] = d1; ny[cn] = d2; nz[cn] = d3; cn++;
645: }
646: }
647: } else
648: if (!strcmp(Kennwort, "endfacet")) {
649: if (STATE > 1) {
650: if ((cv == 3) && (cn > 0)) {
651: NNx = nx[0]; NNy = ny[0]; NNz = nz[0];
652: for (sw = 1; sw < cn; sw++) {
653: NNx += nx[sw]; NNy += ny[sw]; NNz += nz[sw];
654: }
655:
656: vx[3] = vx[1] - vx[0]; vx[4] = vx[2] - vx[1]; vx[5] = vx[0] - vx[2];
657: vy[3] = vy[1] - vy[0]; vy[4] = vy[2] - vy[1]; vy[5] = vy[0] - vy[2];
658: vz[3] = vz[1] - vz[0]; vz[4] = vz[2] - vz[1]; vz[5] = vz[0] - vz[2];
659:
660:
661:
662:
663:
664: Nx = (vy[3] * vz[4] - vz[3] * vy[4]) + (vy[4] * vz[5] - vz[4] * vy[5]) + (vy[5] * vz[3] - vz[5] * vy[3]);
665: Ny = (vz[3] * vx[4] - vx[3] * vz[4]) + (vz[4] * vx[5] - vx[4] * vz[5]) + (vz[5] * vx[3] - vx[5] * vz[3]);
666: Nz = (vx[3] * vy[4] - vy[3] * vx[4]) + (vx[4] * vy[5] - vy[4] * vx[5]) + (vx[5] * vy[3] - vy[5] * vx[3]);
667:
668:
669:
670: NL = sqrt(Nx*Nx + Ny*Ny + Nz*Nz);
671:
672: if (NL >= 1.0e-100L) {
673: if ((d1 = Nx * NNx + Ny * NNy + Nz * NNz) > 0.0) {
674: } else if (d1 < 0.0) {
675: NL *= -1.0;
676: vx[4] = vx[1]; vx[1] = vx[2]; vx[2] = vx[4];
677: vy[4] = vy[1]; vy[1] = vy[2]; vy[2] = vy[4];
678: vz[4] = vz[1]; vz[1] = vz[2]; vz[2] = vz[4];
679: }
680:
681: Nx /= NL; Ny /= NL; Nz /= NL;
682:
683: }
684:
685: store_facet_short(aus, Nx, Ny, Nz, vx, vy, vz);
686: }
687: STATE = 1;
688: }
689: } else
690: if (!strcmp(Kennwort, "outer")) {
691: if (STATE == 2) STATE = 3;
692: } else
693: if (!strcmp(Kennwort, "endloop")) {
694: if (STATE == 3) STATE = 2;
695: } else
696: if (!strcmp(Kennwort, "normal")) {
697: if ((STATE == 2) && (sw == 4) && (cn < 3)) {
698: nx[cn] = d1; ny[cn] = d2; nz[cn] = d3; cn++;
699: }
700: } else
701: if (!strcmp(Kennwort, "vertex")) {
702: if ((STATE == 3) && (sw == 4) && (cv < 3)) {
703: vx[cv] = d1; vy[cv] = d2; vz[cv] = d3; cv++;
704: }
705: }
706: }
707: flush_facets(aus);
708: return 1;
709: }
710:
711:
712: int which_eoln(FILE *ein)
713: { unsigned char C;
714: unsigned long CP;
715: CP = ftell(ein);
716: while (fread(&C, 1, 1, ein) > 0) {
717: switch(C) {
718: case '\n': case '\r':
719: fseek(ein, CP, SEEK_SET);
720: return 1;
721: case '\0':
722: fseek(ein, CP, SEEK_SET);
723: return 2;
724: }
725: }
726: fseek(ein, CP, SEEK_SET);
727: return -1;
728: }
729:
730: void ReadFileIn(char *datei, char *nach)
731: { FILE *ein;
732: char Kopf[8];
733: total_facet_count = 0;
734: if ((ein = fopen(datei, "rb")) == NULL) {
735: fprintf(stderr, "Datei '%s' nicht lesbar!\n", datei);
736: Pause();
737: return;
738: }
739: Kopf[0] = '\0';
740: fread(Kopf, 1, strlen(SLP_STL_ASCII_HEAD), ein);
741: fseek(ein, 0L, SEEK_END); FileSize = ftell(ein); fseek(ein, 0L, SEEK_SET);
742: Kopf[strlen(SLP_STL_ASCII_HEAD)] = '\0';
743: if (!strcmp(Kopf, SLP_STL_ASCII_HEAD)) {
744: switch(which_eoln(ein)) {
745: case 1:
746: if ((aus = aus2 = fopen(nach, "wb")) == NULL) {
747: fprintf(stderr, "Datei '%s' nicht schreibbar!\n", nach);
748: fclose(ein); Pause(); return;
749: }
750: fwrite(&head, 1, sizeof(struct HEAD), aus); swap_still_allowed = 0;
751: ReadFileSLP(ein, aus);
752: fclose(aus);
753: if (!total_facet_count) unlink(nach);
754: break;
755: default:
756: goto reading_unknown_type;
757: }
758: } else {
759: reading_unknown_type:
760: fprintf(stderr, "Unbekannter Datentyp!\n");
761: }
762: fclose(ein);
763: }
764:
765: void ReadFileInIndexed(char *datei, char *nach)
766: { FILE *ein;
767: char Kopf[8], Temp[MAX_PATH];
768: Temp[0] = '\0'; ein = NULL;
769: total_facet_count = 0;
770: if ((ein = fopen(datei, "rb")) == NULL) {
771: fprintf(stderr, "Datei '%s' nicht lesbar!\n", datei);
772: Pause(); return;
773: }
774:
775: Kopf[0] = '\0';
776: fread(Kopf, 1, strlen(SLP_STL_ASCII_HEAD), ein);
777: fseek(ein, 0L, SEEK_END); FileSize = ftell(ein); fseek(ein, 0L, SEEK_SET);
778: Kopf[strlen(SLP_STL_ASCII_HEAD)] = '\0';
779: if (!strcmp(Kopf, SLP_STL_ASCII_HEAD)) {
780: switch(which_eoln(ein)) {
781: case 1:
782:
783:
784:
785:
786: if ((aus2 = fopen(nach, "wb")) == NULL) {
787: fprintf(stderr, "Datei '%s' nicht schreibbar!\n", nach);
788: fclose(ein); fclose(aus); Pause(); return;
789: }
790: fwrite(&head, 1, sizeof(struct HEAD), aus2); swap_still_allowed = 0;
791: ReadFileIndexedSLP(ein, aus2);
792: fclose(ein);
793:
794:
795:
796:
797:
798:
799: fclose(aus2); fclose(ein); ein = NULL;
800:
801: if (!total_facet_count) unlink(nach);
802:
803: break;
804: default:
805: goto reading_unknown_type;
806: }
807: } else {
808: reading_unknown_type:
809: fprintf(stderr, "Unbekannter Datentyp!\n");
810: }
811: if (ein != NULL) fclose(ein);
812: }
813:
814: void ask_if_indexed(void)
815: { int wahl = 2;
816: char Zeile[50];
817: fprintf(stderr, "\nErzeugungsoptionen: Conversion options:\n");
818: fprintf(stderr, " 1 = einfach 1 = simple\n");
819: fprintf(stderr, " 2 = mit Koordinatentabelle 2 = with coordinate table\n");
820: fprintf(stderr, " 3 = zus. Farbtabelle 3 = with color and coordinate table\n");
821: fprintf(stderr, " 0 = ABBRUCH 0 = ABORT\n");
822: fprintf(stderr, " Ihre Wahl / your selection? [%d]? ", wahl);
823: Zeile[0] = '\0'; fgets(Zeile, 50, stdin); sscanf(Zeile, "%d", &wahl);
824: switch(wahl) {
825: case 1: indexed = 0; colorindexed = 0; break;
826: case 2: indexed = 1; colorindexed = 0; break;
827: case 3: indexed = 1; colorindexed = 1; break;
828: case 0: exit(0);
829: }
830: }
831:
832: int main(int argc, char **argv)
833: { int ct, argp;
834: char Erg[MAX_PATH + 3], LongPath[MAX_PATH + 3], *FileIn;
835: #ifdef _WIN32
836: HANDLE Find; WIN32_FIND_DATA fd;
837: #endif
838: int auto_name = 0;
839: #ifdef _WIN32
840: unsigned long s_time, e_time;
841: s_time = GetTickCount();
842:
843: #endif
844: if (argc < 3) {
845: if (argc == 2) {
846: #ifdef _WIN32
847: Find = FindFirstFile(argv[1], &fd);
848: LongPath[0] = '\0'; GetFullPathName(argv[1], MAX_PATH + 3, LongPath, &FileIn);
849: if (LongPath[0]) {
850: strcpy(FileIn, fd.cFileName);
851: FileIn = LongPath;
852: } else FileIn = argv[1];
853: #else
854: FileIn = argv[1];
855: #endif
856: strcpy(Erg, FileIn);
857: for (ct = strlen(Erg) - 1; ct >= 0; ct--) {
858: switch (Erg[ct]) {
859: case '.':
860: strcpy(&(Erg[ct]), ".vtf");
861: ct = -1;
862: break;
863: case '\\':
864: strcat(Erg, ".vtf");
865: ct = -1;
866: break;
867: }
868: }
869: if (strcmp(Erg, FileIn)) {
870: fprintf(stderr, " %s -> %s ...\n", FileIn, Erg);
871: if (access(Erg, 0) >= 0) fprintf(stderr, "\nA C H T U N G ! ! ! W A R N I N G ! ! !\n"
872: "\nDatei wird ueberschrieben! Output file will be replaced!\n");
873: indexed = 1; ask_if_indexed();
874: if (indexed) ReadFileInIndexed(FileIn, Erg);
875: else ReadFileIn(FileIn, Erg);
876: }
877: #ifdef _WIN32
878: FindClose(Find);
879: e_time = GetTickCount();
880: e_time -= s_time;
881: s_time = e_time % 60000L;
882: if (!silent) fprintf(stderr, "%lu Min., %lu Sek., %lu ms\n",
883: e_time / 60000L, s_time / 1000L, s_time % 1000L);
884: #endif
885: return 0;
886: } else {
887: fprintf(stderr, "Zu wenig Argumente!\n");
888: fprintf(stderr, "Gebrauch:\n"
889: " slp2vtf [-index] [-silent] [-swap] <SLP-Datei-'von'> <VTF-Datei-'nach'>\n"
890: " slp2vtf [-colorindex] [-silent] [-swap] <SLP-Datei-'von'> <VTF-Datei-'nach'>\n"
891: " slp2vtf [-auto] [-index] [-silent] [-swap] <SLP-Datei(en)-'von'>\n"
892: " slp2vtf [-auto] [-colorindex] [-silent] [-swap] <SLP-Datei(en)-'von'>\n");
893: Pause(); return 1;
894: }
895: }
896: for (argp = 1; argp < argc; argp++) {
897: if (argv[argp][0] == '-') {
898: if (!strcmp(argv[argp], "-auto")) auto_name = 1;
899: if (!strcmp(argv[argp], "-index")) indexed = 1;
900: if (!strcmp(argv[argp], "-silent")) silent = 1;
901: if (!strcmp(argv[argp], "-swap") && swap_still_allowed) { swaped = 1 - swaped;
902: swap2(&(head.us)); swap4(&(head.ul));
903: swap4((unsigned long *)&(head.f)); swap8((unsigned __int64 *)&(head.d));
904: }
905: if (!strcmp(argv[argp], "-colorindex")) { indexed = 1, colorindexed = 1; }
906: } else {
907: if (auto_name) {
908: #ifdef _WIN32
909: Find = FindFirstFile(argv[argp], &fd);
910: LongPath[0] = '\0'; GetFullPathName(argv[argp], MAX_PATH + 3, LongPath, &FileIn);
911: if (LongPath[0]) {
912: strcpy(FileIn, fd.cFileName);
913: FileIn = LongPath;
914: } else FileIn = argv[argp];
915: #else
916: FileIn = argv[argp];
917: #endif
918: strcpy(Erg, FileIn);
919: for (ct = strlen(Erg) - 1; ct >= 0; ct--) {
920: switch (Erg[ct]) {
921: case '.':
922: strcpy(&(Erg[ct]), ".vtf");
923: ct = -1;
924: break;
925: case '\\': case '/': case ':':
926: strcat(Erg, ".vtf");
927: ct = -1;
928: break;
929: }
930: }
931: if (strcmp(Erg, FileIn)) {
932: if (!silent) fprintf(stderr, " %s -> %s ...\n", FileIn, Erg);
933: if (indexed) ReadFileInIndexed(FileIn, Erg);
934: else ReadFileIn(FileIn, Erg);
935: }
936: #ifdef _WIN32
937: FindClose(Find);
938: #endif
939: } else {
940: if (indexed) ReadFileInIndexed(argv[argp], argv[argp + 1]);
941: else ReadFileIn(argv[argp], argv[argp + 1]);
942: #ifdef _WIN32
943: e_time = GetTickCount();
944: e_time -= s_time;
945: s_time = e_time % 60000L;
946: if (!silent) fprintf(stderr, "%lu Min., %lu Sek., %lu ms\n",
947: e_time / 60000L, s_time / 1000L, s_time % 1000L);
948: #endif
949: return 0;
950: }
951: }
952: }
953: #ifdef _WIN32
954: e_time = GetTickCount();
955: e_time -= s_time;
956: s_time = e_time % 60000L;
957: if (!silent) fprintf(stderr, "%lu Min., %lu Sek., %lu ms\n",
958: e_time / 60000L, s_time / 1000L, s_time % 1000L);
959: #endif
960: return 0;
961: }
962: