1 // $Id: Read_Input.cxx 1107 2011-01-19 23:53:52Z martin $
2 //
3 // Read_Input.cxx - Source module for DRAWxtl V5.5
4 // Coded using the FLTK 1.1.6 widget set
5 //
6 //     Larry W. Finger, Martin Kroeker and Brian Toby
7 //
8 //
9 // This module contains the following routines:
10 //
11 //  Blank_Strip - strips leading spaces from a string
12 //  check_atom_name - return 1 if input names match, 0 otherwise
13 //  expand_atom - generates all atoms of a given type within the unit cell
14 //  findsys - determines crystal system from symmetry information
15 //  find_lattice_type - interpret a set of x',y',z' symmetry operators to find lattice type
16 //  get_label - gets 1-4 character atom label from input string
17 //  getsym - obtain symmetry information from a SHELX-style SYMM card
18 //  Init_DRAWxtl - initialize all global variables
19 //  P_to_C - convert ellipsoid probability to scaling parameter
20 //  read_inp - read and process input ('.str') file
21 //  set_tf_status - sets the status information regarding temperature factors
22 //  skip_blocks - skip over data blocks in a CIF
23 //  Token_Strip - strips tokens from the beginning of a string
24 //  Transform_POV_Color - change input color info to POV form (if necessary)
25 //  Transform_VRML_Color - change input color into rgb triple needed by VRML and openGL
26 //  trim_string - trim strings - remove trailing spaces and control characters
27 //  Unique_Atom - checks that atom position is unique
28 //  vec_dif - find if two vectors are equal
29 //
30 #include <stdio.h>
31 #include <string.h>
32 #include <math.h>
33 #include <stdlib.h>
34 #if defined(WIN32)
35 #define snprintf _snprintf
36 #endif
37 #include <ctype.h>
38 #include "drawxtl.h"
39 #include "draw_ext.h"
40 #include "DRAWxtlViewUI.h"
41 
42 #include "DRAWxtl_proto.h"
43 
44 struct tmp_color_struct
45 {
46     char el_color_tmp[256];
47 };
48 
49 int Block_CIF = 0;
50 
51 int g_Quick;
52 
53 /* ************************************************************** */
54 /* ************************************************************** */
55 
56 void
Blank_Strip(char input[])57 Blank_Strip (char input[])
58 
59 /* routine to suppress any leading spaces in the input string */
60 {
61     unsigned int i, j;
62 
63     for (i = 0; i < strlen(input); i++)
64 	if (input[i] != ' ')
65 	    break;
66     for (j = 0; j < strlen(input); j++) {
67 	input[j] = input[i];
68 	if (input[i++] == '\0')
69 	    break;
70     }
71 }
72 
73 /* ************************************************************** */
74 /* ************************************************************** */
75 
76 int
check_atom_name(char * name1,char * name2)77 check_atom_name (char *name1, char *name2)
78 {
79 // determine if two atom names are the same. Return 1 (TRUE) if they are
80 
81     if (name1[0] == name2[0] && name1[1] == name2[1] &&
82 	name1[2] == name2[2] && name1[3] == name2[3])
83 	return 1;
84     else
85 	return 0;
86 }
87 
88 /* ************************************************************** */
89 /* ************************************************************** */
90 
91 float
convert_pos(char * string)92 convert_pos (char *string)
93 {
94 // routine to convert an atom string to a float. If only digits, a simple sscanf
95 //  is done. If the position is of the form n/m, each part is decoded and the
96 // results of the division is returned.
97 
98     float result;
99 
100     int i, n, m;
101 
102     char *pdest;
103 
104     char sub_string1[10], sub_string2[10];
105 
106     if (!(pdest = strstr (string, "/"))) {
107 	sscanf (string, "%f", &result);	// no / in the input
108     } else {
109 	i = pdest - string + 1;	// number of chars to copy
110 	strncpy (sub_string1, string, i);
111 	sub_string1[i - 1] = '\0';
112 	strcpy (sub_string2, pdest + 1);	// copy part after /
113 	sscanf (sub_string1, "%d", &n);
114 	sscanf (sub_string2, "%d", &m);
115 	result = (float) n / (float) m;
116     }
117     return result;
118 }
119 
120 /* ************************************************************** */
121 /* ************************************************************** */
122 
123 int
end_flip(int value)124 end_flip (int value)
125 {
126 // routine to flip the endian nature of the input integer
127 // This routine was copied from a Web article:
128 //   http://www.codeproject.com/cpp/endianness.asp by Juan Carlos Cobas
129 
130     return (((value & 0x000000FF) << 24) + ((value & 0x0000FF00) << 8) +
131 	    ((value & 0x00FF0000) >> 8) + ((value & 0xFF000000) >> 24));
132 }
133 
134 /* ************************************************************** */
135 /* ************************************************************** */
136 
137 float
end_flip_real(float value)138 end_flip_real (float value)
139 {
140 // routine to flip the endian nature of the input float
141 // This routine was copied from a Web article:
142 //   http://www.codeproject.com/cpp/endianness.asp by Juan Carlos Cobas
143 
144     union u
145     {
146 	float vi;
147 	unsigned char c[4];
148     };
149 
150     union v
151     {
152 	float ni;
153 	unsigned char d[4];
154     };
155 
156     union u un;
157 
158     union v vn;
159 
160     un.vi = value;
161     vn.d[0] = un.c[3];
162     vn.d[1] = un.c[2];
163     vn.d[2] = un.c[1];
164     vn.d[3] = un.c[0];
165     return (vn.ni);
166 
167 }
168 
169 /* ************************************************************** */
170 /* ************************************************************** */
171 
172 void
expand_atom(int natom)173 expand_atom (int natom)
174 
175 /* routine to expand an atom position and obtain all equipoints within
176    the unit cell */
177 /* natom - number of atom in list to expand */
178 {
179     float xp[3], xpp[3];	/* used in generating position */
180 
181     int i, j, k, l;		/* loop variables */
182 
183     ncell = 0;			/* clear list */
184     for (i = 0; i < drvui->ng; ++i) {	/* symmetry operations */
185 	for (j = 0; j <= 2; ++j) {
186 	    xp[j] = drvui->ts[i][j];
187 	    for (k = 0; k <= 2; ++k)
188 		xp[j] = xp[j] + drvui->ss[i][j][k] * drvui->atoms[natom].atom_xyz[k];
189 	}
190 	for (k = 0; k < drvui->nlat; ++k) {	/*lattice points */
191 	    for (l = 0; l <= 2; ++l)
192 		xpp[l] = xp[l] + drvui->lat_pos[k][l];
193 	    add_to_list (xpp, i, i);
194 	    if (!drvui->acentric) {
195 		for (l = 0; l <= 2; ++l)
196 		    xpp[l] = -xpp[l];
197 		if (i == 0)
198 		    add_to_list (xpp, i, -1000);
199 		else
200 		    add_to_list (xpp, i, -i);
201 	    }
202 	}
203     }
204 }
205 
206 /* ************************************************************** */
207 /* ************************************************************** */
208 
209 void
findsys(void)210 findsys (void)
211 /* routine determine crystal system from symmetry information */
212 {
213     int i, j, k;
214 
215     int n, kk = 0, nn, *symlist;
216 
217     int yzx = 0, zxy = 0, ymxmz = 0, mxmyz = 0, myxmz = 0;
218 
219     if (drvui->ng == 1) {	/* only x,y,z => triclinic */
220 	drvui->sys = 1;
221 	return;
222     }
223 
224     if (drvui->ng == 2 && fabs (drvui->lat_con[4] - 90.) < 0.00001) {	/* only two symops => monoclinic */
225 	drvui->sys = 2;
226 	return;
227     }
228 
229     drvui->sys = 3;		/* orthorhombic unless we find specific operators below */
230 
231     for (i = 0; i < drvui->ng; ++i) {
232 	for (j = 0; j <= 2; ++j) {
233 	    if (fabs (drvui->ts[i][j] - 0.33333333) < 0.00001)
234 		drvui->sys = 5;
235 	    if (fabs (drvui->ts[i][j] - 0.16666667) < 0.00001)
236 		drvui->sys = 5;
237 	    if (fabs (drvui->ts[i][j] - 0.66666667) < 0.00001)
238 		drvui->sys = 5;
239 	    if (fabs (drvui->ts[i][j] - 0.83333333) < 0.00001)
240 		drvui->sys = 5;
241 	}
242 	if (drvui->sys == 5)
243 	    return;
244     }
245 
246     if (fabs (drvui->lat_con[5] - 120.0) < 0.00001
247 	&& fabs (drvui->lat_con[4] - 90.0) < 0.0001) {
248 	drvui->sys = 5;
249 	return;
250     }
251 #if 0
252     if (fabs (drvui->lat_con[5] - 54.27) < 0.1
253 	&& fabs (drvui->lat_con[4] - 54.27) < 0.1
254 	&& fabs (drvui->lat_con[3] - 54.27) < 0.1) {
255 	drvui->sys = 5;
256 	return;
257     }
258 #endif
259 
260     n = 0;
261     symlist = (int *) malloc (drvui->ng * sizeof (int));
262     for (i = 0; i < drvui->ng; ++i) {
263 	for (j = 0; j <= 2; ++j) {
264 	    if (drvui->ts[i][j] != 0.0)
265 		break;
266 	    kk = 0;
267 	    for (k = 0; k <= 2; ++k)
268 		if (drvui->ss[i][j][k] != 0)
269 		    kk++;
270 	}
271 	if (kk > 1) {
272 	    drvui->sys = 5;
273 	    free (symlist);
274 	    return;
275 	}
276 	symlist[n++] = i;
277     }
278 
279     for (nn = 0; nn < n; nn++) {
280 	i = symlist[nn];
281 	if (drvui->ss[i][0][1] == 1 && drvui->ss[i][1][2] == 1 && drvui->ss[i][2][0] == 1)
282 	    yzx = 1;
283 	if (drvui->ss[i][0][2] == 1 && drvui->ss[i][1][0] == 1 && drvui->ss[i][2][1] == 1)
284 	    zxy = 1;
285 	if (drvui->ss[i][0][1] == -1 &&
286 	    drvui->ss[i][1][2] == -1 && drvui->ss[i][2][0] == -1)
287 	    yzx = 1;
288 	if (drvui->ss[i][0][2] == -1 &&
289 	    drvui->ss[i][1][0] == -1 && drvui->ss[i][2][1] == -1)
290 	    zxy = 1;
291 	if (drvui->ss[i][0][1] == 1 &&
292 	    drvui->ss[i][1][0] == -1 && drvui->ss[i][2][2] == -1)
293 	    ymxmz = 1;
294 	if (drvui->ss[i][0][0] == -1 &&
295 	    drvui->ss[i][1][1] == -1 && drvui->ss[i][2][2] == 1)
296 	    mxmyz = 1;
297 	if (drvui->ss[i][0][1] == -1 &&
298 	    drvui->ss[i][1][0] == 1 && drvui->ss[i][2][2] == -1)
299 	    myxmz = 1;
300     }
301 
302     if (ymxmz + mxmyz + myxmz == 3)
303 	drvui->sys = 4;		/*tetragonal */
304     if (yzx + zxy == 2)
305 	drvui->sys = 6;		/*cubic */
306 
307     if (drvui->sys == 3 && fabs (drvui->lat_con[4] - 90.0) > 0.0001)
308 	drvui->sys = 2;
309     free (symlist);
310 }
311 
312 /* ************************************************************** */
313 /* ************************************************************** */
314 
315 void
get_label(char input[],char * c1,char * c2,char * c3,char * c4,int strip)316 get_label (char input[], char *c1, char *c2, char *c3, char *c4, int strip)
317 // Routine to get 1 to 4 character atom ID from input line, and shift input
318 //   line to left, if strip true, skip over first token
319 {
320 
321     int i, j;
322 
323     i = 0;
324     if (strip)
325 	while (input[i] != ' ')
326 	    input[i++] = ' ';	// skip over command
327     while (input[i] == ' ')
328 	i++;			// skip whitespace after command
329     *c1 = input[i];		// return first atom label character
330     input[i++] = ' ';
331     *c2 = input[i];		// return 2nd atom label char
332     if (input[i] != ' ')
333 	input[i++] = ' ';	// if 2nd not blank, rub it out
334     *c3 = input[i];		// return 3rd character
335     if (input[i] != ' ')
336 	input[i++] = ' ';	// if 3rd not blank, rub it out
337     *c4 = input[i];		// return 4th character
338     if (input[i] != ' ')
339 	input[i++] = ' ';	// if 4th not blank, rub it out
340     while (input[i] == ' ')
341 	i++;			// skip white space after atom label
342     for (j = 0; i < (int) strlen (input); i++) {
343 	input[j++] = input[i];	// copy rest of command
344     }
345     input[j] = 0;		// put NULL at end
346 }				// end of get_label
347 
348 /* ************************************************************** */
349 /* ************************************************************** */
350 
351 void
getsym(char * text,int num,int kk)352 getsym (char *text, int num, int kk)
353 
354 /* helper routine to parse SHELX or CIF symmetry operator strings */
355 {
356     int i, j;
357 
358     char *txt;
359 
360     char *n;
361 
362     char *d;
363 
364     txt = (char *) zalloc (24 * sizeof (char));
365 //    if (!g_Quick) fprintf(drvui->flout, "Entering getsym with text = %s, num = %d\n",text,num);
366 
367     j = 0;
368 
369     if (drvui->modulated >= 1) {
370 	for (i = 0; i < (int) strlen (text) - 1; i++) {
371 	    if (text[i] == 'X' || text[i] == 'x') {
372 		if (text[i + 1] == '2')
373 		    text[i] = 'Y';
374 		if (text[i + 1] == '3')
375 		    text[i] = 'Z';
376 		if (text[i + 1] == '4')
377 		    text[i] = 'Q';
378 		if (text[i + 1] == '5')
379 		    text[i] = 'R';
380 		if (text[i + 1] == '6')
381 		    text[i] = 'S';
382 		if (text[i] != 'X' && text[i] != 'x')
383 		    text[++i] = ' ';
384 	    }
385 	}
386     }
387 
388     for (i = 0; i < (int) strlen (text); i++)
389 	if (text[i] != ' ' && text[i] != '\n')
390 	    txt[j++] = toupper (text[i]);
391 
392     txt[j] = '\0';
393 
394     if (kk < 3)
395 	drvui->ts[num][kk] = 0.;
396     else
397 	drvui->ts_m[num][kk - 3] = 0.;
398 
399     n = strstr (txt, "/");
400     if (n != NULL) {
401 	n++;
402 	d = n - 3;
403 	if (d < txt || atof (d) == 0.)
404 	    d = n - 2;
405 	if (kk < 3)
406 	    drvui->ts[num][kk] = (float) (atof (d) / atof (n));
407 	else
408 	    drvui->ts_m[num][kk - 3] = (float) (atof (d) / atof (n));
409     }
410 
411     n = strstr (txt, ".");
412     if (n != NULL) {
413 	if (kk < 3) {
414 	    drvui->ts[num][kk] = (float) atof (n);
415 	    if (n != txt) {
416 		if (txt[&txt - &n + 1] == '-')
417 		    drvui->ts[num][kk] *= -1;
418 	    }
419 	} else {
420 	    drvui->ts_m[num][kk - 3] = (float) atof (n);
421 	    if (n != txt) {
422 		if (txt[&txt - &n + 1] == '-')
423 		    drvui->ts_m[num][kk - 3] *= -1;
424 	    }
425 	}
426     }
427 
428     if (kk < 3) {
429 	drvui->ss[num][kk][0] = 0;
430 	drvui->ss[num][kk][1] = 0;
431 	drvui->ss[num][kk][2] = 0;
432     } else {
433 	drvui->ss_m[num][kk - 3][0] = 0;
434 	drvui->ss_m[num][kk - 3][1] = 0;
435 	drvui->ss_m[num][kk - 3][2] = 0;
436     }
437 
438     for (i = 0; i < (int) strlen (txt); i++) {
439 	if (txt[i] == 'X') {
440 	    drvui->ss[num][kk][0] = 1;
441 	    if (i > 0) {
442 		if (txt[i - 1] == '-')
443 		    drvui->ss[num][kk][0] = -1;
444 	    }
445 	}
446 	if (txt[i] == 'Y') {
447 	    drvui->ss[num][kk][1] = 1;
448 	    if (i > 0) {
449 		if (txt[i - 1] == '-')
450 		    drvui->ss[num][kk][1] = -1;
451 	    }
452 	}
453 	if (txt[i] == 'Z') {
454 	    drvui->ss[num][kk][2] = 1;
455 	    if (i > 0) {
456 		if (txt[i - 1] == '-')
457 		    drvui->ss[num][kk][2] = -1;
458 	    }
459 	}
460 	if (txt[i] == 'Q') {
461 	    drvui->ss_m[num][kk - 3][0] = 1;
462 	    if (i > 0) {
463 		if (txt[i - 1] == '-')
464 		    drvui->ss_m[num][kk - 3][0] = -1;
465 	    }
466 	}
467 	if (txt[i] == 'R') {
468 	    drvui->ss_m[num][kk - 3][1] = 1;
469 	    if (i > 0) {
470 		if (txt[i - 1] == '-')
471 		    drvui->ss_m[num][kk - 3][1] = -1;
472 	    }
473 	}
474 	if (txt[i] == 'S') {
475 	    drvui->ss_m[num][kk - 3][2] = 1;
476 	    if (i > 0) {
477 		if (txt[i - 1] == '-')
478 		    drvui->ss_m[num][kk - 3][2] = -1;
479 	    }
480 	}
481     }
482     free (txt);
483 /*
484     if (!g_Quick) {
485        fprintf(drvui->flout, "ss: %d %d %d / %d %d %d / %d %d %d\n", drvui->ss[num][0][0],
486             drvui->ss[num][0][1], drvui->ss[num][0][2], drvui->ss[num][1][0],
487             drvui->ss[num][1][1], drvui->ss[num][1][2], drvui->ss[num][2][0],
488             drvui->ss[num][2][1], drvui->ss[num][2][2]);
489        fprintf(drvui->flout, "ts: %f %f %f\n", drvui->ts[num][0], drvui->ts[num][1], drvui->ts[num][2]);
490        fprintf(drvui->flout, "ss_m: %d %d %d / %d %d %d / %d %d %d\n", drvui->ss_m[num][0][0],
491             drvui->ss_m[num][0][1], drvui->ss_m[num][0][2], drvui->ss_m[num][1][0],
492             drvui->ss_m[num][1][1], drvui->ss_m[num][1][2], drvui->ss_m[num][2][0],
493             drvui->ss_m[num][2][1], drvui->ss_m[num][2][2]);
494        fprintf(drvui->flout, "ts_m: %f %f %f\n", drvui->ts_m[num][0], drvui->ts_m[num][1], drvui->ts_m[num][2]);
495     }
496 */
497 }
498 
499 /* ************************************************************** */
500 /* ************************************************************** */
501 
502 int
get_next_token(char * p,int max_len,FILE * fpin)503 get_next_token (char *p, int max_len, FILE * fpin)
504 {
505 /* routine to return the next token in a stream. A token is the string
506  * characters to the next white space consisting of a space, a tab, or
507  * a newline character. Carriage returns are ignored. The returned value
508  * is 1 (true) if a token is found and 0 (false) if the end of file is
509  * reached */
510 
511     char *pp = p;
512 
513     int inchar;
514 
515     int started = 0;
516 
517     int openquote = -1;
518 
519     int len = max_len - 2;
520 
521     for (;;) {			/* start an infinite loop */
522 	if ((inchar = getc (fpin)) == EOF)
523 	    break;		/* here for end-of-file */
524 	if (inchar == '\t' || inchar == ' ') {
525 	    if (started && openquote != 1) {
526 		*pp = '\0';	/* add null terminator */
527 		return 1;
528 	    }
529 	} else if (inchar == '\n') {
530 	    if (started) {
531 		*pp = '\0';
532 		return 1;
533 	    }
534 	} else if (inchar == '#' && !started) {	// comment - skip to end of line
535 	    char comment[256];
536 	    char *c = comment;
537 	    for (;;) {
538 		if ((inchar = getc (fpin)) == EOF)
539 		    return 0;	/* here for end-of-file */
540 		*c++=(char)inchar;
541 		if (inchar == '\n') {
542 		    *c='\0';
543 		    if (!strncmp(comment," End of data for", 16))
544 			return 0;
545 		    break;
546 		}
547 	    }
548 	} else if (inchar != '\r') {
549 	    *pp++ = (char) inchar;
550 	    started = 1;
551 	    if (inchar == (char) 39)
552 		openquote *= -1;
553 	    if (!--len)
554 		return 0;
555 	}
556     }
557     return 0;
558 }
559 
560 /* ************************************************************** */
561 /* ************************************************************** */
562 
563 void
find_lattice_type(void)564 find_lattice_type (void)
565 {
566 /* routine to scan symmetry elements, find the lattice type, and fill in the coorcdinates
567    of the lattice points */
568 
569     int i;
570 
571     drvui->nbr = 1;
572 
573     for (i = 1; i <= drvui->ng; ++i) {
574 	if (drvui->ss[i - 1][0][0] == 1 && drvui->ss[i - 1][1][1] == 1 && drvui->ss[i - 1][2][2] == 1) {	/* rotational part of symmetry is x,y,z - centering? */
575 	    if (drvui->ts[i - 1][0] == 0. && drvui->ts[i - 1][1] == 0.5 && drvui->ts[i - 1][2] == 0.5) {	/* found x,1/2+y,1/2+z */
576 		if (drvui->nbr == 3 || drvui->nbr == 4)
577 		    drvui->nbr = 5;	/* x,1/2+y,1/2+z && B || C ==> F */
578 		else
579 		    drvui->nbr = 2;	/* x,1/2+y,1/2+z ==> A */
580 	    }
581 	    if (drvui->ts[i - 1][0] == 0.5 && drvui->ts[i - 1][1] == 0. && drvui->ts[i - 1][2] == 0.5) {	/* found 1/2+x,y,1/2+z */
582 		if (drvui->nbr == 2 || drvui->nbr == 4)
583 		    drvui->nbr = 5;	/* 1/2+x,y,1/2+z && A || C ==> F */
584 		else
585 		    drvui->nbr = 3;	/* 1/2+x,y,1/2+z ==> B */
586 	    }
587 	    if (drvui->ts[i - 1][0] == 0.5 && drvui->ts[i - 1][1] == 0.5 && drvui->ts[i - 1][2] == 0.) {	/* found 1/2+x,1/2+y,z */
588 		if (drvui->nbr == 2 || drvui->nbr == 3)
589 		    drvui->nbr = 5;	/* 1/2+x,1/2+y,z && A || B ==> F */
590 		else
591 		    drvui->nbr = 4;	/* 1/2+x,1/2+y,z ==> C */
592 	    }
593 	    if (drvui->nbr == 1 && drvui->ts[i - 1][0] == 0.5
594 		&& drvui->ts[i - 1][1] == 0.5 && drvui->ts[i - 1][2] == 0.5)
595 		drvui->nbr = 6;	// 0.5+X,0.5+Y,0.5+Z ==> I
596 
597 	    if (drvui->ts[i - 1][0] < 0.5 && drvui->ts[i - 1][0] > 0.25)
598 		drvui->nbr = 7;	// 0.33+X ==> R
599 	}
600 
601     }
602 
603     switch (drvui->nbr) {
604     case 1:
605 	drvui->nlat = 1;
606 	break;
607     case 2:
608 	drvui->nlat = 2;
609 	drvui->lat_pos[1][0] = 0.0;
610 	drvui->lat_pos[1][1] = 0.5f;
611 	drvui->lat_pos[1][2] = 0.5f;
612 	break;
613     case 3:
614 	drvui->nlat = 2;
615 	drvui->lat_pos[1][0] = 0.5f;
616 	drvui->lat_pos[1][1] = 0.0;
617 	drvui->lat_pos[1][2] = 0.5f;
618 	break;
619     case 4:
620 	drvui->nlat = 2;
621 	drvui->lat_pos[1][0] = 0.5f;
622 	drvui->lat_pos[1][1] = 0.5f;
623 	drvui->lat_pos[1][2] = 0.0;
624 	break;
625     case 5:
626 	drvui->nlat = 4;
627 	drvui->lat_pos[1][0] = 0.0;
628 	drvui->lat_pos[1][1] = 0.5f;
629 	drvui->lat_pos[1][2] = 0.5f;
630 	drvui->lat_pos[2][0] = 0.5f;
631 	drvui->lat_pos[2][1] = 0.0;
632 	drvui->lat_pos[2][2] = 0.5f;
633 	drvui->lat_pos[3][0] = 0.5f;
634 	drvui->lat_pos[3][1] = 0.5f;
635 	drvui->lat_pos[3][2] = 0.0;
636 	break;
637     case 6:
638 	drvui->nlat = 2;
639 	drvui->lat_pos[1][0] = 0.5f;
640 	drvui->lat_pos[1][1] = 0.5f;
641 	drvui->lat_pos[1][2] = 0.5f;
642 	break;
643     case 7:
644 	drvui->nlat = 3;
645 	drvui->lat_pos[1][0] = (1.f / 3.f);
646 	drvui->lat_pos[1][1] = (2.f / 3.f);
647 	drvui->lat_pos[1][2] = (2.f / 3.f);
648 	drvui->lat_pos[2][0] = (2.f / 3.f);
649 	drvui->lat_pos[2][1] = (1.f / 3.f);
650 	drvui->lat_pos[2][2] = (1.f / 3.f);
651     }
652 }
653 
654 
655 /* ************************************************************** */
656 /* ************************************************************** */
657 
658 /* ************************************************************** */
659 /* ************************************************************** */
660 
661 void
Init_DRAWxtl(void)662 Init_DRAWxtl (void)
663 {
664     int j, l, m;
665 
666 /* Initialize */
667     drvui->X_Origin = drvui->Y_Origin = drvui->Z_Origin = 0.5f;
668     drvui->X_Boxlim = drvui->Y_Boxlim = drvui->Z_Boxlim = 20.0f;
669     drvui->Trans[0] = drvui->Trans[1] = drvui->Trans[2] = 0.0f;
670     drvui->automation =0;
671     xrot = yrot = zrot = 0.0f;
672     boxflag = packflag = clipflag = 0;
673     drvui->do_ellipsoids = edges = 0;
674     drvui->Ellipsoid_Prob = 0.5f;
675     cur_cen[0] = 0.25f;
676     cur_cen[1] = 0.25f;
677     cur_cen[2] = 0.25f;		// location of cursor (fractional coordinates)
678     drvui->cur_step = 0.5f;	// amount to jump cursor in A
679     Unit_Cell = M_cameras = no_comment = Labels = Vrml2 = 1;
680     X3D = 0;
681     Display_axes = drvui->El_Cutout = 0;
682     strcpy (drvui->Cutout_color, "Gray20");
683     strcpy (drvui->Ellipaxis_color, "Gray20");
684     drvui->Ellipaxis_width = 0.;
685     drvui->SpMult = drvui->BndMult = Magnification = 1.0f;
686     drvui->Ellipsoid_Scale = P_to_C (0.5f);
687     Options = 0;
688     FourierMapType = 0;
689     ShowMapLegend = 0;
690     drvui->Fourier2d = 0;
691     Map_Info.info_valid = 0;
692     Map_Info.map_type = -1;
693     Map_Info.res = 4;
694     drvui->sys = 0;
695     drvui->polylimit = 0.1f;
696     drvui->Phong_Value = 0.2f;
697     drvui->Phong_Size = 1.0f;
698     DepthCue = 0.0f;
699     drvui->noshadow = 0;
700     drvui->rad_edge = 0.0f;
701 /*
702   drvui->ambient = 0.0f;
703   drvui->diffuse = 0.0f;
704   drvui->specular = 0.0f;
705   drvui->roughness = 0.0f;
706 */
707     printdist = 3.5f;
708     origin[0] = drvui->X_Origin;
709     origin[1] = drvui->Y_Origin;
710     origin[2] = drvui->Z_Origin;
711     boxlim[0] = drvui->X_Boxlim;
712     boxlim[1] = drvui->Y_Boxlim;
713     boxlim[2] = drvui->Z_Boxlim;
714     docell = Unit_Cell;
715     Color_Warning = 0;
716     drvui->El_Cutout = 0;
717     strcpy (drvui->Cutout_color, "");
718     rad_cell = 0.02f;
719     drvui->Sphere_Mult = drvui->SpMult;
720     drvui->Bond_Mult = drvui->BndMult;
721     natom = 0;
722     drvui->nmag = 0;
723     drvui->nedges = 0;
724     drvui->nsphere = drvui->npoly = drvui->nbond = drvui->nplane = 1;
725     drvui->n_ellips = drvui->ncone = drvui->nlabel = drvui->nbplane = 1;
726     drvui->nsurf = drvui->natprop = 1 ;
727     drvui->nlabel = 1;
728 //  POV_Max[0] = POV_Max[1] = POV_Max[2] = -99999.0f;
729 //  POV_Min[0] = POV_Min[1] = POV_Min[2] = 99999.0f;
730     drvui->glback[0] = drvui->glback[1] = drvui->glback[2] = 1.0f;
731     slabmode = 0;
732     domolcomp = 0;
733     drvui->mol_d = 0.0f;
734     drvui->modulated = 0;
735     for (j = 0; j < 3; j++)
736 	drvui->phaseshift[j] = 0.0;
737     Omit->nomits = 0;
738     drvui->no_subsys = 1;	/* initialize the subsystem variables */
739     for (l = 0; l < 3; l++) {
740 	for (m = 0; m < 3; m++)
741 	    drvui->subsys_fact[0][l][m] = 0.0f;
742 	drvui->subsys_fact[0][l][l] = 1.0f;	/* set to identity */
743     }
744     drvui->subsys_ref_volume = 1.0f;
745     drvui->subsys_vol[0] = 1.0;
746     memset (Omit->omit1, 0, 1000);
747     memset (Omit->omit2, 0, 1000);
748     memset (drvui->slab_con, 0, sizeof (drvui->slab_con));
749     memset (drvui->slab_rot, 0, sizeof (drvui->slab_rot));
750     memset (drvui->slab_off, 0, sizeof (drvui->slab_off));
751 // clear all the color variables
752     memset (drvui->col_cell, 0, sizeof (drvui->col_cell));
753     memset (drvui->col_edge, 0, sizeof (drvui->col_edge));
754     memset (drvui->col_bg, 0, sizeof (drvui->col_bg));
755     memset (drvui->Cutout_color, 0, sizeof (drvui->Cutout_color));
756     memset (drvui->col_edge, 0, sizeof (drvui->col_edge));
757 
758     strcpy (drvui->col_cell, "Black");	/* preset unit-cell colors to Black */
759     strcpy (drvui->col_bg, "White");
760     strcpy (Map_Info.title, " Title not given in map file");
761     if (drvui->voidflag > 0 && drvui->voidmap) {
762 	for (int j = 0; j < drvui->voidgrid[1]; j++) {
763 	    for (int k = 0; k < drvui->voidgrid[2]; k++)
764 		free (drvui->voidmap[j][k]);
765 	    free (drvui->voidmap[j]);
766 	}
767 	free (drvui->voidmap);
768 	drvui->voidmap = NULL;
769     }
770     drvui->voidflag = 0;
771 }
772 
773 /* ************************************************************** */
774 /* ************************************************************** */
775 
776 float
P_to_C(float prob)777 P_to_C (float prob)
778 
779 /* Routine to convert probability to ellipsoid scaling, C.  Given probability
780    'prob', calculate value of C required for ellipsoid,
781 
782    C^2 = (delx/sigx)^2 + (dely/sigy)^2 + (delz/sigz)^2,
783 
784    where 'prob' is the probability that a random point in the distribution
785    will fall inside the ellipsoid.  Table values taken from D.B. Owen,
786    "Handbook of Statistical Tables", Addison-Wesley, Reading, Mass., 1962.
787 
788    N.B. The present version of the tables only handles probabilities from
789    0.01 to 0.99.
790 */
791 #define N_C 99
792 {
793     static double C_table[N_C + 1] =
794 	{ 0.3389, 0.4299, 0.4951, 0.5479, 0.5932, 0.6334, 0.6699, 0.7035,
795 	0.7349, 0.7644,
796 	0.7924, 0.8192, 0.8447, 0.8694, 0.8932, 0.9162, 0.9386, 0.9605,
797 	0.9818, 1.0026,
798 	1.0230, 1.0430, 1.0627, 1.0821, 1.1012, 1.1200, 1.1386, 1.1570,
799 	1.1751, 1.1932,
800 	1.2110, 1.2288, 1.2464, 1.2638, 1.2812, 1.2985, 1.3158, 1.3330,
801 	1.3501, 1.3672,
802 	1.3842, 1.4013, 1.4183, 1.4354, 1.4524, 1.4695, 1.4866, 1.5037,
803 	1.5209, 1.5382,
804 	1.5555, 1.5729, 1.5904, 1.6080, 1.6257, 1.6436, 1.6616, 1.6797,
805 	1.6980, 1.7164,
806 	1.7351, 1.7540, 1.7730, 1.7924, 1.8119, 1.8318, 1.8519, 1.8724,
807 	1.8932, 1.9144,
808 	1.9360, 1.9580, 1.9804, 2.0034, 2.0269, 2.0510, 2.0757, 2.1012,
809 	2.1274, 2.1544,
810 	2.1824, 2.2114, 2.2416, 2.2730, 2.3059, 2.3404, 2.3767, 2.4153,
811 	2.4563, 2.5003,
812 	2.5478, 2.5997, 2.6571, 2.7216, 2.7955, 2.8829, 2.9912, 3.1365,
813 	3.3682, 5.9503
814     };
815 
816     int i;
817 
818     double C;
819 
820     i = (int) (100.0 * prob);	/* find correct table entry */
821     if (i > N_C)
822 	i = N_C;
823 /* interpolate (linear) */
824     C = C_table[i - 1] + (prob - 0.01 * i) * (C_table[i] - C_table[i - 1]);
825     return ((float) C);
826 }
827 
828 
829 /* ************************************************************** */
830 /* ************************************************************** */
831 
832 void
read_inp(int Quick)833 read_inp (int Quick)
834 
835 /* routine to read and process input file */
836 {
837     char input[256];		/* input buffer for data read from file */
838 
839     char input2[256];		/* input buffer for data read from file */
840 
841     char string[256];		/* temporary string */
842 
843     char filename[256];		/* used for map file name */
844 
845     int intype;			/* type of datum read */
846 
847     int i, j, k;		/* temporary */
848 
849     char t_name[5];		/* temporary atom name storage */
850 
851     char t_color[40];		/* temporary ellipsoid color storage */
852 
853     int in_line = 0;		/* flag for inline import of foreign files */
854 
855     float t_rad;
856 
857     int n_el_tmp = 0;
858 
859     int done;
860 
861     int tmp_frame_no = 1;	// number of frame being processed
862 
863     FILE *tout = 0;
864 
865     int curframe;
866 
867     drvui->lat_con[0] = 0.0f;
868 
869     char atom_pos[3][30];
870 
871     int average = 0;
872 
873     char modl[5];
874 
875     int modnum;
876 
877     float avg_occ, min_occ;
878 
879     struct tmp_color_struct *el_color_tmp;
880 
881 /* ************************************************************** */
882 /* ************************************************************** */
883 /*
884     Commands Implemented
885 
886     arrow
887     atom
888     average
889     axislines
890     background
891     bestplane
892     betaij
893     bij,Bij
894     bond
895     bounds
896     box
897     cell
898     clip
899     cutout
900     dash
901     depthcue
902     edges
903     ellipcolor
904     ellipsoids
905     finish
906     frame
907     import
908     inline
909     labelscale
910     labeltext
911     list
912     lonepair
913     lookat
914     magtrans
915     magnification
916     mapcalclimits
917     mapcontour
918     mapcontour2d
919     maplegend
920     mapread
921     mapregion
922     mapslice
923     molcomp
924     nolabels
925     noshadow
926     occupancy
927     origin
928     orthographic
929     pack
930     phong
931     plane
932     polyedge
933     polysz
934     polytolerance
935     polylimit
936     polyfudge
937     polyvert
938     rem, REM
939     shell
940     slab
941     special
942     spgp, sgrp, spgr
943     sphere
944     title, titl
945     uij,Uij
946     values
947     vectors
948     view
949     voids
950     vrml1
951     vrml2
952     vrml97
953     x3d
954     xyzoff
955     end, END
956                                                                   */
957 /* ************************************************************** */
958 /* ************************************************************** */
959 
960     el_color_tmp =
961 	(tmp_color_struct *) zalloc (drvui->ellips_alloc *
962 				     sizeof (struct tmp_color_struct));
963     if (!el_color_tmp) {
964 	Error_Box ("Unable to allocate temporary space.\n");
965 	exit (0);
966     }
967 
968     drvui->xyzoff_read = 0;
969     drvui->voidflag = 0;
970     Map_Info.xlim[0] = 0.0f;
971     Map_Info.xlim[1] = 1.0f;
972     Map_Info.ylim[0] = 0.0f;
973     Map_Info.ylim[1] = 1.0f;
974     Map_Info.zlim[0] = 0.0f;
975     Map_Info.zlim[1] = 1.0f;
976     Map_Info.x4lim[0] = 0.0f;
977     Map_Info.x4lim[1] = 0.0f;
978     Map_Info.x5lim[0] = 0.0f;
979     Map_Info.x5lim[1] = 0.0f;
980     Map_Info.x6lim[0] = 0.0f;
981     Map_Info.x6lim[1] = 0.0f;
982     drvui->numOfFourierContours = 0;
983     drvui->frames[drvui->frame_no].slice = 0;
984     curframe = drvui->frame_no;
985     if (curframe > 1) {
986 	if (packflag)
987 	    for (i = 0; i < 6; i++) {
988 		drvui->frames[curframe].cryst_lim[i] =
989 		    drvui->frames[curframe - 1].cryst_lim[i];
990 	} else
991 	    for (i = 3; i < 6; i++) {
992 		drvui->frames[curframe].cryst_lim[i] = 1.;
993 	    }
994     }
995 
996     for (i = 0; i < 3; i++)
997 	drvui->xyzoff[i] = 0.0f;
998     while (!feof (drvui->fpin)) {
999 	strcpy (t_color, drvui->ellips[0].ellips_l);
1000 	memset (t_color, 0, 40);
1001 	memset (string, 0, 256);
1002 	memset (input, 0, sizeof (input));
1003 	if (fgets (input, 256, drvui->fpin)) {	/* read a line */
1004 	    trim_string (input, 256);	// kill any ^M or ^J at end of line
1005 	    Blank_Strip (input);	// suppress any leading blanks
1006 	    strcpy (input2, input);	// make a copy for listing file
1007 	    for (i = strlen (input); i < 255; i++) {	//pad line with blanks
1008 		input[i] = ' ';
1009 	    }
1010 	    input[255] = 0;	// force a terminator
1011 	} else {
1012 	    Error_Box ("Error reading file.");
1013 	    free (el_color_tmp);
1014 	    return;
1015 	}
1016 	intype = 1000;
1017 	in_line = 0;
1018 	if (!strncmp (input, "titl", 4) || !strncmp (input, "TITL", 4)) {
1019 	    if (drvui->frame_no == 1)
1020 		intype = 1;	// only echo title in first frame
1021 	    else
1022 		intype = 0;
1023 	}
1024 	if (strncmp (input, "rem", 3) == 0 || strncmp (input, "REM", 3) == 0) {
1025 	    if (tmp_frame_no == drvui->frame_no)
1026 		intype = 1;	// only echo rem in its frame
1027 	    else
1028 		intype = 0;
1029 	}
1030 	if (strncmp (input, "cell", 4) == 0)
1031 	    intype = 2;
1032 	if (strncmp (input, "sgrp", 4) == 0) {
1033 	    if (tmp_frame_no == drvui->frame_no)
1034 		intype = 3;
1035 	    else
1036 		intype = 0;	// ignore sgrp command if not current frame
1037 	}
1038 	if (strncmp (input, "spgp", 4) == 0) {
1039 	    if (tmp_frame_no == drvui->frame_no)
1040 		intype = 3;
1041 	    else
1042 		intype = 0;	// ignore spgp command if not current frame
1043 	}
1044 	if (strncmp (input, "spgr", 4) == 0) {
1045 	    if (tmp_frame_no == drvui->frame_no)
1046 		intype = 3;
1047 	    else
1048 		intype = 0;	// ignore spgr command if not current frame
1049 	}
1050 	if (strncmp (input, "ellipsoids", 10) == 0)
1051 	    intype = 4;
1052 	if (strncmp (input, "lookat", 6) == 0)
1053 	    intype = 5;
1054 	if (strncmp (input, "atom", 4) == 0) {
1055 	    if (tmp_frame_no == drvui->frame_no)
1056 		intype = 6;
1057 	    else
1058 		intype = 0;	// ignore atom command if not current frame
1059 	}
1060 	if (strncmp (input, "polysz", 6) == 0) {
1061 	    if (tmp_frame_no == drvui->frame_no)
1062 		intype = 7;
1063 	    else
1064 		intype = 0;	// ignore polysz command if not current frame
1065 	}
1066 	if (strncmp (input, "sphere", 6) == 0) {
1067 	    if (tmp_frame_no == drvui->frame_no)
1068 		intype = 8;
1069 	    else
1070 		intype = 0;	// ignore sphere command if not current frame
1071 	}
1072 	if (strncmp (input, "end", 3) == 0)
1073 	    intype = 9;
1074 	if (strncmp (input, "END", 3) == 0)
1075 	    intype = 9;
1076 	if (strncmp (input, "xyzoff", 6) == 0)
1077 	    intype = 10;
1078 	if (strncmp (input, "bond", 4) == 0) {
1079 	    if (tmp_frame_no == drvui->frame_no)
1080 		intype = 11;
1081 	    else
1082 		intype = 0;	// ignore bond command if not current frame
1083 	}
1084 	if (strncmp (input, "box", 3) == 0)
1085 	    intype = 12;
1086 	if (strncmp (input, "edges", 5) == 0)
1087 	    intype = 13;
1088 	if (strncmp (input, "view", 4) == 0)
1089 	    intype = 14;
1090 	if (strncmp (input, "plane", 5) == 0) {
1091 	    if (tmp_frame_no == drvui->frame_no)
1092 		intype = 15;
1093 	    else
1094 		intype = 0;	// ignore plane command if not current frame
1095 	}
1096 	if (strncmp (input, "bij", 3) == 0)
1097 	    intype = 16;
1098 	if (strncmp (input, "Bij", 3) == 0)
1099 	    intype = 16;
1100 	if (strncmp (input, "betaij", 6) == 0)
1101 	    intype = 17;
1102 	if (strncmp (input, "uij", 3) == 0)
1103 	    intype = 18;
1104 	if (strncmp (input, "Uij", 3) == 0)
1105 	    intype = 18;
1106 	if (strncmp (input, "bounds", 6) == 0)
1107 	    intype = 1;		//19;
1108 	if (strncmp (input, "pack", 4) == 0) {
1109 	    if (tmp_frame_no == drvui->frame_no)
1110 		intype = 20;
1111 	    else
1112 		intype = 0;	// ignore pack command if not current frame
1113 	}
1114 	if (strncmp (input, "magnification", 13) == 0)
1115 	    intype = 21;
1116 	if (strncmp (input, "origin", 6) == 0)
1117 	    intype = 22;
1118 	if (strncmp (input, "ellipcolor", 10) == 0)
1119 	    intype = 23;
1120 	if (strncmp (input, "inline", 6) == 0) {
1121 	    if (tmp_frame_no == drvui->frame_no) {
1122 		intype = 24;
1123 	    } else {		// skip ahead to next frame or end
1124 		int end_seen = 0;	// some formats have their own END card
1125 
1126 		while (!feof (drvui->fpin) && intype != 0) {
1127 		    if (fgets (input, 256, drvui->fpin)) {	/* read a line */
1128 			trim_string (input, 256);	// kill any ^M or ^J at end of line
1129 			Blank_Strip (input);	// suppress any leading blanks
1130 			input[255] = 0;	// force a terminator
1131 			if (strncmp (input, "frame", 5) == 0) {
1132 			    intype = 37;
1133 			    break;
1134 			}
1135 			if (strncmp (input, "end", 3) == 0) {
1136 			    if (strstr (input2, "schakal") && end_seen == 0) {
1137 				end_seen = 1;
1138 			    } else {
1139 				intype = 9;
1140 				break;
1141 			    }
1142 			}
1143 		    } else {
1144 			Error_Box ("Error reading file.");
1145 			free (el_color_tmp);
1146 			return;
1147 		    }
1148 		}		// advance to next frame or end command
1149 	    }			// if not in current frame
1150 	}
1151 	if (strncmp (input, "import", 6) == 0) {
1152 	    if (tmp_frame_no == drvui->frame_no)
1153 		intype = 25;
1154 	    else
1155 		intype = 0;	// ignore import command if not current frame
1156 	}
1157 	if (strncmp (input, "orthographic", 12) == 0)
1158 	    intype = 26;
1159 	if (strncmp (input, "vectors", 7) == 0) {
1160 	    if (tmp_frame_no == 1) {
1161 		intype = 27;
1162 	    } else {
1163 		intype = 0;
1164 	    }
1165 	}
1166 	if (strncmp (input, "phong", 5) == 0)
1167 	    intype = 28;
1168 	if (strncmp (input, "molcomp", 7) == 0)
1169 	    intype = 29;
1170 	if (strncmp (input, "cutout", 6) == 0)
1171 	    intype = 30;
1172 	if (strncmp (input, "depthcue", 8) == 0)
1173 	    intype = 31;
1174 	if (strncmp (input, "vrml1", 5) == 0)
1175 	    intype = 32;
1176 	if (strncmp (input, "vrml2", 5) == 0)
1177 	    intype = 1;
1178 	if (strncmp (input, "vrml97", 6) == 0)
1179 	    intype = 1;
1180 	if (strncmp (input, "polytol", 7) == 0)
1181 	    intype = 33;
1182 	if (strncmp (input, "polylimit", 9) == 0)
1183 	    intype = 33;
1184 	if (strncmp (input, "polyfudge", 9) == 0)
1185 	    intype = 33;
1186 	if (strncmp (input, "clip", 4) == 0) {
1187 	    if (tmp_frame_no == drvui->frame_no)
1188 		intype = 34;
1189 	    else
1190 		intype = 0;	// ignore clip command if not current frame
1191 	}
1192 	if (strncmp (input, "list", 4) == 0)
1193 	    intype = 35;
1194 	if (strncmp (input, "polyedge", 8) == 0) {
1195 	    if (tmp_frame_no == drvui->frame_no)
1196 		intype = 36;
1197 	    else
1198 		intype = 0;
1199 	}
1200 	if (strncmp (input, "frame", 5) == 0)
1201 	    intype = 37;
1202 	if (strncmp (input, "axislines", 9) == 0)
1203 	    intype = 38;
1204 	if (strncmp (input, "shell", 5) == 0) {
1205 	    if (tmp_frame_no == drvui->frame_no)
1206 		intype = 39;
1207 	    else
1208 		intype = 0;	// ignore shell command if not current frame
1209 	}
1210 	if (strncmp (input, "nolabels", 8) == 0)
1211 	    intype = 40;
1212 	if (strncmp (input, "lonepair", 8) == 0) {
1213 	    if (tmp_frame_no == drvui->frame_no)
1214 		intype = 41;
1215 	    else
1216 		intype = 0;	// ignore lonepair command if not current frame
1217 	}
1218 	if (strncmp (input, "labeltext", 9) == 0)
1219 	    intype = 42;
1220 	if (strncmp (input, "polyvert", 8) == 0) {
1221 	    if (tmp_frame_no == drvui->frame_no)
1222 		intype = 43;
1223 	    else
1224 		intype = 0;	// ignore polyvert command if not current frame
1225 	}
1226 	if (strncmp (input, "background", 10) == 0)
1227 	    intype = 44;
1228 	if (strncmp (input, "slab", 4) == 0)
1229 	    intype = 45;
1230 	if (strncmp (input, "mag_trans", 9) == 0)
1231 	    intype = 46;
1232 	if (strncmp (input, "special", 7) == 0)
1233 	    intype = 47;
1234 	if (strncmp (input, "noshadow", 8) == 0)
1235 	    intype = 48;
1236 	if (strncmp (input, "finish", 6) == 0)
1237 	    intype = 49;
1238 	if (strncmp (input, "arrow", 5) == 0) {
1239 	    if (tmp_frame_no == drvui->frame_no)
1240 		intype = 50;
1241 	    else
1242 		intype = 0;	// ignore arrow command if not current frame
1243 	}
1244 	if (strncmp (input, "dash", 4) == 0) {
1245 	    if (tmp_frame_no == drvui->frame_no)
1246 		intype = 51;
1247 	    else
1248 		intype = 0;	// ignore bond command if not current frame
1249 	}
1250 	if (strncmp (input, "mapcontour", 10) == 0)
1251 	    intype = 52;
1252 	if (strncmp (input, "mapcontour2d", 12) == 0)
1253 	    intype = 61;
1254 	if (strncmp (input, "mapread", 7) == 0) {
1255 	    if (tmp_frame_no == drvui->frame_no)
1256 		intype = 53;
1257 	    else
1258 		intype = 0;
1259 	}
1260 	if (strncmp (input, "mapregion", 9) == 0) {
1261 	    if (tmp_frame_no == drvui->frame_no)
1262 		intype = 54;
1263 	    else
1264 		intype = 0;
1265 	}
1266 	if (strncmp (input, "mapcalclimits", 13) == 0)
1267 	    intype = 55;
1268 	if (strncmp (input, "labelscale", 10) == 0)
1269 	    intype = 56;
1270 	if (strncmp (input, "bestplane", 9) == 0)
1271 	    intype = 57;
1272 	if (strncmp (input, "average", 7) == 0)
1273 	    intype = 58;
1274 	if (strncmp (input, "occupancy", 9) == 0)
1275 	    intype = 59;
1276 	if (strncmp (input, "phaseshift", 10) == 0)
1277 	    intype = 60;
1278 	if (strncmp (input, "aimsurf", 7) == 0)
1279 	    intype = 62;
1280 	if (strncmp (input, "voids", 5) == 0)
1281 	    intype = 63;
1282 	if (strncmp (input, "values", 6) == 0)
1283 	    intype = 64;
1284 	if (strncmp (input, "mapslice", 8) == 0) {
1285 	    if (tmp_frame_no == drvui->frame_no)
1286 		intype = 65;
1287 	    else
1288 		intype = 0;
1289 	}
1290 	if (strncmp (input, "qvector", 7) == 0)
1291 	    intype = 66;
1292 	if (strncmp (input, "maplegend", 9) == 0)
1293 	    intype = 67;
1294 	if (strncmp (input, "x3d", 3) == 0)
1295 	    intype = 68;
1296 
1297 	switch (intype) {
1298 
1299 	case 0:
1300 	    break;
1301 	case 1:
1302 	    break;		// ignore title except for listing
1303 	case 2:		// cell command
1304 	    for (i = 3; i <= 5; ++i)
1305 		drvui->lat_con[i] = 0.0f;
1306 	    sscanf (input, "%s %f %f %f %f %f %f", string, &drvui->lat_con[0]
1307 		    , &drvui->lat_con[1], &drvui->lat_con[2], &drvui->lat_con[3],
1308 		    &drvui->lat_con[4]
1309 		    , &drvui->lat_con[5]);
1310 	    break;
1311 	case 3:
1312 	    symop (input);	/* process space group information */
1313 	    break;
1314 	case 4:		/* ellipsoids command */
1315 	    drvui->do_ellipsoids = 1;
1316 	    (void) sscanf (input, "%s %f", string, &drvui->Ellipsoid_Prob);
1317 	    if (drvui->Ellipsoid_Prob > 1)
1318 		drvui->Ellipsoid_Prob *= 0.01f;	/* Probability to fraction */
1319 	    break;
1320 	case 5:		// read vectors for lookat command
1321 	    sscanf (input, "%s %f %f %f %f %f %f", string, &drvui->lookat_v1[0],
1322 		    &drvui->lookat_v1[1], &drvui->lookat_v1[2], &drvui->lookat_v2[0],
1323 		    &drvui->lookat_v2[1], &drvui->lookat_v2[2]);
1324 	    Options = Options | L_OPT;
1325 	    break;
1326 	case 6:		/* atom command */
1327 	    char t_atom[5];
1328 
1329 	    get_label (input, &t_atom[0], &t_atom[1], &t_atom[2], &t_atom[3], 1);
1330 	    t_atom[4] = 0;
1331 	    strcpy (drvui->atoms[natom].atom_l, t_atom);
1332 	    (void) sscanf (input, "%d %s %s %s", &drvui->atoms[natom].atom_n, atom_pos[0],
1333 			   atom_pos[1], atom_pos[2]);
1334 	    drvui->atoms[natom].sv_atom_n = drvui->atoms[natom].atom_n;
1335 	    for (i = 0; i < 3; i++)
1336 		drvui->atoms[natom].atom_xyz[i] = convert_pos (atom_pos[i]);
1337 	    drvui->atoms[natom].atom_fn = tmp_frame_no;
1338 	    natom++;
1339 	    check_dynamic_storage ();
1340 	    break;
1341 	case 7:		/* polysz command */
1342 	case 39:		/* shell command */
1343 	case 43:		/* polyvert command */
1344 	    get_label (input, &drvui->polyhedra[drvui->npoly].poly_l[0],
1345 		       &drvui->polyhedra[drvui->npoly].poly_l[1]
1346 		       , &drvui->polyhedra[drvui->npoly].poly_l[2],
1347 		       &drvui->polyhedra[drvui->npoly].poly_l[3], 1);
1348 	    if (intype == 7) {
1349 		(void) sscanf (input, "%f %39c",
1350 			       &drvui->polyhedra[drvui->npoly].poly_size, string);
1351 	    } else if (intype == 39) {
1352 		(void) sscanf (input, "%f %f %39c",
1353 			       &drvui->polyhedra[drvui->npoly].poly_min,
1354 			       &drvui->polyhedra[drvui->npoly].poly_size, string);
1355 	    } else if (intype == 43) {
1356 		get_label (input, &drvui->polyhedra[drvui->npoly].poly_t[0],
1357 			   &drvui->polyhedra[drvui->npoly].poly_t[1]
1358 			   , &drvui->polyhedra[drvui->npoly].poly_t[2],
1359 			   &drvui->polyhedra[drvui->npoly].poly_t[3], 0);
1360 		(void) sscanf (input, "%f %39c",
1361 			       &drvui->polyhedra[drvui->npoly].poly_size, string);
1362 	    }
1363 	    trim_string (string, 40);
1364 	    if (!strlen (string))
1365 		strcpy (string, "White");
1366 	    strcpy (drvui->polyhedra[drvui->npoly].poly_col, string);
1367 	    if (intype == 7 || intype == 43)
1368 		drvui->polyhedra[drvui->npoly].poly_min = 0.005f;
1369 	    drvui->polyhedra[drvui->npoly].poly_fn = tmp_frame_no;
1370 	    if (intype == 7 || intype == 39)
1371 		strcpy (drvui->polyhedra[drvui->npoly].poly_t, "");
1372 	    drvui->polyhedra[drvui->npoly].poly_rad_edge = 0.0f;
1373 	    drvui->npoly++;
1374 	    check_dynamic_storage ();
1375 	    break;
1376 	case 8:		/* sphere command */
1377 	    get_label (input, &drvui->spheres[drvui->nsphere].sphere_l[0],
1378 		       &drvui->spheres[drvui->nsphere].sphere_l[1]
1379 		       , &drvui->spheres[drvui->nsphere].sphere_l[2],
1380 		       &drvui->spheres[drvui->nsphere].sphere_l[3], 1);
1381 	    char str[9][40], *pnt;
1382 
1383 	    double inpval[9];
1384 
1385 	    i = sscanf (input, "%s %s %s %s %s %s %s %s %s", str[0], str[1], str[2],
1386 			str[3], str[4], str[5], str[6], str[7], str[8]);
1387 	    for (j = 0; j < i; j++)
1388 		inpval[j] = strtod (str[j], &pnt);
1389 	    drvui->spheres[drvui->nsphere].sphere_n = -1;
1390 	    if (i == 2 || i == 4 || i == 6) {
1391 		drvui->spheres[drvui->nsphere].sphere_size = (float) inpval[0];
1392 		j = 1;
1393 	    } else if (i == 3 || i == 5 || i == 7) {
1394 		drvui->spheres[drvui->nsphere].sphere_n = (int) (inpval[0] + 0.01);
1395 		drvui->spheres[drvui->nsphere].sphere_size = (float) inpval[1];
1396 		j = 2;
1397 	    } else {
1398 		Error_Box ("Improperly formed sphere command.");
1399 	    }
1400 	    strcpy (string, str[j]);
1401 	    for (k = j + 1; k < i; k++) {
1402 		strcat (string, " ");
1403 		strcat (string, str[k]);
1404 	    }
1405 	    trim_string (string, 40);
1406 	    if (!strlen (string))
1407 		strcpy (string, "White");
1408 	    strcpy (drvui->spheres[drvui->nsphere].sphere_col, string);
1409 	    drvui->spheres[drvui->nsphere].sphere_fn = tmp_frame_no;
1410 	    drvui->nsphere++;
1411 	    check_dynamic_storage ();
1412 	    break;
1413 	case 9:		/* end or END */
1414 	    if (!drvui->lat_con[0]) {
1415 		if (errorbox) {	// make sure that the original error message gets a chance to appear
1416 		    int n;
1417 
1418 		    for (n = 0; n < 10; n++)
1419 			Fl::wait (1);
1420 		}
1421 		Error_Box ("There is no 'cell' line in your input file.");
1422 	    }
1423 	    label_cell ();
1424 	    if (Quick == 2) {
1425 		drvui->max_frame = tmp_frame_no;
1426 		drvui->Old_Xrot = xrot;
1427 		drvui->Old_Yrot = yrot;
1428 		drvui->Old_Zrot = zrot;
1429 	    }
1430 	    if (average == 1)
1431 		drvui->modulated = -1;
1432 	    int frame;
1433 
1434 	    for (frame = 1; frame <= drvui->max_frame; frame++) {
1435 		if (!Quick) {
1436 		    strcpy (input, drvui->Cur_Root);
1437 		    sprintf (input2, ".frm%d", frame);
1438 		    strcat (input, input2);
1439 		    tout = fopen (input, "w");
1440 		}
1441 		for (i = 0; i < natom; i++) {	/* shift atom coordinates for origin offset */
1442 		    if (drvui->atoms[i].atom_fn != frame)
1443 			continue;
1444 		    drvui->atoms[i].TF_status = -1;	// initialize TF type/status
1445 		    for (j = 0; j < 3; j++)
1446 			drvui->atoms[i].atom_xyz[j] -= drvui->xyzoff[j];
1447 		    strncpy (t_atom, drvui->atoms[i].atom_l, 4);
1448 		    t_atom[4] = 0;
1449 		    if (!Quick)
1450 			fprintf (tout, "%s %d\n", t_atom, drvui->atoms[i].sv_atom_n);
1451 		}
1452 		if (!Quick) {
1453 		    fclose (tout);
1454 		}
1455 	    }
1456 	    if (n_el_tmp > 0) {
1457 		strcpy (input, "");
1458 		for (i = 0; i < n_el_tmp; i++) {
1459 		    get_label (el_color_tmp[i].el_color_tmp, &t_name[0], &t_name[1],
1460 			       &t_name[2], &t_name[3], 0);
1461 		    t_name[4] = 0;
1462 		    if (el_color_tmp[i].el_color_tmp[0] == '*') {
1463 			(void) sscanf (el_color_tmp[i].el_color_tmp, "%s %39c", string,
1464 				       t_color);
1465 			j = -1;
1466 		    } else {
1467 			(void) sscanf (el_color_tmp[i].el_color_tmp, "%d %39c", &j,
1468 				       t_color);
1469 		    }
1470 		    trim_string (t_color, 40);
1471 		    if (!strlen (t_color))
1472 			strcpy (t_color, "White");
1473 		    for (k = 1; k < drvui->n_ellips; k++) {	/* find this atom in ellipsoid list */
1474 			if (check_atom_name (t_name, drvui->ellips[k].ellips_l)) {
1475 			    if ((j == -1) || (j == drvui->ellips[k].ellips_n)) {
1476 				drvui->ellips[k].ell_type += 1000;	// >= 1000 means ellipcolor read
1477 				strcpy (drvui->ellips[k].ellips_col, t_color);	/* copy color */
1478 				drvui->ellips[k].save_el_number = j;
1479 			    }
1480 			}
1481 		    }
1482 		}
1483 		n_el_tmp = 0;
1484 	    }
1485 	    free (el_color_tmp);
1486 
1487 	    if (drvui->natprop > 0) {
1488 
1489 		for (i = 0; i < drvui->natprop; i++) {
1490 		    j = drvui->atprops[i].atprop_n;
1491 		    for (k = 0; k < natom; k++) {	/* find this atom in list */
1492 			if (check_atom_name (drvui->atprops[i].atprop_l, drvui->atoms[k].atom_l)) {
1493 			    if ((j == -1) || (j == drvui->atoms[k].atom_n)) {
1494 				drvui->atoms[k].radius = drvui->atprops[i].radius;
1495 			    }
1496 			}
1497 		    }
1498 		}
1499 	    }
1500 
1501 	    for (i = 1; i < drvui->nsphere; i++) {	// remove any auto-generated ellipsoids that
1502 		for (j = 1; j < drvui->n_ellips; j++) {	//     interfere with spheres
1503 		    if (drvui->ellips[j].ell_type == 1001) {
1504 			if (check_atom_name
1505 			    (drvui->spheres[i].sphere_l, drvui->ellips[j].ellips_l)) {
1506 			    if (drvui->spheres[i].sphere_n == -1
1507 				|| drvui->spheres[i].sphere_n ==
1508 				drvui->ellips[j].save_el_number) {
1509 				drvui->ellips[j].ell_type = 1;
1510 			    }
1511 			}
1512 		    }
1513 		}
1514 	    }
1515 	    if (FourierMapType)
1516 		drvui->mainWindow->cursor (FL_CURSOR_WAIT);
1517 	    switch (FourierMapType) {
1518 	    case 1:
1519 		read_grd (FourierFileName, Quick);
1520 		break;
1521 	    case 2:
1522 		read_stf (FourierFileName, Quick);
1523 		break;
1524 	    case 3:
1525 		read_w2k (FourierFileName, Quick);
1526 		break;
1527 	    case 4:
1528 		read_vasp (FourierFileName, Quick);
1529 		break;
1530 	    case 5:
1531 		read_flp (FourierFileName, Quick);
1532 		break;
1533 	    case 6:
1534 		read_fcf (FourierFileName, Quick);
1535 		break;
1536 	    case 7:
1537 		read_dn6 (FourierFileName, Quick);
1538 		break;
1539 	    case 8:
1540 		read_m80 (FourierFileName, Quick);
1541 		break;
1542 	    case 9:
1543 		read_exc (FourierFileName, Quick);
1544 		break;
1545 	    case 10:
1546 		read_m81 (FourierFileName, Quick);
1547 		break;
1548 	    case 11:
1549 		read_xsf (FourierFileName, Quick);
1550 		break;
1551 	    default:
1552 		break;
1553 	    }
1554 	    if (FourierMapType)
1555 		drvui->mainWindow->cursor (FL_CURSOR_DEFAULT);
1556 	    for (frame = 1; frame <= drvui->max_frame; frame++) {
1557 		if (drvui->frames[frame].map_lim_set == 0) {	// mapregion line NOT read
1558 		    xMin = Map_Info.xlim[0];
1559 		    xMax = Map_Info.xlim[1];
1560 		    yMin = Map_Info.ylim[0];
1561 		    yMax = Map_Info.ylim[1];
1562 		    zMin = Map_Info.zlim[0];
1563 		    zMax = Map_Info.zlim[1];
1564 		    x4Val = x5Val = x6Val = 0.0f;
1565 		    drvui->frames[frame].map_lim[0]=xMin;
1566 		    drvui->frames[frame].map_lim[3]=xMax;
1567 		    drvui->frames[frame].map_lim[1]=yMin;
1568 		    drvui->frames[frame].map_lim[4]=yMax;
1569 		    drvui->frames[frame].map_lim[2]=zMin;
1570 		    drvui->frames[frame].map_lim[5]=zMax;
1571 		    drvui->frames[frame].map_lim[6]=x4Val;
1572 		    drvui->frames[frame].map_lim[7]=x5Val;
1573 		    drvui->frames[frame].map_lim[8]=x6Val;
1574 		}
1575 		if (drvui->frames[frame].slice >0 ) { // calculate 2d plane in cartesian space
1576 		    float p[3];
1577 		    vnormalize(drvui->frames[frame].mapnorm);
1578 		    drvui->frames[frame].planeeq[0] = (float)drvui->frames[frame].mapnorm[0];
1579 		    drvui->frames[frame].planeeq[1] = (float)drvui->frames[frame].mapnorm[1];
1580 		    drvui->frames[frame].planeeq[2] = (float)drvui->frames[frame].mapnorm[2];
1581 		    make_bmat (drvui->sys, drvui->lat_con, drvui->b_mat, drvui->ginv,drvui->rec_lat_con);
1582 		    Convert_Cryst_Cart(drvui->b_mat, drvui->frames[frame].mapslice, p, origin);
1583 		    drvui->frames[frame].planeeq[3] = -(float) (drvui->frames[frame].mapnorm[0] * p[0]
1584 						    + drvui->frames[frame].mapnorm[1] * p[1]
1585 						    + drvui->frames[frame].mapnorm[2] * p[2]);
1586 		}
1587 	    }
1588 	    if (drvui->subsys_vol[0] == 1.0f)
1589 		drvui->subsys_vol[0] = drvui->subsys_ref_volume;
1590 	    return;		/* thru with end */
1591 	case 10:		/* xyzoff command */
1592 	    (void) sscanf (input, "%s %s %s %s", string, atom_pos[0], atom_pos[1],
1593 			   atom_pos[2]);
1594 	    for (i = 0; i < 3; i++)
1595 		drvui->xyzoff[i] = convert_pos (atom_pos[i]);
1596 	    drvui->xyzoff_read = 1;
1597 	    break;
1598 	case 51:		/* dash command */
1599 	case 11:		/* bond command */
1600 	    if (intype == 51) {
1601 		k = sscanf (input, "%s %d", string, &j);
1602 		if (k == 2)	/* number of segments if given */
1603 		    Token_Strip (input, 1);
1604 		else
1605 		    j = 5;
1606 	    }
1607 	    get_label (input, &drvui->bonds[drvui->nbond].bond_l1[0],
1608 		       &drvui->bonds[drvui->nbond].bond_l1[1]
1609 		       , &drvui->bonds[drvui->nbond].bond_l1[2],
1610 		       &drvui->bonds[drvui->nbond].bond_l1[3], 1);
1611 	    get_label (input, &drvui->bonds[drvui->nbond].bond_l2[0],
1612 		       &drvui->bonds[drvui->nbond].bond_l2[1]
1613 		       , &drvui->bonds[drvui->nbond].bond_l2[2],
1614 		       &drvui->bonds[drvui->nbond].bond_l2[3], 0);
1615 	    (void) sscanf (input, "%f %f %f %39c", &drvui->bonds[drvui->nbond].bond_size,
1616 			   &drvui->bonds[drvui->nbond].bond_min,
1617 			   &drvui->bonds[drvui->nbond].bond_max, string);
1618 	    trim_string (string, 40);
1619 	    if (strlen (string) == 0)
1620 		strcpy (string, "Grey");
1621 	    strcpy (drvui->bonds[drvui->nbond].col_bond, string);
1622 	    drvui->bonds[drvui->nbond].bond_fn = tmp_frame_no;
1623 	    if (intype == 11)
1624 		drvui->bonds[drvui->nbond].bond_style = 0;
1625 	    else
1626 		drvui->bonds[drvui->nbond].bond_style = j;
1627 	    drvui->nbond++;
1628 	    check_dynamic_storage ();
1629 	    break;
1630 	case 12:		/* box command */
1631 	    (void) sscanf (input, "%s %f %39c", string, &rad_cell, t_color);
1632 	    trim_string (t_color, 40);
1633 	    strcpy (drvui->col_cell, t_color);
1634 	    if (strlen (drvui->col_cell) == 0)
1635 		strcpy (drvui->col_cell, "Black");
1636 	    if (rad_cell == 0.0) {
1637 		docell = 0;
1638 	    }
1639 	    break;
1640 	case 13:		/* edges command */
1641 	    (void) sscanf (input, "%s %f %39c", string, &drvui->rad_edge, t_color);
1642 	    trim_string (t_color, 40);
1643 	    strcpy (drvui->col_edge, t_color);
1644 	    if (drvui->rad_edge > 0.005)
1645 		edges = 2;
1646 	    if (strlen (drvui->col_edge) == 0)
1647 		strcpy (drvui->col_edge, "Black");
1648 	    break;
1649 	case 14:		/* view command */
1650 //      if ((Options & V_OPT) == 0)         // only if no -v switch
1651 	    (void) sscanf (input, "%s %f %f %f", string, &xrot, &yrot, &zrot);
1652 	    break;
1653 	case 15:		/* plane command */
1654 	    get_label (input, &drvui->planes[drvui->nplane].plane_l[0],
1655 		       &drvui->planes[drvui->nplane].plane_l[1]
1656 		       , &drvui->planes[drvui->nplane].plane_l[2],
1657 		       &drvui->planes[drvui->nplane].plane_l[3], 1);
1658 	    (void) sscanf (input, "%f %39c", &drvui->planes[drvui->nplane].plane_size,
1659 			   string);
1660 	    trim_string (string, 40);
1661 	    if (!strlen (string))
1662 		strcpy (string, "White");
1663 	    strcpy (drvui->planes[drvui->nplane].plane_col, string);
1664 	    drvui->planes[drvui->nplane].plane_fn = tmp_frame_no;
1665 	    drvui->nplane++;
1666 	    check_dynamic_storage ();
1667 	    break;
1668 	case 16:		/* bij or Bij command */
1669 	    drvui->ellips[drvui->n_ellips].ell_type = 2;
1670 	case 17:		/* betaij command */
1671 	    if (intype == 17)
1672 		drvui->ellips[drvui->n_ellips].ell_type = 0;
1673 	case 18:		/* uij or Uij command */
1674 	    if (intype == 18)
1675 		drvui->ellips[drvui->n_ellips].ell_type = 1;
1676 	    get_label (input, &drvui->ellips[drvui->n_ellips].ellips_l[0],
1677 		       &drvui->ellips[drvui->n_ellips].ellips_l[1],
1678 		       &drvui->ellips[drvui->n_ellips].ellips_l[2],
1679 		       &drvui->ellips[drvui->n_ellips].ellips_l[3], 1);
1680 	    drvui->ellips[drvui->n_ellips].ellips_l[4] = 0;
1681 	    (void) sscanf (input, "%d %f %f %f %f %f %f %39c", &drvui->ellips[drvui->n_ellips].ellips_n, &drvui->ellips[drvui->n_ellips].ellips[0], &drvui->ellips[drvui->n_ellips].ellips[1], &drvui->ellips[drvui->n_ellips].ellips[2], &drvui->ellips[drvui->n_ellips].ellips[3], &drvui->ellips[drvui->n_ellips].ellips[4], &drvui->ellips[drvui->n_ellips].ellips[5], string);	// read unique coefficients and color
1682 	    drvui->ellips[drvui->n_ellips].save_el_number =
1683 		drvui->ellips[drvui->n_ellips].ellips_n;
1684 	    trim_string (string, 40);
1685 	    strcpy (drvui->ellips[drvui->n_ellips].ellips_col, string);
1686 	    if (!strlen (drvui->ellips[drvui->n_ellips].ellips_col))
1687 		strcpy (drvui->ellips[drvui->n_ellips].ellips_col, "Gray80");
1688 	    drvui->n_ellips++;
1689 	    check_dynamic_storage ();
1690 	    break;
1691 	case 19:		/* bounds command */
1692 //      if ((Options & B_OPT) == 0) {         // only do this if no -b switch
1693 	    (void) sscanf (input, "%s %f %f %f", string, &boxlim[0], &boxlim[1],
1694 			   &boxlim[2]);
1695 	    boxflag = 1;
1696 //      }
1697 	    break;
1698 	case 20:		/* pack command */
1699 //      if ((Options & P_OPT) == 0) {         // only if no -p switch
1700 	    (void) sscanf (input, "%s %f %f %f %f %f %f", string,
1701 			   &drvui->frames[tmp_frame_no].cryst_lim[0],
1702 			   &drvui->frames[tmp_frame_no].cryst_lim[3],
1703 			   &drvui->frames[tmp_frame_no].cryst_lim[1],
1704 			   &drvui->frames[tmp_frame_no].cryst_lim[4],
1705 			   &drvui->frames[tmp_frame_no].cryst_lim[2],
1706 			   &drvui->frames[tmp_frame_no].cryst_lim[5]);
1707 	    packflag = 1;
1708 //      }
1709 	    break;
1710 	case 21:		/* magnification command */
1711 //      if ((Options & M_OPT) == 0)         // only if no -m switch
1712 	    (void) sscanf (input, "%s %f", string, &Magnification);
1713 	    break;
1714 	case 22:		/* origin command */
1715 //      if ((Options & O_OPT) == 0) {         // only if no -o switch
1716 	    (void) sscanf (input, "%s %f %f %f", string, &origin[0], &origin[1],
1717 			   &origin[2]);
1718 //      }
1719 	    break;
1720 	case 23:		/* ellipcolor command */
1721 	    Token_Strip (input, 1);
1722 	    strcpy (el_color_tmp[n_el_tmp++].el_color_tmp, input);
1723 	    break;
1724 	case 24:		/* inline command */
1725 	    in_line = 1;
1726 	case 25:		/* import command */
1727 	    char filetype[10];
1728 
1729 	    done = 0;
1730 	    if (!Quick)
1731 		fprintf (drvui->flout, "*         %s\n======================= Start of import/inline commands\n", input2);	// echo to listing file
1732 	    intype = 0;
1733 	    Token_Strip (input, 1);	/* strip command */
1734 	    sscanf (input, "%s", filetype);
1735 	    Token_Strip (input, 1);	/* strip filetype */
1736 	    trim_string (input, 256);	/* and remove trailing blanks */
1737 
1738 	    if (strncmp (filetype, "gsas", 4) == 0) {
1739 		import_gsas (input, in_line, Quick, tmp_frame_no);
1740 		done = 1;
1741 	    }
1742 	    if (strncmp (filetype, "pcr", 3) == 0) {
1743 		import_pcr (input, in_line, Quick, tmp_frame_no);
1744 		done = 1;
1745 	    }
1746 	    if (strncmp (filetype, "cif", 3) == 0) {
1747 		int ii, jj;
1748 
1749 		ii = strlen (input) - 1;
1750 		if (isdigit (input[ii])) {	// if number at end
1751 		    for (jj = ii; jj > ii - 6; jj--) {
1752 			if (isspace (input[jj])) {	// separate number
1753 			    input[jj] = '\0';
1754 			    Block_CIF = atoi (&input[jj + 1]);
1755 			    break;
1756 			}
1757 			if (isalpha (input[jj]))
1758 			    break;	// unless it is attached to filename
1759 		    }
1760 		} else {
1761 		    Block_CIF = 0;
1762 		}
1763 		import_cif (input, in_line, Quick, &Block_CIF, tmp_frame_no);
1764 		done = 1;
1765 	    }
1766 	    if (strncmp (filetype, "schakal", 7) == 0) {
1767 		import_schakal (input, in_line, Quick, tmp_frame_no);
1768 		done = 1;
1769 	    }
1770 	    if (strncmp (filetype, "shakal", 6) == 0) {
1771 		import_schakal (input, in_line, Quick, tmp_frame_no);
1772 		done = 1;
1773 	    }
1774 	    if (strncmp (filetype, "shelx", 5) == 0) {
1775 		import_shelx (input, in_line, Quick, tmp_frame_no);
1776 		done = 1;
1777 	    }
1778 	    if (strncmp (filetype, "fdat", 4) == 0) {
1779 		import_fdat (input, in_line, Quick, tmp_frame_no);
1780 		done = 1;
1781 	    }
1782 	    if (strncmp (filetype, "csd", 3) == 0) {
1783 		import_fdat (input, in_line, Quick, tmp_frame_no);
1784 		done = 1;
1785 	    }
1786 	    if (strncmp (filetype, "ccdf", 4) == 0) {
1787 		import_fdat (input, in_line, Quick, tmp_frame_no);
1788 		done = 1;
1789 	    }
1790 	    if (strncmp (filetype, "wien2k", 6) == 0) {
1791 		import_wien (input, in_line, Quick, tmp_frame_no);
1792 		done = 1;
1793 	    }
1794 	    if (strncmp (filetype, "discus", 6) == 0) {
1795 		import_discus (input, in_line, Quick, tmp_frame_no);
1796 		done = 1;
1797 	    }
1798 	    if (strncmp (filetype, "exciting", 8) == 0
1799 		|| strncmp (filetype, "elk", 3) == 0) {
1800 		import_exc (input, in_line, Quick, tmp_frame_no);
1801 		done = 1;
1802 	    }
1803 	    if (!done) {
1804 		char string[256];
1805 
1806 		sprintf (string, "Import/inline source type '%s' not recognized.", input);
1807 		Error_Box (string);
1808 		free (el_color_tmp);
1809 		return;
1810 	    }
1811 	    if (!Quick)
1812 		fprintf (drvui->flout,
1813 			 "======================= End of import/inline commands\n");
1814 	    break;
1815 	case 26:		/* orthographic */
1816 	    M_cameras = 0;
1817 	    break;
1818 	case 27:{		/* unit cell direction vectors */
1819 		float v[3];
1820 
1821 		Display_axes = 1;
1822 		offset[0] = offset[1] = offset[2] = 0.0f;
1823 		i = sscanf (input, "%s %f %f %f", string, &v[0], &v[1], &v[2]);
1824 		if (i == 4)
1825 		    for (i = 0; i < 3; i++)
1826 			offset[i] = v[i];
1827 	    }
1828 	    break;
1829 	case 28:		/* phong */
1830 	    (void) sscanf (input, "%s %f %f", string, &drvui->Phong_Value,
1831 			   &drvui->Phong_Size);
1832 	    break;
1833 	case 29:		/* molcomp */
1834 	    (void) sscanf (input, "%s %f", string, &drvui->mol_d);
1835 	    domolcomp = 1;
1836 	    break;
1837 	case 30:		/* cutout */
1838 	    drvui->El_Cutout = 1;
1839 	    (void) sscanf (input, "%s %39c", string, t_color);
1840 	    trim_string (t_color, 40);
1841 	    if (!strlen (t_color))
1842 		strcpy (t_color, "White");
1843 	    strcpy (drvui->Cutout_color, t_color);
1844 	    break;
1845 	case 31:		/* depthcue - thickness of edges scaled by Z coordinate */
1846 	    (void) sscanf (input, "%s %f", string, &DepthCue);
1847 	    break;
1848 	case 32:		/* vrml1 - turn on VRML1 output */
1849 	    Vrml2 = 0;
1850 	    break;
1851 	case 33:		/* polylimit (formerly polyfudge) */
1852 	    (void) sscanf (input, "%s %f", string, &drvui->polylimit);
1853 	    if (!Quick)
1854 		fprintf (drvui->flout,
1855 			 "Tolerance factor for non-planarity of polyhedra faces set to %f. This option should be used with care\n",
1856 			 drvui->polylimit);
1857 	    break;
1858 	case 34:		/* clip command */
1859 	    (void) sscanf (input, "%s %f %f %f %f %f %f", string,
1860 			   &drvui->frames[tmp_frame_no].clip_lim[0],
1861 			   &drvui->frames[tmp_frame_no].clip_lim[3],
1862 			   &drvui->frames[tmp_frame_no].clip_lim[1],
1863 			   &drvui->frames[tmp_frame_no].clip_lim[4],
1864 			   &drvui->frames[tmp_frame_no].clip_lim[2],
1865 			   &drvui->frames[tmp_frame_no].clip_lim[5]);
1866 	    clipflag = 1;
1867 	    break;
1868 	case 35:		/* list - limit for printed distance table */
1869 	    (void) sscanf (input, "%s %f", string, &printdist);
1870 	    if (!Quick)
1871 		fprintf (drvui->flout,
1872 			 "Interatomic distances up to %6.3f input units will be tabulated in the logfile\n",
1873 			 printdist);
1874 	    break;
1875 	case 36:		/* polyedge - enables individual coloring of polyhedral edges */
1876 	    get_label (input, &t_name[0], &t_name[1], &t_name[2], &t_name[3], 1);
1877 	    (void) sscanf (input, "%f %39c", &t_rad, t_color);
1878 	    t_name[4] = 0;
1879 	    trim_string (t_color, 40);
1880 	    if (!strlen (t_color))
1881 		strcpy (t_color, "White");
1882 	    for (i = 1; i < drvui->npoly; i++) {	/* find this atom in poly list */
1883 		if ((t_name[0] == drvui->polyhedra[i].poly_l[0]) &&
1884 		    (t_name[1] == drvui->polyhedra[i].poly_l[1]) &&
1885 		    (t_name[2] == drvui->polyhedra[i].poly_l[2])
1886 		    && (t_name[3] == drvui->polyhedra[i].poly_l[3])) {
1887 		    edges = 1;
1888 		    drvui->polyhedra[i].poly_rad_edge = t_rad;
1889 		    strcpy (drvui->polyhedra[i].poly_col_edge, t_color);
1890 		}
1891 	    }
1892 	    trim_string (t_name, 4);
1893 	    strcpy (drvui->polyedges[drvui->nedges].name, t_name);
1894 	    strcpy (drvui->polyedges[drvui->nedges].color, t_color);
1895 	    drvui->polyedges[drvui->nedges].radius = t_rad;
1896 	    drvui->nedges++;
1897 	    check_dynamic_storage ();
1898 	    break;
1899 	case 37:		/* frame command */
1900 	    /* if the current frame inherited a clip flag, default clip limit to pack range */
1901 	    if (clipflag == 1
1902 		&& drvui->frames[tmp_frame_no].clip_lim[0] ==
1903 		drvui->frames[tmp_frame_no].clip_lim[3]) {
1904 		for (i = 0; i < 6; i++)
1905 		    drvui->frames[tmp_frame_no].clip_lim[i] =
1906 			drvui->frames[tmp_frame_no].cryst_lim[i];
1907 	    }
1908 	    tmp_frame_no++;
1909 	    i = drvui->max_frame;
1910 	    drvui->max_frame = tmp_frame_no;
1911 	    check_dynamic_storage ();
1912 	    drvui->max_frame = i;
1913 	    break;
1914 	case 38:		/* axislines */
1915 	    (void) sscanf (input, "%s %f %39c", string, &drvui->Ellipaxis_width, t_color);
1916 	    trim_string (t_color, 40);
1917 	    strcpy (drvui->Ellipaxis_color, t_color);
1918 	    if (strlen (drvui->Ellipaxis_color) == 0)
1919 		strcpy (drvui->Ellipaxis_color, "Gray20");
1920 	    break;
1921 	case 40:		/* nolabels command */
1922 	    Labels = 0;		/* set value false */
1923 	    break;
1924 	case 41:		/* lonepair command */
1925 	    get_label (input, &drvui->cones[drvui->ncone].cone_l1[0],
1926 		       &drvui->cones[drvui->ncone].cone_l1[1]
1927 		       , &drvui->cones[drvui->ncone].cone_l1[2],
1928 		       &drvui->cones[drvui->ncone].cone_l1[3], 1);
1929 	    (void) sscanf (input, "%d %f %f %f %39c",
1930 			   &drvui->cones[drvui->ncone].numlonepairs,
1931 			   &drvui->cones[drvui->ncone].cone_height,
1932 			   &drvui->cones[drvui->ncone].cone_min,
1933 			   &drvui->cones[drvui->ncone].cone_max, t_color);
1934 	    trim_string (t_color, 40);
1935 	    strcpy (drvui->cones[drvui->ncone].col_cone, t_color);
1936 	    if (strlen (t_color) == 0)
1937 		strcpy (drvui->cones[drvui->ncone].col_cone, "Grey");
1938 	    drvui->cones[drvui->ncone].cone_fn = tmp_frame_no;
1939 	    drvui->ncone++;
1940 	    check_dynamic_storage ();
1941 	    break;
1942 	case 42:		/* labeltext command */
1943 	    memset (drvui->labels[drvui->nlabel].label_label, 0, 64);
1944 	    Token_Strip (input, 1);
1945 	    (void) sscanf (input, "%f %f %f %63c",
1946 			   &(drvui->labels[drvui->nlabel].label_x[0]),
1947 			   &(drvui->labels[drvui->nlabel].label_x[1]),
1948 			   &(drvui->labels[drvui->nlabel].label_x[2]),
1949 			   drvui->labels[drvui->nlabel].label_label);
1950 	    trim_string (drvui->labels[drvui->nlabel].label_label, 64);
1951 	    drvui->labels[drvui->nlabel].label_fn = tmp_frame_no;
1952 	    intype = 0;
1953 	    if (!strcmp (drvui->labels[drvui->nlabel].label_label, "a") && curframe != 1)
1954 		break;
1955 	    if (!strcmp (drvui->labels[drvui->nlabel].label_label, "b") && curframe != 1)
1956 		break;
1957 	    if (!strcmp (drvui->labels[drvui->nlabel].label_label, "c") && curframe != 1)
1958 		break;
1959 	    if (!strcmp (drvui->labels[drvui->nlabel].label_label, "o") && curframe != 1)
1960 		break;
1961 	    intype = 42;
1962 	    drvui->nlabel++;
1963 	    check_dynamic_storage ();
1964 	    break;
1965 	case 44:		// background (color) command
1966 	    Token_Strip (input, 1);
1967 	    strncpy (drvui->col_bg, input, 30);
1968 	    trim_string (drvui->col_bg, 40);
1969 	    if (strlen (drvui->col_bg) < 2)
1970 		strcpy (drvui->col_bg, "White");
1971 	    strcpy (input, drvui->col_bg);
1972 	    Transform_VRML_Color (input);
1973 	    sscanf (input, "%f %f %f", &drvui->glback[0], &drvui->glback[1],
1974 		    &drvui->glback[2]);
1975 	    break;
1976 	case 45:
1977 	    (void) sscanf (input, "%*s %f %f %f %f %f %f %f %f %f %f %f %f %d",
1978 			   &drvui->slab_con[0], &drvui->slab_con[1], &drvui->slab_con[2],
1979 			   &drvui->slab_con[3], &drvui->slab_con[4], &drvui->slab_con[5],
1980 			   &drvui->slab_off[0], &drvui->slab_off[1], &drvui->slab_off[2],
1981 			   &drvui->slab_rot[0], &drvui->slab_rot[1], &drvui->slab_rot[2],
1982 			   &slabmode);
1983 
1984 	    break;
1985 	case 46:		// mag_trans command
1986 	    Token_Strip (input, 1);
1987 	    (void) sscanf (input, "%f %f %f %f %f %f %f %f %f", &drvui->mag_matrix[0][0],
1988 			   &drvui->mag_matrix[0][1], &drvui->mag_matrix[0][2],
1989 			   &drvui->mag_matrix[1][0], &drvui->mag_matrix[1][1],
1990 			   &drvui->mag_matrix[1][2], &drvui->mag_matrix[2][0],
1991 			   &drvui->mag_matrix[2][1], &drvui->mag_matrix[2][2]);
1992 	    break;
1993 	case 47:		// special command
1994 	    if (!Quick)
1995 		break;
1996 	    (void) sscanf (input, "%*7c %d %d", &Omit->omit1[Omit->nomits],
1997 			   &Omit->omit2[Omit->nomits]);
1998 	    Omit->nomits++;
1999 	    break;
2000 	case 48:		// noshadow command
2001 	    drvui->noshadow = 1;
2002 	    break;
2003 	case 49:		// finish command
2004 	    (void) sscanf (input, "%*6c %f %f %f %f", &drvui->ambient,
2005 			   &drvui->diffuse, &drvui->specular, &drvui->roughness);
2006 	    break;
2007 	case 50:		// arrow command
2008 	    Token_Strip (input, 1);
2009 	    (void) sscanf (input, "%f %f %f %f %f %f %f %f %39c",
2010 			   &drvui->arrows[drvui->nmag].mag_xp[0],
2011 			   &drvui->arrows[drvui->nmag].mag_xp[1],
2012 			   &drvui->arrows[drvui->nmag].mag_xp[2],
2013 			   &drvui->arrows[drvui->nmag].mag_xc[0],
2014 			   &drvui->arrows[drvui->nmag].mag_xc[1],
2015 			   &drvui->arrows[drvui->nmag].mag_xc[2],
2016 			   &drvui->arrows[drvui->nmag].arrow_length,
2017 			   &drvui->arrows[drvui->nmag].arrow_diam, t_color);
2018 	    trim_string (t_color, 40);
2019 	    if (!strlen (t_color))
2020 		strcpy (t_color, "White");
2021 	    strcpy (drvui->arrows[drvui->nmag].col_arrow, t_color);
2022 	    drvui->arrows[drvui->nmag].arrow_fn = tmp_frame_no;
2023 	    drvui->nmag++;
2024 	    check_dynamic_storage ();
2025 	    break;
2026 	case 52:		/* mapcontour command */
2027 	    {
2028 	    drvui->numOfFourierContours++;
2029 	    check_dynamic_storage ();
2030 	    Token_Strip (input, 1);
2031 	    (void) sscanf (input, "%f %s %69c",
2032 			   &drvui->fourier[drvui->numOfFourierContours].
2033 			   FourierContourLevel, string, t_color);
2034 	    trim_string (t_color, 70);
2035 	    if (!strlen (t_color))
2036 		strcpy (t_color, "White");
2037 	    char *amp  = strchr(t_color,'&');
2038 	    if (amp) {
2039 		*amp='\0';
2040 		amp++;
2041 		strcpy(drvui->fourier[drvui->numOfFourierContours].FourierBackColor,amp);
2042 	    }
2043 	    strcpy (drvui->fourier[drvui->numOfFourierContours].FourierContourColor,
2044 		    t_color);
2045 	    if (strncmp (string, "mesh", 4) == 0)
2046 		drvui->fourier[drvui->numOfFourierContours].FourierContourSolid = 0;
2047 	    else
2048 		drvui->fourier[drvui->numOfFourierContours].FourierContourSolid = 1;
2049 	    }
2050 	    break;
2051 	case 53:		/* mapread command */
2052 	    char string2[20], res[20];
2053 
2054 	    if (!Quick)
2055 		break;
2056 	    Token_Strip (input, 1);
2057 	    i = sscanf(input, "%s %s %s %s", string, filename, string2, res);
2058 	    strcpy (FourierFileName, filename);
2059 	    if (i < 4)
2060 		Map_Info.res = 4; /* No resolution specified - set 0.25 A */
2061 	    else
2062 		sscanf(res, "%d", &Map_Info.res);
2063 	    if (Map_Info.res <= 0)
2064 		Map_Info.res = 1;
2065 	    if (i < 3)
2066 		strcpy(string2, "Fo"); /* Map type not specified - default to Fo */
2067 	    if (strncmp (string, "grd", 3) == 0) {
2068 		FourierMapType = 1;
2069 	    } else if (strncmp (string, "stf", 3) == 0) {
2070 		FourierMapType = 2;
2071 	    } else if (strncmp (string, "w2k", 3) == 0) {
2072 		FourierMapType = 3;
2073 	    } else if (strncmp (string, "vsp", 3) == 0) {
2074 		FourierMapType = 4;
2075 	    } else if (strncmp (string, "flp", 3) == 0) {
2076 		FourierMapType = 5;
2077 	    } else if (strncmp (string, "fcf", 3) == 0) {
2078 		FourierMapType = 6;
2079 		Map_Info.map_type = 0;
2080 		if (!strcmp (string2, "Fc"))
2081 		    Map_Info.map_type = 1;
2082 		else if (!strcmp (string2, "Fo-Fc"))
2083 		    Map_Info.map_type = 2;
2084 		else if (!strcmp (string2, "2Fo-Fc"))
2085 		    Map_Info.map_type = 3;
2086 		else if (!strcmp (string2, "Fo2"))
2087 		    Map_Info.map_type = 4;
2088 	    } else if (strncmp (string, "dn6", 3) == 0) {
2089 		FourierMapType = 7;
2090 	    } else if (strncmp (string, "m80", 3) == 0) {
2091 		FourierMapType = 8;
2092 		Map_Info.map_type = 0;
2093 		if (!strcmp (string2, "Fc"))
2094 		    Map_Info.map_type = 1;
2095 		else if (!strcmp (string2, "Fo-Fc"))
2096 		    Map_Info.map_type = 2;
2097 		else if (!strcmp (string2, "2Fo-Fc"))
2098 		    Map_Info.map_type = 3;
2099 		else if (!strcmp (string2, "Fo2"))
2100 		    Map_Info.map_type = 4;
2101 	    } else if (strncmp (string, "m81", 3) == 0) {
2102 		FourierMapType = 10;
2103 		Map_Info.map_type = 0;
2104 		if (!strcmp (string2, "Fc"))
2105 		    Map_Info.map_type = 1;
2106 		else if (!strcmp (string2, "Fo-Fc"))
2107 		    Map_Info.map_type = 2;
2108 		else if (!strcmp (string2, "2Fo-Fc"))
2109 		    Map_Info.map_type = 3;
2110 		else if (!strcmp (string2, "Fo2"))
2111 		    Map_Info.map_type = 4;
2112 	    } else if (strncmp (string, "exc", 3) == 0) {
2113 		FourierMapType = 9;
2114 	    } else if (strncmp (string, "xsf", 3) == 0) {
2115 		FourierMapType = 11;
2116 	    } else {
2117 		Error_Box ("mapread command does not specify a legal file type.");
2118 	    }
2119 	    break;
2120 	case 54:		/* mapregion command */
2121 	    Token_Strip (input, 1);
2122 	    (void) sscanf (input, "%f %f %f %f %f %f %f %f %f", &xMin, &xMax, &yMin,
2123 			   &yMax, &zMin, &zMax, &x4Val, &x5Val, &x6Val);
2124 	    drvui->frames[tmp_frame_no].map_lim_set= 1;
2125 	    drvui->frames[tmp_frame_no].map_lim[0]=xMin;
2126 	    drvui->frames[tmp_frame_no].map_lim[3]=xMax;
2127 	    drvui->frames[tmp_frame_no].map_lim[1]=yMin;
2128 	    drvui->frames[tmp_frame_no].map_lim[4]=yMax;
2129 	    drvui->frames[tmp_frame_no].map_lim[2]=zMin;
2130 	    drvui->frames[tmp_frame_no].map_lim[5]=zMax;
2131 	    drvui->frames[tmp_frame_no].map_lim[6]=x4Val;
2132 	    drvui->frames[tmp_frame_no].map_lim[7]=x5Val;
2133 	    drvui->frames[tmp_frame_no].map_lim[8]=x6Val;
2134 	    i = 0;
2135 	    if (fabs (xMax - xMin) < 0.001f)
2136 		i++;
2137 	    if (fabs (yMax - yMin) < 0.001f)
2138 		i++;
2139 	    if (fabs (zMax - zMin) < 0.001f)
2140 		i++;
2141 	    if (i == 1)
2142 		drvui->Fourier2d = 1;
2143 	    break;
2144 	case 55:		/* mapcalclimits command */
2145 	    Token_Strip (input, 1);
2146 	    (void) sscanf (input, "%f %f %f %f %f %f", &Map_Info.xlim[0],
2147 			   &Map_Info.xlim[1], &Map_Info.ylim[0], &Map_Info.ylim[1],
2148 			   &Map_Info.zlim[0], &Map_Info.zlim[1]);
2149 	    break;
2150 	case 56:		/* labelscale command */
2151 	    Token_Strip (input, 1);
2152 	    (void) sscanf (input, "%f", &drvui->label_scale);
2153 	    break;
2154 	case 57:		/* bestplane command */
2155 	    char bplane[15][5];
2156 
2157 	    sscanf (input, "%*s %d", &drvui->bplanes[drvui->nbplane].nbatoms);
2158 	    if (drvui->bplanes[drvui->nbplane].nbatoms > 15) {
2159 		Error_Box ("Cannot handle more than 15 atoms in a best plane.");
2160 		if (el_color_tmp)
2161 		    free (el_color_tmp);
2162 		return;
2163 	    }
2164 	    Token_Strip (input, 2);
2165 	    for (i = 0; i < drvui->bplanes[drvui->nbplane].nbatoms; i++) {
2166 		sscanf (input, "%s", bplane[i]);
2167 		Token_Strip (input, 1);
2168 	    }
2169 	    memset (drvui->bplanes[drvui->nbplane].bplane_col, 0, 40);
2170 	    sscanf (input, "%f %f %39c", &drvui->bplanes[drvui->nbplane].bplane_d1,
2171 		    &drvui->bplanes[drvui->nbplane].bplane_d2, t_color);
2172 	    trim_string (t_color, 40);
2173 	    if (!strlen (t_color))
2174 		strcpy (t_color, "White");
2175 	    strcpy (drvui->bplanes[drvui->nbplane].bplane_col, t_color);
2176 	    for (i = 0; i < drvui->bplanes[drvui->nbplane].nbatoms; i++) {
2177 		memset (drvui->bplanes[drvui->nbplane].bplane_t[i], 0, 4);
2178 		strcpy (drvui->bplanes[drvui->nbplane].bplane_t[i], bplane[i]);
2179 		char *p = strstr (bplane[i], "*");
2180 
2181 		if (p != NULL) {
2182 		    *p = '\0';
2183 		    drvui->bplanes[drvui->nbplane].bplane_n[i] = -1;
2184 		} else {
2185 		    for (j = 1; j < 4; j++)
2186 			if (bplane[i][j] <= '9') {
2187 			    char *q = drvui->bplanes[drvui->nbplane].bplane_t[i] + j;
2188 
2189 			    drvui->bplanes[drvui->nbplane].bplane_n[i] =
2190 				strtol (q, NULL, 10);
2191 			    for (k = j; k < 4; k++)
2192 				drvui->bplanes[drvui->nbplane].bplane_t[i][k] = ' ';
2193 			    break;
2194 			}
2195 		}
2196 	    }
2197 	    drvui->nbplane++;
2198 	    check_dynamic_storage ();
2199 	    break;
2200 	case 58:
2201 	    average = 1;
2202 	    break;
2203 	case 59:
2204 	    Token_Strip (input, 1);
2205 	    memset (modl, 0, 4);
2206 	    sscanf (input, "%s %d %f %f", modl, &modnum, &avg_occ, &min_occ);
2207 	    if (modl[1] == '\0')
2208 		modl[1] = modl[2] = modl[3] = ' ';
2209 	    if (modl[2] == '\0')
2210 		modl[2] = modl[3] = ' ';
2211 	    if (modl[3] == 0)
2212 		modl[3] = ' ';
2213 	    modl[4] = '\0';
2214 	    for (j = 0; j < natom; j++) {
2215 		if (check_atom_name (modl, drvui->atoms[j].atom_l)
2216 		    && modnum == drvui->atoms[j].atom_n) {
2217 		    drvui->atoms[j].occupancy = avg_occ;
2218 		    drvui->atoms[j].min_occ = min_occ;
2219 		    break;
2220 		}
2221 	    }
2222 	    break;
2223 	case 60:
2224 	    sscanf (input, "%*s %f %f %f", &drvui->phaseshift[0], &drvui->phaseshift[1],
2225 		    &drvui->phaseshift[2]);
2226 	    for (j = 0; j < 3; j++)
2227 		drvui->phaseshift[j] = (float) fmod (drvui->phaseshift[j], 1.);
2228 	    break;
2229 	case 61:		/* mapcontour2d command */
2230 	    drvui->numOfFourierContours++;
2231 	    check_dynamic_storage ();
2232 	    Token_Strip (input, 1);
2233 	    (void) sscanf (input, "%f %f %f %39c",
2234 			   &drvui->fourier[drvui->numOfFourierContours].
2235 			   FourierContourLevel,
2236 			   &drvui->fourier[drvui->numOfFourierContours].
2237 			   FourierContourStep,
2238 			   &drvui->fourier[drvui->numOfFourierContours].FourierContourTop,
2239 			   t_color);
2240 	    trim_string (t_color, 40);
2241 	    if (!strlen (t_color))
2242 		strcpy (t_color, "White");
2243 	    strcpy (drvui->fourier[drvui->numOfFourierContours].FourierContourColor,
2244 		    t_color);
2245 	    break;
2246 	case 62:
2247 	    memset (modl, 0, 4);
2248 	    sscanf (input, "%*s %s %d %s %s %39c", modl, &modnum, filename, string,
2249 		    t_color);
2250 	    if (modl[1] == '\0')
2251 		modl[1] = modl[2] = modl[3] = ' ';
2252 	    if (modl[2] == '\0')
2253 		modl[2] = modl[3] = ' ';
2254 	    if (modl[3] == 0)
2255 		modl[3] = ' ';
2256 	    modl[4] = '\0';
2257 	    if (drvui->nsurf == MAX_SURF) {
2258 		if (!Quick)
2259 		    fprintf (drvui->flout,
2260 			     "Maximum number of surfaces exceeded, skipping\n");
2261 		break;
2262 	    }
2263 	    strcpy (drvui->surfatom[drvui->nsurf], modl);
2264 	    drvui->surfnum[drvui->nsurf] = modnum;
2265 	    if (!strncmp (string, "mesh", 4)) {
2266 		drvui->surftype[drvui->nsurf] = 0;
2267 	    } else if (!strncmp (string, "solid", 5)) {
2268 		drvui->surftype[drvui->nsurf] = 1;
2269 	    } else
2270 		drvui->surftype[drvui->nsurf] = 2;
2271 	    trim_string (t_color, 40);
2272 	    if (!strlen (t_color))
2273 		strcpy (t_color, "White");
2274 	    strcpy (drvui->surfcolor[drvui->nsurf], t_color);
2275 	    strcpy (drvui->surffile[drvui->nsurf], filename);
2276 	    read_aim (filename, Quick);
2277 	    drvui->nsurf++;
2278 	    break;
2279 	case 63:		/* voids command */
2280 	    sscanf (input, "%*s %d %f %d %d %d %39c", &j, &drvui->probesize,
2281 		    &drvui->voidgrid[0], &drvui->voidgrid[1], &drvui->voidgrid[2],
2282 		    t_color);
2283 	    trim_string (t_color, 40);
2284 	    if (!strlen (t_color))
2285 		strcpy (t_color, "White");
2286 	    strcpy (drvui->voidcolor, t_color);
2287 	    if (drvui->voidflag >= 0) {
2288 		drvui->voidflag = j;
2289 		if (j == 1) {
2290 		    drvui->voidmap =
2291 			(char ***) zalloc (drvui->voidgrid[0] * sizeof (*drvui->voidmap));
2292 		    for (j = 0; j < drvui->voidgrid[0]; j++) {
2293 			drvui->voidmap[j] =
2294 			    (char **) zalloc (drvui->voidgrid[1] *
2295 					      sizeof (*drvui->voidmap[j]));
2296 			for (k = 0; k < drvui->voidgrid[1]; k++)
2297 			    drvui->voidmap[j][k] =
2298 				(char *) zalloc (drvui->voidgrid[2] *
2299 						 sizeof (*drvui->voidmap[j][k]));
2300 		    }
2301 		}
2302 	    }
2303 	    break;
2304 	case 64:		/* values command */
2305 	    get_label (input, &drvui->atprops[drvui->natprop].atprop_l[0],
2306 		       &drvui->atprops[drvui->natprop].atprop_l[1],
2307 		       &drvui->atprops[drvui->natprop].atprop_l[2],
2308 		       &drvui->atprops[drvui->natprop].atprop_l[3], 1);
2309 
2310 	    i = sscanf (input, "%s %s", str[0], str[1]);
2311 	    if (atoi (str[0]) == 0)
2312 		drvui->atprops[drvui->natprop].atprop_n = -1;
2313 	    else
2314 		drvui->atprops[drvui->natprop].atprop_n = atoi(str[0]);
2315 	    drvui->atprops[drvui->natprop].radius = (float)atof (str[1]);
2316 	    drvui->atprops[drvui->natprop].atprop_fn = tmp_frame_no;
2317 	    drvui->natprop++;
2318 	    check_dynamic_storage ();
2319 	    break;
2320 	case 65: /* mapslice command */
2321 	    Token_Strip (input,1);
2322 	    j = sscanf (input,"%f %f %f %f %f %f %d",&drvui->frames[tmp_frame_no].mapslice[0],
2323 		    &drvui->frames[tmp_frame_no].mapslice[1],&drvui->frames[tmp_frame_no].mapslice[2],
2324 		    &drvui->frames[tmp_frame_no].mapnorm[0],&drvui->frames[tmp_frame_no].mapnorm[1],
2325 		    &drvui->frames[tmp_frame_no].mapnorm[2],&drvui->frames[tmp_frame_no].slice);
2326 	    if (j <7) drvui->frames[tmp_frame_no].slice = 1;
2327 	    break;
2328 	case 66: /* qvector command */
2329 	    Token_Strip (input,1);
2330 	    j = drvui->no_cell_vec;
2331 	    sscanf (input,"%f %f %f",  &drvui->cell_vec[j][0],
2332 		&drvui->cell_vec[j][1], &drvui->cell_vec[j][2]);
2333 	    drvui->no_cell_vec++;
2334 	    drvui->modulated++;
2335 	    break;
2336 	case 67:
2337 	    ShowMapLegend = 1;
2338 	    break;
2339 	case 68:
2340 	    Vrml2 = 1;
2341 	    X3D = 1;
2342 	    break;
2343 	default:
2344 	    if (!Quick)
2345 		fprintf (drvui->flout,
2346 			 "********** Next line does not start with a recognizable keyword - ignored\n");
2347 	    break;
2348 	}
2349 	if (!Quick && intype)
2350 	    fprintf (drvui->flout, "*         %s\n", input2);	// echo to listing file
2351     }
2352     if (drvui->n_ellips > 1)
2353 	drvui->do_ellipsoids = 1;
2354     if (packflag != 0) {
2355 	boxlim[0] = boxlim[1] = boxlim[2] = 500.0f;
2356     }
2357 }				/* end of read_inp */
2358 
2359 /* ************************************************************** */
2360 /* ************************************************************** */
2361 
2362 void
set_tf_status(void)2363 set_tf_status (void)
2364 {
2365 // set the TF_status flags for the atoms in the list
2366 
2367     int i, j;
2368 
2369     for (i = 0; i < natom; i++) {
2370 	if (drvui->atoms[i].atom_fn != drvui->frame_no)
2371 	    continue;
2372 	drvui->atoms[i].TF_status = -1;
2373 	for (j = 1; j < drvui->n_ellips; j++) {
2374 	    if (check_atom_name (drvui->atoms[i].atom_l, drvui->ellips[j].ellips_l)) {
2375 		if (drvui->ellips[j].ellips_n == -1
2376 		    || drvui->ellips[j].ellips_n == drvui->atoms[i].sv_atom_n) {
2377 		    if (drvui->ellips[j].ell_type > 1000) {
2378 			drvui->atoms[i].TF_status = 1;
2379 			j = drvui->n_ellips;
2380 			break;
2381 		    } else {
2382 			if (drvui->ellips[j].ell_type > 0) {
2383 			    drvui->atoms[i].TF_status = 0;
2384 			    j = drvui->n_ellips;
2385 			    break;
2386 			}
2387 		    }
2388 		}
2389 	    }
2390 	}
2391 	j = drvui->atoms[i].TF_status;
2392     }
2393 }
2394 
2395 
2396 /* ************************************************************** */
2397 /* ************************************************************** */
2398 
2399 void
skip_blocks(int i,FILE * in)2400 skip_blocks (int i, FILE * in)
2401 {
2402 // routine to skip data blocks in a CIF
2403     char string[256];
2404 
2405     int j;
2406 
2407     memset (string, 0, 255);
2408     for (j = 0; j <= i; j++) {
2409 	while (strncmp (string, "data_", 5) != 0) {
2410 	    if (!fgets (string, 255, in)) {	/* search for data_ keyword */
2411 		Error_Box ("Error skipping data blocks in CIF Import File, Run aborted.");
2412 		(void) fclose (in);
2413 		return;
2414 	    }
2415 	}
2416 	memset (string, 0, 255);
2417     }
2418 }
2419 
2420 
2421 /* ************************************************************** */
2422 /* ************************************************************** */
2423 
2424 void
Token_Strip(char string[],int no)2425 Token_Strip (char string[], int no)
2426 
2427 /*  string[] - input output string */
2428 /*  no - number of tokens to strip */
2429 /* routine to strip tokens from the leading part of a string */
2430 {
2431     int i, j;
2432     int l = strlen(string);
2433 
2434     for (i = 0, j = 0; i < no; i++) {	/* loop through tokens to be removed */
2435 	while (j < l-1 && string[j++] != ' ')
2436 	    string[j - 1] = ' ';	/* characters to space */
2437 	while (j < l && string[j] == ' ')
2438 	    j++;		/* skip all spaces */
2439     }
2440     Blank_Strip (string);	/* move stuff to left */
2441 }
2442 
2443 /* ************************************************************** */
2444 /* ************************************************************** */
2445 
2446 void
Transform_POV_Color(char * color)2447 Transform_POV_Color (char *color)
2448 {
2449 // Transform a POV color is specified in the form f1 f2 f2 {filter f} format,
2450 // where {filter} is optional. If a color name is specified, return with no
2451 // action.
2452     float red, green, blue, filter;
2453 
2454     char working[120], string[20];
2455 
2456     char *p;
2457 
2458     if (!strtod (color, &p) && p == color)
2459 	return;			/* we have the color name form */
2460 
2461     strcpy (working, color);	/* make a working copy */
2462     (void) sscanf (working, "%f %f %f", &red, &green, &blue);
2463 
2464     if ((p = strstr (working, "filter"))) {	/* if "filter" given, return rgbf<...> form */
2465 	(void) sscanf (p, "%s %f", string, &filter);
2466 	sprintf (working, "rgbf <%.4f,%.4f,%.4f,%.4f>", red, green, blue, filter);
2467     } else {			/* return rgb <...> form */
2468 	sprintf (working, "rgb <%.4f,%.4f,%.4f>", red, green, blue);
2469     }
2470     strcpy (color, working);	/* reformatted color to caller */
2471 }
2472 
2473 /* ************************************************************** */
2474 /* ************************************************************** */
2475 
2476 void
Transform_VRML_Color(char * input)2477 Transform_VRML_Color (char *input)
2478 {
2479     char *transp_start;
2480 
2481     char transp[20];
2482 
2483     float fval;
2484 
2485     int i;
2486 
2487     char *a, b[30], line[81];
2488 
2489     char thecolor[50];
2490 
2491     char keyword[80];
2492 
2493     float thered, thegreen, theblue;
2494 
2495     char POV_incpath[255] = "\0";
2496 
2497     FILE *colinc;
2498 
2499 /*
2500    VRML routine to transform VRML (and openGL) colors into RGB triples
2501    derived from 'colors.inc' of POV
2502 
2503    If the color information is "float1 float2 float3", then extract the rgb
2504    values from the input.   LWF 9/30/05
2505 */
2506 
2507     i = strlen (input);
2508     if (i == 0)
2509 	return;
2510     if (input[i - 1] < ' ')
2511 	input[i - 1] = 0;	// get rid of any ^J character
2512     transp[0] = '\0';
2513     transp_start = strstr (input, "filter");
2514     if (transp_start) {
2515 	fval = (float) atof (transp_start + 6);
2516 	sprintf (transp, " transparency %5.2f", fval / 2.);
2517     }
2518     if (strtod (input, &a) || a != input) {	// rgb form of color
2519 	sscanf (input, "%f %f %f", &thered, &thegreen, &theblue);
2520 	sprintf (input, "%.6f %.6f %.6f", thered, thegreen, theblue);
2521 	strcat (input, transp);
2522 	return;
2523     }
2524     if (!strncmp (input, "Black", 5)) {
2525 	strncpy (input, "0 0 0\0", 6);
2526 	strcat (input, transp);
2527 	return;
2528     }
2529     if (!strncmp (input, "Brass", 5)) {
2530 	strncpy (input, ".71 .65 .26\0", 12);
2531 	strcat (input, transp);
2532 	return;
2533     }
2534     if (!strncmp (input, "Bronze2", 7)) {
2535 	strncpy (input, ".65 .49 .24\0", 12);
2536 	strcat (input, transp);
2537 	return;
2538     }
2539     if (!strncmp (input, "Bronze", 6)) {
2540 	strncpy (input, ".55 .47 .14\0", 12);
2541 	strcat (input, transp);
2542 	return;
2543     }
2544     if (!strncmp (input, "BlueViolet", 10)) {
2545 	strncpy (input, ".62352 .372549 .623529\0", 24);
2546 	strcat (input, transp);
2547 	return;
2548     }
2549     if (!strncmp (input, "Blue", 3)) {
2550 	strncpy (input, "0 0 1\0", 6);
2551 	strcat (input, transp);
2552 	return;
2553     }
2554     if (!strncmp (input, "Brown", 5)) {
2555 	strncpy (input, ".647059 .164706 .164706\0", 24);
2556 	strcat (input, transp);
2557 	return;
2558     }
2559     if (!strncmp (input, "Copper", 6)) {
2560 	strncpy (input, ".72 .45 .20\0", 12);
2561 	strcat (input, transp);
2562 	return;
2563     }
2564     if (!strncmp (input, "Cyan", 3)) {
2565 	strncpy (input, "0 1 1\0", 6);
2566 	strcat (input, transp);
2567 	return;
2568     }
2569     if (!strncmp (input, "DimGray", 7)) {
2570 	strncpy (input, ".329412 .329412 .329412\0", 24);
2571 	strcat (input, transp);
2572 	return;
2573     }
2574     if (!strncmp (input, "DimGrey", 7)) {
2575 	strncpy (input, ".329412 .329412 .329412\0", 24);
2576 	strcat (input, transp);
2577 	return;
2578     }
2579     if (!strncmp (input, "Aquamarine", 10)) {
2580 	strncpy (input, ".439216 .858824 .576471\0", 24);
2581 	strcat (input, transp);
2582 	return;
2583     }
2584     if (!strncmp (input, "CadetBlue", 9)) {
2585 	strncpy (input, ".372549 .623529 .623529\0", 24);
2586 	strcat (input, transp);
2587 	return;
2588     }
2589     if (!strncmp (input, "Coral", 5)) {
2590 	strncpy (input, "1.0 .498039 .0\0", 24);
2591 	strcat (input, transp);
2592 	return;
2593     }
2594     if (!strncmp (input, "CornflowerBlue", 14)) {
2595 	strncpy (input, ".258824 .258824 .435294\0", 24);
2596 	strcat (input, transp);
2597 	return;
2598     }
2599     if (!strncmp (input, "DarkGreen", 9)) {
2600 	strncpy (input, ".184314 .309804 .184314\0", 24);
2601 	strcat (input, transp);
2602 	return;
2603     }
2604     if (!strncmp (input, "DarkOliveGreen", 14)) {
2605 	strncpy (input, ".309804 .309804 .184314\0", 24);
2606 	strcat (input, transp);
2607 	return;
2608     }
2609     if (!strncmp (input, "DarkOrchid", 10)) {
2610 	strncpy (input, ".6 .196078 .8\0", 24);
2611 	strcat (input, transp);
2612 	return;
2613     }
2614     if (!strncmp (input, "DarkSlateBlue", 13)) {
2615 	strncpy (input, ".119608 .137255 .556863\0", 24);
2616 	strcat (input, transp);
2617 	return;
2618     }
2619     if (!strncmp (input, "DarkSlateGray", 13)) {
2620 	strncpy (input, ".184314 .309804 .309804\0", 24);
2621 	strcat (input, transp);
2622 	return;
2623     }
2624     if (!strncmp (input, "DarkSlateGrey", 13)) {
2625 	strncpy (input, ".184314 .309804 .309804\0", 24);
2626 	strcat (input, transp);
2627 	return;
2628     }
2629     if (!strncmp (input, "DarkTurquoise", 13)) {
2630 	strncpy (input, ".439216 .576471 .858824\0", 24);
2631 	strcat (input, transp);
2632 	return;
2633     }
2634     if (!strncmp (input, "Firebrick", 9)) {
2635 	strncpy (input, ".556863 .137255 .137255\0", 24);
2636 	strcat (input, transp);
2637 	return;
2638     }
2639     if (!strncmp (input, "ForestGreen", 11)) {
2640 	strncpy (input, ".137255 .556863 .137255\0", 24);
2641 	strcat (input, transp);
2642 	return;
2643     }
2644     if (!strncmp (input, "Goldenrod", 9)) {
2645 	strncpy (input, ".858824 .858824 .439216\0", 24);
2646 	strcat (input, transp);
2647 	return;
2648     }
2649     if (!strncmp (input, "Gold", 4)) {
2650 	strncpy (input, ".8 .498039 .196078\0", 24);
2651 	strcat (input, transp);
2652 	return;
2653     }
2654     if (!strncmp (input, "Gray05", 6)) {
2655 	strncpy (input, ".05 .05 .05\0", 12);
2656 	strcat (input, transp);
2657 	return;
2658     }
2659     if (!strncmp (input, "Gray10", 6)) {
2660 	strncpy (input, ".10 .10 .10\0", 12);
2661 	strcat (input, transp);
2662 	return;
2663     }
2664     if (!strncmp (input, "Gray15", 6)) {
2665 	strncpy (input, ".15 .15 .15\0", 12);
2666 	strcat (input, transp);
2667 	return;
2668     }
2669     if (!strncmp (input, "Gray20", 6)) {
2670 	strncpy (input, ".20 .20 .20\0", 12);
2671 	strcat (input, transp);
2672 	return;
2673     }
2674     if (!strncmp (input, "Gray25", 6)) {
2675 	strncpy (input, ".25 .25 .25\0", 12);
2676 	strcat (input, transp);
2677 	return;
2678     }
2679     if (!strncmp (input, "Gray30", 6)) {
2680 	strncpy (input, ".30 .30 .30\0", 12);
2681 	strcat (input, transp);
2682 	return;
2683     }
2684     if (!strncmp (input, "Gray35", 6)) {
2685 	strncpy (input, ".35 .35 .35\0", 12);
2686 	strcat (input, transp);
2687 	return;
2688     }
2689     if (!strncmp (input, "Gray40", 6)) {
2690 	strncpy (input, ".40 .40 .40\0", 12);
2691 	strcat (input, transp);
2692 	return;
2693     }
2694     if (!strncmp (input, "Gray45", 6)) {
2695 	strncpy (input, ".45 .45 .45\0", 12);
2696 	strcat (input, transp);
2697 	return;
2698     }
2699     if (!strncmp (input, "Gray50", 6)) {
2700 	strncpy (input, ".50 .50 .50\0", 12);
2701 	strcat (input, transp);
2702 	return;
2703     }
2704     if (!strncmp (input, "Gray55", 6)) {
2705 	strncpy (input, ".55 .55 .55\0", 12);
2706 	strcat (input, transp);
2707 	return;
2708     }
2709     if (!strncmp (input, "Gray60", 6)) {
2710 	strncpy (input, ".60 .60 .60\0", 12);
2711 	strcat (input, transp);
2712 	return;
2713     }
2714     if (!strncmp (input, "Gray65", 6)) {
2715 	strncpy (input, ".65 .65 .65\0", 12);
2716 	strcat (input, transp);
2717 	return;
2718     }
2719     if (!strncmp (input, "Gray70", 6)) {
2720 	strncpy (input, ".70 .70 .70\0", 12);
2721 	strcat (input, transp);
2722 	return;
2723     }
2724     if (!strncmp (input, "Gray75", 6)) {
2725 	strncpy (input, ".75 .75 .75\0", 12);
2726 	strcat (input, transp);
2727 	return;
2728     }
2729     if (!strncmp (input, "Gray80", 6)) {
2730 	strncpy (input, ".80 .80 .80\0", 12);
2731 	strcat (input, transp);
2732 	return;
2733     }
2734     if (!strncmp (input, "Gray85", 6)) {
2735 	strncpy (input, ".85 .85 .85\0", 12);
2736 	strcat (input, transp);
2737 	return;
2738     }
2739     if (!strncmp (input, "Gray90", 6)) {
2740 	strncpy (input, ".90 .90 .90\0", 12);
2741 	strcat (input, transp);
2742 	return;
2743     }
2744     if (!strncmp (input, "Gray95", 6)) {
2745 	strncpy (input, ".95 .95 .95\0", 12);
2746 	strcat (input, transp);
2747 	return;
2748     }
2749     if (!strncmp (input, "Gray", 4)) {
2750 	strncpy (input, ".752941 .752941 .752941\0", 24);
2751 	strcat (input, transp);
2752 	return;
2753     }
2754     if (!strncmp (input, "Grey", 4)) {
2755 	strncpy (input, ".752941 .752941 .752941\0", 24);
2756 	strcat (input, transp);
2757 	return;
2758     }
2759     if (!strncmp (input, "GreenYellow", 11)) {
2760 	strncpy (input, ".576471 .858824 .439216\0", 24);
2761 	strcat (input, transp);
2762 	return;
2763     }
2764     if (!strncmp (input, "Green", 5)) {
2765 	strncpy (input, "0 1 0\0", 6);
2766 	strcat (input, transp);
2767 	return;
2768     }
2769     if (!strncmp (input, "IndianRed", 9)) {
2770 	strncpy (input, ".309804 .184314 .184314\0", 24);
2771 	strcat (input, transp);
2772 	return;
2773     }
2774     if (!strncmp (input, "Khaki", 5)) {
2775 	strncpy (input, ".623529 .623529 .372549\0", 24);
2776 	strcat (input, transp);
2777 	return;
2778     }
2779     if (!strncmp (input, "LightBlue", 9)) {
2780 	strncpy (input, ".74902 .847059 .847059\0", 24);
2781 	strcat (input, transp);
2782 	return;
2783     }
2784     if (!strncmp (input, "LightGray", 9)) {
2785 	strncpy (input, ".658824 .658824 .658824\0", 24);
2786 	strcat (input, transp);
2787 	return;
2788     }
2789     if (!strncmp (input, "LightGrey", 9)) {
2790 	strncpy (input, ".658824 .658824 .658824\0", 24);
2791 	strcat (input, transp);
2792 	return;
2793     }
2794     if (!strncmp (input, "Light_Purple", 12)) {
2795 	strncpy (input, ".87 .58 .98\0", 12);
2796 	strcat (input, transp);
2797 	return;
2798     }
2799     if (!strncmp (input, "LightSteelBlue", 14)) {
2800 	strncpy (input, ".560784 .560784 .737255\0", 24);
2801 	strcat (input, transp);
2802 	return;
2803     }
2804     if (!strncmp (input, "LimeGreen", 9)) {
2805 	strncpy (input, ".196078 .8 .196078\0", 24);
2806 	strcat (input, transp);
2807 	return;
2808     }
2809     if (!strncmp (input, "Magenta", 7)) {
2810 	strncpy (input, "1 0 1\0", 6);
2811 	strcat (input, transp);
2812 	return;
2813     }
2814     if (!strncmp (input, "Maroon", 6)) {
2815 	strncpy (input, ".556863 .137255 .419608\0", 24);
2816 	strcat (input, transp);
2817 	return;
2818     }
2819     if (!strncmp (input, "MediumAquamarine", 16)) {
2820 	strncpy (input, ".196078 .8 .6\0", 24);
2821 	strcat (input, transp);
2822 	return;
2823     }
2824     if (!strncmp (input, "MediumBlue", 10)) {
2825 	strncpy (input, ".196078 .196078 .8\0", 24);
2826 	strcat (input, transp);
2827 	return;
2828     }
2829     if (!strncmp (input, "MediumForestGreen", 17)) {
2830 	strncpy (input, ".419608 .556863 .137255\0", 24);
2831 	strcat (input, transp);
2832 	return;
2833     }
2834     if (!strncmp (input, "MediumGoldenrod", 15)) {
2835 	strncpy (input, ".917647 .917647 .678431\0", 24);
2836 	strcat (input, transp);
2837 	return;
2838     }
2839     if (!strncmp (input, "MediumOrchid", 12)) {
2840 	strncpy (input, ".576471 .439216 .858824\0", 24);
2841 	strcat (input, transp);
2842 	return;
2843     }
2844     if (!strncmp (input, "MediumSeaGreen", 14)) {
2845 	strncpy (input, ".258824 .435294 .258824\0", 24);
2846 	strcat (input, transp);
2847 	return;
2848     }
2849     if (!strncmp (input, "MediumSlateBlue", 15)) {
2850 	strncpy (input, ".498039 0.  1.0\0", 24);
2851 	strcat (input, transp);
2852 	return;
2853     }
2854     if (!strncmp (input, "MediumSpringGreen", 17)) {
2855 	strncpy (input, ".498039 1.0 0\0", 24);
2856 	strcat (input, transp);
2857 	return;
2858     }
2859     if (!strncmp (input, "MediumTurquoise", 15)) {
2860 	strncpy (input, ".439216 .858824 .858824\0", 24);
2861 	strcat (input, transp);
2862 	return;
2863     }
2864     if (!strncmp (input, "MediumVioletRed", 15)) {
2865 	strncpy (input, ".858824 .439216 .576471\0", 24);
2866 	strcat (input, transp);
2867 	return;
2868     }
2869     if (!strncmp (input, "MidnightBlue", 12)) {
2870 	strncpy (input, ".184314 .184314 .309804\0", 24);
2871 	strcat (input, transp);
2872 	return;
2873     }
2874     if (!strncmp (input, "NavyBlue", 8)) {
2875 	strncpy (input, ".137255 .137255 .556863\0", 24);
2876 	strcat (input, transp);
2877 	return;
2878     }
2879     if (!strncmp (input, "Navy", 4)) {
2880 	strncpy (input, ".137255 .137255 .556863\0", 24);
2881 	strcat (input, transp);
2882 	return;
2883     }
2884     if (!strncmp (input, "OrangeRed", 9)) {
2885 	strncpy (input, "1.0 .498039 0.0\0", 24);
2886 	strcat (input, transp);
2887 	return;
2888     }
2889     if (!strncmp (input, "Orange", 6)) {
2890 	strncpy (input, "1 .5 .0\0", 24);
2891 	strcat (input, transp);
2892 	return;
2893     }
2894     if (!strncmp (input, "Orchid", 6)) {
2895 	strncpy (input, ".858824 .439216 .858824\0", 24);
2896 	strcat (input, transp);
2897 	return;
2898     }
2899     if (!strncmp (input, "PaleGreen", 9)) {
2900 	strncpy (input, ".560784 .737255 .560784\0", 24);
2901 	strcat (input, transp);
2902 	return;
2903     }
2904     if (!strncmp (input, "Pink", 4)) {
2905 	strncpy (input, ".737255 .560784 .560784\0", 24);
2906 	strcat (input, transp);
2907 	return;
2908     }
2909     if (!strncmp (input, "Plum", 4)) {
2910 	strncpy (input, ".917647 .678431 .917647\0", 24);
2911 	strcat (input, transp);
2912 	return;
2913     }
2914     if (!strncmp (input, "Red", 3)) {
2915 	strncpy (input, "1 0 0\0", 6);
2916 	strcat (input, transp);
2917 	return;
2918     }
2919     if (!strncmp (input, "RichBlue", 8)) {
2920 	strncpy (input, ".35 .35 .67\0", 12);
2921 	strcat (input, transp);
2922 	return;
2923     }
2924     if (!strncmp (input, "Salmon", 6)) {
2925 	strncpy (input, ".435294 .258824 .258824\0", 24);
2926 	strcat (input, transp);
2927 	return;
2928     }
2929     if (!strncmp (input, "SeaGreen", 8)) {
2930 	strncpy (input, ".137255 .556863 .419608\0", 24);
2931 	strcat (input, transp);
2932 	return;
2933     }
2934     if (!strncmp (input, "Sienna", 6)) {
2935 	strncpy (input, ".556863 .419608 .137255\0", 24);
2936 	strcat (input, transp);
2937 	return;
2938     }
2939     if (!strncmp (input, "SkyBlue", 7)) {
2940 	strncpy (input, ".196078 .6 .8\0", 14);
2941 	strcat (input, transp);
2942 	return;
2943     }
2944     if (!strncmp (input, "SlateBlue", 9)) {
2945 	strncpy (input, "0 .498039 1\0", 12);
2946 	strcat (input, transp);
2947 	return;
2948     }
2949     if (!strncmp (input, "SpringGreen", 11)) {
2950 	strncpy (input, "0 1 .498039\0", 12);
2951 	strcat (input, transp);
2952 	return;
2953     }
2954     if (!strncmp (input, "SteelBlue", 9)) {
2955 	strncpy (input, ".137255 .419608 .556863\0", 24);
2956 	strcat (input, transp);
2957 	return;
2958     }
2959     if (!strncmp (input, "SummerSky", 9)) {
2960 	strncpy (input, ".22 .69 .87\0", 12);
2961 	strcat (input, transp);
2962 	return;
2963     }
2964     if (!strncmp (input, "Tan", 3)) {
2965 	strncpy (input, ".858824 .576471 .439216\0", 24);
2966 	strcat (input, transp);
2967 	return;
2968     }
2969     if (!strncmp (input, "Thistle", 7)) {
2970 	strncpy (input, ".847059 .74902 .847059\0", 23);
2971 	strcat (input, transp);
2972 	return;
2973     }
2974     if (!strncmp (input, "Turquoise", 9)) {
2975 	strncpy (input, ".678431 .917647 .917647\0", 24);
2976 	strcat (input, transp);
2977 	return;
2978     }
2979     if (!strncmp (input, "VioletRed", 9)) {
2980 	strncpy (input, ".8 .196078 .6\0", 14);
2981 	strcat (input, transp);
2982 	return;
2983     }
2984     if (!strncmp (input, "Violet", 6)) {
2985 	strncpy (input, ".309804 .184314 .309804\0", 24);
2986 	strcat (input, transp);
2987 	return;
2988     }
2989     if (!strncmp (input, "VLightGray", 10)) {
2990 	strncpy (input, ".8 .8 .8\0", 9);
2991 	strcat (input, transp);
2992 	return;
2993     }
2994     if (!strncmp (input, "VLightGrey", 10)) {
2995 	strncpy (input, ".8 .8 .8\0", 9);
2996 	strcat (input, transp);
2997 	return;
2998     }
2999     if (!strncmp (input, "Wheat", 5)) {
3000 	strncpy (input, ".847059 .847059 .74902\0", 23);
3001 	strcat (input, transp);
3002 	return;
3003     }
3004     if (!strncmp (input, "Silver", 6)) {
3005 	strncpy (input, ".90 .91 .98\0", 12);
3006 	strcat (input, transp);
3007 	return;
3008     }
3009     if (!strncmp (input, "BrightGold", 10)) {
3010 	strncpy (input, ".85 .85 .10\0", 12);
3011 	strcat (input, transp);
3012 	return;
3013     }
3014     if (!strncmp (input, "OldGold", 7)) {
3015 	strncpy (input, ".81 .71 .23\0", 12);
3016 	strcat (input, transp);
3017 	return;
3018     }
3019     if (!strncmp (input, "Feldspar", 8)) {
3020 	strncpy (input, ".82 .57 .46\0", 12);
3021 	strcat (input, transp);
3022 	return;
3023     }
3024     if (!strncmp (input, "Quartz", 6)) {
3025 	strncpy (input, ".85 .85 .95\0", 12);
3026 	strcat (input, transp);
3027 	return;
3028     }
3029     if (!strncmp (input, "Mica", 4)) {
3030 	strncpy (input, "0 0 0\0", 6);
3031 	strcat (input, transp);
3032 	return;
3033     }
3034     if (!strncmp (input, "NeonPink", 8)) {
3035 	strncpy (input, "1 .43 .78\0", 10);
3036 	strcat (input, transp);
3037 	return;
3038     }
3039     if (!strncmp (input, "DarkPurple", 10)) {
3040 	strncpy (input, ".53 .12 .47\0", 12);
3041 	strcat (input, transp);
3042 	return;
3043     }
3044     if (!strncmp (input, "NeonBlue", 8)) {
3045 	strncpy (input, ".3 .3 1\0", 8);
3046 	strcat (input, transp);
3047 	return;
3048     }
3049     if (!strncmp (input, "CoolCopper", 10)) {
3050 	strncpy (input, ".85 .53 .10\0", 12);
3051 	strcat (input, transp);
3052 	return;
3053     }
3054     if (!strncmp (input, "MandarinOrange", 14)) {
3055 	strncpy (input, ".89 .47 .20\0", 12);
3056 	strcat (input, transp);
3057 	return;
3058     }
3059     if (!strncmp (input, "LightWood", 9)) {
3060 	strncpy (input, ".91 .76 .65\0", 12);
3061 	strcat (input, transp);
3062 	return;
3063     }
3064     if (!strncmp (input, "MediumWood", 10)) {
3065 	strncpy (input, ".65 .50 .39\0", 12);
3066 	strcat (input, transp);
3067 	return;
3068     }
3069     if (!strncmp (input, "DarkWood", 8)) {
3070 	strncpy (input, ".52 .37 .26\0", 12);
3071 	strcat (input, transp);
3072 	return;
3073     }
3074     if (!strncmp (input, "SpicyPink", 9)) {
3075 	strncpy (input, "1 .11 .68\0", 10);
3076 	strcat (input, transp);
3077 	return;
3078     }
3079     if (!strncmp (input, "SemiSweetChoc", 13)) {
3080 	strncpy (input, ".42 .26 .15\0", 12);
3081 	strcat (input, transp);
3082 	return;
3083     }
3084     if (!strncmp (input, "BakersChoc", 10)) {
3085 	strncpy (input, ".36 .20 .09\0", 12);
3086 	strcat (input, transp);
3087 	return;
3088     }
3089     if (!strncmp (input, "Flesh", 5)) {
3090 	strncpy (input, ".96 .80 .69\0", 12);
3091 	strcat (input, transp);
3092 	return;
3093     }
3094     if (!strncmp (input, "NewTan", 6)) {
3095 	strncpy (input, ".92 .78 .62\0", 12);
3096 	strcat (input, transp);
3097 	return;
3098     }
3099     if (!strncmp (input, "NewMidnightBlue", 15)) {
3100 	strncpy (input, "0 0 .61\0", 8);
3101 	strcat (input, transp);
3102 	return;
3103     }
3104     if (!strncmp (input, "VeryDarkBrown", 13)) {
3105 	strncpy (input, ".35 .16 .14\0", 12);
3106 	strcat (input, transp);
3107 	return;
3108     }
3109     if (!strncmp (input, "DarkBrown", 9)) {
3110 	strncpy (input, ".36 .25 .20\0", 12);
3111 	strcat (input, transp);
3112 	return;
3113     }
3114     if (!strncmp (input, "DarkTan", 7)) {
3115 	strncpy (input, ".59 .41 .31\0", 12);
3116 	strcat (input, transp);
3117 	return;
3118     }
3119     if (!strncmp (input, "GreenCopper", 11)) {
3120 	strncpy (input, ".32 .49 .46\0", 12);
3121 	strcat (input, transp);
3122 	return;
3123     }
3124     if (!strncmp (input, "DkGreenCopper", 13)) {
3125 	strncpy (input, ".29 .46 .43\0", 12);
3126 	strcat (input, transp);
3127 	return;
3128     }
3129     if (!strncmp (input, "DustyRose", 9)) {
3130 	strncpy (input, ".52 .39 .39\0", 12);
3131 	strcat (input, transp);
3132 	return;
3133     }
3134     if (!strncmp (input, "HuntersGreen", 12)) {
3135 	strncpy (input, ".13 .37 .31\0", 12);
3136 	strcat (input, transp);
3137 	return;
3138     }
3139     if (!strncmp (input, "Scarlet", 7)) {
3140 	strncpy (input, ".55 .09 .09\0", 12);
3141 	strcat (input, transp);
3142 	return;
3143     }
3144     if (!strncmp (input, "Med_Purple", 10)) {
3145 	strncpy (input, ".73 .16 .96\0", 12);
3146 	strcat (input, transp);
3147 	return;
3148     }
3149     if (!strncmp (input, "White", 5)) {
3150 	strncpy (input, "1 1 1\0", 6);
3151 	strcat (input, transp);
3152 	return;
3153     }
3154     if (!strncmp (input, "Very_Light_Purple", 17)) {
3155 	strncpy (input, ".94 .81 .99\0", 12);
3156 	strcat (input, transp);
3157 	return;
3158     }
3159     if (!strncmp (input, "YellowGreen", 11)) {
3160 	strncpy (input, ".6 .8 .196078\0", 14);
3161 	strcat (input, transp);
3162 	return;
3163     }
3164     if (!strncmp (input, "Yellow", 6)) {
3165 	strncpy (input, "1 1 0\0", 6);
3166 	strcat (input, transp);
3167 	return;
3168     }
3169 
3170 /* try to find it in colors.inc, if povray options include +L path or if POV_Include is non-blank */
3171     colinc = NULL;
3172     if (strlen (drvui->POV_Include) > 10) {
3173 	colinc = fopen (drvui->POV_Include, "r");
3174     }
3175     if (!colinc) {
3176 	strncpy (b, drvui->POV_Options, 29);
3177 	b[29] = '\0';
3178 	a = strstr (b, "+L");
3179 	if (a != NULL) {
3180 	    sscanf (a + 2, "%s", POV_incpath);
3181 	    if (POV_incpath != NULL) {
3182 		strcat (POV_incpath, "/colors.inc");
3183 		colinc = fopen (POV_incpath, "r");
3184 		if (colinc) {
3185 		    strcpy (drvui->POV_Include, POV_incpath);
3186 		    WriteConfig ();
3187 		}
3188 	    }
3189 	}
3190     }
3191     if (colinc != NULL) {
3192 	if (transp_start != NULL)
3193 	    *(transp_start - 1) = '\0';
3194 	while (!feof (colinc)) {
3195 	    if (fgets (line, 80, colinc) == NULL)
3196 		continue;
3197 	    sscanf (line, "%s %s = color red %f green %f blue %f", keyword, thecolor,
3198 		    &thered, &thegreen, &theblue);
3199 	    if (strcmp (keyword, "#declare"))
3200 		continue;
3201 	    if (!strcmp (thecolor, input)) {
3202 		snprintf (input, 30, "%3.2f %3.2f %3.2f%c", thered, thegreen, theblue, 0);
3203 		if (transp_start == NULL) {
3204 		    transp[0] = '\0';
3205 		    transp_start = strstr (line, "filter");
3206 		    if (transp_start != NULL) {
3207 			fval = (float) atof (transp_start + 6);
3208 			sprintf (transp, " transparency %5.2f", fval / 2.);
3209 		    }
3210 		}
3211 		strcat (input, transp);
3212 		fclose (colinc);
3213 		return;
3214 	    }
3215 	}
3216 	fclose (colinc);
3217     }
3218 
3219     if (Color_Warning <= 5) {
3220 	char string[256];
3221 
3222 	sprintf (string, " **** Warning - Non-standard color \"%s\" encountered. ****",
3223 		 input);
3224 	Error_Box (string);
3225 	Color_Warning++;
3226     }
3227 
3228     if (sscanf (input, " %f %f %f", &thered, &thegreen, &theblue) < 3) {
3229 	strcpy (input, "1. 1. 1.");	// substitute White if no color triplet
3230     } else {
3231 	snprintf (input, 30, "%3.2f %3.2f %3.2f%c", thered, thegreen, theblue, 0);
3232 	strcat (input, transp);
3233     }
3234 }
3235 
3236 /* ************************************************************** */
3237 /* ************************************************************** */
3238 
3239 void
trim_string(char string[],int len)3240 trim_string (char string[], int len)
3241 {
3242 // trim string - remove trailing ^J (Windows) and spaces. 'len' is maximum length
3243     int i;
3244 
3245     string[len - 1] = 0;
3246     if (strlen (string) == 0) {
3247 //        strcpy(string,"White");
3248 	return;
3249     }
3250     for (i = 0; i < (int) strlen (string); i++) {
3251 	if ((unsigned char) string[i] < ' ') {
3252 	    string[i] = 0;
3253 	    break;
3254 	}
3255     }
3256     for (i = strlen (string); i > 0; --i) {
3257 	if (string[i - 1] <= ' ') {
3258 	    string[i - 1] = 0;
3259 	} else
3260 	    break;
3261     }
3262 }
3263 
3264 /* ************************************************************** */
3265 /* ************************************************************** */
3266 
3267 int
Unique_Atom(void)3268 Unique_Atom (void)
3269 // routine to check if atom at position 'natom' is unique. Returns 1 if it
3270 //   is. If the position is a duplicate, returns 0.
3271 {
3272     int j, k, test;
3273 
3274     for (k = 0; k < natom - 1; k++) {	/* loop through atoms */
3275 	if (drvui->atoms[k].atom_fn != drvui->frame_no)
3276 	    continue;
3277 	if (drvui->atoms[k].atom_n == drvui->atoms[natom].atom_n) {
3278 	    test = 0;
3279 	    for (j = 0; j < 4; j++) {
3280 		if (drvui->atoms[k].atom_l[j] != drvui->atoms[natom].atom_l[j])
3281 		    test = 1;
3282 	    }
3283 	    if (!test) {	/* name and number the same - check coordinates */
3284 		expand_atom (natom);	/* find all of test atoms in unit cell */
3285 		for (j = 0; j < ncell; j++) {
3286 		    if ((fabs (drvui->atoms[k].atom_xyz[1] - drvui->cell_xyz[j][1]) <
3287 			 0.0001)
3288 			&& (fabs (drvui->atoms[k].atom_xyz[2] - drvui->cell_xyz[j][2]) <
3289 			    0.0001)
3290 			&& (fabs (drvui->atoms[k].atom_xyz[0] - drvui->cell_xyz[j][0]) <
3291 			    0.0001))
3292 			return (0);	/* duplicate */
3293 		}
3294 	    }
3295 	}
3296     }
3297     return (1);			/* unique */
3298 }
3299 
3300 /* ************************************************************** */
3301 /* ************************************************************** */
3302 
3303 int
vec_dif(int n1,float v1[3],int n2,float v2[3],int n3,float v3[3],float v[3])3304 vec_dif (int n1, float v1[3], int n2, float v2[3], int n3, float v3[3], float v[3])
3305 {
3306 /* routine to determine if vector v == n1*v1+n2*v2+n3*v3, returns 1 if equal, 0 if not */
3307     int i;
3308 
3309     float d[3];
3310 
3311     for (i = 0; i < 3; i++)
3312 	d[i] = v[i] - n1 * v1[i] - n2 * v2[i] - n3 * v3[i];
3313     return d[0] * d[0] + d[1] * d[1] + d[2] * d[2] < 1.0e-4 ? 1 : 0;
3314 }
3315