nirt.c

Go to the documentation of this file.
00001 /*                          N I R T . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1988-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup librt */
00023 
00024 /*@{*/
00025 /** @file nirt.c
00026  *  Routines to interface to nirt.
00027  *
00028  *  Functions -
00029  *      dgo_nirt_cmd          trace a single ray from current view
00030  *
00031  *  Author -
00032  *      Michael John Muuss
00033  *      Robert G. Parker
00034  *
00035  *  Source -
00036  *      SECAD/VLD Computing Consortium, Bldg 394
00037  *      The U. S. Army Ballistic Research Laboratory
00038  *      Aberdeen Proving Ground, Maryland  21005
00039  *
00040  *
00041  *  Description -
00042  *      This code was imported from MGED's/rtif.c and modified to work as part
00043  *      of the drawable geometry object.
00044  *
00045  */
00046 /*@}*/
00047 
00048 #ifndef lint
00049 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/nirt.c,v 14.16 2006/09/16 02:04:25 lbutler Exp $ (BRL)";
00050 #endif
00051 
00052 #include "common.h"
00053 
00054 #include <stdlib.h>
00055 #include <stdio.h>
00056 #ifdef HAVE_STRING_H
00057 #  include <string.h>
00058 #else
00059 #  include <strings.h>
00060 #endif
00061 #include <math.h>
00062 #include <signal.h>
00063 #ifdef HAVE_SYS_TIME_H
00064 #  include <sys/time.h>         /* For struct timeval */
00065 #endif
00066 #include <sys/stat.h>           /* for chmod() */
00067 #ifdef HAVE_FCNTL_H
00068 #  include <fcntl.h>
00069 #endif
00070 #ifdef HAVE_UNISTD_H
00071 #  include <unistd.h>
00072 #endif
00073 #ifdef HAVE_SYS_TYPES_H
00074 #  include <sys/types.h>
00075 #endif
00076 #ifdef HAVE_SYS_WAIT_H
00077 #  include <sys/wait.h>
00078 #endif
00079 
00080 #include "tcl.h"
00081 #include "machine.h"
00082 #include "cmd.h"                        /* includes bu.h */
00083 #include "vmath.h"
00084 #include "raytrace.h"
00085 #include "solid.h"
00086 #include "./qray.h"
00087 
00088 
00089 /* defined in qray.c */
00090 extern void dgo_qray_data_to_vlist(struct dg_obj *dgop, struct bn_vlblock *vbp, struct dg_qray_dataList *headp, fastf_t *dir, int do_overlaps);
00091 
00092 /* defined in dg_obj.c */
00093 extern int dgo_build_tops(Tcl_Interp *interp, struct solid *hsp, char **start, register char **end);
00094 extern void dgo_cvt_vlblock_to_solids(struct dg_obj *dgop, Tcl_Interp *interp, struct bn_vlblock *vbp, char *name, int copy);
00095 extern void dgo_pr_wait_status(Tcl_Interp *interp, int status);
00096 
00097 /*
00098  *                      F _ N I R T
00099  *
00100  *  Invoke nirt with the current view & stuff
00101  */
00102 int
00103 dgo_nirt_cmd(struct dg_obj      *dgop,
00104              struct view_obj    *vop,
00105              Tcl_Interp         *interp,
00106              int                argc,
00107              char               **argv)
00108 {
00109         register char **vp;
00110         FILE *fp_in;
00111         FILE *fp_out, *fp_err;
00112         int pid, rpid;
00113         int retcode;
00114 #ifndef _WIN32
00115         int pipe_in[2];
00116         int pipe_out[2];
00117         int pipe_err[2];
00118 #else
00119         HANDLE pipe_in[2],hSaveStdin,pipe_inDup;
00120         HANDLE pipe_out[2],hSaveStdout,pipe_outDup;
00121         HANDLE pipe_err[2],hSaveStderr,pipe_errDup;
00122         STARTUPINFO si;
00123         PROCESS_INFORMATION pi;
00124         SECURITY_ATTRIBUTES sa;
00125         char name[1024];
00126         char line1[2048];
00127 #endif
00128         int use_input_orig = 0;
00129         vect_t  center_model;
00130         vect_t dir;
00131         vect_t cml;
00132         register int i;
00133         register struct solid *sp;
00134         char line[RT_MAXLINE];
00135         char *val;
00136         struct bu_vls vls;
00137         struct bu_vls o_vls;
00138         struct bu_vls p_vls;
00139         struct bu_vls t_vls;
00140         struct bn_vlblock *vbp;
00141         struct dg_qray_dataList *ndlp;
00142         struct dg_qray_dataList HeadQRayData;
00143 
00144         vp = &dgop->dgo_rt_cmd[0];
00145         *vp++ = "nirt";
00146 
00147         /* swipe x, y, z off the end if present */
00148         if (argc > 3) {
00149                 if (sscanf(argv[argc-3], "%lf", &center_model[X]) == 1 &&
00150                     sscanf(argv[argc-2], "%lf", &center_model[Y]) == 1 &&
00151                     sscanf(argv[argc-1], "%lf", &center_model[Z]) == 1){
00152                         use_input_orig = 1;
00153                         argc -= 3;
00154                         VSCALE(center_model, center_model, dgop->dgo_wdbp->dbip->dbi_local2base);
00155                 }
00156         }
00157 
00158         /* Calculate point from which to fire ray */
00159         if (!use_input_orig) {
00160                 VSET(center_model, -vop->vo_center[MDX],
00161                      -vop->vo_center[MDY], -vop->vo_center[MDZ]);
00162         }
00163 
00164 #if 0
00165         if (mged_variables->mv_perspective_mode) {
00166                 point_t pt, eye;
00167 
00168                 /* get eye point */
00169                 VSET(pt, 0.0, 0.0, 1.0);
00170                 MAT4X3PNT(eye, vop->vo_view2model, pt);
00171                 VSCALE(eye, eye, base2local);
00172 
00173                 /* point passed in is actually the aim point */
00174                 VSCALE(cml, center_model, base2local);
00175                 VSUB2(dir, cml, eye);
00176                 VUNITIZE(dir);
00177 
00178                 /* copy eye point to cml (cml is used for the "xyz" command to nirt */
00179                 VMOVE(cml, eye);
00180         } else {
00181                 VSCALE(cml, center_model, base2local);
00182                 VMOVEN(dir, vop->vo_rotation + 8, 3);
00183                 VSCALE(dir, dir, -1.0);
00184         }
00185 #else
00186         VSCALE(cml, center_model, dgop->dgo_wdbp->dbip->dbi_base2local);
00187         VMOVEN(dir, vop->vo_rotation + 8, 3);
00188         VSCALE(dir, dir, -1.0);
00189 #endif
00190 
00191         bu_vls_init(&p_vls);
00192         bu_vls_printf(&p_vls, "xyz %lf %lf %lf;",
00193                 cml[X], cml[Y], cml[Z]);
00194         bu_vls_printf(&p_vls, "dir %lf %lf %lf; s",
00195                 dir[X], dir[Y], dir[Z]);
00196 
00197         i = 0;
00198         if (DG_QRAY_GRAPHICS(dgop)) {
00199 
00200                 *vp++ = "-e";
00201                 *vp++ = DG_QRAY_FORMAT_NULL;
00202 
00203                 /* first ray  ---- returns partitions */
00204                 *vp++ = "-e";
00205                 *vp++ = DG_QRAY_FORMAT_P;
00206 
00207                 /* ray start, direction, and 's' command */
00208                 *vp++ = "-e";
00209                 *vp++ = bu_vls_addr(&p_vls);
00210 
00211                 /* second ray  ---- returns overlaps */
00212                 *vp++ = "-e";
00213                 *vp++ = DG_QRAY_FORMAT_O;
00214 
00215                 /* ray start, direction, and 's' command */
00216                 *vp++ = "-e";
00217                 *vp++ = bu_vls_addr(&p_vls);
00218 
00219                 if (DG_QRAY_TEXT(dgop)) {
00220                         char *cp;
00221                         int count = 0;
00222 
00223                         bu_vls_init(&o_vls);
00224 
00225                         /* get 'r' format now; prepend its' format string with a newline */
00226                         val = bu_vls_addr(&dgop->dgo_qray_fmts[0].fmt);
00227 
00228                         /* find first '"' */
00229                         while(*val != '"' && *val != '\0')
00230                                 ++val;
00231 
00232                         if(*val == '\0')
00233                                 goto done;
00234                         else
00235                                 ++val;      /* skip first '"' */
00236 
00237                         /* find last '"' */
00238                         cp = (char *)strrchr(val, '"');
00239 
00240                         if (cp != (char *)NULL) /* found it */
00241                                 count = cp - val;
00242 
00243 done:
00244                         if(*val == '\0')
00245                             bu_vls_printf(&o_vls, " fmt r \"\\n\" ");
00246                         else{
00247                             bu_vls_printf(&o_vls, " fmt r \"\\n%*s\" ", count, val);
00248 
00249                             if (count)
00250                                 val += count + 1;
00251                             bu_vls_printf(&o_vls, "%s", val);
00252                         }
00253 
00254                         i = 1;
00255 
00256                         *vp++ = "-e";
00257                         *vp++ = bu_vls_addr(&o_vls);
00258                 }
00259         }
00260 
00261         if (DG_QRAY_TEXT(dgop)) {
00262 
00263                 bu_vls_init(&t_vls);
00264 
00265                 /* load vp with formats for printing */
00266                 for(; dgop->dgo_qray_fmts[i].type != (char)NULL; ++i)
00267                         bu_vls_printf(&t_vls, "fmt %c %s; ",
00268                                       dgop->dgo_qray_fmts[i].type,
00269                                       bu_vls_addr(&dgop->dgo_qray_fmts[i].fmt));
00270 
00271                 *vp++ = "-e";
00272                 *vp++ = bu_vls_addr(&t_vls);
00273 
00274                 /* nirt does not like the trailing ';' */
00275                 bu_vls_trunc(&t_vls, -2);
00276         }
00277 
00278         /* include nirt script string */
00279         if (bu_vls_strlen(&dgop->dgo_qray_script)) {
00280                 *vp++ = "-e";
00281                 *vp++ = bu_vls_addr(&dgop->dgo_qray_script);
00282         }
00283 
00284         *vp++ = "-e";
00285         *vp++ = bu_vls_addr(&p_vls);
00286 
00287         for (i=1; i < argc; i++)
00288                 *vp++ = argv[i];
00289         *vp++ = dgop->dgo_wdbp->dbip->dbi_filename;
00290 
00291         dgop->dgo_rt_cmd_len = vp - dgop->dgo_rt_cmd;
00292 
00293         /* Note - dgo_build_tops sets the last vp to (char *)0 */
00294         dgop->dgo_rt_cmd_len += dgo_build_tops(interp,
00295                                                (struct solid *)&dgop->dgo_headSolid,
00296                                                vp,
00297                                                &dgop->dgo_rt_cmd[RT_MAXARGS]);
00298 
00299         if (dgop->dgo_qray_cmd_echo) {
00300                 /* Print out the command we are about to run */
00301                 vp = &dgop->dgo_rt_cmd[0];
00302                 while (*vp)
00303                         Tcl_AppendResult(interp, *vp++, " ", (char *)NULL);
00304 
00305                 Tcl_AppendResult(interp, "\n", (char *)NULL);
00306         }
00307 
00308         if (use_input_orig) {
00309                 bu_vls_init(&vls);
00310                 bu_vls_printf(&vls, "\nFiring from (%lf, %lf, %lf)...\n",
00311                               center_model[X], center_model[Y], center_model[Z]);
00312                 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00313                 bu_vls_free(&vls);
00314         } else
00315                 Tcl_AppendResult(interp, "\nFiring from view center...\n", (char *)NULL);
00316 
00317 #ifndef _WIN32
00318         (void)pipe(pipe_in);
00319         (void)pipe(pipe_out);
00320         (void)pipe(pipe_err);
00321         (void)signal(SIGINT, SIG_IGN);
00322         if ((pid = fork()) == 0) {
00323                 /* Redirect stdin, stdout, stderr */
00324                 (void)close(0);
00325                 (void)dup( pipe_in[0] );
00326                 (void)close(1);
00327                 (void)dup( pipe_out[1] );
00328                 (void)close(2);
00329                 (void)dup ( pipe_err[1] );
00330 
00331                 /* close pipes */
00332                 (void)close(pipe_in[0]);
00333                 (void)close(pipe_in[1]);
00334                 (void)close(pipe_out[0]);
00335                 (void)close(pipe_out[1]);
00336                 (void)close(pipe_err[0]);
00337                 (void)close(pipe_err[1]);
00338                 for (i=3; i < 20; i++)
00339                         (void)close(i);
00340                 (void)signal(SIGINT, SIG_DFL);
00341                 (void)execvp(dgop->dgo_rt_cmd[0], dgop->dgo_rt_cmd);
00342                 perror (dgop->dgo_rt_cmd[0]);
00343                 exit(16);
00344         }
00345 
00346         /* use fp_in to feed view info to nirt */
00347         (void)close(pipe_in[0]);
00348         fp_in = fdopen(pipe_in[1], "w");
00349 
00350         /* use fp_out to read back the result */
00351         (void)close(pipe_out[1]);
00352         fp_out = fdopen(pipe_out[0], "r");
00353 
00354         /* use fp_err to read any error messages */
00355         (void)close(pipe_err[1]);
00356         fp_err = fdopen(pipe_err[0], "r");
00357 
00358         /* send quit command to nirt */
00359         fwrite("q\n", 1, 2, fp_in);
00360         (void)fclose(fp_in);
00361 
00362 #else
00363         memset((void *)&si, 0, sizeof(STARTUPINFO));
00364         memset((void *)&pi, 0, sizeof(PROCESS_INFORMATION));
00365         memset((void *)&sa, 0, sizeof(SECURITY_ATTRIBUTES));
00366 
00367         sa.nLength = sizeof(sa);
00368         sa.bInheritHandle = TRUE;
00369         sa.lpSecurityDescriptor = NULL;
00370 
00371         /* Create a pipe for the child process's STDOUT. */
00372         CreatePipe( &pipe_out[0], &pipe_out[1], &sa, 0);
00373 
00374         /* Create noninheritable read handle and close the inheritable read handle. */
00375         DuplicateHandle(GetCurrentProcess(), pipe_out[0],
00376                         GetCurrentProcess(),  &pipe_outDup ,
00377                         0,  FALSE,
00378                         DUPLICATE_SAME_ACCESS);
00379         CloseHandle(pipe_out[0]);
00380 
00381         /* Create a pipe for the child process's STDERR. */
00382         CreatePipe( &pipe_err[0], &pipe_err[1], &sa, 0);
00383 
00384         /* Create noninheritable read handle and close the inheritable read handle. */
00385         DuplicateHandle(GetCurrentProcess(), pipe_err[0],
00386                         GetCurrentProcess(),  &pipe_errDup ,
00387                         0,  FALSE,
00388                         DUPLICATE_SAME_ACCESS);
00389         CloseHandle(pipe_err[0]);
00390 
00391         /* The steps for redirecting child process's STDIN:
00392          *     1.  Save current STDIN, to be restored later.
00393          *     2.  Create anonymous pipe to be STDIN for child process.
00394          *     3.  Set STDIN of the parent to be the read handle to the
00395          *         pipe, so it is inherited by the child process.
00396          *     4.  Create a noninheritable duplicate of the write handle,
00397          *         and close the inheritable write handle.
00398          */
00399 
00400         /* Create a pipe for the child process's STDIN. */
00401         CreatePipe(&pipe_in[0], &pipe_in[1], &sa, 0);
00402 
00403         /* Duplicate the write handle to the pipe so it is not inherited. */
00404         DuplicateHandle(GetCurrentProcess(), pipe_in[1],
00405                         GetCurrentProcess(), &pipe_inDup,
00406                         0, FALSE,                  /* not inherited */
00407                         DUPLICATE_SAME_ACCESS);
00408         CloseHandle(pipe_in[1]);
00409 
00410         si.cb = sizeof(STARTUPINFO);
00411         si.lpReserved = NULL;
00412         si.lpReserved2 = NULL;
00413         si.cbReserved2 = 0;
00414         si.lpDesktop = NULL;
00415         si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
00416         si.hStdInput   = pipe_in[0];
00417         si.hStdOutput  = pipe_out[1];
00418         si.hStdError   = pipe_err[1];
00419         si.wShowWindow = SW_HIDE;
00420 
00421         sprintf(line1,"%s ", dgop->dgo_rt_cmd[0]);
00422         for (i=1; i<dgop->dgo_rt_cmd_len; i++) {
00423             /* skip commands */
00424             if (strstr(dgop->dgo_rt_cmd[i], "-e") != NULL)
00425                 ++i;
00426             else { /* append other arguments (i.e. options, file and obj(s)) */
00427                 sprintf(name,"\"%s\" ", dgop->dgo_rt_cmd[i]);
00428                 strcat(line1, name);
00429             }
00430         }
00431 
00432         CreateProcess(NULL, line1, NULL, NULL, TRUE,
00433                       DETACHED_PROCESS, NULL, NULL,
00434                       &si, &pi);
00435 
00436         /* use fp_in to feed view info to nirt */
00437         CloseHandle(pipe_in[0]);
00438         fp_in = _fdopen(_open_osfhandle((HFILE)pipe_inDup,_O_TEXT), "wb");
00439         _setmode(_fileno(fp_in), _O_BINARY);
00440 
00441         /* send commands down the pipe */
00442         for (i=1; i<dgop->dgo_rt_cmd_len-2; i++)
00443             if (strstr(dgop->dgo_rt_cmd[i], "-e") != NULL)
00444                 fprintf(fp_in, "%s\n", dgop->dgo_rt_cmd[++i]);
00445 
00446         /* use fp_out to read back the result */
00447         CloseHandle(pipe_out[1]);
00448         fp_out = _fdopen(_open_osfhandle((HFILE)pipe_outDup,_O_TEXT), "rb");
00449         _setmode(_fileno(fp_out), _O_BINARY);
00450 
00451         /* use fp_err to read any error messages */
00452         CloseHandle(pipe_err[1]);
00453         fp_err = _fdopen(_open_osfhandle((HFILE)pipe_errDup,_O_TEXT), "rb");
00454         _setmode(_fileno(fp_err), _O_BINARY);
00455 
00456         /* send quit command to nirt */
00457         fwrite( "q\n", 1, 2, fp_in );
00458         (void)fclose(fp_in);
00459 
00460 #endif
00461 
00462         bu_vls_free(&p_vls);   /* use to form "partition" part of nirt command above */
00463         if (DG_QRAY_GRAPHICS(dgop)) {
00464 
00465                 if (DG_QRAY_TEXT(dgop))
00466                         bu_vls_free(&o_vls); /* used to form "overlap" part of nirt command above */
00467 
00468                 BU_LIST_INIT(&HeadQRayData.l);
00469 
00470                 /* handle partitions */
00471                 while (fgets(line, RT_MAXLINE, fp_out) != (char *)NULL) {
00472                         if (line[0] == '\n') {
00473                                 Tcl_AppendResult(interp, line+1, (char *)NULL);
00474                                 break;
00475                         }
00476 
00477                         BU_GETSTRUCT(ndlp, dg_qray_dataList);
00478                         BU_LIST_APPEND(HeadQRayData.l.back, &ndlp->l);
00479 
00480                         if (sscanf(line, "%le %le %le %le",
00481                                    &ndlp->x_in, &ndlp->y_in, &ndlp->z_in, &ndlp->los) != 4)
00482                                 break;
00483                 }
00484 
00485                 vbp = rt_vlblock_init();
00486                 dgo_qray_data_to_vlist(dgop, vbp, &HeadQRayData, dir, 0);
00487                 bu_list_free(&HeadQRayData.l);
00488                 dgo_cvt_vlblock_to_solids(dgop, interp, vbp, bu_vls_addr(&dgop->dgo_qray_basename), 0);
00489                 rt_vlblock_free(vbp);
00490 
00491                 /* handle overlaps */
00492                 while (fgets(line, RT_MAXLINE, fp_out) != (char *)NULL) {
00493                         if (line[0] == '\n') {
00494                                 Tcl_AppendResult(interp, line+1, (char *)NULL);
00495                                 break;
00496                         }
00497 
00498                         BU_GETSTRUCT(ndlp, dg_qray_dataList);
00499                         BU_LIST_APPEND(HeadQRayData.l.back, &ndlp->l);
00500 
00501                         if (sscanf(line, "%le %le %le %le",
00502                                    &ndlp->x_in, &ndlp->y_in, &ndlp->z_in, &ndlp->los) != 4)
00503                                 break;
00504                 }
00505                 vbp = rt_vlblock_init();
00506                 dgo_qray_data_to_vlist(dgop, vbp, &HeadQRayData, dir, 1);
00507                 bu_list_free(&HeadQRayData.l);
00508                 dgo_cvt_vlblock_to_solids(dgop, interp, vbp, bu_vls_addr(&dgop->dgo_qray_basename), 0);
00509                 rt_vlblock_free(vbp);
00510         }
00511 
00512         /*
00513          * Notify observers, if any, before generating textual output since
00514          * such an act (observer notification) wipes out whatever gets stuffed
00515          * into interp->result.
00516          */
00517         dgo_notify(dgop, interp);
00518 
00519         if (DG_QRAY_TEXT(dgop)) {
00520                 bu_vls_free(&t_vls);
00521 
00522                 while (fgets(line, RT_MAXLINE, fp_out) != (char *)NULL)
00523                         Tcl_AppendResult(interp, line, (char *)NULL);
00524         }
00525 
00526         (void)fclose(fp_out);
00527 
00528         while (fgets(line, RT_MAXLINE, fp_err) != (char *)NULL)
00529                 Tcl_AppendResult(interp, line, (char *)NULL);
00530         (void)fclose(fp_err);
00531 
00532 
00533 #ifndef _WIN32
00534 
00535         /* Wait for program to finish */
00536         while ((rpid = wait(&retcode)) != pid && rpid != -1)
00537                 ;       /* NULL */
00538 
00539         if( retcode != 0 )
00540                 dgo_pr_wait_status(interp, retcode);
00541 #else
00542         /* Wait for program to finish */
00543         WaitForSingleObject( pi.hProcess, INFINITE );
00544 
00545 #endif
00546 
00547         FOR_ALL_SOLIDS(sp, &dgop->dgo_headSolid)
00548                 sp->s_wflag = DOWN;
00549 
00550         return TCL_OK;
00551 }
00552 
00553 int
00554 dgo_vnirt_cmd(struct dg_obj     *dgop,
00555               struct view_obj   *vop,
00556               Tcl_Interp        *interp,
00557               int               argc,
00558               char              **argv) {
00559     register int i;
00560     int status;
00561     fastf_t sf = 1.0 * DG_INV_GED;
00562     vect_t view_ray_orig;
00563     vect_t center_model;
00564     struct bu_vls x_vls;
00565     struct bu_vls y_vls;
00566     struct bu_vls z_vls;
00567     char **av;
00568 
00569     if (argc < 3 || MAXARGS < argc) {
00570         struct bu_vls vls;
00571 
00572         bu_vls_init(&vls);
00573         bu_vls_printf(&vls, "helplib_alias dgo_vnirt %s", argv[0]);
00574         Tcl_Eval(interp, bu_vls_addr(&vls));
00575         bu_vls_free(&vls);
00576 
00577         return TCL_ERROR;
00578     }
00579 
00580     /*
00581      * The last two arguments are expected to be x,y in view coordinates.
00582      * It is also assumed that view z will be the front of the viewing cube.
00583      * These coordinates are converted to x,y,z in model coordinates and then
00584      * converted to local units before being handed to nirt. All other
00585      * arguments are passed straight through to nirt.
00586      */
00587     if(sscanf(argv[argc-2], "%lf", &view_ray_orig[X]) != 1 ||
00588        sscanf(argv[argc-1], "%lf", &view_ray_orig[Y]) != 1){
00589         return TCL_ERROR;
00590     }
00591     view_ray_orig[Z] = DG_GED_MAX;
00592     argc -= 2;
00593 
00594     av = (char **)bu_malloc(sizeof(char *) * (argc + 4), "dgo_vnirt_cmd: av");
00595 
00596     /* Calculate point from which to fire ray */
00597     VSCALE(view_ray_orig, view_ray_orig, sf);
00598     MAT4X3PNT(center_model, vop->vo_view2model, view_ray_orig);
00599     VSCALE(center_model, center_model, dgop->dgo_wdbp->dbip->dbi_base2local);
00600 
00601     bu_vls_init(&x_vls);
00602     bu_vls_init(&y_vls);
00603     bu_vls_init(&z_vls);
00604     bu_vls_printf(&x_vls, "%lf", center_model[X]);
00605     bu_vls_printf(&y_vls, "%lf", center_model[Y]);
00606     bu_vls_printf(&z_vls, "%lf", center_model[Z]);
00607 
00608     /* pass remaining arguments to nirt */
00609     av[0] = "nirt";
00610     for(i = 1; i < argc; ++i)
00611         av[i] = argv[i];
00612 
00613     /* pass modified coordinates to nirt */
00614     av[i++] = bu_vls_addr(&x_vls);
00615     av[i++] = bu_vls_addr(&y_vls);
00616     av[i++] = bu_vls_addr(&z_vls);
00617     av[i] = (char *)NULL;
00618 
00619     status = dgo_nirt_cmd(dgop, vop, interp, argc + 3, av);
00620 
00621     bu_vls_free(&x_vls);
00622     bu_vls_free(&y_vls);
00623     bu_vls_free(&z_vls);
00624     bu_free((genptr_t)av, "dgo_vnirt_cmd: av");
00625 
00626     return status;
00627 }
00628 
00629 /*
00630  * Local Variables:
00631  * mode: C
00632  * tab-width: 8
00633  * c-basic-offset: 4
00634  * indent-tabs-mode: t
00635  * End:
00636  * ex: shiftwidth=4 tabstop=8
00637  */

Generated on Mon Sep 18 01:24:52 2006 for BRL-CAD by  doxygen 1.4.6