vdraw.c

Go to the documentation of this file.
00001 /*                         V D R A W . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2004-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 /** @file vdraw.c
00025  * Edit vector lists and display them as pseudosolids.
00026 
00027 OPEN COMMAND
00028 vdraw   open                    - with no argument, asks if there is
00029                                   an open vlist (1 yes, 0 no)
00030 
00031                 name            - opens the specified vlist
00032                                   returns 1 if creating new vlist
00033                                           0 if opening an existing vlist
00034 
00035 EDITING COMMANDS - no return value
00036 
00037 vdraw   write   i       c x y z - write params into i-th vector
00038                 next    c x y z - write params to end of vector list
00039 
00040 vdraw   insert  i       c x y z - insert params in front of i-th vector
00041 
00042 vdraw   delete  i               - delete i-th vector
00043                 last            - delete last vector on list
00044                 all             - delete all vectors on list
00045 
00046 PARAMETER SETTING COMMAND - no return value
00047 vdraw   params  color           - set the current color with 6 hex digits
00048                                   representing rrggbb
00049                 name            - change the name of the current vlist
00050 
00051 QUERY COMMAND
00052 vdraw   read    i               - returns contents of i-th vector "c x y z"
00053                 color           - return the current color in hex
00054                 length          - return number of vectors in list
00055                 name            - return name of current vlist
00056 
00057 DISPLAY COMMAND -
00058 vdraw   send                    - send the current vlist to the display
00059                                   returns 0 on success, -1 if the name
00060                                   conflicts with an existing true solid
00061 
00062 CURVE COMMANDS
00063 vdraw   vlist   list            - return list of all existing vlists
00064                 delete  name    - delete the named vlist
00065 
00066 All textual arguments can be replaced by their first letter.
00067 (e.g. "vdraw d a" instead of "vdraw delete all"
00068 
00069 In the above listing:
00070 "i" refers to an integer
00071 "c" is an integer representing one of the following rt_vlist commands:
00072          RT_VLIST_LINE_MOVE     0       / begin new line /
00073          RT_VLIST_LINE_DRAW     1       / draw line /
00074          RT_VLIST_POLY_START    2       / pt[] has surface normal /
00075          RT_VLIST_POLY_MOVE     3       / move to first poly vertex /
00076          RT_VLIST_POLY_DRAW     4       / subsequent poly vertex /
00077          RT_VLIST_POLY_END      5       / last vert (repeats 1st), draw poly /
00078          RT_VLIST_POLY_VERTNORM 6       / per-vertex normal, for interpolation /
00079 
00080 "x y z" refer to floating point values which represent a point or normal
00081         vector. For commands 0,1,3,4, and 5, they represent a point, while
00082         for commands 2 and 6 they represent normal vectors
00083 
00084 author - Carl Nuzman
00085 
00086 Example Use -
00087         vdraw open rays
00088         vdraw delete all
00089         foreach partition $ray {
00090                 ...stuff...
00091                 vdraw write next 0 $inpt
00092                 vdraw write next 1 $outpt
00093         }
00094         vdraw send
00095 
00096 Acknowledgements:
00097   Modifications by Bob Parker:
00098         *- adapt for use in LIBRT's "Drawable Geometry" object
00099         *- build separate vdraw commands
00100 
00101 ********************************************************************/
00102 /*@}*/
00103 
00104 #include "common.h"
00105 
00106 #include <stdlib.h>
00107 #include <stdio.h>
00108 #ifdef HAVE_STRING_H
00109 #  include <string.h>
00110 #else
00111 #  include <strings.h>
00112 #endif
00113 #include <math.h>
00114 #include <signal.h>
00115 #include "tcl.h"
00116 
00117 #include "machine.h"
00118 #include "cmd.h"
00119 #include "vmath.h"
00120 #include "mater.h"
00121 #include "nmg.h"
00122 #include "raytrace.h"
00123 
00124 
00125 #ifndef M_SQRT2
00126 #define M_SQRT2         1.41421356237309504880
00127 #endif
00128 
00129 #define REV_BU_LIST_FOR(p,structure,hp) \
00130         (p)=BU_LIST_LAST(structure,hp); \
00131         BU_LIST_NOT_HEAD(p,hp);         \
00132         (p)=BU_LIST_PLAST(structure,p)
00133 
00134 /* defined in librt/dg_obj.c */
00135 extern int dgo_invent_solid(struct dg_obj *dgop, Tcl_Interp *interp, char *name, struct bu_list *vhead, long int rgb, int copy, fastf_t transparency, int dmode);
00136 extern void dgo_notify(struct dg_obj *dgop, Tcl_Interp *interp);
00137 
00138 static int vdraw_write_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00139 static int vdraw_insert_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00140 static int vdraw_delete_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00141 static int vdraw_read_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00142 static int vdraw_send_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00143 static int vdraw_params_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00144 static int vdraw_open_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00145 static int vdraw_vlist_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv);
00146 
00147 struct bu_cmdtab vdraw_cmds[] = {
00148         {"write",               vdraw_write_tcl},
00149         {"insert",              vdraw_insert_tcl},
00150         {"delete",              vdraw_delete_tcl},
00151         {"read",                vdraw_read_tcl},
00152         {"send",                vdraw_send_tcl},
00153         {"params",              vdraw_params_tcl},
00154         {"open",                vdraw_open_tcl},
00155         {"vlist",               vdraw_vlist_tcl},
00156         {(char *)0,             (int (*)())0 }
00157 };
00158 
00159 /*
00160  * Usage:
00161  *        write i|next c x y z
00162  */
00163 static int
00164 vdraw_write_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00165 {
00166         struct dg_obj *dgop = (struct dg_obj *)clientData;
00167         int index, uind;
00168         struct rt_vlist *vp, *cp;
00169 
00170         if (!dgop->dgo_currVHead) {
00171                 Tcl_AppendResult(interp, "vdraw write: no vlist is currently open.", (char *)NULL);
00172                 return TCL_ERROR;
00173         }
00174         if (argc < 4) {
00175                 Tcl_AppendResult(interp, "vdraw write: not enough args\n", (char *)NULL);
00176                 return TCL_ERROR;
00177         }
00178         if (argv[1][0] == 'n') { /* next */
00179                 for (REV_BU_LIST_FOR(vp, rt_vlist, &(dgop->dgo_currVHead->vdc_vhd))) {
00180                         if (vp->nused > 0) {
00181                                 break;
00182                         }
00183                 }
00184                 if (BU_LIST_IS_HEAD(vp,&(dgop->dgo_currVHead->vdc_vhd))) {
00185                                 /* we went all the way through */
00186                         vp = BU_LIST_PNEXT(rt_vlist, vp);
00187                         if (BU_LIST_IS_HEAD(vp,&(dgop->dgo_currVHead->vdc_vhd))) {
00188                                 RT_GET_VLIST(vp);
00189                                 BU_LIST_INSERT(&(dgop->dgo_currVHead->vdc_vhd), &(vp->l));
00190                         }
00191                 }
00192                 if (vp->nused >= RT_VLIST_CHUNK) {
00193                         vp = BU_LIST_PNEXT(rt_vlist, vp);
00194                         if (BU_LIST_IS_HEAD(vp,&(dgop->dgo_currVHead->vdc_vhd))) {
00195                                 RT_GET_VLIST(vp);
00196                                 BU_LIST_INSERT(&(dgop->dgo_currVHead->vdc_vhd),&(vp->l));
00197                         }
00198                 }
00199                 cp = vp;
00200                 index = vp->nused;
00201         } else if (sscanf(argv[1], "%d", &uind) < 1) {
00202                 Tcl_AppendResult(interp, "vdraw: write index not an integer\n", (char *)NULL);
00203                 return TCL_ERROR;
00204         } else {
00205                 /* uind holds user-specified index */
00206                 /* only allow one past the end */
00207 
00208                 for (BU_LIST_FOR(vp, rt_vlist, &(dgop->dgo_currVHead->vdc_vhd))) {
00209                         if (uind < RT_VLIST_CHUNK){
00210                                 /* this is the right vlist */
00211                                 break;
00212                         }
00213                         if (vp->nused == 0){
00214                                 break;
00215                         }
00216                         uind -= vp->nused;
00217                 }
00218 
00219                 if (BU_LIST_IS_HEAD(vp,&(dgop->dgo_currVHead->vdc_vhd))) {
00220                         if (uind > 0) {
00221                                 Tcl_AppendResult(interp, "vdraw: write out of range\n", (char *)NULL);
00222                                 return TCL_ERROR;
00223                         }
00224                         RT_GET_VLIST(vp);
00225                         BU_LIST_INSERT(&(dgop->dgo_currVHead->vdc_vhd),&(vp->l));
00226                 }
00227                 if (uind > vp->nused) {
00228                         Tcl_AppendResult(interp, "vdraw: write out of range\n", (char *)NULL);
00229                         return TCL_ERROR;
00230                 }
00231                 cp = vp;
00232                 index = uind;
00233         }
00234 
00235         if (sscanf(argv[2],"%d",&(cp->cmd[index])) < 1) {
00236                 Tcl_AppendResult(interp, "vdraw: cmd not an integer\n", (char *)NULL);
00237                 return TCL_ERROR;
00238         }
00239         if (argc == 6) {
00240                 cp->pt[index][0] = atof(argv[3]);
00241                 cp->pt[index][1] = atof(argv[4]);
00242                 cp->pt[index][2] = atof(argv[5]);
00243         } else {
00244                 if (argc != 4 ||
00245                     bn_decode_vect(cp->pt[index], argv[3]) != 3) {
00246                         Tcl_AppendResult(interp,
00247                                          "vdraw write: wrong # args, need either x y z or {x y z}\n", (char *)NULL);
00248                         return TCL_ERROR;
00249                 }
00250         }
00251         /* increment counter only if writing onto end */
00252         if (index == cp->nused)
00253                 cp->nused++;
00254 
00255         return TCL_OK;
00256 }
00257 
00258 /*
00259  * Usage:
00260  *        insert i c x y z
00261  */
00262 int
00263 vdraw_insert_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00264 {
00265         struct dg_obj *dgop = (struct dg_obj *)clientData;
00266         struct rt_vlist *vp, *cp, *wp;
00267         int i;
00268         int index;
00269         int uind;
00270 
00271         if (!dgop->dgo_currVHead) {
00272                 Tcl_AppendResult(interp, "vdraw: no vlist is currently open.", (char *)NULL);
00273                 return TCL_ERROR;
00274         }
00275         if (argc < 6) {
00276                 Tcl_AppendResult(interp, "vdraw: not enough args", (char *)NULL);
00277                 return TCL_ERROR;
00278         }
00279         if (sscanf(argv[2], "%d", &uind) < 1) {
00280                 Tcl_AppendResult(interp, "vdraw: insert index not an integer\n", (char *)NULL);
00281                 return TCL_ERROR;
00282         }
00283 
00284         /* uinds hold user specified index */
00285         for (BU_LIST_FOR(vp, rt_vlist, &(dgop->dgo_currVHead->vdc_vhd))) {
00286                 if (uind < RT_VLIST_CHUNK) {
00287                                 /* this is the right vlist */
00288                         break;
00289                 }
00290                 if (vp->nused == 0){
00291                         break;
00292                 }
00293                 uind -= vp->nused;
00294         }
00295 
00296         if (BU_LIST_IS_HEAD(vp,&(dgop->dgo_currVHead->vdc_vhd))) {
00297                 if (uind > 0) {
00298                         Tcl_AppendResult(interp, "vdraw: insert out of range\n", (char *)NULL);
00299                         return TCL_ERROR;
00300                 }
00301                 RT_GET_VLIST(vp);
00302                 BU_LIST_INSERT(&(dgop->dgo_currVHead->vdc_vhd),&(vp->l));
00303         }
00304         if (uind > vp->nused) {
00305                 Tcl_AppendResult(interp, "vdraw: insert out of range\n", (char *)NULL);
00306                 return TCL_ERROR;
00307         }
00308 
00309 
00310         cp = vp;
00311         index = uind;
00312 
00313         vp = BU_LIST_LAST(rt_vlist, &(dgop->dgo_currVHead->vdc_vhd));
00314         vp->nused++;
00315 
00316         while (vp != cp) {
00317                 for (i = vp->nused-1; i > 0; i--) {
00318                         vp->cmd[i] = vp->cmd[i-1];
00319                         VMOVE(vp->pt[i],vp->pt[i-1]);
00320                 }
00321                 wp = BU_LIST_PLAST(rt_vlist,vp);
00322                 vp->cmd[0] = wp->cmd[RT_VLIST_CHUNK-1];
00323                 VMOVE(vp->pt[0],wp->pt[RT_VLIST_CHUNK-1]);
00324                 vp = wp;
00325         }
00326 
00327         for (i=vp->nused-1; i>index; i--) {
00328                 vp->cmd[i] = vp->cmd[i-1];
00329                 VMOVE(vp->pt[i],vp->pt[i-1]);
00330         }
00331         if (sscanf(argv[2],"%d",&(vp->cmd[index])) < 1) {
00332                 Tcl_AppendResult(interp, "vdraw: cmd not an integer\n", (char *)NULL);
00333                 return TCL_ERROR;
00334         }
00335         vp->pt[index][0] = atof(argv[3]);
00336         vp->pt[index][1] = atof(argv[4]);
00337         vp->pt[index][2] = atof(argv[5]);
00338 
00339         return TCL_OK;
00340 }
00341 
00342 /*
00343  * Usage:
00344  *        delete i|last|all
00345  */
00346 int
00347 vdraw_delete_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00348 {
00349         struct dg_obj *dgop = (struct dg_obj *)clientData;
00350         struct rt_vlist *vp, *wp;
00351         int i;
00352         int uind;
00353 
00354         if (!dgop->dgo_currVHead) {
00355                 Tcl_AppendResult(interp, "vdraw: no vlist is currently open.", (char *)NULL);
00356                 return TCL_ERROR;
00357         }
00358         if (argc < 2) {
00359                 Tcl_AppendResult(interp, "vdraw: not enough args\n", (char *)NULL);
00360                 return TCL_ERROR;
00361         }
00362         if (argv[1][0] == 'a') {
00363                 /* delete all */
00364                 for (BU_LIST_FOR(vp, rt_vlist, &(dgop->dgo_currVHead->vdc_vhd))) {
00365                         vp->nused = 0;
00366                 }
00367                 return TCL_OK;
00368         }
00369         if (argv[1][0] == 'l') {
00370                 /* delete last */
00371                 for (REV_BU_LIST_FOR(vp, rt_vlist, &(dgop->dgo_currVHead->vdc_vhd))) {
00372                         if (vp->nused > 0) {
00373                                 vp->nused--;
00374                                 break;
00375                         }
00376                 }
00377                 return TCL_OK;
00378         }
00379         if (sscanf(argv[1], "%d", &uind) < 1) {
00380                 Tcl_AppendResult(interp, "vdraw: delete index not an integer\n", (char *)NULL);
00381                 return TCL_ERROR;
00382         }
00383 
00384         for (BU_LIST_FOR(vp, rt_vlist, &(dgop->dgo_currVHead->vdc_vhd))) {
00385                 if (uind < RT_VLIST_CHUNK) {
00386                                 /* this is the right vlist */
00387                         break;
00388                 }
00389                 if ( vp->nused == 0) {
00390                                 /* no point going further */
00391                         break;
00392                 }
00393                 uind -= vp->nused;
00394         }
00395 
00396         if (uind >= vp->nused) {
00397                 Tcl_AppendResult(interp, "vdraw: delete out of range\n", (char *)NULL);
00398                 return TCL_ERROR;
00399         }
00400 
00401         for (i = uind; i < vp->nused - 1; i++) {
00402                 vp->cmd[i] = vp->cmd[i+1];
00403                 VMOVE(vp->pt[i],vp->pt[i+1]);
00404         }
00405 
00406         wp = BU_LIST_PNEXT(rt_vlist, vp);
00407         while (BU_LIST_NOT_HEAD(wp, &(dgop->dgo_currVHead->vdc_vhd))) {
00408                 if (wp->nused == 0) {
00409                         break;
00410                 }
00411 
00412                 vp->cmd[RT_VLIST_CHUNK-1] = wp->cmd[0];
00413                 VMOVE(vp->pt[RT_VLIST_CHUNK-1],wp->pt[0]);
00414 
00415                 for (i=0; i< wp->nused - 1; i++) {
00416                         wp->cmd[i] = wp->cmd[i+1];
00417                         VMOVE(wp->pt[i],wp->pt[i+1]);
00418                 }
00419                 vp = wp;
00420                 wp = BU_LIST_PNEXT(rt_vlist, vp);
00421         }
00422 
00423         if (vp->nused <= 0) {
00424                 /* this shouldn't happen */
00425                 Tcl_AppendResult(interp, "vdraw: vlist corrupt", (char *)NULL);
00426                 return TCL_ERROR;
00427         }
00428         vp->nused--;
00429 
00430         return TCL_OK;
00431 }
00432 
00433 /*
00434  * Usage:
00435  *        read i|color|length|name
00436  */
00437 static int
00438 vdraw_read_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00439 {
00440         struct dg_obj *dgop = (struct dg_obj *)clientData;
00441         struct rt_vlist *vp;
00442         struct bu_vls vls;
00443         int uind;
00444         int length;
00445 
00446         if (!dgop->dgo_currVHead) {
00447                 Tcl_AppendResult(interp, "vdraw: no vlist is currently open.", (char *)NULL);
00448                 return TCL_ERROR;
00449         }
00450         if (argc < 2) {
00451                 Tcl_AppendResult(interp, "vdraw: need index to read\n", (char *)NULL);
00452                 return TCL_ERROR;
00453         }
00454         if (argv[1][0] == 'c') {
00455                 /* read color of current solid */
00456                 bu_vls_init(&vls);
00457                 bu_vls_printf(&vls, "%.6lx", dgop->dgo_currVHead->vdc_rgb);
00458                 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00459                 bu_vls_free(&vls);
00460                 return TCL_OK;
00461         }
00462         if (argv[1][0] == 'n') {
00463                 /*read name of currently open solid*/
00464                 bu_vls_init(&vls);
00465                 bu_vls_printf(&vls, "%.89s", dgop->dgo_currVHead->vdc_name);
00466                 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00467                 bu_vls_free(&vls);
00468                 return TCL_OK;
00469         }
00470         if (argv[1][0] == 'l') {
00471                 /* return lenght of list */
00472                 length = 0;
00473                 vp = BU_LIST_FIRST(rt_vlist, &(dgop->dgo_currVHead->vdc_vhd));
00474                 while (!BU_LIST_IS_HEAD(vp, &(dgop->dgo_currVHead->vdc_vhd))) {
00475                         length += vp->nused;
00476                         vp = BU_LIST_PNEXT(rt_vlist, vp);
00477                 }
00478                 bu_vls_init(&vls);
00479                 bu_vls_printf(&vls, "%d", length);
00480                 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00481                 bu_vls_free(&vls);
00482                 return TCL_OK;
00483         }
00484         if (sscanf(argv[1], "%d", &uind) < 1) {
00485                 Tcl_AppendResult(interp, "vdraw: read index not an integer\n", (char *)NULL);
00486                 return TCL_ERROR;
00487         }
00488 
00489         for (BU_LIST_FOR(vp, rt_vlist, &(dgop->dgo_currVHead->vdc_vhd))) {
00490                 if (uind < RT_VLIST_CHUNK) {
00491                                 /* this is the right vlist */
00492                         break;
00493                 }
00494                 if ( vp->nused == 0) {
00495                                 /* no point going further */
00496                         break;
00497                 }
00498                 uind -= vp->nused;
00499         }
00500 
00501         if (uind >= vp->nused) {
00502                 Tcl_AppendResult(interp, "vdraw: read out of range\n", (char *)NULL);
00503                 return TCL_ERROR;
00504         }
00505 
00506         bu_vls_init(&vls);
00507         bu_vls_printf(&vls, "%d %.12e %.12e %.12e",
00508                 vp->cmd[uind], vp->pt[uind][0],
00509                 vp->pt[uind][1],vp->pt[uind][2]);
00510         Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00511         bu_vls_free(&vls);
00512 
00513         return TCL_OK;
00514 }
00515 
00516 /*
00517  * Usage:
00518  *        send
00519  */
00520 static int
00521 vdraw_send_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00522 {
00523         struct dg_obj *dgop = (struct dg_obj *)clientData;
00524         struct directory *dp;
00525         struct bu_vls vls;
00526         char solid_name [RT_VDRW_MAXNAME+RT_VDRW_PREFIX_LEN+1];
00527         int index;
00528         int real_flag;
00529 
00530         if (!dgop->dgo_currVHead) {
00531                 Tcl_AppendResult(interp, "vdraw: no vlist is currently open.", (char *)NULL);
00532                 return TCL_ERROR;
00533         }
00534 
00535         sprintf(solid_name, RT_VDRW_PREFIX);
00536         strncat(solid_name, dgop->dgo_currVHead->vdc_name, RT_VDRW_MAXNAME);
00537         if ((dp = db_lookup(dgop->dgo_wdbp->dbip, solid_name, LOOKUP_QUIET)) == DIR_NULL) {
00538                 real_flag = 0;
00539         } else {
00540                 real_flag = (dp->d_addr == RT_DIR_PHONY_ADDR) ? 0 : 1;
00541         }
00542 
00543         if (real_flag) {
00544                 /* solid exists - don't kill */
00545                 Tcl_AppendResult(interp, "-1", (char *)NULL);
00546                 return TCL_OK;
00547         }
00548 
00549 #if 0
00550         {
00551                 char *av[4];
00552 
00553                 av[0] = "kill";
00554                 av[1] = "-f";
00555                 av[2] = solid_name;
00556                 av[3] = NULL;
00557 
00558                 (void)f_kill(clientData, interp, 3, av);
00559         }
00560 #endif
00561 
00562         /* 0 means OK, -1 means conflict with real solid name */
00563         index = dgo_invent_solid(dgop,
00564                                  interp,
00565                                  solid_name,
00566                                  &(dgop->dgo_currVHead->vdc_vhd),
00567                                  dgop->dgo_currVHead->vdc_rgb,
00568                                  1, 0.0, 0);
00569         dgo_notify(dgop, interp);
00570 
00571         bu_vls_init(&vls);
00572         bu_vls_printf(&vls,"%d",index);
00573         Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00574         bu_vls_free(&vls);
00575 
00576         return TCL_OK;
00577 }
00578 
00579 /*
00580  * Usage:
00581  *        params color|name
00582  */
00583 static int
00584 vdraw_params_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00585 {
00586         struct dg_obj *dgop = (struct dg_obj *)clientData;
00587         struct vd_curve *rcp;
00588         unsigned long rgb;
00589 
00590         if (!dgop->dgo_currVHead) {
00591                 Tcl_AppendResult(interp, "vdraw: no vlist is currently open.", (char *)NULL);
00592                 return TCL_ERROR;
00593         }
00594         if (argc < 3) {
00595                 Tcl_AppendResult(interp, "vdraw: need params to set\n", (char *)NULL);
00596                 return TCL_ERROR;
00597         }
00598         if (argv[1][0] == 'c') {
00599                 if (sscanf(argv[2],"%lx", &rgb)>0)
00600                         dgop->dgo_currVHead->vdc_rgb = rgb;
00601                 return TCL_OK;
00602         }
00603         if (argv[1][0] == 'n') {
00604                 /* check for conflicts with existing vlists*/
00605                 for (BU_LIST_FOR(rcp, vd_curve, &dgop->dgo_headVDraw)) {
00606                         if (!strncmp( rcp->vdc_name, argv[1], RT_VDRW_MAXNAME)) {
00607                                 struct bu_vls vls;
00608 
00609                                 bu_vls_init(&vls);
00610                                 bu_vls_printf(&vls, "vdraw: name %.40s is already in use\n", argv[1]);
00611                                 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00612                                 return TCL_ERROR;
00613                         }
00614                 }
00615                 /* otherwise name not yet used */
00616                 strncpy(dgop->dgo_currVHead->vdc_name, argv[2], RT_VDRW_MAXNAME);
00617                 dgop->dgo_currVHead->vdc_name[RT_VDRW_MAXNAME] = (char) NULL;
00618                 Tcl_AppendResult(interp,"0",(char *)NULL);
00619                 return TCL_OK;
00620         }
00621 
00622         return TCL_OK;
00623 }
00624 
00625 /*
00626  * Usage:
00627  *        open [name]
00628  */
00629 static int
00630 vdraw_open_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00631 {
00632         struct dg_obj *dgop = (struct dg_obj *)clientData;
00633         struct vd_curve *rcp;
00634         struct rt_vlist *vp;
00635         char temp_name[RT_VDRW_MAXNAME+1];
00636 
00637         if (argc < 1 || 2 < argc) {
00638                 struct bu_vls vls;
00639 
00640                 bu_vls_init(&vls);
00641                 bu_vls_printf(&vls, "helplib vdraw_open");
00642                 Tcl_Eval(interp, bu_vls_addr(&vls));
00643                 bu_vls_free(&vls);
00644 
00645                 return TCL_ERROR;
00646         }
00647 
00648         if (argc == 1) {
00649                 if (dgop->dgo_currVHead) {
00650                         Tcl_AppendResult(interp, "1", (char *)NULL);
00651                         return TCL_OK;
00652                 } else {
00653                         Tcl_AppendResult(interp, "0", (char *)NULL);
00654                         return TCL_OK;
00655                 }
00656         }
00657 
00658         strncpy(temp_name, argv[1], RT_VDRW_MAXNAME);
00659         temp_name[RT_VDRW_MAXNAME] = (char) NULL;
00660         dgop->dgo_currVHead = (struct vd_curve *) NULL;
00661         for (BU_LIST_FOR(rcp, vd_curve, &dgop->dgo_headVDraw)) {
00662                 if (!strncmp(rcp->vdc_name, temp_name, RT_VDRW_MAXNAME)) {
00663                         dgop->dgo_currVHead = rcp;
00664                         break;
00665                 }
00666         }
00667 
00668         if (!dgop->dgo_currVHead) { /* create new entry */
00669                 BU_GETSTRUCT(rcp, vd_curve);
00670                 BU_LIST_APPEND(&dgop->dgo_headVDraw, &(rcp->l));
00671                 strcpy(rcp->vdc_name, temp_name);
00672                 rcp->vdc_name[RT_VDRW_MAXNAME] = (char) NULL;
00673                 rcp->vdc_rgb = RT_VDRW_DEF_COLOR;
00674                 BU_LIST_INIT(&(rcp->vdc_vhd));
00675                 RT_GET_VLIST(vp);
00676                 BU_LIST_APPEND(&(rcp->vdc_vhd), &(vp->l));
00677                 dgop->dgo_currVHead = rcp;
00678                 /* 1 means new entry */
00679                 Tcl_AppendResult(interp, "1", (char *)NULL);
00680                 return TCL_OK;
00681         } else { /* entry already existed */
00682                 if (BU_LIST_IS_EMPTY(&(dgop->dgo_currVHead->vdc_vhd))) {
00683                         RT_GET_VLIST(vp);
00684                         BU_LIST_APPEND(&(dgop->dgo_currVHead->vdc_vhd), &(vp->l));
00685                 }
00686                 dgop->dgo_currVHead->vdc_name[RT_VDRW_MAXNAME] = (char) NULL; /*safety*/
00687                 /* 0 means entry already existed*/
00688                 Tcl_AppendResult(interp, "0", (char *)NULL);
00689                 return TCL_OK;
00690         }
00691 }
00692 
00693 /*
00694  * Usage:
00695  *        vlist list
00696  *        vlist delete name
00697  */
00698 static int
00699 vdraw_vlist_tcl(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00700 {
00701         struct dg_obj *dgop = (struct dg_obj *)clientData;
00702         struct vd_curve *rcp, *rcp2;
00703         struct bu_vls vls;
00704 
00705         if (argc < 2) {
00706                 Tcl_AppendResult(interp,"vdraw: need more args",(char *)NULL);
00707                 return TCL_ERROR;
00708         }
00709 
00710         switch  (argv[1][0]) {
00711         case 'l':
00712                 bu_vls_init(&vls);
00713                 for (BU_LIST_FOR(rcp, vd_curve, &dgop->dgo_headVDraw)) {
00714                         bu_vls_strcat(&vls, rcp->vdc_name);
00715                         bu_vls_strcat(&vls, " ");
00716                 }
00717 
00718                 Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00719                 bu_vls_free(&vls);
00720                 return TCL_OK;
00721         case 'd':
00722                 if (argc < 3) {
00723                         Tcl_AppendResult(interp,"vdraw: need name of vlist to delete", (char *)NULL);
00724                         return TCL_ERROR;
00725                 }
00726                 rcp2 = (struct vd_curve *)NULL;
00727                 for (BU_LIST_FOR(rcp, vd_curve, &dgop->dgo_headVDraw)) {
00728                         if (!strncmp(rcp->vdc_name,argv[2],RT_VDRW_MAXNAME)) {
00729                                 rcp2 = rcp;
00730                                 break;
00731                         }
00732                 }
00733                 if (!rcp2) {
00734                         bu_vls_init(&vls);
00735                         bu_vls_printf(&vls, "vdraw: vlist %.40s not found", argv[2]);
00736                         Tcl_AppendResult(interp, bu_vls_addr(&vls), (char *)NULL);
00737                         bu_vls_free(&vls);
00738                         return TCL_ERROR;
00739                 }
00740                 BU_LIST_DEQUEUE(&(rcp2->l));
00741                 if (dgop->dgo_currVHead == rcp2) {
00742                         if (BU_LIST_IS_EMPTY(&dgop->dgo_headVDraw)) {
00743                                 dgop->dgo_currVHead = (struct vd_curve *)NULL;
00744                         } else {
00745                                 dgop->dgo_currVHead = BU_LIST_LAST(vd_curve,&dgop->dgo_headVDraw);
00746                         }
00747                 }
00748                 RT_FREE_VLIST(&(rcp2->vdc_vhd));
00749                 bu_free((genptr_t) rcp2, "vd_curve");
00750                 return TCL_OK;
00751         default:
00752                 Tcl_AppendResult(interp,"vdraw: unknown option to vdraw vlist", (char *)NULL);
00753                 return TCL_ERROR;
00754         }
00755 }
00756 
00757 /*
00758  * Local Variables:
00759  * mode: C
00760  * tab-width: 8
00761  * c-basic-offset: 4
00762  * indent-tabs-mode: t
00763  * End:
00764  * ex: shiftwidth=4 tabstop=8
00765  */

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