001: /* neut2slp.c

002:  * by Arnold Wendl, Fürth, anno Domini 2003

003:  * Das neutrale Lösungsübergabeformat in eine SLP-Datei wandeln

004:  */
005: #include <stdio.h>
006: #include <mem.h>
007: #include <malloc.h>
008: #include <windows.h> /* Codepageumschaltung */
009: 
010: char SETUP_FILE[MAX_PATH] = "neut2slp.map";
011: char PROGRAMM[MAX_PATH] = "rtd";
012: int delete_slp = 0;
013: 
014: typedef struct TP_MATRIX {
015:   float MATRIX[12];
016: } MATRIX;
017: 
018: struct TP_BausteinReferenz {
019:   int Nr;
020:   MATRIX Mat;
021:   float scale;
022:   char Datei[MAX_PATH];
023:   struct TP_BausteinReferenz *next;
024: } *BausteinReferenz = NULL;
025: 
026: void AddBausteinReferenz(int Nr, MATRIX Mat, float scale, char *Datei)
027: { struct TP_BausteinReferenz *neu;
028:   if ((neu = malloc(sizeof(struct TP_BausteinReferenz))) == NULL) return;
029:   neu->Nr = Nr;
030:   neu->Mat = Mat;
031:   neu->scale = scale;
032:   strncpy(neu->Datei, Datei, MAX_PATH);
033:   neu->Datei[MAX_PATH - 1] = '\0';
034:   neu->next = BausteinReferenz;
035:   BausteinReferenz = neu;
036: }
037: 
038: int SetUpBausteinReferenz(void)
039: { FILE *dat;
040:   char Dat[2 * MAX_PATH], Zeile[2 * MAX_PATH];
041:   MATRIX Mat; float Scale; int BS;
042:   if ((dat = fopen(SETUP_FILE, "r")) == NULL) {
043:     fprintf(stderr, "Konfiguration '%s' nicht lesbar!\n", SETUP_FILE);
044:     return -1;
045:   }
046:   while (fgets(Zeile, 2 * MAX_PATH, dat)) {
047:     Dat[0] = '\0';
048:     sscanf(Zeile, "%d%f%f%f%f%f%f%f%f%f%f%f%f%f%s", &BS,
049:       &(Mat.MATRIX[ 0]), &(Mat.MATRIX[ 1]), &(Mat.MATRIX[ 2]), 
050:       &(Mat.MATRIX[ 3]), &(Mat.MATRIX[ 4]), &(Mat.MATRIX[ 5]), 
051:       &(Mat.MATRIX[ 6]), &(Mat.MATRIX[ 7]), &(Mat.MATRIX[ 8]), 
052:       &(Mat.MATRIX[ 9]), &(Mat.MATRIX[10]), &(Mat.MATRIX[11]), 
053:       &Scale, Dat);
054:     if (Dat[0]) AddBausteinReferenz(BS, Mat, Scale, Dat);
055:   }
056:   fclose(dat);
057:   return 0;
058: }
059: 
060: struct TP_BausteinReferenz *BausteinRefernezByNumber(int Nr)
061: { struct TP_BausteinReferenz *br;
062:   for (br = BausteinReferenz; br != NULL; br = br->next)
063:    if (br->Nr == Nr) return br;
064:   return NULL;
065: }
066: 
067: MATRIX MatMul(MATRIX m1, MATRIX m2)
068: { MATRIX erg;
069:   memset(&erg, 0, sizeof(MATRIX));
070:   erg.MATRIX[0] = m1.MATRIX[0] * m2.MATRIX[0] + m1.MATRIX[3] * m2.MATRIX[1] + m1.MATRIX[6] * m2.MATRIX[2];
071:   erg.MATRIX[1] = m1.MATRIX[1] * m2.MATRIX[0] + m1.MATRIX[4] * m2.MATRIX[1] + m1.MATRIX[7] * m2.MATRIX[2];
072:   erg.MATRIX[2] = m1.MATRIX[2] * m2.MATRIX[0] + m1.MATRIX[5] * m2.MATRIX[1] + m1.MATRIX[8] * m2.MATRIX[2];
073:   erg.MATRIX[3] = m1.MATRIX[0] * m2.MATRIX[3] + m1.MATRIX[3] * m2.MATRIX[4] + m1.MATRIX[6] * m2.MATRIX[5];
074:   erg.MATRIX[4] = m1.MATRIX[1] * m2.MATRIX[3] + m1.MATRIX[4] * m2.MATRIX[4] + m1.MATRIX[7] * m2.MATRIX[5];
075:   erg.MATRIX[5] = m1.MATRIX[2] * m2.MATRIX[3] + m1.MATRIX[5] * m2.MATRIX[4] + m1.MATRIX[8] * m2.MATRIX[5];
076:   erg.MATRIX[6] = m1.MATRIX[0] * m2.MATRIX[6] + m1.MATRIX[3] * m2.MATRIX[7] + m1.MATRIX[6] * m2.MATRIX[8];
077:   erg.MATRIX[7] = m1.MATRIX[1] * m2.MATRIX[6] + m1.MATRIX[4] * m2.MATRIX[7] + m1.MATRIX[7] * m2.MATRIX[8];
078:   erg.MATRIX[8] = m1.MATRIX[2] * m2.MATRIX[6] + m1.MATRIX[5] * m2.MATRIX[7] + m1.MATRIX[8] * m2.MATRIX[8];
079:   erg.MATRIX[ 9] = m1.MATRIX[0] * m2.MATRIX[9] + m1.MATRIX[3] * m2.MATRIX[10] + m1.MATRIX[6] * m2.MATRIX[11] + m1.MATRIX[ 9];
080:   erg.MATRIX[10] = m1.MATRIX[1] * m2.MATRIX[9] + m1.MATRIX[4] * m2.MATRIX[10] + m1.MATRIX[7] * m2.MATRIX[11] + m1.MATRIX[10];
081:   erg.MATRIX[11] = m1.MATRIX[2] * m2.MATRIX[9] + m1.MATRIX[5] * m2.MATRIX[10] + m1.MATRIX[8] * m2.MATRIX[11] + m1.MATRIX[11];
082:   return erg;
083: }
084: 
085: void SchreibeBausteinSLP(FILE *aus, float size, char *von, MATRIX m)
086: { char Zeile[100];
087:   FILE *ein;
088:   float fx, fy, fz;
089:   if ((ein = fopen(von, "rb")) == NULL) {
090:     fprintf(stderr, "Kann Datei '%s' nicht lesen!\n", von);
091:     return;
092:   }
093:   while (fgets(Zeile, 100, ein) != NULL) {
094:     if (!strncmp(Zeile, "      normal ", 13)) {
095:       sscanf(&(Zeile[13]), "%e%e%e", &fx, &fy, &fz);
096:       fprintf(aus, "      normal %.6e %.6e %.6e\r\n",
097:         m.MATRIX[0] * fx + m.MATRIX[3] * fy + m.MATRIX[6] * fz,
098:         m.MATRIX[1] * fx + m.MATRIX[4] * fy + m.MATRIX[7] * fz,
099:         m.MATRIX[2] * fx + m.MATRIX[5] * fy + m.MATRIX[8] * fz);
100:     } else
101:     if (!strncmp(Zeile, "      vertex ", 13)) {
102:       sscanf(&(Zeile[13]), "%e%e%e", &fx, &fy, &fz);
103:       fprintf(aus, "      vertex %.6e %.6e %.6e\r\n",
104:         m.MATRIX[0] * fx + m.MATRIX[3] * fy + m.MATRIX[6] * fz + size * m.MATRIX[ 9],
105:         m.MATRIX[1] * fx + m.MATRIX[4] * fy + m.MATRIX[7] * fz + size * m.MATRIX[10],
106:         m.MATRIX[2] * fx + m.MATRIX[5] * fy + m.MATRIX[8] * fz + size * m.MATRIX[11]);
107:     } else
108:       fprintf(aus, "%s", Zeile);
109:   }
110:   fclose(ein);
111: }
112: 
113: void Verarbeite(char *D)
114: { char Pfad[MAX_PATH], CMD[2 * MAX_PATH + 5];
115:   int ct;
116:   struct TP_BausteinReferenz *br;
117:   FILE *Aus, *Ein;
118:   MATRIX Mat;
119:   strcpy(Pfad, D);
120:   ct = strlen(Pfad) - 4;
121:   if ((ct > 0) && !stricmp(&(Pfad[ct]), ".pos")) strcpy(&(Pfad[ct]), ".slp");
122:   fprintf(stderr, "%s -> %s ...\n", D, Pfad);
123:   if ((Ein = fopen(D, "r")) == NULL) {
124:     fprintf(stderr, "Datei '%s' nicht lesbar!\n", D);
125:     return;
126:   }
127:   if ((Aus = fopen(Pfad, "wb")) == NULL) {
128:     fprintf(stderr, "Datei '%s' kann nicht erzeugt werden!\n", Pfad);
129:     fclose(Ein);
130:     return;
131:   }
132:   while (fgets(CMD, 2 * MAX_PATH, Ein)) {
133:     ct = -1;
134:     sscanf(CMD, "%d%f%f%f%f%f%f%f%f%f%f%f%f", &ct,
135:       &(Mat.MATRIX[ 0]), &(Mat.MATRIX[ 1]), &(Mat.MATRIX[ 2]), 
136:       &(Mat.MATRIX[ 3]), &(Mat.MATRIX[ 4]), &(Mat.MATRIX[ 5]), 
137:       &(Mat.MATRIX[ 6]), &(Mat.MATRIX[ 7]), &(Mat.MATRIX[ 8]), 
138:       &(Mat.MATRIX[ 9]), &(Mat.MATRIX[10]), &(Mat.MATRIX[11]));
139:     if (ct >= 0) {
140:       if ((br = BausteinRefernezByNumber(ct)) == NULL) {
141:         fprintf(stderr, "Baustein Nr. %d ist aber nicht definiert!\n", ct);
142:       } else {
143:         SchreibeBausteinSLP(Aus, br->scale, br->Datei, MatMul(Mat, br->Mat));
144:       }
145:     }
146:   }
147:   fclose(Aus); fclose(Ein);
148:   if (PROGRAMM[0]) {
149:     sprintf(CMD, "%s %s", PROGRAMM, Pfad);
150:     system(CMD);
151:     if (delete_slp) unlink(Pfad);
152:   }
153: }
154: 
155: void show_syntax(void)
156: { printf("SYNTAX:\n"
157:          "neut2slp [Optionen] <POS-Dateien>\n\n"
158:          "Erzeugt aus den Teilenummern und Tranformationsmatrizen der\n"
159:          "'XXX.pos'-Datei eine 'XXX.slp'-Datei und startet danach ein\n"
160:          "Programm zum Ansehen der SLP-Datei.\n\n"
161:          "  <POS-Dateien> auch mehrfach\n"
162:          " Optionen:\n"
163:          "  -M<MAP-Datei>        alternative Einrichtdatei angeben\n"
164:          "      Standard: neut2slp.map\n"
165:          "  -L<Viewer-Programm>  Programm, welches die SLP-Datei darstellen soll\n"
166:          "      Standard: rtd\n"
167:          "  -L-                  Kein Viewerprogramm starten\n"
168:          "  -d                   SLP-Datei danach löschen - unsinnig,\n"
169:          "                       mit Option -L- zusammen benutzen zu wollen.\n"
170:          " Alle Optionsparameter müssen direkt auf den Optionsbuchstaben folgen,\n"
171:          " es sind keine Leerzeichen dazwischen erlaubt.\n\n"
172:          "Arnold Wendl, Fürth, anno Domini 2003\n");
173: }
174: 
175: int main(int argc, char **argv)
176: { int ct, initialized = 0;
177:   UINT CodePage;
178:   CodePage = GetConsoleOutputCP();
179:   SetConsoleOutputCP(1252);
180:   if (argc <= 1) { show_syntax(); return 1; }
181:   for (ct = 1; ct < argc; ct++) if (argv[ct][0] == '-') {
182:     switch (argv[ct][1]) {
183:       case 'M':
184:         strncpy(SETUP_FILE, &(argv[ct][2]), MAX_PATH);
185:         SETUP_FILE[MAX_PATH - 1] = '\0';
186:       break;
187:       case 'd': delete_slp = 1;
188:       break;
189:       case 'L':
190:         if (argv[ct][2] == '-') PROGRAMM[0] = '\0';
191:         else {
192:           strncpy(PROGRAMM, &(argv[ct][2]), MAX_PATH);
193:           PROGRAMM[MAX_PATH - 1] = '\0';
194:         }
195:       break;
196:       default:
197:         show_syntax();
198:     }
199:   } else {
200:     if (!initialized) {
201:       if (SetUpBausteinReferenz()) return 1;
202:       initialized = 1;
203:     }
204:     Verarbeite(argv[ct]);
205:   }
206:   SetConsoleOutputCP(CodePage);
207:   return 0;
208: }
209: