ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/ranimove.c
Revision: 3.9
Committed: Tue Oct 21 19:19:29 2003 UTC (20 years, 6 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.8: +3 -1 lines
Log Message:
Various platform compatibility fixes.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id";
3 #endif
4 /*
5 * Radiance object animation program
6 *
7 * Main program and control file handling.
8 *
9 * See ranimove.h and the ranimove(1) man page for details.
10 */
11
12 #include "copyright.h"
13
14 #include <time.h>
15 #ifdef _WIN32
16 #include <winsock.h> /* struct timeval. XXX find a replacement? */
17 #else
18 #include <sys/time.h>
19 #endif
20 #include <ctype.h>
21 #include <string.h>
22
23 #include "paths.h"
24 #include "ranimove.h"
25
26 int NVARS = NV_INIT; /* total number of variables */
27
28 VARIABLE vv[] = VV_INIT; /* variable-value pairs */
29
30 extern int nowarn; /* don't report warnings? */
31 int silent = 0; /* run silently? */
32
33 int quickstart = 0; /* time initial frame as well? */
34
35 int nprocs = 1; /* number of rendering processes */
36
37 int rtperfrm = 60; /* seconds to spend per frame */
38
39 double ndthresh = 2.; /* noticeable difference threshold */
40 int ndtset = 0; /* user threshold -- stop when reached? */
41
42 int fbeg = 1; /* starting frame */
43 int fend = 0; /* ending frame */
44 int fcur; /* current frame being rendered */
45
46 char lorendoptf[32]; /* low quality options file */
47 RAYPARAMS lorendparams; /* low quality rendering parameters */
48 char hirendoptf[32]; /* high quality options file */
49 RAYPARAMS hirendparams; /* high quality rendering parameters */
50 RAYPARAMS *curparams; /* current parameter settings */
51 int twolevels; /* low and high quality differ */
52
53 double mblur; /* vflt(MBLUR) */
54 double rate; /* vflt(RATE) */
55
56 char objtmpf[32]; /* object temporary file */
57
58 struct ObjMove *obj_move; /* object movements */
59
60 int haveprio = 0; /* high-level saliency specified */
61
62 int gargc; /* global argc for printargs */
63 char **gargv; /* global argv for printargs */
64
65
66 int
67 main(argc, argv)
68 int argc;
69 char *argv[];
70 {
71 int explicate = 0;
72 char *cfname;
73 int i;
74
75 progname = argv[0]; /* get arguments */
76 gargc = argc;
77 gargv = argv;
78 for (i = 1; i < argc && argv[i][0] == '-'; i++)
79 switch (argv[i][1]) {
80 case 't': /* seconds per frame */
81 rtperfrm = atoi(argv[++i]);
82 break;
83 case 'd': /* noticeable difference */
84 ndthresh = atof(argv[++i]);
85 ndtset = 1;
86 break;
87 case 'e': /* print variables */
88 explicate++;
89 break;
90 case 's': /* silent running */
91 silent++;
92 break;
93 case 'q': /* start quickly */
94 quickstart++;
95 break;
96 case 'w': /* turn off warnings */
97 nowarn++;
98 break;
99 case 'f': /* frame range */
100 switch (sscanf(argv[++i], "%d,%d", &fbeg, &fend)) {
101 case 2:
102 if ((fbeg <= 0) | (fend < fbeg))
103 goto userr;
104 break;
105 case 1:
106 if (fbeg <= 0)
107 goto userr;
108 fend = 0;
109 break;
110 default:
111 goto userr;
112 }
113 break;
114 case 'n': /* number of processes */
115 nprocs = atoi(argv[++i]);
116 break;
117 default:
118 goto userr;
119 }
120 if (rtperfrm <= 0) {
121 if (!ndtset)
122 error(USER, "specify -d jnd with -t 0");
123 rtperfrm = 7*24*3600;
124 }
125 if (i != argc-1)
126 goto userr;
127 cfname = argv[i];
128 /* load variables */
129 loadvars(cfname);
130 /* check variables */
131 checkvalues();
132 /* load RIF if any */
133 if (vdef(RIF))
134 getradfile(vval(RIF));
135 /* set defaults */
136 setdefaults();
137 /* print variables */
138 if (explicate)
139 printvars(stdout);
140 /* run animation */
141 if (nprocs > 0)
142 animate();
143 /* all done */
144 if (lorendoptf[0])
145 unlink(lorendoptf);
146 if (hirendoptf[0] && strcmp(hirendoptf, lorendoptf))
147 unlink(hirendoptf);
148 if (objtmpf[0])
149 unlink(objtmpf);
150 return(0);
151 userr:
152 fprintf(stderr,
153 "Usage: %s [-n nprocs][-f beg,end][-t sec][-d jnd][-s][-w][-e] anim_file\n",
154 progname);
155 quit(1);
156 }
157
158
159 void
160 eputs(s) /* put string to stderr */
161 register char *s;
162 {
163 static int midline = 0;
164
165 if (!*s)
166 return;
167 if (!midline++) {
168 fputs(progname, stderr);
169 fputs(": ", stderr);
170 }
171 fputs(s, stderr);
172 if (s[strlen(s)-1] == '\n') {
173 fflush(stderr);
174 midline = 0;
175 }
176 }
177
178
179 void
180 setdefaults() /* set default values */
181 {
182 int nviews;
183 int decades;
184 char buf[256];
185 int i;
186
187 if (!vdef(OCTREEF)) {
188 sprintf(errmsg, "%s or %s must be defined",
189 vnam(OCTREEF), vnam(RIF));
190 error(USER, errmsg);
191 }
192 if (!vdef(VIEWFILE)) {
193 sprintf(errmsg, "%s must be defined", vnam(VIEWFILE));
194 error(USER, errmsg);
195 }
196 nviews = countviews();
197 if (!nviews)
198 error(USER, "no views in view file");
199 if (!vdef(END)) {
200 if (nviews == 1) {
201 sprintf(errmsg, "%s must be defined for single view",
202 vnam(END));
203 error(USER, errmsg);
204 }
205 sprintf(buf, "%d", nviews);
206 vval(END) = savqstr(buf);
207 vdef(END)++;
208 }
209 if (!fend)
210 fend = vint(END);
211 if (fbeg > fend)
212 error(USER, "begin after end");
213 if (!vdef(BASENAME)) {
214 decades = (int)log10((double)vint(END)) + 1;
215 if (decades < 3) decades = 3;
216 sprintf(buf, "frame%%0%dd", decades);
217 vval(BASENAME) = savqstr(buf);
218 vdef(BASENAME)++;
219 }
220 if (!vdef(RATE)) {
221 vval(RATE) = "8";
222 vdef(RATE)++;
223 }
224 rate = vflt(RATE);
225 if (!vdef(RESOLUTION)) {
226 vval(RESOLUTION) = "640";
227 vdef(RESOLUTION)++;
228 }
229 if (!vdef(MBLUR)) {
230 vval(MBLUR) = "0";
231 vdef(MBLUR)++;
232 }
233 mblur = vflt(MBLUR);
234 if (mblur > 1.)
235 mblur = 1.;
236 /* set up objects */
237 if (vdef(MOVE)) {
238 obj_move = (struct ObjMove *)malloc(
239 sizeof(struct ObjMove)*vdef(MOVE) );
240 if (obj_move == NULL)
241 error(SYSTEM, "out of memory in setdefaults");
242 for (i = 0; i < vdef(MOVE); i++)
243 setmove(&obj_move[i], nvalue(MOVE, i));
244 }
245 /* set up high quality options */
246 setrendparams(hirendoptf, vval(HIGHQ));
247 ray_save(&hirendparams);
248 /* set up low quality options */
249 setrendparams(lorendoptf, vval(LOWQ));
250 ray_save(&lorendparams);
251 curparams = &lorendparams;
252 twolevels = memcmp(&lorendparams, &hirendparams, sizeof(RAYPARAMS));
253 }
254
255
256 void
257 setmove(om, ms) /* assign a move object from spec. */
258 struct ObjMove *om;
259 char *ms;
260 {
261 char parname[128];
262 char *cp;
263
264 ms = nextword(parname, sizeof(parname), ms);
265 if (!parname[0])
266 goto badspec;
267 for (cp = parname; *cp; cp++)
268 if (isspace(*cp))
269 *cp = '_';
270 for (om->parent = (om - obj_move); om->parent--; )
271 if (!strcmp(parname, obj_move[om->parent].name))
272 break;
273 if (om->parent < 0 &&
274 strcmp(parname, ".") && strcmp(parname, VOIDID)) {
275 sprintf(errmsg, "undefined parent object '%s'", parname);
276 error(USER, errmsg);
277 }
278 ms = nextword(om->name, sizeof(om->name), ms);
279 if (!om->name[0])
280 goto badspec;
281 for (cp = om->name; *cp; cp++)
282 if (isspace(*cp))
283 *cp = '_';
284 ms = nextword(om->xf_file, sizeof(om->xf_file), ms);
285 if (!strcmp(om->xf_file, "."))
286 om->xf_file[0] = '\0';
287 if (!om->xf_file[0]) {
288 om->xfs[0] = '\0';
289 } else if (om->xf_file[0] == '-') {
290 strcpy(om->xfs, om->xf_file);
291 om->xf_file[0] = '\0';
292 }
293 ms = nextword(om->spec, sizeof(om->spec), ms);
294 if (om->spec[0]) {
295 if (!strcmp(om->spec, ".") || !strcmp(om->spec, VOIDID))
296 om->spec[0] = '\0';
297 ms = nextword(om->prio_file, sizeof(om->prio_file), ms);
298 } else
299 om->prio_file[0] = '\0';
300 if (om->prio_file[0]) {
301 if (isflt(om->prio_file)) {
302 om->prio = atof(om->prio_file);
303 om->prio_file[0] = '\0';
304 haveprio |= ((om->prio < 0.95) | (om->prio > 1.05));
305 } else
306 haveprio = 1;
307 } else
308 om->prio = 1.;
309 om->cfm = -1;
310 return;
311 badspec:
312 error(USER, "bad object specification");
313 }
314
315
316 void
317 setrendparams(optf, qval) /* set global rendering parameters */
318 char *optf;
319 char *qval;
320 {
321 char *argv[1024];
322 char **av = argv;
323 int ac, i, rval;
324
325 av[ac=0] = NULL;
326 /* load options from file, first */
327 if (optf != NULL && *optf) {
328 ac = wordfile(av, optf);
329 if (ac < 0) {
330 sprintf(errmsg, "cannot load options file \"%s\"",
331 optf);
332 error(SYSTEM, errmsg);
333 }
334 }
335 /* then from options string */
336 if (qval != NULL && qval[0] == '-')
337 ac += wordstring(av+ac, qval);
338
339 /* restore default parameters */
340 ray_restore(NULL);
341 /* set what we have */
342 for (i = 0; i < ac; i++) {
343 while ((rval = expandarg(&ac, &av, i)) > 0)
344 ;
345 if (rval < 0) {
346 sprintf(errmsg, "cannot expand '%s'", av[i]);
347 error(SYSTEM, errmsg);
348 }
349 if (!strcmp(av[i], "-w")) {
350 nowarn++;
351 continue;
352 }
353 rval = getrenderopt(ac-i, av+i);
354 if (rval < 0) {
355 sprintf(errmsg, "bad render option at '%s'", av[i]);
356 error(USER, errmsg);
357 }
358 i += rval;
359 }
360 }
361
362
363 void
364 getradfile(rfargs) /* run rad and get needed variables */
365 char *rfargs;
366 {
367 static short mvar[] = {OCONV,OCTREEF,RESOLUTION,EXPOSURE,-1};
368 char combuf[256];
369 register int i;
370 register char *cp;
371 char *pippt;
372 /* create rad command */
373 strcpy(lorendoptf, "ranim0.opt");
374 sprintf(combuf,
375 "rad -v 0 -s -e -w %s %s oconv=-f OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
376 rfargs,
377 (vdef(LOWQ) && vval(LOWQ)[0]!='-') ? vval(LOWQ) : "",
378 lorendoptf);
379 cp = combuf;
380 while (*cp) {
381 if (*cp == '|') pippt = cp;
382 cp++;
383 } /* match unset variables */
384 for (i = 0; mvar[i] >= 0; i++)
385 if (!vdef(mvar[i])) {
386 *cp++ = '|';
387 strcpy(cp, vnam(mvar[i]));
388 while (*cp) cp++;
389 pippt = NULL;
390 }
391 if (pippt != NULL)
392 strcpy(pippt, "> " NULL_DEVICE); /* nothing to match */
393 else {
394 strcpy(cp, ")[ \t]*=' > ranimove.var");
395 cp += 11; /* point to file name */
396 }
397 system(combuf); /* ignore exit code */
398 if (pippt == NULL) { /* load variables and remove file */
399 loadvars(cp);
400 unlink(cp);
401 }
402 if (!vdef(HIGHQ) || vval(HIGHQ)[0]=='-') {
403 strcpy(hirendoptf, lorendoptf);
404 return;
405 }
406 /* get high quality options */
407 strcpy(hirendoptf, "ranim1.opt");
408 sprintf(combuf, "rad -v 0 -s -w %s %s OPTFILE=%s",
409 rfargs, vval(HIGHQ), hirendoptf);
410 system(combuf);
411 }
412
413
414 void
415 animate() /* run through animation */
416 {
417 int rpass;
418
419 if (fbeg > 1) /* synchronize transforms */
420 getoctspec(fbeg-1);
421
422 for (fcur = fbeg; fcur <= fend; fcur++) {
423 if (!silent)
424 printf("Frame %d:\n", fcur);
425 /* base rendering */
426 init_frame();
427 /* refinement */
428 for (rpass = 0; refine_frame(rpass); rpass++)
429 ;
430 /* final filter pass */
431 filter_frame();
432 /* output frame */
433 send_frame();
434 }
435 /* free resources */
436 free_frame();
437 if (nprocs > 1)
438 ray_pdone(1);
439 else
440 ray_done(1);
441 getview(0);
442 getexp(0);
443 }
444
445
446 VIEW *
447 getview(n) /* get view number n */
448 int n;
449 {
450 static FILE *viewfp = NULL; /* view file pointer */
451 static int viewnum = 0; /* current view number */
452 static VIEW curview = STDVIEW; /* current view */
453 char linebuf[256];
454
455 if (n == 0) { /* signal to close file and clean up */
456 if (viewfp != NULL) {
457 fclose(viewfp);
458 viewfp = NULL;
459 viewnum = 0;
460 curview = stdview;
461 }
462 return(NULL);
463 }
464 if (viewfp == NULL) { /* open file */
465 if ((viewfp = fopen(vval(VIEWFILE), "r")) == NULL) {
466 perror(vval(VIEWFILE));
467 quit(1);
468 }
469 } else if (n > 0 && n < viewnum) { /* rewind file */
470 if (viewnum == 1 && feof(viewfp))
471 return(&curview); /* just one view */
472 if (fseek(viewfp, 0L, 0) == EOF) {
473 perror(vval(VIEWFILE));
474 quit(1);
475 }
476 curview = stdview;
477 viewnum = 0;
478 }
479 if (n < 0) { /* get next view */
480 register int c = getc(viewfp);
481 if (c == EOF)
482 return(NULL); /* that's it */
483 ungetc(c, viewfp);
484 n = viewnum + 1;
485 }
486 while (n > viewnum) { /* scan to desired view */
487 if (fgets(linebuf, sizeof(linebuf), viewfp) == NULL)
488 return(viewnum==1 ? &curview : (VIEW *)NULL);
489 if (isview(linebuf) && sscanview(&curview, linebuf) > 0)
490 viewnum++;
491 }
492 return(&curview); /* return it */
493 }
494
495
496 int
497 countviews() /* count views in view file */
498 {
499 int n;
500
501 if (getview(n=1) == NULL)
502 return(0);
503 while (getview(-1) != NULL)
504 n++;
505 return(n);
506 }
507
508
509 char *
510 getexp(n) /* get exposure for nth frame */
511 int n;
512 {
513 extern char *fskip();
514 static char expval[32];
515 static FILE *expfp = NULL;
516 static int curfrm = 0;
517 register char *cp;
518
519 if (n == 0) { /* signal to close file */
520 if (expfp != NULL) {
521 fclose(expfp);
522 expfp = NULL;
523 }
524 return(NULL);
525 }
526 if (!vdef(EXPOSURE)) /* no setting (auto) */
527 return(NULL);
528 if (isflt(vval(EXPOSURE))) /* always the same */
529 return(vval(EXPOSURE));
530 if (expfp == NULL) { /* open exposure file */
531 if ((expfp = fopen(vval(EXPOSURE), "r")) == NULL) {
532 sprintf(errmsg, "cannot open exposure file \"%s\"",
533 vval(EXPOSURE));
534 error(SYSTEM, errmsg);
535 }
536 curfrm = 0;
537 }
538 if (curfrm > n) { /* rewind if necessary */
539 rewind(expfp);
540 curfrm = 0;
541 }
542 while (n > curfrm) { /* read to line */
543 if (fgets(expval, sizeof(expval), expfp) == NULL) {
544 sprintf(errmsg, "%s: too few exposures",
545 vval(EXPOSURE));
546 error(USER, errmsg);
547 }
548 if (strlen(expval) == sizeof(expval)-1)
549 goto formerr;
550 curfrm++;
551 }
552 cp = fskip(expval); /* check format */
553 if (cp != NULL)
554 while (isspace(*cp))
555 *cp++ = '\0';
556 if (cp == NULL || *cp)
557 goto formerr;
558 return(expval); /* return value */
559 formerr:
560 sprintf(errmsg, "%s: exposure format error on line %d",
561 vval(EXPOSURE), curfrm);
562 error(USER, errmsg);
563 }
564
565
566 double
567 expspec_val(s) /* get exposure value from spec. */
568 char *s;
569 {
570 double expval;
571
572 if (s == NULL || !*s)
573 return(1.0);
574
575 expval = atof(s);
576 if ((s[0] == '+') | (s[0] == '-'))
577 return(pow(2.0, expval));
578 return(expval);
579 }
580
581
582 char *
583 getoctspec(n) /* get octree for the given frame */
584 int n;
585 {
586 static char combuf[1024];
587 int cfm = 0;
588 int uses_inline;
589 FILE *fp;
590 int i;
591 /* is octree static? */
592 if (!vdef(MOVE))
593 return(vval(OCTREEF));
594 /* done already */
595 if (n == cfm)
596 return(combuf);
597 /* else create object file */
598 strcpy(objtmpf, "movinobj.rad");
599 fp = fopen(objtmpf, "w");
600 if (fp == NULL) {
601 sprintf(errmsg, "cannot write to moving objects file '%s'",
602 objtmpf);
603 error(SYSTEM, errmsg);
604 }
605 uses_inline = 0;
606 for (i = 0; i < vdef(MOVE); i++) {
607 int inlc = (obj_move[i].spec[0] == '!');
608 if (!obj_move[i].spec[0])
609 continue;
610 if (inlc)
611 fprintf(fp, "%s %d \\\n\t| xform",
612 obj_move[i].spec, n);
613 else
614 fputs("!xform", fp);
615 fprintf(fp, " -n %s", getobjname(&obj_move[i]));
616 fputs(getxf(&obj_move[i], n), fp);
617 if (!inlc)
618 fprintf(fp, " %s\n", obj_move[i].spec);
619 else
620 fputc('\n', fp);
621 uses_inline |= inlc;
622 }
623 if (fclose(fp) == EOF)
624 error(SYSTEM, "error writing moving objects file");
625 if (uses_inline)
626 sprintf(combuf, "!oconv %s -f -i '%s' %s",
627 vdef(OCONV) ? vval(OCONV) : "",
628 vval(OCTREEF), objtmpf);
629 else
630 sprintf(combuf, "!xform -f %s | oconv -f -i '%s' -",
631 objtmpf, vval(OCTREEF));
632 return(combuf);
633 }
634
635
636 char *
637 getobjname(om) /* get fully qualified object name */
638 register struct ObjMove *om;
639 {
640 static char objName[512];
641 register char *cp = objName;
642
643 strcpy(cp, om->name);
644 while (om->parent >= 0) {
645 while (*cp) cp++;
646 *cp++ = '@';
647 om = &obj_move[om->parent];
648 strcpy(cp, om->name);
649 }
650 return(objName);
651 }
652
653
654 char *
655 getxf(om, n) /* get total transform for object */
656 register struct ObjMove *om;
657 int n;
658 {
659 static char xfsbuf[4096];
660 char *xfp;
661 int framestep = 0;
662 XF oxf;
663 FILE *fp;
664 char abuf[512];
665 char *av[64];
666 int ac;
667 int i;
668 register char *cp;
669 /* get parent transform, first */
670 if (om->parent >= 0)
671 xfp = getxf(&obj_move[om->parent], n);
672 else
673 *(xfp = xfsbuf + sizeof(xfsbuf)-1) = '\0';
674 /* get transform spec. & priority */
675 if (om->cfm != n) {
676 if (om->xf_file[0]) {
677 fp = fopen(om->xf_file, "r");
678 if (fp == NULL) {
679 sprintf(errmsg,
680 "cannot open transform file '%s'",
681 om->xf_file);
682 error(SYSTEM, errmsg);
683 }
684 for (i = 0; i < n; i++)
685 if (fgetline(om->xfs, sizeof(om->xfs), fp)
686 == NULL) {
687 sprintf(errmsg,
688 "too few transforms in file '%s'",
689 om->xf_file);
690 error(USER, errmsg);
691 }
692 fclose(fp);
693 }
694 strcpy(cp=abuf, om->xfs);
695 ac = 0;
696 for ( ; ; ) {
697 while (isspace(*cp))
698 *cp++ = '\0';
699 if (!*cp)
700 break;
701 av[ac++] = cp;
702 while (*++cp && !isspace(*cp))
703 ;
704 }
705 av[ac] = NULL;
706 if (xf(&oxf, ac, av) != ac ||
707 fabs(oxf.sca) <= FTINY) {
708 sprintf(errmsg, "bad transform args: %s",
709 om->xfs);
710 error(USER, errmsg);
711 }
712 copymat4(om->xfm, oxf.xfm);
713 if (om->prio_file[0]) {
714 fp = fopen(om->prio_file, "r");
715 if (fp == NULL) {
716 sprintf(errmsg,
717 "cannot open priority file '%s'",
718 om->prio_file);
719 error(SYSTEM, errmsg);
720 }
721 for (i = 0; i < n; i++)
722 if (fgets(abuf, sizeof(abuf), fp)
723 == NULL) {
724 sprintf(errmsg,
725 "too few priorities in file '%s'",
726 om->prio_file);
727 error(USER, errmsg);
728 }
729 fclose(fp);
730 cp = fskip(abuf);
731 if (cp != NULL)
732 while (isspace(*cp))
733 *cp++ = '\0';
734 if (cp == NULL || *cp) {
735 sprintf(errmsg,
736 "priority '%s' in file '%s' not a number",
737 abuf, om->prio_file);
738 error(USER, errmsg);
739 }
740 om->prio = atof(abuf);
741 }
742 framestep = (n == om->cfm + 1);
743 om->cfm = n;
744 }
745 /* prepend to parent transform */
746 if (om->xfs[0]) {
747 i = strlen(om->xfs);
748 if (xfp - i <= xfsbuf)
749 error(INTERNAL, "transform too long in getxf");
750 cp = om->xfs + i;
751 while (i--)
752 *--xfp = *--cp;
753 *--xfp = ' ';
754 }
755 if (framestep)
756 copymat4(oxf.xfm, om->cxfm);
757 if (om->parent >= 0) {
758 multmat4(om->cxfm, om->xfm, obj_move[om->parent].cxfm);
759 om->cprio = obj_move[om->parent].cprio * om->prio;
760 } else {
761 copymat4(om->cxfm, om->xfm);
762 om->cprio = om->prio;
763 }
764 /* XXX bxfm relies on call order */
765 if (framestep) {
766 if (invmat4(om->bxfm, om->cxfm))
767 multmat4(om->bxfm, om->bxfm, oxf.xfm);
768 else
769 setident4(om->bxfm);
770 }
771 /* all done */
772 return(xfp);
773 }
774
775
776 int
777 getmove(obj) /* find matching move object */
778 OBJECT obj;
779 {
780 static int lasti;
781 static OBJECT lasto = OVOID;
782 char *onm, *objnm;
783 int len, len2;
784 register int i;
785
786 if (obj == OVOID)
787 return(-1);
788 if (obj == lasto)
789 return(lasti);
790 /* look for matching object */
791 onm = objptr(obj)->oname;
792 for (i = vdef(MOVE); i--; ) {
793 objnm = obj_move[i].name;
794 len = strlen(objnm);
795 if (!strncmp(onm, objnm, len)) {
796 if ((obj_move[i].parent < 0) & (onm[len] == '.'))
797 break;
798 objnm = getobjname(&obj_move[i]) + len;
799 len2 = strlen(objnm);
800 if (!strncmp(onm+len, objnm, len2) && onm[len+len2] == '.')
801 break;
802 }
803 }
804 lasto = obj; /* cache what we found */
805 return(lasti = i);
806 }
807
808
809 double
810 obj_prio(obj) /* return priority for object */
811 OBJECT obj;
812 {
813 int moi;
814
815 if (obj == OVOID || (moi = getmove(obj)) < 0)
816 return(1.0);
817 return(obj_move[moi].cprio);
818 }
819
820
821 double
822 getTime() /* get current time (CPU or real) */
823 {
824 struct timeval time_now;
825 /* return CPU time if one process */
826 if (nprocs == 1)
827 return((double)clock()*(1.0/(double)CLOCKS_PER_SEC));
828 /* otherwise, return wall time */
829 gettimeofday(&time_now, NULL);
830 return((double)time_now.tv_sec + 1e-6*(double)time_now.tv_usec);
831 }