Ignore:
Timestamp:
Dec 27, 2007 9:06:49 AM (17 years ago)
Author:
gah
Message:

Changes for heightmap viewer

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/vizservers/nanovis/Command.cpp

    r829 r834  
     1
     2/*
     3 * ----------------------------------------------------------------------
     4 * Command.cpp
     5 *
     6 *      This modules creates the Tcl interface to the nanovis server.
     7 *      The communication protocol of the server is the Tcl language.
     8 *      Commands given to the server by clients are executed in a
     9 *      safe interpreter and the resulting image rendered offscreen
     10 *      is returned as BMP-formatted image data.
     11 *
     12 * ======================================================================
     13 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
     14 *           Michael McLennan <mmclennan@purdue.edu>
     15 *           Purdue Rendering and Perceptualization Lab (PURPL)
     16 *
     17 *  Copyright (c) 2004-2006  Purdue Research Foundation
     18 *
     19 *  See the file "license.terms" for information on usage and
     20 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     21 * ======================================================================
     22 */
     23
     24
    125#include "Command.h"
    2 
    326
    427#include "nanovis.h"
     
    3457// EXTERN DECLARATIONS
    3558// in Nv.cpp
     59
    3660extern VolumeRenderer* g_vol_render;
    3761extern PointSetRenderer* g_pointset_renderer;
     
    5478extern Camera* cam;
    5579
    56 extern char *def_transfunc;
    57 extern Tcl_HashTable tftable;
    5880extern float live_diffuse;
    5981extern float live_specular;
     
    6991extern Rappture::Outcome load_volume_stream(int index, std::iostream& fin);
    7092extern Rappture::Outcome load_volume_stream2(int index, std::iostream& fin);
    71 extern void load_volume(int index, int width, int height, int depth, int n_component, float* data, double vmin, double vmax,
    72                 double nzero_min);
    73 extern TransferFunction* get_transfunc(char *name);
    74 extern void resize_offscreen_buffer(int w, int h);
    75 extern void offscreen_buffer_capture();
     93extern void load_volume(int index, int width, int height, int depth,
     94        int n_component, float* data, double vmin, double vmax,
     95        double nzero_min);
     96
     97extern TransferFunction* nv_get_transfunc(const char *name);
     98extern TransferFunction* nv_set_transfunc(const char *name, int nSlots,
     99        float *data);
     100
     101extern void nv_resize_offscreen_buffer(int w, int h);
     102extern void nv_offscreen_buffer_capture();
    76103extern void bmp_header_add_int(unsigned char* header, int& pos, int data);
    77104extern void bmp_write(const char* cmd);
    78105extern void bmp_write_to_file();
    79 extern void display();
    80 extern void display_offscreen_buffer();
    81 extern void read_screen();
    82 extern int renderLegend(int ivol, int width, int height, const char* volArg);
     106extern void nv_display();
     107extern void nv_display_offscreen_buffer();
     108extern void nv_read_screen();
     109extern int nv_render_legend(TransferFunction *tf, double min, double max,
     110        int width, int height, const char* volArg);
    83111
    84112// Tcl interpreter for incoming messages
    85 Tcl_Interp *interp;
    86 Tcl_DString cmdbuffer;
    87 
    88 static int ScreenShotCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    89 static int CameraCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    90 static int CutplaneCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    91 static int LegendCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    92 static int ScreenCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    93 static int TransfuncCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    94 static int UpCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    95 static int VolumeCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    96 
    97 static int PlaneNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    98 static int PlaneLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    99 static int PlaneEnableCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    100 
    101 static int GridCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    102 static int AxisCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    103 
    104 static int GetVolumeIndices _ANSI_ARGS_((Tcl_Interp *interp, int argc, CONST84 char *argv[], vector<int>* vectorPtr));
    105 static int GetIndices(Tcl_Interp *interp, int argc, CONST84 char *argv[], vector<int>* vectorPtr);
    106 static int GetAxis _ANSI_ARGS_((Tcl_Interp *interp, char *str, int *valPtr));
    107 static int GetColor _ANSI_ARGS_((Tcl_Interp *interp, char *str, float *rgbPtr));
    108 
     113static Tcl_Interp *interp;
     114static Tcl_DString cmdbuffer;
     115
     116// default transfer function
     117static const char def_transfunc[] = "transfunc define default {\n\
     118  0.0  1 1 1\n\
     119  0.2  1 1 0\n\
     120  0.4  0 1 0\n\
     121  0.6  0 1 1\n\
     122  0.8  0 0 1\n\
     123  1.0  1 0 1\n\
     124} {\n\
     125  0.00  1.0\n\
     126  0.05  0.0\n\
     127  0.15  0.0\n\
     128  0.20  1.0\n\
     129  0.25  0.0\n\
     130  0.35  0.0\n\
     131  0.40  1.0\n\
     132  0.45  0.0\n\
     133  0.55  0.0\n\
     134  0.60  1.0\n\
     135  0.65  0.0\n\
     136  0.75  0.0\n\
     137  0.80  1.0\n\
     138  0.85  0.0\n\
     139  0.95  0.0\n\
     140  1.00  1.0\n\
     141}";
     142
     143static Tcl_CmdProc AxisCmd;
     144static Tcl_CmdProc CameraCmd;
     145static Tcl_CmdProc CutplaneCmd;
     146static Tcl_CmdProc GridCmd;
     147static Tcl_CmdProc LegendCmd;
     148static Tcl_CmdProc PlaneEnableCmd;
     149static Tcl_CmdProc PlaneLinkCmd;
     150static Tcl_CmdProc PlaneNewCmd;
     151static Tcl_CmdProc ScreenCmd;
     152static Tcl_CmdProc ScreenShotCmd;
     153static Tcl_CmdProc TransfuncCmd;
     154static Tcl_CmdProc UniRect2dCmd;
     155static Tcl_CmdProc UpCmd;
     156static Tcl_CmdProc VolumeCmd;
     157
     158static int GetVolumeIndices(Tcl_Interp *interp, int argc, const char *argv[],
     159        vector<int>* vectorPtr);
     160static int GetVolume(Tcl_Interp *interp, const char *string,
     161        Volume **volPtrPtr);
     162static int GetVolumeIndex(Tcl_Interp *interp, const char *string,
     163        int *indexPtr);
     164static int GetHeightMap(Tcl_Interp *interp, const char *string,
     165        HeightMap **hmPtrPtr);
     166static int GetIndices(Tcl_Interp *interp, int argc, const char *argv[],
     167        vector<int>* vectorPtr);
     168static int GetAxis(Tcl_Interp *interp, const char *string, int *valPtr);
     169static int GetColor(Tcl_Interp *interp, const char *string, float *rgbPtr);
     170static int FillBufferFromStdin(Tcl_Interp *interp, Rappture::Buffer &buf,
     171        int nBytes);
     172static HeightMap *CreateHeightMap(ClientData clientData, Tcl_Interp *interp,
     173        int argc, const char *argv[]);
     174
     175
     176static int
     177GetFloat(Tcl_Interp *interp, const char *string, float *valuePtr)
     178{
     179    double value;
     180
     181    if (Tcl_GetDouble(interp, string, &value) != TCL_OK) {
     182        return TCL_ERROR;
     183    }
     184    *valuePtr = (float)value;
     185}
    109186
    110187/*
     
    121198 * ----------------------------------------------------------------------
    122199 */
    123 static int CameraCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    124 {
    125         if (argc < 2) {
    126                 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    127                         " option arg arg...\"", (char*)NULL);
    128                 return TCL_ERROR;
    129     }
    130 
    131     char c = *argv[1];
    132         if (c == 'a' && strcmp(argv[1],"angle") == 0) {
     200static int
     201CameraCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     202{
     203    if (argc < 2) {
     204        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     205                         " option arg arg...\"", (char*)NULL);
     206        return TCL_ERROR;
     207    }
     208
     209    char c = argv[1][0];
     210    if ((c == 'a') && (strcmp(argv[1],"angle") == 0)) {
    133211        if (argc != 5) {
    134                     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    135                             " angle xangle yangle zangle\"", (char*)NULL);
    136                     return TCL_ERROR;
    137         }
    138 
     212            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     213                             " angle xangle yangle zangle\"", (char*)NULL);
     214            return TCL_ERROR;
     215        }
    139216        double xangle, yangle, zangle;
    140             if (Tcl_GetDouble(interp, argv[2], &xangle) != TCL_OK) {
    141                     return TCL_ERROR;
    142             }
    143             if (Tcl_GetDouble(interp, argv[3], &yangle) != TCL_OK) {
    144                     return TCL_ERROR;
    145             }
    146             if (Tcl_GetDouble(interp, argv[4], &zangle) != TCL_OK) {
    147                     return TCL_ERROR;
    148             }
    149             cam->rotate(xangle, yangle, zangle);
    150 
    151             return TCL_OK;
    152         }
    153         else if (c == 'a' && strcmp(argv[1],"aim") == 0) {
     217        if ((Tcl_GetDouble(interp, argv[2], &xangle) != TCL_OK) ||
     218            (Tcl_GetDouble(interp, argv[3], &yangle) != TCL_OK) ||
     219            (Tcl_GetDouble(interp, argv[4], &zangle) != TCL_OK)) {
     220            return TCL_ERROR;
     221        }
     222        cam->rotate(xangle, yangle, zangle);
     223    } else if ((c == 'a') && (strcmp(argv[1], "aim") == 0)) {
    154224        if (argc != 5) {
    155                     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    156                             " aim x y z\"", (char*)NULL);
    157                     return TCL_ERROR;
    158         }
    159 
     225            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     226                             " aim x y z\"", (char*)NULL);
     227            return TCL_ERROR;
     228        }
     229       
    160230        double x0, y0, z0;
    161             if (Tcl_GetDouble(interp, argv[2], &x0) != TCL_OK) {
    162                     return TCL_ERROR;
    163             }
    164             if (Tcl_GetDouble(interp, argv[3], &y0) != TCL_OK) {
    165                     return TCL_ERROR;
    166             }
    167             if (Tcl_GetDouble(interp, argv[4], &z0) != TCL_OK) {
    168                     return TCL_ERROR;
    169             }
    170             cam->aim(x0, y0, z0);
    171 
    172             return TCL_OK;
    173         }
    174         else if (c == 'z' && strcmp(argv[1],"zoom") == 0) {
     231        if ((Tcl_GetDouble(interp, argv[2], &x0) != TCL_OK) ||
     232            (Tcl_GetDouble(interp, argv[3], &y0) != TCL_OK) ||
     233            (Tcl_GetDouble(interp, argv[4], &z0) != TCL_OK)) {
     234            return TCL_ERROR;
     235        }
     236        cam->aim(x0, y0, z0);
     237    } else if ((c == 'z') && (strcmp(argv[1],"zoom") == 0)) {
    175238        if (argc != 3) {
    176                     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    177                             " zoom factor\"", (char*)NULL);
    178                     return TCL_ERROR;
    179         }
    180 
     239            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     240                             " zoom factor\"", (char*)NULL);
     241            return TCL_ERROR;
     242        }
     243       
    181244        double zoom;
    182             if (Tcl_GetDouble(interp, argv[2], &zoom) != TCL_OK) {
    183                     return TCL_ERROR;
    184             }
    185 
     245        if (Tcl_GetDouble(interp, argv[2], &zoom) != TCL_OK) {
     246            return TCL_ERROR;
     247        }
     248       
    186249        live_obj_z = -2.5/zoom;
    187                 cam->move(live_obj_x, live_obj_y, live_obj_z);
    188 
    189             return TCL_OK;
    190     }
    191 
     250        cam->move(live_obj_x, live_obj_y, live_obj_z);
     251    } else {
    192252        Tcl_AppendResult(interp, "bad option \"", argv[1],
    193                 "\": should be aim, angle, or zoom", (char*)NULL);
    194         return TCL_ERROR;
     253                     "\": should be aim, angle, or zoom", (char*)NULL);
     254        return TCL_ERROR;
     255    }
     256    return TCL_OK;
    195257}
    196258
    197259static int
    198 ScreenShotCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     260ScreenShotCmd(ClientData cdata, Tcl_Interp *interp, int argc,
     261              const char *argv[])
    199262{
    200263    int old_win_width = win_width;
     
    202265
    203266#ifdef XINETD
    204     resize_offscreen_buffer(1024, 1024);
     267    nv_resize_offscreen_buffer(1024, 1024);
    205268    cam->set_screen_size(30, 90, 1024 - 60, 1024 - 120);
    206     offscreen_buffer_capture();  //enable offscreen render
    207     display();
     269    nv_offscreen_buffer_capture();  //enable offscreen render
     270    nv_display();
    208271
    209272    // INSOO
    210273    // TBD
    211274    Volume* vol = volume[0];
    212     TransferFunction* tf = g_vol_render->get_volume_shading(vol);
    213     if (tf)
    214     {
     275    TransferFunction* tf;
     276    tf = g_vol_render->get_volume_shading(vol);
     277    if (tf != NULL) {
    215278        float data[512];
     279
    216280        for (int i=0; i < 256; i++) {
    217281            data[i] = data[i+256] = (float)(i/255.0);
    218282        }
    219283        Texture2D* plane = new Texture2D(256, 2, GL_FLOAT, GL_LINEAR, 1, data);
    220         g_color_table_renderer->render(1024, 1024, plane, tf, vol->range_min(), vol->range_max());
     284        g_color_table_renderer->render(1024, 1024, plane, tf, vol->range_min(),
     285                vol->range_max());
    221286        delete plane;
    222287    }
    223 
    224     read_screen();
     288    nv_read_screen();
    225289    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    226 
    227290    bmp_write("nv>screenshot -bytes");
    228    
    229     resize_offscreen_buffer(old_win_width, old_win_height);
     291    nv_resize_offscreen_buffer(old_win_width, old_win_height);
    230292#endif
    231 
    232         return TCL_OK;
     293    return TCL_OK;
    233294}
    234295
     
    247308 * are updated.
    248309 * ----------------------------------------------------------------------
    249 */
    250 
     310 */
    251311static int
    252 CutplaneCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     312CutplaneCmd(ClientData cdata, Tcl_Interp *interp, int argc,
     313            const char *argv[])
    253314{
    254315    if (argc < 2) {
     
    258319    }
    259320
    260     char c = *argv[1];
    261     if (c == 's' && strcmp(argv[1],"state") == 0) {
     321    char c = argv[1][0];
     322    if ((c == 's') && (strcmp(argv[1],"state") == 0)) {
    262323        if (argc < 4) {
    263324            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    280341            return TCL_ERROR;
    281342        }
    282 
    283         vector<int>::iterator iter = ivol.begin();
    284         while (iter != ivol.end()) {
    285             if (state) {
     343        if (state) {
     344            vector<int>::iterator iter;
     345            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    286346                volume[*iter]->enable_cutplane(axis);
    287             } else {
     347            }
     348        } else {
     349            vector<int>::iterator iter;
     350            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    288351                volume[*iter]->disable_cutplane(axis);
    289             }
    290             ++iter;
    291         }
    292         return TCL_OK;
    293     }
    294     else if (c == 'p' && strcmp(argv[1],"position") == 0) {
     352            }
     353        }
     354    } else if ((c == 'p') && (strcmp(argv[1],"position") == 0)) {
    295355        if (argc < 4) {
    296356            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    299359        }
    300360
    301         double relval;
    302         if (Tcl_GetDouble(interp, argv[2], &relval) != TCL_OK) {
     361        float relval;
     362        if (GetFloat(interp, argv[2], &relval) != TCL_OK) {
    303363            return TCL_ERROR;
    304364        }
    305365        // keep this just inside the volume so it doesn't disappear
    306         if (relval < 0.01) { relval = 0.01; }
    307         if (relval > 0.99) { relval = 0.99; }
     366        if (relval < 0.01f) {
     367            relval = 0.01f;
     368        } else if (relval > 0.99f) {
     369            relval = 0.99f;
     370        }
    308371
    309372        int axis;
    310         if (GetAxis(interp, (char*) argv[3], &axis) != TCL_OK) {
     373        if (GetAxis(interp, argv[3], &axis) != TCL_OK) {
    311374            return TCL_ERROR;
    312375        }
    313376
    314377        vector<int> ivol;
    315         if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) {
     378        if (GetVolumeIndices(interp, argc - 4, argv + 4, &ivol) != TCL_OK) {
    316379            return TCL_ERROR;
    317380        }
    318 
    319         vector<int>::iterator iter = ivol.begin();
    320         while (iter != ivol.end()) {
    321             volume[*iter]->move_cutplane(axis, (float)relval);
    322             ++iter;
    323         }
    324         return TCL_OK;
    325     }
    326 
    327     Tcl_AppendResult(interp, "bad option \"", argv[1],
    328         "\": should be position or state", (char*)NULL);
    329     return TCL_ERROR;
    330 }
    331 
     381        vector<int>::iterator iter;
     382        for (iter = ivol.begin(); iter != ivol.end(); iter++) {
     383            volume[*iter]->move_cutplane(axis, relval);
     384        }
     385    } else {
     386        Tcl_AppendResult(interp, "bad option \"", argv[1],
     387                         "\": should be position or state", (char*)NULL);
     388        return TCL_ERROR;
     389    }
     390    return TCL_OK;
     391}
    332392
    333393/*
     
    343403 */
    344404static int
    345 LegendCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     405LegendCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    346406{
    347407    if (argc != 4) {
     
    351411    }
    352412
    353     TransferFunction *tf = NULL;
    354     int ivol;
    355     if (Tcl_GetInt(interp, argv[1], &ivol) != TCL_OK) {
     413    Volume *vol;
     414    if (GetVolume(interp, argv[1], &vol) != TCL_OK) {
    356415        return TCL_ERROR;
    357416    }
    358 
    359     if (ivol < n_volumes) {
    360         tf = g_vol_render->get_volume_shading(volume[ivol]);
    361     }
     417    TransferFunction *tf;
     418    tf = g_vol_render->get_volume_shading(vol);
    362419    if (tf == NULL) {
    363         Tcl_AppendResult(interp, "transfer function not defined for volume ", argv[1], (char*)NULL);
     420        Tcl_AppendResult(interp, "no transfer function defined for volume \"",
     421                argv[1], "\"", (char*)NULL);
    364422        return TCL_ERROR;
    365423    }
     
    375433        return TCL_ERROR;
    376434    }
    377 
    378     renderLegend(ivol, width, height, argv[1]);
    379 
     435    nv_render_legend(tf, vol->range_min(), vol->range_max(), width, height,
     436        argv[1]);
    380437    return TCL_OK;
    381438}
     
    391448 */
    392449static int
    393 ScreenCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     450ScreenCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    394451{
    395452    int w, h;
     
    406463        return TCL_ERROR;
    407464    }
    408     resize_offscreen_buffer(w, h);
    409 
     465    nv_resize_offscreen_buffer(w, h);
    410466    return TCL_OK;
    411467}
     
    422478 */
    423479static int
    424 TransfuncCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    425 {
    426         if (argc < 2) {
    427                 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    428                         " option arg arg...\"", (char*)NULL);
    429                 return TCL_ERROR;
    430     }
    431 
    432     char c = *argv[1];
    433         if (c == 'd' && strcmp(argv[1],"define") == 0) {
     480TransfuncCmd(ClientData cdata, Tcl_Interp *interp, int argc,
     481             const char *argv[])
     482{
     483    if (argc < 2) {
     484        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     485                         " option arg arg...\"", (char*)NULL);
     486        return TCL_ERROR;
     487    }
     488
     489    char c = argv[1][0];
     490    if ((c == 'd') && (strcmp(argv[1],"define") == 0)) {
    434491        if (argc != 5) {
    435                     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    436                             argv[1], " define name colormap alphamap\"", (char*)NULL);
     492            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     493                " define name colormap alphamap\"", (char*)NULL);
    437494            return TCL_ERROR;
    438495        }
     
    440497        // decode the data and store in a series of fields
    441498        Rappture::Field1D rFunc, gFunc, bFunc, wFunc;
    442         int cmapc, wmapc, i, j;
    443         char **cmapv, **wmapv;
    444 
    445         if (Tcl_SplitList(interp, argv[3], &cmapc, (const char***)&cmapv) != TCL_OK) {
     499        int cmapc, wmapc, i;
     500        const char **cmapv;
     501        const char **wmapv;
     502
     503        wmapv = cmapv = NULL;
     504        if (Tcl_SplitList(interp, argv[3], &cmapc, &cmapv) != TCL_OK) {
    446505            return TCL_ERROR;
    447506        }
    448         if (cmapc % 4 != 0) {
    449             Tcl_Free((char*)cmapv);
    450                     Tcl_AppendResult(interp, "bad colormap in transfunc: should be ",
     507        if ((cmapc % 4) != 0) {
     508            Tcl_AppendResult(interp, "bad colormap in transfunc: should be ",
    451509                "{ v r g b ... }", (char*)NULL);
    452             return TCL_ERROR;
    453         }
    454 
    455         if (Tcl_SplitList(interp, argv[4], &wmapc, (const char***)&wmapv) != TCL_OK) {
    456             return TCL_ERROR;
    457         }
    458         if (wmapc % 2 != 0) {
    459             Tcl_Free((char*)cmapv);
    460             Tcl_Free((char*)wmapv);
    461                     Tcl_AppendResult(interp, "bad alphamap in transfunc: should be ",
    462                 "{ v w ... }", (char*)NULL);
    463             return TCL_ERROR;
    464         }
    465 
     510            Tcl_Free((char*)cmapv);
     511            return TCL_ERROR;
     512        }
     513
     514        if (Tcl_SplitList(interp, argv[4], &wmapc, &wmapv) != TCL_OK) {
     515            Tcl_Free((char*)cmapv);
     516            return TCL_ERROR;
     517        }
     518        if ((wmapc % 2) != 0) {
     519            Tcl_AppendResult(interp, "wrong # elements in alphamap: should be ",
     520                        " { v w ... }", (char*)NULL);
     521            Tcl_Free((char*)cmapv);
     522            Tcl_Free((char*)wmapv);
     523            return TCL_ERROR;
     524        }
    466525        for (i=0; i < cmapc; i += 4) {
     526            int j;
    467527            double vals[4];
     528
    468529            for (j=0; j < 4; j++) {
    469530                if (Tcl_GetDouble(interp, cmapv[i+j], &vals[j]) != TCL_OK) {
    470                     Tcl_Free((char*)cmapv);
    471                     Tcl_Free((char*)wmapv);
    472                     return TCL_ERROR;
     531                    Tcl_Free((char*)cmapv);
     532                    Tcl_Free((char*)wmapv);
     533                    return TCL_ERROR;
    473534                }
    474                 if (vals[j] < 0 || vals[j] > 1) {
    475                     Tcl_Free((char*)cmapv);
    476                     Tcl_Free((char*)wmapv);
    477                             Tcl_AppendResult(interp, "bad value \"", cmapv[i+j],
     535                if ((vals[j] < 0.0) || (vals[j] > 1.0)) {
     536                    Tcl_AppendResult(interp, "bad value \"", cmapv[i+j],
    478537                        "\": should be in the range 0-1", (char*)NULL);
    479                     return TCL_ERROR;
     538                    Tcl_Free((char*)cmapv);
     539                    Tcl_Free((char*)wmapv);
     540                    return TCL_ERROR;
    480541                }
    481542            }
     
    484545            bFunc.define(vals[0], vals[3]);
    485546        }
    486 
    487547        for (i=0; i < wmapc; i += 2) {
    488548            double vals[2];
     549            int j;
     550
    489551            for (j=0; j < 2; j++) {
    490552                if (Tcl_GetDouble(interp, wmapv[i+j], &vals[j]) != TCL_OK) {
    491                     Tcl_Free((char*)cmapv);
    492                     Tcl_Free((char*)wmapv);
    493                     return TCL_ERROR;
     553                    Tcl_Free((char*)cmapv);
     554                    Tcl_Free((char*)wmapv);
     555                    return TCL_ERROR;
    494556                }
    495                 if (vals[j] < 0 || vals[j] > 1) {
    496                     Tcl_Free((char*)cmapv);
    497                     Tcl_Free((char*)wmapv);
    498                             Tcl_AppendResult(interp, "bad value \"", wmapv[i+j],
     557                if ((vals[j] < 0.0) || (vals[j] > 1.0)) {
     558                    Tcl_AppendResult(interp, "bad value \"", wmapv[i+j],
    499559                        "\": should be in the range 0-1", (char*)NULL);
    500                     return TCL_ERROR;
     560                    Tcl_Free((char*)cmapv);
     561                    Tcl_Free((char*)wmapv);
     562                    return TCL_ERROR;
    501563                }
    502564            }
     
    518580
    519581        // find or create this transfer function
    520         int newEntry;
    521         Tcl_HashEntry *entryPtr;
    522582        TransferFunction *tf;
    523 
    524         entryPtr = Tcl_CreateHashEntry(&tftable, argv[2], &newEntry);
    525         if (newEntry) {
    526             tf = new TransferFunction(nslots, data);
    527             Tcl_SetHashValue(entryPtr, (ClientData)tf);
    528         } else {
    529             tf = (TransferFunction*)Tcl_GetHashValue(entryPtr);
    530             tf->update(data);
    531         }
    532 
    533         return TCL_OK;
    534     }
    535 
    536 
    537     Tcl_AppendResult(interp, "bad option \"", argv[1],
    538         "\": should be define", (char*)NULL);
    539     return TCL_ERROR;
     583        tf = nv_get_transfunc(argv[2]);
     584        if (tf != NULL) {
     585            tf->update(data);
     586        } else {
     587            tf = nv_set_transfunc(argv[2], nslots, data);
     588        }
     589    } else {
     590        Tcl_AppendResult(interp, "bad option \"", argv[1],
     591                "\": should be define", (char*)NULL);
     592        return TCL_ERROR;
     593    }
     594    return TCL_OK;
    540595}
    541596
     
    550605 */
    551606static int
    552 UpCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     607UpCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    553608{
    554609    if (argc != 2) {
     
    559614
    560615    int sign = 1;
     616
    561617    char *axisName = (char*)argv[1];
    562618    if (*axisName == '-') {
     
    569625        return TCL_ERROR;
    570626    }
    571 
    572627    updir = (axis+1)*sign;
    573 
    574628    return TCL_OK;
    575629}
     
    591645 * ----------------------------------------------------------------------
    592646 */
    593 
    594647static int
    595 VolumeCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     648VolumeCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    596649{
    597650    if (argc < 2) {
     
    601654    }
    602655
    603     char c = *argv[1];
    604     if (c == 'a' && strcmp(argv[1],"axis") == 0) {
     656    char c = argv[1][0];
     657    if ((c == 'a') && (strcmp(argv[1],"axis") == 0)) {
    605658        if (argc < 3) {
    606659            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    608661            return TCL_ERROR;
    609662        }
    610         c = *argv[2];
    611         if (c == 'l' && strcmp(argv[2],"label") == 0) {
     663        c = argv[2][0];
     664        if ((c == 'l') && (strcmp(argv[2],"label") == 0)) {
    612665            if (argc < 4) {
    613666                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    622675
    623676            vector<int> ivol;
    624             if (GetVolumeIndices(interp, argc-5, argv+5, &ivol) != TCL_OK) {
    625                 return TCL_ERROR;
    626             }
    627 
    628             vector<int>::iterator iter = ivol.begin();
    629             while (iter != ivol.end()) {
     677            if (GetVolumeIndices(interp, argc - 5, argv + 5, &ivol) != TCL_OK) {
     678                return TCL_ERROR;
     679            }
     680
     681            vector<int>::iterator iter;
     682            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    630683                volume[*iter]->set_label(axis, (char*)argv[4]);
    631                 ++iter;
    632             }
    633             return TCL_OK;
    634         }
    635 
    636         Tcl_AppendResult(interp, "bad option \"", argv[2],
    637             "\": should be label", (char*)NULL);
    638         return TCL_ERROR;
    639     }
    640     else if (c == 'd' && strcmp(argv[1],"data") == 0) {
     684            }
     685        } else {
     686            Tcl_AppendResult(interp, "bad option \"", argv[2],
     687                             "\": should be label", (char*)NULL);
     688            return TCL_ERROR;
     689        }
     690    } else if ((c == 'd') && (strcmp(argv[1],"data") == 0)) {
    641691        if (argc < 3) {
    642692            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    644694            return TCL_ERROR;
    645695        }
    646         c = *argv[2];
    647         if (c == 's' && strcmp(argv[2],"state") == 0) {
     696        c = argv[2][0];
     697        if ((c == 's') && (strcmp(argv[2],"state") == 0)) {
    648698            if (argc < 4) {
    649699                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    651701                return TCL_ERROR;
    652702            }
    653 
    654703            int state;
    655704            if (Tcl_GetBoolean(interp, argv[3], &state) != TCL_OK) {
    656705                return TCL_ERROR;
    657706            }
    658 
    659707            vector<int> ivol;
    660708            if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) {
    661709                return TCL_ERROR;
    662710            }
    663 
    664             vector<int>::iterator iter = ivol.begin();
    665             while (iter != ivol.end()) {
    666                 if (state) {
     711            if (state) {
     712                vector<int>::iterator iter;
     713                for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    667714                    volume[*iter]->enable_data();
    668                 } else {
     715                }
     716            } else {
     717                vector<int>::iterator iter;
     718                for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    669719                    volume[*iter]->disable_data();
    670                 }
    671                 ++iter;
    672             }
    673             return TCL_OK;
    674         }
    675         else if (c == 'f' && strcmp(argv[2],"follows") == 0) {
     720                }
     721            }
     722        } else if (c == 'f' && strcmp(argv[2],"follows") == 0) {
    676723            printf("Data Loading\n");
    677724            //fflush(stdout);
     
    689736            int totalsize = nbytes;
    690737            char buffer[8096];
    691             while (nbytes > 0)
    692             {
    693                 int chunk = (sizeof(buffer) < nbytes) ? sizeof(buffer) : nbytes;
    694                 int status = fread(buffer, 1, chunk, stdin);
     738            while (nbytes > 0) {
     739                int chunk, status;
     740
     741                chunk = (sizeof(buffer) < nbytes) ? sizeof(buffer) : nbytes;
     742                status = fread(buffer, 1, chunk, stdin);
    695743                //printf("Begin Reading [%d Read : %d Left]\n", status, nbytes - status);
    696744                fflush(stdout);
     
    705753                }
    706754            }
    707 
    708755            err = Rappture::encoding::decode(buf,RPENC_Z|RPENC_B64|RPENC_HDR);
    709756            if (err) {
     
    721768#ifdef _LOCAL_ZINC_TEST_
    722769            //FILE* fp = fopen("/home/nanohub/vrinside/nv/data/HOON/QDWL_100_100_50_strain_8000i.nd_zatom_12_1", "rb");
    723             FILE* fp = fopen("/home/nanohub/vrinside/nv/data/HOON/GaAs_AlGaAs_2QD_B4.nd_zc_1_wf", "rb");
    724             unsigned char* b = (unsigned char*) malloc(buf.size());
    725             if (fp == 0)
    726             {
     770            FILE* fp;
     771
     772            fp = fopen("/home/nanohub/vrinside/nv/data/HOON/GaAs_AlGaAs_2QD_B4.nd_zc_1_wf", "rb");
     773            if (fp == NULL) {
    727774                printf("cannot open the file\n");
    728775                fflush(stdout);
    729776                return TCL_ERROR;
    730777            }
     778            unsigned char* b = (unsigned char*)malloc(buf.size());
    731779            fread(b, buf.size(), 1, fp);
    732780            fclose(fp);
    733781#endif
    734 
    735            
    736782            printf("Checking header[%s]\n", header);
    737783            fflush(stdout);
    738             if (!strcmp(header, "<HDR>"))
    739             {
     784            if (strcmp(header, "<HDR>") == 0) {
    740785                Volume* vol = NULL;
    741786
     
    754799                printf("finish loading\n");
    755800                fflush(stdout);
    756                 if (vol)
    757                 {
    758                     while (n_volumes <= n)
    759                     {
     801                if (vol) {
     802                    while (n_volumes <= n) {
    760803                        volume.push_back((Volume*) NULL);
    761804                        n_volumes++;
    762805                    }
    763806
    764                     if (volume[n] != NULL)
    765                     {
     807                    if (volume[n] != NULL) {
    766808                        delete volume[n];
    767809                        volume[n] = NULL;
     
    775817                    volume[n] = vol;
    776818                }
    777             }
    778819#ifdef __TEST_CODE__
    779             else if (!strcmp(header, "<FET>"))
    780             {
     820            } else if (strcmp(header, "<FET>") == 0) {
    781821                printf("FET loading...\n");
    782822                fflush(stdout);
     
    789829                    return TCL_ERROR;
    790830                }
    791             }
    792831#endif
    793             else
    794             {
     832            } else {
    795833                printf("OpenDX loading...\n");
    796834                fflush(stdout);
     
    814852            //   appear at all.
    815853            //
    816             if (volume[n])
    817             {
     854            if (volume[n] != NULL) {
    818855                volume[n]->set_n_slice(256-n);
    819856                volume[n]->disable_cutplane(0);
     
    821858                volume[n]->disable_cutplane(2);
    822859
    823                 g_vol_render->add_volume(volume[n], get_transfunc("default"));
    824             }
    825 
    826             return TCL_OK;
    827         }
    828         Tcl_AppendResult(interp, "bad option \"", argv[2],
    829             "\": should be follows or state", (char*)NULL);
    830         return TCL_ERROR;
    831     }
    832     else if (c == 'o' && strcmp(argv[1],"outline") == 0) {
     860                g_vol_render->add_volume(volume[n],nv_get_transfunc("default"));
     861            }
     862        } else {
     863            Tcl_AppendResult(interp, "bad option \"", argv[2],
     864                             "\": should be follows or state", (char*)NULL);
     865            return TCL_ERROR;
     866        }
     867    } else if (c == 'o' && strcmp(argv[1],"outline") == 0) {
    833868        if (argc < 3) {
    834869            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    836871            return TCL_ERROR;
    837872        }
    838         c = *argv[2];
    839         if (c == 's' && strcmp(argv[2],"state") == 0) {
     873        c = argv[2][0];
     874        if ((c == 's') && (strcmp(argv[2],"state") == 0)) {
    840875            if (argc < 3) {
    841876                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    848883                return TCL_ERROR;
    849884            }
    850 
    851885            vector<int> ivol;
    852886            if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) {
    853887                return TCL_ERROR;
    854888            }
    855 
    856             vector<int>::iterator iter = ivol.begin();
    857             while (iter != ivol.end()) {
    858                 if (state) {
     889            if (state) {
     890                vector<int>::iterator iter;
     891                for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    859892                    volume[*iter]->enable_outline();
    860                 } else {
     893                }
     894            } else {
     895                vector<int>::iterator iter;
     896                for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    861897                    volume[*iter]->disable_outline();
     898                }
     899            }
     900        } else if (c == 'v' && strcmp(argv[2],"visible") == 0) {
     901            int ivisible;
     902
     903            if (Tcl_GetBoolean(interp, argv[3], &ivisible) != TCL_OK) {
     904                return TCL_ERROR;
     905            }           
     906            if (!ivisible) {
     907                for (int i = 0; i < n_volumes; ++i) {
     908                    if (volume[i]) {
     909                        volume[i]->disable_outline();
     910                    }
    862911                }
    863                 ++iter;
    864             }
    865             return TCL_OK;
    866         }
    867         else if (c == 'v' && strcmp(argv[2],"visible") == 0) {
    868             if (argv[3] == "false")
    869             {
    870                 for (int i = 0; i < n_volumes; ++i)
    871                 {
    872                     if (volume[i]) volume[i]->disable_outline();
     912            } else {
     913                for (int i = 0; i < n_volumes; ++i) {
     914                    if (volume[i]) {
     915                        volume[i]->enable_outline();
     916                    }
    873917                }
    874918            }
    875             else if (argv[3] == "true")
    876             {
    877                 for (int i = 0; i < n_volumes; ++i)
    878                 {
    879                     if (volume[i]) volume[i]->enable_outline();
    880                 }
    881             }
    882 
    883             return TCL_OK;
    884         }
    885         else if (c == 'c' && strcmp(argv[2],"color") == 0) {
     919        } else if ((c == 'c') && (strcmp(argv[2],"color") == 0)) {
    886920            if (argc < 3) {
    887921                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    889923                return TCL_ERROR;
    890924            }
    891 
    892925            float rgb[3];
    893             if (GetColor(interp, (char*) argv[3], rgb) != TCL_OK) {
    894                 return TCL_ERROR;
    895             }
    896 
     926            if (GetColor(interp, argv[3], rgb) != TCL_OK) {
     927                return TCL_ERROR;
     928            }
    897929            vector<int> ivol;
    898             if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) {
    899                 return TCL_ERROR;
    900             }
    901 
    902             vector<int>::iterator iter = ivol.begin();
    903             while (iter != ivol.end()) {
     930            if (GetVolumeIndices(interp, argc - 4, argv + 4, &ivol) != TCL_OK) {
     931                return TCL_ERROR;
     932            }
     933            vector<int>::iterator iter;
     934            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    904935                volume[*iter]->set_outline_color(rgb);
    905                 ++iter;
    906             }
    907             return TCL_OK;
    908         }
    909 
    910         Tcl_AppendResult(interp, "bad option \"", argv[2],
    911             "\": should be color or state", (char*)NULL);
    912         return TCL_ERROR;
    913     }
    914     else if (c == 's' && strcmp(argv[1],"shading") == 0) {
     936            }
     937        } else {
     938            Tcl_AppendResult(interp, "bad option \"", argv[2],
     939                             "\": should be color or state", (char*)NULL);
     940            return TCL_ERROR;
     941        }
     942    } else if ((c == 's') && (strcmp(argv[1],"shading") == 0)) {
    915943        if (argc < 3) {
    916944            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    918946            return TCL_ERROR;
    919947        }
    920         c = *argv[2];
    921         if (c == 't' && strcmp(argv[2],"transfunc") == 0) {
     948        c = argv[2][0];
     949        if ((c == 't') && (strcmp(argv[2],"transfunc") == 0)) {
    922950            if (argc < 4) {
    923951                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    925953                return TCL_ERROR;
    926954            }
    927 
    928             TransferFunction *tf = get_transfunc((char*)argv[3]);
     955            TransferFunction *tf;
     956            tf = nv_get_transfunc(argv[3]);
    929957            if (tf == NULL) {
    930958                Tcl_AppendResult(interp, "transfer function \"", argv[3],
     
    932960                return TCL_ERROR;
    933961            }
    934 
    935962            vector<int> ivol;
    936963            if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) {
    937964                return TCL_ERROR;
    938965            }
    939 
    940             vector<int>::iterator iter = ivol.begin();
    941             while (iter != ivol.end()) {
     966            vector<int>::iterator iter;
     967            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
    942968                g_vol_render->shade_volume(volume[*iter], tf);
    943                 ++iter;
    944             }
    945             return TCL_OK;
    946         }
    947         else if (c == 'd' && strcmp(argv[2],"diffuse") == 0) {
     969            }
     970        } else if ((c == 'd') && (strcmp(argv[2], "diffuse") == 0)) {
    948971            if (argc < 4) {
    949972                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    952975            }
    953976
    954             double dval;
    955             if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) {
    956                 return TCL_ERROR;
    957             }
    958 
     977            float diffuse;
     978            if (GetFloat(interp, argv[3], &diffuse) != TCL_OK) {
     979                return TCL_ERROR;
     980            }
    959981            vector<int> ivol;
    960982            if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) {
    961983                return TCL_ERROR;
    962984            }
    963 
    964             vector<int>::iterator iter = ivol.begin();
    965             while (iter != ivol.end()) {
    966                 volume[*iter]->set_diffuse((float)dval);
    967                 ++iter;
    968             }
    969             return TCL_OK;
    970         }
    971         else if (c == 'o' && strcmp(argv[2],"opacity") == 0) {
     985            vector<int>::iterator iter;
     986            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
     987                volume[*iter]->set_diffuse(diffuse);
     988            }
     989        } else if ((c == 'o') && (strcmp(argv[2], "opacity") == 0)) {
    972990            if (argc < 4) {
    973991                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    975993                return TCL_ERROR;
    976994            }
    977 
    978             double dval;
    979             if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) {
    980                 return TCL_ERROR;
    981             }
    982 
     995            float opacity;
     996            if (GetFloat(interp, argv[3], &opacity) != TCL_OK) {
     997                return TCL_ERROR;
     998            }
    983999            vector<int> ivol;
    9841000            if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) {
    9851001                return TCL_ERROR;
    9861002            }
    987 
    988             vector<int>::iterator iter = ivol.begin();
    989             while (iter != ivol.end()) {
    990                 volume[*iter]->set_opacity_scale((float)dval);
    991                 ++iter;
    992             }
    993             return TCL_OK;
    994         }
    995         else if (c == 's' && strcmp(argv[2],"specular") == 0) {
     1003            vector<int>::iterator iter;
     1004            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
     1005                volume[*iter]->set_opacity_scale(opacity);
     1006            }
     1007        } else if ((c == 's') && (strcmp(argv[2], "specular") == 0)) {
    9961008            if (argc < 4) {
    9971009                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    9991011                return TCL_ERROR;
    10001012            }
    1001 
    1002             double dval;
    1003             if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) {
    1004                 return TCL_ERROR;
    1005             }
    1006 
     1013            float specular;
     1014            if (GetFloat(interp, argv[3], &specular) != TCL_OK) {
     1015                return TCL_ERROR;
     1016            }
    10071017            vector<int> ivol;
    10081018            if (GetVolumeIndices(interp, argc-4, argv+4, &ivol) != TCL_OK) {
    10091019                return TCL_ERROR;
    10101020            }
    1011 
    1012             vector<int>::iterator iter = ivol.begin();
    1013             while (iter != ivol.end()) {
    1014                 volume[*iter]->set_specular((float)dval);
    1015                 ++iter;
    1016             }
    1017             return TCL_OK;
    1018         }
    1019         Tcl_AppendResult(interp, "bad option \"", argv[2],
    1020             "\": should be diffuse, opacity, specular, or transfunc", (char*)NULL);
    1021         return TCL_ERROR;
    1022     }
    1023     else if (c == 's' && strcmp(argv[1],"state") == 0) {
     1021            vector<int>::iterator iter;
     1022            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
     1023                volume[*iter]->set_specular(specular);
     1024            }
     1025        } else {
     1026            Tcl_AppendResult(interp, "bad option \"", argv[2], "\": should be ",
     1027                "diffuse, opacity, specular, or transfunc", (char*)NULL);
     1028            return TCL_ERROR;
     1029        }
     1030    } else if ((c == 's') && (strcmp(argv[1], "state") == 0)) {
    10241031        if (argc < 3) {
    10251032            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    10271034            return TCL_ERROR;
    10281035        }
    1029 
    10301036        int state;
    10311037        if (Tcl_GetBoolean(interp, argv[2], &state) != TCL_OK) {
    10321038            return TCL_ERROR;
    10331039        }
    1034 
    10351040        vector<int> ivol;
    10361041        if (GetVolumeIndices(interp, argc-3, argv+3, &ivol) != TCL_OK) {
    10371042            return TCL_ERROR;
    10381043        }
    1039 
    1040         vector<int>::iterator iter = ivol.begin();
    1041         while (iter != ivol.end()) {
    1042             if (state) {
    1043                 volume[*iter]->enable();
    1044             } else {
    1045                 volume[*iter]->disable();
    1046             }
    1047             ++iter;
    1048         }
    1049         return TCL_OK;
    1050     }
    1051     else if (c == 't' && strcmp(argv[1],"test2") == 0) {
     1044        if (state) {
     1045            vector<int>::iterator iter;
     1046            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
     1047                volume[*iter]->enable();
     1048            }
     1049        } else {
     1050            vector<int>::iterator iter;
     1051            for (iter = ivol.begin(); iter != ivol.end(); iter++) {
     1052                volume[*iter]->disable();
     1053            }
     1054        }
     1055    } else if ((c == 't') && (strcmp(argv[1],"test2") == 0)) {
    10521056        volume[1]->disable_data();
    10531057        volume[1]->disable();
    10541058        return TCL_OK;
    1055     }
    1056 
    1057     Tcl_AppendResult(interp, "bad option \"", argv[1],
    1058         "\": should be data, outline, shading, or state", (char*)NULL);
    1059     return TCL_ERROR;
    1060 }
    1061 
    1062 
    1063 int HeightMapCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]))
    1064 {
    1065     if (argc < 2)
    1066     {
    1067         {   
    1068         srand( (unsigned)time( NULL ) );
    1069         int size = 20 * 20;
    1070         float sigma = 5.0f;
    1071         float mean = exp(0.0f) / (sigma * sqrt(2.0f));
    1072         float* data = (float*) malloc(sizeof(float) * size);
    1073 
    1074         float x;
    1075         for (int i = 0; i < size; ++i)
    1076         {
    1077             x = - 10 + i%20;
    1078             data[i] = exp(- (x * x)/(2 * sigma * sigma)) / (sigma * sqrt(2.0f)) / mean;
    1079         }
    1080 
    1081         HeightMap* heightMap = new HeightMap();
    1082         heightMap->setHeight(0, 0, 1, 1, 20, 20, data);
    1083         heightMap->setColorMap(get_transfunc("default"));
    1084         heightMap->setVisible(true);
    1085         heightMap->setLineContourVisible(true);
    1086         g_heightMap.push_back(heightMap);
    1087         }
    1088 
    1089         return TCL_OK;
    1090     }
    1091 
    1092     char c = *argv[1];
    1093     if (c == 'd' && strcmp(argv[1],"data") == 0)
    1094     {
     1059    } else {
     1060        Tcl_AppendResult(interp, "bad option \"", argv[1], "\": should be ",
     1061                "data, outline, shading, or state", (char*)NULL);
     1062        return TCL_ERROR;
     1063    }
     1064    return TCL_OK;
     1065}
     1066
     1067static int
     1068HeightMapCmd(ClientData cdata, Tcl_Interp *interp, int argc,
     1069             const char *argv[])
     1070{
     1071    fprintf(stderr, "in heightmap command\n");
     1072    fflush(stderr);
     1073    if (argc < 2) {
     1074        srand((unsigned)time(NULL));
     1075        int size = 20 * 20;
     1076        double sigma = 5.0;
     1077        double mean = exp(0.0) / (sigma * sqrt(2.0));
     1078        float* data = (float*) malloc(sizeof(float) * size);
     1079       
     1080        float x;
     1081        for (int i = 0; i < size; ++i) {
     1082            x = - 10 + i%20;
     1083            data[i] = exp(- (x * x)/(2 * sigma * sigma)) /
     1084                (sigma * sqrt(2.0)) / mean;
     1085        }
     1086        HeightMap* heightMap = new HeightMap();
     1087        heightMap->setHeight(0.0f, 0.0f, 1.0f, 1.0f, 20, 20, data);
     1088        heightMap->setColorMap(nv_get_transfunc("default"));
     1089        heightMap->setVisible(true);
     1090        heightMap->setLineContourVisible(true);
     1091        g_heightMap.push_back(heightMap);
     1092        return TCL_OK;
     1093    }
     1094   
     1095    char c = argv[1][0];
     1096    if ((c == 'c') && (strcmp(argv[1], "create") == 0)) {
     1097        HeightMap *hMap;
     1098
     1099        /* heightmap create xmin ymin xmax ymax xnum ynum values */
     1100        hMap = CreateHeightMap(cdata, interp, argc - 2, argv + 2);
     1101        if (hMap == NULL) {
     1102            return TCL_ERROR;
     1103        }
     1104        g_heightMap.push_back(hMap);
     1105        /* FIXME: Convert this file to use Tcl_CmdObjProc */
     1106        sprintf(interp->result, "%d", g_heightMap.size() - 1);
     1107        return TCL_OK;
     1108    } else if ((c == 'd') && (strcmp(argv[1],"data") == 0)) {
     1109        fprintf(stderr, "heightmap data\n");
     1110    fflush(stderr);
     1111        //bytes
     1112        char c;
     1113        c = argv[2][0];
     1114        if ((c == 'v') && (strcmp(argv[2],"visible") == 0)) {
     1115            int ivisible;
     1116            vector<int> indices;
     1117
     1118            if (Tcl_GetBoolean(interp, argv[3], &ivisible) != TCL_OK) {
     1119                return TCL_ERROR;
     1120            }
     1121            if (GetIndices(interp, argc-4, argv+4, &indices) != TCL_OK) {
     1122               return TCL_ERROR;
     1123            }
     1124            bool visible;
     1125            visible = (bool)ivisible;
     1126            for (int i = 0; i < indices.size(); ++i) {
     1127                if ((indices[i] < g_heightMap.size()) &&
     1128                    (g_heightMap[indices[i]] != NULL)) {
     1129                    g_heightMap[indices[i]]->setVisible(visible);
     1130                }
     1131            }
     1132        } else if ((c == 'f') && (strcmp(argv[2],"follows") == 0)) {
     1133            Rappture::Buffer buf;
     1134            int nBytes;
     1135
     1136            fprintf(stderr, "in data follows\n");
     1137    fflush(stderr);
     1138            if (Tcl_GetInt(interp, argv[3], &nBytes) != TCL_OK) {
     1139                return TCL_ERROR;
     1140            }
     1141            fprintf(stderr, "expecting %d bytes\n", nBytes);
     1142    fflush(stderr);
     1143            if (FillBufferFromStdin(interp, buf, nBytes) != TCL_OK) {
     1144                return TCL_ERROR;
     1145            }
     1146            if (Tcl_Eval(interp, buf.bytes()) != TCL_OK) {
     1147                fprintf(stderr, "error in command: %s\n",
     1148                        Tcl_GetStringResult(interp));
     1149    fflush(stderr);
     1150                return TCL_ERROR;
     1151            }
     1152        } else {
     1153            Tcl_AppendResult(interp, "unknown option \"", argv[2], "\": ",
     1154                             "should be visible or follows", (char *)NULL);
     1155            return TCL_ERROR;
     1156        }
     1157    } else if ((c == 'l') && (strcmp(argv[1], "linecontour") == 0)) {
    10951158        //bytes
    10961159        vector<int> indices;
    1097         if (strcmp(argv[2],"visible") == 0)
    1098         {
    1099             bool visible = !strcmp(argv[3], "true");
    1100            
    1101             if (GetIndices(interp, argc-4, argv+4, &indices) != TCL_OK)
    1102             {
    1103                return TCL_ERROR;
    1104             }
    1105 
    1106             for (int i = 0; i < indices.size(); ++i)
    1107             {
    1108                 if ((indices[i] < g_heightMap.size()) && (g_heightMap[indices[i]] != NULL))
    1109                 {
    1110                     g_heightMap[indices[i]]->setVisible(visible);
    1111                 }
    1112             }
    1113             return TCL_OK;
    1114         }
    1115         else if (c == 'f' && strcmp(argv[2],"follows") == 0) {
    1116             int nbytes;
    1117             if (Tcl_GetInt(interp, argv[3], &nbytes) != TCL_OK) {
    1118                 return TCL_ERROR;
    1119             }
    1120         }
    1121     }
    1122     else if (c == 'l' && (strcmp(argv[1], "linecontour") == 0))
    1123     {
    1124         //bytes
    1125         vector<int> indices;
    1126         if (strcmp(argv[2],"visible") == 0)
    1127         {
    1128            
    1129             bool visible = !(strcmp("true", argv[3]));
    1130             printf("heightmap linecontour visible %s\n", (visible)?"true":"false");
    1131             if (GetIndices(interp, argc-4, argv+4, &indices) != TCL_OK)
    1132             {
    1133                 return TCL_ERROR;
    1134             }
    1135 
    1136             for (int i = 0; i < indices.size(); ++i)
    1137             {
    1138                 printf("heightmap index %d\n");
    1139                 if ((indices[i] < g_heightMap.size()) && (g_heightMap[indices[i]] != NULL))
    1140                 {
    1141                     printf("heightmap index %d visible applied\n");
     1160        char c;
     1161        c = argv[2][0];
     1162        if ((c == 'v') && (strcmp(argv[2],"visible") == 0)) {
     1163            int ivisible;
     1164            bool visible;
     1165
     1166            if (Tcl_GetBoolean(interp, argv[3], &ivisible) != TCL_OK) {
     1167                return TCL_ERROR;
     1168            }
     1169            visible = (bool)ivisible;
     1170            if (GetIndices(interp, argc-4, argv+4, &indices) != TCL_OK) {
     1171                return TCL_ERROR;
     1172            }
     1173            for (int i = 0; i < indices.size(); ++i) {
     1174                if ((indices[i] < g_heightMap.size()) &&
     1175                    (g_heightMap[indices[i]] != NULL)) {
    11421176                    g_heightMap[indices[i]]->setLineContourVisible(visible);
    11431177                }
    11441178            }
    1145             return TCL_OK;
    1146         }
    1147         else if (strcmp(argv[2],"color") == 0)
    1148         {
    1149             double r, g, b;
    1150             if ((Tcl_GetDouble(interp, argv[3], &r) == TCL_OK) &&
    1151                 (Tcl_GetDouble(interp, argv[4], &g) == TCL_OK) &&
    1152                 (Tcl_GetDouble(interp, argv[5], &b) == TCL_OK)) {
    1153                 r = r / 255.0;
    1154                 g = g / 255.0;
    1155                 b = b / 255.0;
    1156             }
    1157             else
    1158             {
    1159                 return TCL_ERROR;
    1160             }
    1161 
     1179        } else if ((c == 'c') && (strcmp(argv[2],"color") == 0)) {
     1180            float r, g, b;
     1181            if ((GetFloat(interp, argv[3], &r) != TCL_OK) ||
     1182                (GetFloat(interp, argv[4], &g) != TCL_OK) ||
     1183                (GetFloat(interp, argv[5], &b) != TCL_OK)) {
     1184                return TCL_ERROR;
     1185            }           
    11621186            vector<int> indices;
    1163             if (GetIndices(interp, argc-6, argv+6, &indices) != TCL_OK)
    1164             {
    1165                 return TCL_ERROR;
    1166             }
    1167             for (int i = 0; i < indices.size(); ++i)
    1168             {
    1169                 if ((indices[i] < g_heightMap.size()) && (g_heightMap[indices[i]] != NULL))
    1170                 {
     1187            if (GetIndices(interp, argc-6, argv+6, &indices) != TCL_OK) {
     1188                return TCL_ERROR;
     1189            }
     1190            for (int i = 0; i < indices.size(); ++i) {
     1191                if ((indices[i] < g_heightMap.size()) &&
     1192                    (g_heightMap[indices[i]] != NULL)) {
    11711193                    g_heightMap[indices[i]]->setLineContourColor(r, g, b);
    11721194                }
    11731195            }
    1174 
    1175             return TCL_OK;
    1176         }
    1177     }
    1178     else if (c == 't' && (strcmp(argv[1], "transfunc") == 0))
    1179     {
    1180         TransferFunction *tf = get_transfunc((char*)argv[2]);
     1196        } else {
     1197            Tcl_AppendResult(interp, "unknown option \"", argv[2], "\": ",
     1198                             "should be visible or color", (char *)NULL);
     1199            return TCL_ERROR;
     1200        }
     1201    } else if ((c == 't') && (strcmp(argv[1], "transfunc") == 0)) {
     1202        TransferFunction *tf;
     1203
     1204        tf = nv_get_transfunc(argv[2]);
    11811205        if (tf == NULL) {
    1182             Tcl_AppendResult(interp, "transfer function \"", argv[3],
     1206            Tcl_AppendResult(interp, "transfer function \"", argv[2],
    11831207                "\" is not defined", (char*)NULL);
    11841208            return TCL_ERROR;
    11851209        }
    1186 
    11871210        vector<int> indices;
    1188         if (GetVolumeIndices(interp, argc - 3, argv + 3, &indices) != TCL_OK)
    1189         {
    1190             for (int i = 0; i < indices.size(); ++i)
    1191             {
    1192                 if ((indices[i] < g_heightMap.size()) && (g_heightMap[indices[i]] != NULL))
    1193                 {
    1194                     g_heightMap[indices[i]]->setColorMap(tf);
    1195                 }
    1196             }
    1197         }
    1198         return TCL_OK;
    1199     }
    1200    
    1201     Tcl_AppendResult(interp, "bad option \"", argv[1],
    1202         "\": should be data, outline, shading, or state", (char*)NULL);
    1203     return TCL_ERROR;
    1204 }
    1205 
    1206 int GridCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]))
    1207 {
    1208     char c = *argv[1];
    1209     if (c == 'v' && strcmp(argv[1],"visible") == 0)
    1210     {
    1211         if (strcmp(argv[2],"true") == 0)
    1212         {
    1213             g_grid->setVisible(true);
    1214             return TCL_OK;
    1215         }
    1216         else if (strcmp(argv[2],"false") == 0)
    1217         {
    1218             g_grid->setVisible(false);
    1219             return TCL_OK;
    1220         }
    1221     }
    1222     else if (c == 'l' && strcmp(argv[1],"linecount") == 0)
    1223     {
     1211        if (GetIndices(interp, argc - 3, argv + 3, &indices) != TCL_OK) {
     1212            return TCL_ERROR;
     1213        }
     1214        for (int i = 0; i < indices.size(); ++i) {
     1215            if ((indices[i] < g_heightMap.size()) &&
     1216                (g_heightMap[indices[i]] != NULL)) {
     1217                g_heightMap[indices[i]]->setColorMap(tf);
     1218            }
     1219        }
     1220    } else if ((c == 'l') && (strcmp(argv[1], "legend") == 0)) {
     1221        if (argc != 5) {
     1222            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     1223                             " legend index width height\"", (char*)NULL);
     1224            return TCL_ERROR;
     1225        }
     1226        HeightMap *hMap;
     1227        if (GetHeightMap(interp, argv[2], &hMap) != TCL_OK) {
     1228            return TCL_ERROR;
     1229        }
     1230        TransferFunction *tf;
     1231        tf = hMap->getColorMap();
     1232        if (tf == NULL) {
     1233            Tcl_AppendResult(interp,
     1234                        "no transfer function defined for heightmap \"",
     1235                        argv[1], "\"", (char*)NULL);
     1236            return TCL_ERROR;
     1237        }
     1238        int width, height;
     1239        if ((Tcl_GetInt(interp, argv[3], &width) != TCL_OK) ||
     1240            (Tcl_GetInt(interp, argv[4], &height) != TCL_OK)) {
     1241            return TCL_ERROR;
     1242        }
     1243        nv_render_legend(tf, hMap->range_min(), hMap->range_max(),
     1244                         width, height, argv[1]);
     1245    } else {
     1246        Tcl_AppendResult(interp, "bad option \"", argv[1],
     1247        "\": should be data, linecontour, legend, or transfunc", (char*)NULL);
     1248        return TCL_ERROR;
     1249    }
     1250    return TCL_OK;
     1251}
     1252
     1253static int
     1254GridCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
     1255{
     1256    char c = argv[1][0];
     1257    if ((c == 'v') && (strcmp(argv[1],"visible") == 0)) {
     1258        int ivisible;
     1259
     1260        if (Tcl_GetBoolean(interp, argv[2], &ivisible) != TCL_OK) {
     1261            return TCL_ERROR;
     1262        }
     1263        g_grid->setVisible((bool)ivisible);
     1264    } else if ((c == 'l') && (strcmp(argv[1],"linecount") == 0)) {
    12241265        int x, y, z;
    12251266
    1226         if ((Tcl_GetInt(interp, argv[2], &x) == TCL_OK) &&
    1227             (Tcl_GetInt(interp, argv[3], &y) == TCL_OK) &&
    1228             (Tcl_GetInt(interp, argv[4], &z) == TCL_OK)) {
    1229 
    1230             if (g_grid) g_grid->setGridLineCount(x, y, z);
    1231 
    1232             return TCL_OK;
    1233         }
    1234     }
    1235     else if (c == 'a' && strcmp(argv[1],"axiscolor") == 0)
    1236     {
    1237         int r, g, b;
    1238         if ((Tcl_GetInt(interp, argv[2], &r) == TCL_OK) &&
    1239             (Tcl_GetInt(interp, argv[3], &g) == TCL_OK) &&
    1240             (Tcl_GetInt(interp, argv[4], &b) == TCL_OK)) {
    1241 
    1242             if (g_grid) g_grid->setAxisColor(r / 255.0f, g / 255.0f, b / 255.0f);
    1243             return TCL_OK;
    1244         }
    1245     }
    1246     else if (c == 'l' && strcmp(argv[1],"linecolor") == 0)
    1247     {
    1248         int r, g, b;
    1249         if ((Tcl_GetInt(interp, argv[2], &r) == TCL_OK) &&
    1250             (Tcl_GetInt(interp, argv[3], &g) == TCL_OK) &&
    1251             (Tcl_GetInt(interp, argv[4], &b) == TCL_OK)) {
    1252 
    1253             if (g_grid) g_grid->setGridLineColor(r / 255.0f, g / 255.0f, b / 255.0f);
    1254             return TCL_OK;
    1255         }
    1256     }
    1257     else if (c == 'm')
    1258     {
    1259         if (strcmp(argv[1],"minmax") == 0)
    1260         {
    1261             double x1, y1, z1, x2, y2, z2;
    1262             if ((Tcl_GetDouble(interp, argv[2], &x1) == TCL_OK) &&
    1263                 (Tcl_GetDouble(interp, argv[3], &y1) == TCL_OK) &&
    1264                 (Tcl_GetDouble(interp, argv[4], &z1) == TCL_OK) &&
    1265                 (Tcl_GetDouble(interp, argv[5], &x2) == TCL_OK) &&
    1266                 (Tcl_GetDouble(interp, argv[6], &y2) == TCL_OK) &&
    1267                 (Tcl_GetDouble(interp, argv[7], &z2) == TCL_OK)) {
    1268 
    1269                 if (g_grid) g_grid->setMinMax(Vector3(x1, y1, z1), Vector3(x2, y2, z2));
    1270 
    1271                 return TCL_OK;
    1272             }
    1273         }
    1274     }
    1275     else if (c == 'a' && strcmp(argv[1],"axisname") == 0)
    1276     {
    1277         int axisID = 0;
    1278         if (!strcmp(argv[2], "x")) axisID = 0;
    1279         if (!strcmp(argv[2], "y")) axisID = 1;
    1280         if (!strcmp(argv[2], "z")) axisID = 2;
    1281        
    1282         if (g_grid) g_grid->setAxisName(axisID, argv[3]);
    1283         return TCL_OK;
    1284     }
    1285 
    1286     Tcl_AppendResult(interp, "bad option \"", argv[1],
    1287         "\": should be data, outline, shading, or state", (char*)NULL);
    1288     return TCL_ERROR;
    1289 }
    1290 
    1291 
    1292 int AxisCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]))
     1267        if ((Tcl_GetInt(interp, argv[2], &x) != TCL_OK) ||
     1268            (Tcl_GetInt(interp, argv[3], &y) != TCL_OK) ||
     1269            (Tcl_GetInt(interp, argv[4], &z) != TCL_OK)) {
     1270            return TCL_ERROR;
     1271        }
     1272        if (g_grid) {
     1273            g_grid->setGridLineCount(x, y, z);
     1274        }
     1275    } else if ((c == 'a') && (strcmp(argv[1],"axiscolor") == 0)) {
     1276        float r, g, b;
     1277        if ((GetFloat(interp, argv[2], &r) != TCL_OK) ||
     1278            (GetFloat(interp, argv[3], &g) != TCL_OK) ||
     1279            (GetFloat(interp, argv[4], &b) != TCL_OK)) {
     1280            return TCL_ERROR;
     1281        }
     1282        if (g_grid) {
     1283            g_grid->setAxisColor(r, g, b);
     1284        }
     1285    } else if ((c == 'l') && (strcmp(argv[1],"linecolor") == 0)) {
     1286        float r, g, b;
     1287        if ((GetFloat(interp, argv[2], &r) != TCL_OK) ||
     1288            (GetFloat(interp, argv[3], &g) != TCL_OK) ||
     1289            (GetFloat(interp, argv[4], &b) != TCL_OK)) {
     1290            return TCL_ERROR;
     1291        }
     1292        if (g_grid) {
     1293            g_grid->setGridLineColor(r, g, b);
     1294        }
     1295    } else if ((c == 'm') && (strcmp(argv[1],"minmax") == 0)) {
     1296        double x1, y1, z1, x2, y2, z2;
     1297        if ((Tcl_GetDouble(interp, argv[2], &x1) != TCL_OK) ||
     1298            (Tcl_GetDouble(interp, argv[3], &y1) != TCL_OK) ||
     1299            (Tcl_GetDouble(interp, argv[4], &z1) != TCL_OK) ||
     1300            (Tcl_GetDouble(interp, argv[5], &x2) != TCL_OK) ||
     1301            (Tcl_GetDouble(interp, argv[6], &y2) != TCL_OK) ||
     1302            (Tcl_GetDouble(interp, argv[7], &z2) != TCL_OK)) {
     1303            return TCL_ERROR;
     1304        }
     1305        if (g_grid) {
     1306            g_grid->setMinMax(Vector3(x1, y1, z1), Vector3(x2, y2, z2));
     1307        }
     1308    } else if ((c == 'a') && (strcmp(argv[1],"axisname") == 0)) {
     1309        int axisId;
     1310        if (GetAxis(interp, argv[2], &axisId) != TCL_OK) {
     1311            return TCL_ERROR;
     1312        }
     1313        if (g_grid) {
     1314            g_grid->setAxisName(axisId, argv[3]);
     1315        }
     1316    } else {
     1317        Tcl_AppendResult(interp, "bad option \"", argv[1],
     1318                         "\": should be data, outline, shading, or state",
     1319                         (char*)NULL);
     1320        return TCL_ERROR;
     1321    }
     1322    return TCL_OK;
     1323}
     1324
     1325static int
     1326AxisCmd(ClientData cdata, Tcl_Interp *interp, int argc, const char *argv[])
    12931327{
    12941328    if (argc < 2) {
     
    12971331        return TCL_ERROR;
    12981332    }
    1299 
    1300     char c = *argv[1];
    1301     if (c == 'v' && strcmp(argv[1],"visible") == 0)
    1302     {
    1303         if (strcmp(argv[2],"true") == 0)
    1304         {
    1305             axis_on = true;
    1306         }
    1307         else if (strcmp(argv[2],"false") == 0)
    1308         {
    1309             axis_on = false;
    1310         }
    1311            
    1312         return TCL_OK;
    1313     }
    1314 
    1315     Tcl_AppendResult(interp, "bad option \"", argv[1],
    1316         "\": should be data, outline, shading, or state", (char*)NULL);
    1317     return TCL_ERROR;
    1318 }
    1319 
     1333    char c = argv[1][0];
     1334    if ((c == 'v') && (strcmp(argv[1],"visible") == 0)) {
     1335        int ivisible;
     1336
     1337        if (Tcl_GetBoolean(interp, argv[2], &ivisible) != TCL_OK) {
     1338            return TCL_ERROR;
     1339        }
     1340        axis_on = (bool)ivisible;
     1341    } else {
     1342        Tcl_AppendResult(interp, "bad axis option \"", argv[1],
     1343                         "\": should be visible", (char*)NULL);
     1344        return TCL_ERROR;
     1345    }
     1346    return TCL_OK;
     1347}
    13201348
    13211349/*
    13221350 * ----------------------------------------------------------------------
    1323  * FUNCTION: GetVolumeIndices()
     1351 * FUNCTION: GetHeightMap
    13241352 *
    13251353 * Used internally to decode a series of volume index values and
     
    13331361 */
    13341362static int
    1335 GetVolumeIndices(Tcl_Interp *interp, int argc, CONST84 char *argv[],
     1363GetHeightMap(Tcl_Interp *interp, const char *string, HeightMap **hmPtrPtr)
     1364{
     1365    int mapIndex;
     1366    if (Tcl_GetInt(interp, string, &mapIndex) != TCL_OK) {
     1367        return TCL_ERROR;
     1368    }
     1369    if ((mapIndex < 0) || (mapIndex >= g_heightMap.size()) ||
     1370        (g_heightMap[mapIndex] == NULL)) {
     1371        Tcl_AppendResult(interp, "invalid heightmap index \"", string, "\"",
     1372                         (char *)NULL);
     1373        return TCL_ERROR;
     1374    }
     1375    *hmPtrPtr = g_heightMap[mapIndex];
     1376    return TCL_OK;
     1377}
     1378
     1379/*
     1380 * ----------------------------------------------------------------------
     1381 * FUNCTION: GetVolumeIndex
     1382 *
     1383 * Used internally to decode a series of volume index values and
     1384 * store then in the specified vector.  If there are no volume index
     1385 * arguments, this means "all volumes" to most commands, so all
     1386 * active volume indices are stored in the vector.
     1387 *
     1388 * Updates pushes index values into the vector.  Returns TCL_OK or
     1389 * TCL_ERROR to indicate an error.
     1390 * ----------------------------------------------------------------------
     1391 */
     1392static int
     1393GetVolumeIndex(Tcl_Interp *interp, const char *string, int *indexPtr)
     1394{
     1395    int ivol;
     1396    if (Tcl_GetInt(interp, string, &ivol) != TCL_OK) {
     1397        return TCL_ERROR;
     1398    }
     1399    if ((ivol < 0) || (ivol >= volume.size())) {
     1400        Tcl_AppendResult(interp, "bad volume index \"", string,
     1401                         "\"", (char*)NULL);
     1402        return TCL_ERROR;
     1403    }
     1404    *indexPtr = ivol;
     1405    return TCL_OK;
     1406}
     1407
     1408/*
     1409 * ----------------------------------------------------------------------
     1410 * FUNCTION: GetVolume
     1411 *
     1412 * Used internally to decode a series of volume index values and
     1413 * store then in the specified vector.  If there are no volume index
     1414 * arguments, this means "all volumes" to most commands, so all
     1415 * active volume indices are stored in the vector.
     1416 *
     1417 * Updates pushes index values into the vector.  Returns TCL_OK or
     1418 * TCL_ERROR to indicate an error.
     1419 * ----------------------------------------------------------------------
     1420 */
     1421static int
     1422GetVolume(Tcl_Interp *interp, const char *string, Volume **volPtrPtr)
     1423{
     1424    int ivol;
     1425    if (GetVolumeIndex(interp, string, &ivol) != TCL_OK) {
     1426        return TCL_ERROR;
     1427    }
     1428    if (volume[ivol] == NULL) {
     1429        Tcl_AppendResult(interp, "no volume defined for index \"", string,
     1430                         "\"", (char*)NULL);
     1431        return TCL_ERROR;
     1432    }
     1433    *volPtrPtr = volume[ivol];
     1434    return TCL_OK;
     1435}
     1436
     1437/*
     1438 * ----------------------------------------------------------------------
     1439 * FUNCTION: GetVolumeIndices()
     1440 *
     1441 * Used internally to decode a series of volume index values and
     1442 * store then in the specified vector.  If there are no volume index
     1443 * arguments, this means "all volumes" to most commands, so all
     1444 * active volume indices are stored in the vector.
     1445 *
     1446 * Updates pushes index values into the vector.  Returns TCL_OK or
     1447 * TCL_ERROR to indicate an error.
     1448 * ----------------------------------------------------------------------
     1449 */
     1450static int
     1451GetVolumeIndices(Tcl_Interp *interp, int argc, const char *argv[],
    13361452    vector<int>* vectorPtr)
    13371453{
     
    13451461        int ivol;
    13461462        for (int n=0; n < argc; n++) {
    1347             if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
    1348                 return TCL_ERROR;
    1349             }
    1350             if (ivol < 0 || ivol >= volume.size()) {
    1351                 Tcl_AppendResult(interp, "bad volume index \"", argv[n],
    1352                     "\"", (char*)NULL);
    1353                 return TCL_ERROR;
    1354             }
     1463            if (GetVolumeIndex(interp, argv[n], &ivol) != TCL_OK) {
     1464                return TCL_ERROR;
     1465            }
    13551466            if (volume[ivol] != NULL) {
    13561467                vectorPtr->push_back(ivol);
     
    13611472}
    13621473
    1363 
    13641474static int
    1365 GetIndices(Tcl_Interp *interp, int argc, CONST84 char *argv[],
     1475GetIndices(Tcl_Interp *interp, int argc, const char *argv[],
    13661476    vector<int>* vectorPtr)
    13671477{
     
    13881498 */
    13891499static int
    1390 GetAxis(Tcl_Interp *interp, char *str, int *valPtr)
    1391 {
    1392     if (strcmp(str,"x") == 0) {
    1393         *valPtr = 0;
    1394         return TCL_OK;
    1395     }
    1396     else if (strcmp(str,"y") == 0) {
    1397         *valPtr = 1;
    1398         return TCL_OK;
    1399     }
    1400     else if (strcmp(str,"z") == 0) {
    1401         *valPtr = 2;
    1402         return TCL_OK;
    1403     }
    1404     Tcl_AppendResult(interp, "bad axis \"", str,
    1405         "\": should be x, y, or z", (char*)NULL);
     1500GetAxis(Tcl_Interp *interp, const char *string, int *valPtr)
     1501{
     1502    if (string[1] == '\0') {
     1503        if (string[0] == 'x') {
     1504            *valPtr = 0;
     1505            return TCL_OK;
     1506        } else if (string[0] == 'y') {
     1507            *valPtr = 1;
     1508            return TCL_OK;
     1509        } else if (string[0] == 'z') {
     1510            *valPtr = 2;
     1511            return TCL_OK;
     1512        }
     1513        /*FALLTHRU*/
     1514    }
     1515    Tcl_AppendResult(interp, "bad axis \"", string,
     1516        "\": should be x, y, or z", (char*)NULL);
    14061517    return TCL_ERROR;
    14071518}
     
    14181529 */
    14191530static int
    1420 GetColor(Tcl_Interp *interp, char *str, float *rgbPtr)
    1421 {
    1422     int rgbc;
    1423     char **rgbv;
    1424     if (Tcl_SplitList(interp, str, &rgbc, (const char***)&rgbv) != TCL_OK) {
     1531GetColor(Tcl_Interp *interp, const char *string, float *rgbPtr)
     1532{
     1533    int argc;
     1534    const char **argv;
     1535
     1536    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
    14251537        return TCL_ERROR;
    14261538    }
    1427     if (rgbc != 3) {
    1428         Tcl_AppendResult(interp, "bad color \"", str,
    1429             "\": should be {R G B} as double values 0-1", (char*)NULL);
     1539    if (argc != 3) {
     1540        Tcl_AppendResult(interp, "bad color \"", string,
     1541            "\": should list of R G B values 0.0 - 1.0", (char*)NULL);
    14301542        return TCL_ERROR;
    14311543    }
    1432 
    1433     double rval, gval, bval;
    1434     if (Tcl_GetDouble(interp, rgbv[0], &rval) != TCL_OK) {
    1435         Tcl_Free((char*)rgbv);
     1544    if ((GetFloat(interp, argv[0], rgbPtr + 0) != TCL_OK) ||
     1545        (GetFloat(interp, argv[1], rgbPtr + 1) != TCL_OK) ||
     1546        (GetFloat(interp, argv[2], rgbPtr + 2) != TCL_OK)) {
     1547        Tcl_Free((char*)argv);
    14361548        return TCL_ERROR;
    14371549    }
    1438     if (Tcl_GetDouble(interp, rgbv[1], &gval) != TCL_OK) {
    1439         Tcl_Free((char*)rgbv);
    1440         return TCL_ERROR;
    1441     }
    1442     if (Tcl_GetDouble(interp, rgbv[2], &bval) != TCL_OK) {
    1443         Tcl_Free((char*)rgbv);
    1444         return TCL_ERROR;
    1445     }
    1446     Tcl_Free((char*)rgbv);
    1447 
    1448     rgbPtr[0] = (float)rval;
    1449     rgbPtr[1] = (float)gval;
    1450     rgbPtr[2] = (float)bval;
    1451 
     1550    Tcl_Free((char*)argv);
    14521551    return TCL_OK;
    14531552}
     
    14551554
    14561555static int
    1457 PlaneNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]))
    1458 {
    1459   fprintf(stderr, "load plane for 2D visualization command\n");
    1460 
    1461   int index, w, h;
    1462 
    1463   if (argc != 4) {
    1464     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    1465                 " plane_index w h \"", (char*)NULL);
    1466     return TCL_ERROR;
    1467   }
    1468   if (Tcl_GetInt(interp, argv[1], &index) != TCL_OK) {
    1469         return TCL_ERROR;
    1470   }
    1471   if (Tcl_GetInt(interp, argv[2], &w) != TCL_OK) {
    1472         return TCL_ERROR;
    1473   }
    1474   if (Tcl_GetInt(interp, argv[3], &h) != TCL_OK) {
    1475         return TCL_ERROR;
    1476   }
    1477 
    1478   //Now read w*h*4 bytes. The server expects the plane to be a stream of floats
    1479   char* tmp = new char[int(w*h*sizeof(float))];
    1480   bzero(tmp, w*h*4);
    1481   int status = read(0, tmp, w*h*sizeof(float));
    1482   if (status <= 0){
    1483     exit(0);
    1484   }
    1485  
    1486   plane[index] = new Texture2D(w, h, GL_FLOAT, GL_LINEAR, 1, (float*)tmp);
    1487  
    1488   delete[] tmp;
    1489   return TCL_OK;
    1490 }
    1491 
    1492 
    1493 static
    1494 int PlaneLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]))
    1495 {
    1496   fprintf(stderr, "link the plane to the 2D renderer command\n");
    1497 
    1498   int plane_index, tf_index;
    1499 
    1500   if (argc != 3) {
    1501     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    1502                 " plane_index tf_index \"", (char*)NULL);
    1503     return TCL_ERROR;
    1504   }
    1505   if (Tcl_GetInt(interp, argv[1], &plane_index) != TCL_OK) {
    1506         return TCL_ERROR;
    1507   }
    1508   if (Tcl_GetInt(interp, argv[2], &tf_index) != TCL_OK) {
    1509         return TCL_ERROR;
    1510   }
    1511 
    1512   //plane_render->add_plane(plane[plane_index], tf[tf_index]);
    1513 
    1514   return TCL_OK;
     1556PlaneNewCmd(ClientData cdata, Tcl_Interp *interp, int argc,
     1557            const char *argv[])
     1558{
     1559    fprintf(stderr, "load plane for 2D visualization command\n");
     1560   
     1561    int index, w, h;
     1562   
     1563    if (argc != 4) {
     1564        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     1565                         " plane_index w h \"", (char*)NULL);
     1566        return TCL_ERROR;
     1567    }
     1568    if (Tcl_GetInt(interp, argv[1], &index) != TCL_OK) {
     1569        return TCL_ERROR;
     1570    }
     1571    if (Tcl_GetInt(interp, argv[2], &w) != TCL_OK) {
     1572        return TCL_ERROR;
     1573    }
     1574    if (Tcl_GetInt(interp, argv[3], &h) != TCL_OK) {
     1575        return TCL_ERROR;
     1576    }
     1577   
     1578    //Now read w*h*4 bytes. The server expects the plane to be a stream of floats
     1579    char* tmp = new char[int(w*h*sizeof(float))];
     1580    if (tmp == NULL) {
     1581        Tcl_AppendResult(interp, "can't allocate stream data", (char *)NULL);
     1582        return TCL_ERROR;
     1583    }
     1584    bzero(tmp, w*h*4);
     1585    int status = read(0, tmp, w*h*sizeof(float));
     1586    if (status <= 0) {
     1587        exit(0);                // Bail out on read error?  Should log the
     1588                                // error and return a non-zero exit status.
     1589    }
     1590    plane[index] = new Texture2D(w, h, GL_FLOAT, GL_LINEAR, 1, (float*)tmp);
     1591    delete[] tmp;
     1592    return TCL_OK;
     1593}
     1594
     1595
     1596static int PlaneLinkCmd(ClientData cdata, Tcl_Interp *interp, int argc,
     1597        const char *argv[])
     1598{
     1599    fprintf(stderr, "link the plane to the 2D renderer command\n");
     1600   
     1601    int plane_index, tf_index;
     1602   
     1603    if (argc != 3) {
     1604        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     1605                         " plane_index tf_index \"", (char*)NULL);
     1606        return TCL_ERROR;
     1607    }
     1608    if (Tcl_GetInt(interp, argv[1], &plane_index) != TCL_OK) {
     1609        return TCL_ERROR;
     1610    }
     1611    if (Tcl_GetInt(interp, argv[2], &tf_index) != TCL_OK) {
     1612        return TCL_ERROR;
     1613    }
     1614    //plane_render->add_plane(plane[plane_index], tf[tf_index]);
     1615    return TCL_OK;
    15151616}
    15161617
    15171618//Enable a 2D plane for render
    15181619//The plane_index is the index mantained in the 2D plane renderer
    1519 static
    1520 int PlaneEnableCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]))
    1521 {
    1522   fprintf(stderr, "enable a plane so the 2D renderer can render it command\n");
    1523 
    1524   int plane_index, mode;
    1525 
    1526   if (argc != 3) {
    1527     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    1528                 " plane_index mode \"", (char*)NULL);
    1529     return TCL_ERROR;
    1530   }
    1531   if (Tcl_GetInt(interp, argv[1], &plane_index) != TCL_OK) {
    1532         return TCL_ERROR;
    1533   }
    1534   if (Tcl_GetInt(interp, argv[2], &mode) != TCL_OK) {
    1535         return TCL_ERROR;
    1536   }
    1537 
    1538   if(mode==0)
    1539     plane_render->set_active_plane(-1);
    1540   else
     1620static int PlaneEnableCmd(ClientData cdata, Tcl_Interp *interp, int argc,
     1621        const char *argv[])
     1622{
     1623    fprintf(stderr,"enable a plane so the 2D renderer can render it command\n");
     1624   
     1625    if (argc != 3) {
     1626        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     1627                         " plane_index mode \"", (char*)NULL);
     1628        return TCL_ERROR;
     1629    }
     1630    int plane_index;
     1631    if (Tcl_GetInt(interp, argv[1], &plane_index) != TCL_OK) {
     1632        return TCL_ERROR;
     1633    }
     1634    int mode;
     1635    if (Tcl_GetInt(interp, argv[2], &mode) != TCL_OK) {
     1636        return TCL_ERROR;
     1637    }
     1638    if (mode == 0) {
     1639        plane_index = -1;
     1640    }
    15411641    plane_render->set_active_plane(plane_index);
    1542 
    1543   return TCL_OK;
    1544 }
    1545 
    1546 
    1547 void initTcl()
     1642    return TCL_OK;
     1643}
     1644
     1645
     1646void
     1647initTcl()
    15481648{
    15491649    interp = Tcl_CreateInterp();
     
    15911691    // get screenshot
    15921692    Tcl_CreateCommand(interp, "screenshot", ScreenShotCmd,
     1693        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
     1694
     1695    Tcl_CreateCommand(interp, "unirect2d", UniRect2dCmd,
    15931696        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
    15941697
     
    16051708}
    16061709
    1607 void xinetd_listen()
    1608 {
    1609 
     1710
     1711void
     1712xinetd_listen()
     1713{
    16101714    int flags = fcntl(0, F_GETFL, 0);
    16111715    fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
     
    16501754        // back to original flags during command evaluation...
    16511755        fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
    1652 
    16531756        status = Tcl_Eval(interp, Tcl_DStringValue(&cmdbuffer));
    16541757        Tcl_DStringSetLength(&cmdbuffer, 0);
     
    16711774    //
    16721775    // INSOO
    1673     offscreen_buffer_capture();  //enable offscreen render
    1674 
    1675     display();
     1776    nv_offscreen_buffer_capture();  //enable offscreen render
     1777
     1778    nv_display();
    16761779
    16771780    // INSOO
    16781781#ifdef XINETD
    1679    read_screen();
     1782   nv_read_screen();
    16801783   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    16811784#else
    1682    display_offscreen_buffer(); //display the final rendering on screen
    1683    read_screen();
     1785   nv_display_offscreen_buffer(); //display the final rendering on screen
     1786   nv_read_screen();
    16841787   glutSwapBuffers();
    16851788#endif   
     
    16981801
    16991802
     1803/*
     1804 * -----------------------------------------------------------------------
     1805 *
     1806 * FillBufferFromStdin --
     1807 *
     1808 *      Read the requested number of bytes from standard input into the given
     1809 *      buffer.  The buffer is then decompressed and decoded.
     1810 *
     1811 * -----------------------------------------------------------------------
     1812 */
     1813static int
     1814FillBufferFromStdin(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes)
     1815{
     1816    char buffer[8096];
     1817
     1818    while (nBytes > 0) {
     1819        int chunk, nRead;
     1820
     1821        chunk = (sizeof(buffer) < nBytes) ? sizeof(buffer) : nBytes;
     1822        nRead = fread(buffer, 1, chunk, stdin);
     1823        if (ferror(stdin) && feof(stdin)) {
     1824            Tcl_AppendResult(interp,
     1825                             "data unpacking failed: unexpected EOF",
     1826                             (char*)NULL);
     1827            return TCL_ERROR;
     1828        }
     1829        buf.append(buffer, nRead);
     1830        nBytes -= nRead;
     1831    }
     1832    if (strncmp("@@RP-ENC", buf.bytes(), 8) == 0) {
     1833        Rappture::Outcome err;
     1834
     1835        err = Rappture::encoding::decode(buf, RPENC_Z|RPENC_B64|RPENC_HDR);
     1836        buf.append("\0", 1);
     1837        fflush(stderr);
     1838        if (err) {
     1839            printf("ERROR -- DECODING\n");
     1840            fflush(stdout);
     1841            Tcl_AppendResult(interp, err.remark().c_str(), (char*)NULL);
     1842            return TCL_ERROR;
     1843        }
     1844    }
     1845    return TCL_OK;
     1846}
     1847
     1848/*
     1849 * -----------------------------------------------------------------------
     1850 *
     1851 * CreateHeightMap --
     1852 *
     1853 *      Creates a heightmap from the given the data. The format of the data
     1854 *      should be as follows:
     1855 *
     1856 *              xMin, xMax, xNum, yMin, yMax, yNum, heights...
     1857 *
     1858 *      xNum and yNum must be integer values, all others are real numbers.
     1859 *      The number of heights must be xNum * yNum;
     1860 *
     1861 * -----------------------------------------------------------------------
     1862 */
     1863static HeightMap *
     1864CreateHeightMap(ClientData clientData, Tcl_Interp *interp, int argc,
     1865        const char *argv[])
     1866{
     1867    float xMin, yMin, xMax, yMax;
     1868    int xNum, yNum;
     1869
     1870    if (argc != 7) {
     1871        Tcl_AppendResult(interp,
     1872        "wrong # of values: should be xMin yMin xMax yMax xNum yNum heights",
     1873                (char *)NULL);
     1874        return NULL;
     1875    }
     1876    if ((GetFloat(interp, argv[0], &xMin) != TCL_OK) ||
     1877        (GetFloat(interp, argv[1], &yMin) != TCL_OK) ||
     1878        (GetFloat(interp, argv[2], &xMax) != TCL_OK) ||
     1879        (GetFloat(interp, argv[3], &yMax) != TCL_OK) ||
     1880        (Tcl_GetInt(interp, argv[4], &xNum) != TCL_OK) ||
     1881        (Tcl_GetInt(interp, argv[5], &yNum) != TCL_OK)) {
     1882        return NULL;
     1883    }
     1884    int nValues;
     1885    const char **elem;
     1886    if (Tcl_SplitList(interp, argv[6], &nValues, &elem) != TCL_OK) {
     1887        return NULL;
     1888    }
     1889    if ((xNum <= 0) || (yNum <= 0)) {
     1890        Tcl_AppendResult(interp, "bad number of x or y values", (char *)NULL);
     1891        goto error;
     1892    }
     1893    if (nValues != (xNum * yNum)) {
     1894        Tcl_AppendResult(interp, "wrong # of heights", (char *)NULL);
     1895        goto error;
     1896    }
     1897
     1898    float *heights;
     1899    heights = new float[nValues];
     1900    if (heights == NULL) {
     1901        Tcl_AppendResult(interp, "can't allocate array of heights",
     1902                (char *)NULL);
     1903        goto error;
     1904    }
     1905
     1906    int i;
     1907    for (i = 0; i < nValues; i++) {
     1908        if (GetFloat(interp, elem[i], heights + i) != TCL_OK) {
     1909            delete [] heights;
     1910            goto error;
     1911        }
     1912    }
     1913    HeightMap* hMap;
     1914    hMap = new HeightMap();
     1915    hMap->setHeight(xMin, yMin, xMax, yMax, xNum, yNum, heights);
     1916    hMap->setColorMap(nv_get_transfunc("default"));
     1917    hMap->setVisible(true);
     1918    hMap->setLineContourVisible(true);
     1919
     1920    Tcl_Free((char *)elem);
     1921    delete [] heights;
     1922    return hMap;
     1923 error:
     1924    Tcl_Free((char *)elem);
     1925    return NULL;
     1926}
     1927
     1928/*
     1929 * This command should be Tcl procedure instead of a C command.  The reason
     1930 * for this that 1) we are using a safe interpreter so we would need a master
     1931 * interpreter to load the Tcl environment properly (including our "unirect2d"
     1932 * procedure). And 2) the way nanovis is currently deployed, doesn't make it
     1933 * easy to add new directories for procedures, since it's loaded into /tmp.
     1934 *
     1935 * Ideally, the "unirect2d" proc would do a rundimentary parsing of the data
     1936 * to verify the structure and then pass it to the appropiate Tcl command
     1937 * (heightmap, volume, etc). Our C command always creates a heightmap. 
     1938 */
     1939static int
     1940UniRect2dCmd(ClientData, Tcl_Interp *interp, int argc, const char *argv[])
     1941{   
     1942    int xNum, yNum, zNum;
     1943    float xMin, yMin, xMax, yMax;
     1944    float *zValues;
     1945
     1946    fprintf(stderr, "in unirect2d command\n");
     1947    fflush(stderr);
     1948    if ((argc & 0x01) == 0) {
     1949        Tcl_AppendResult(interp,
     1950                "wrong number of arguments: should be key-value pairs",
     1951                (char *)NULL);
     1952        return TCL_ERROR;
     1953    }
     1954    xNum = yNum = zNum = 0;
     1955    xMin = yMin = xMax = yMax = 0.0f;
     1956    int i;
     1957    for (i = 1; i < argc; i += 2) {
     1958        if (strcmp(argv[i], "xmin") == 0) {
     1959            if (GetFloat(interp, argv[i+1], &xMin) != TCL_OK) {
     1960                return TCL_ERROR;
     1961            }
     1962        } else if (strcmp(argv[i], "xmax") == 0) {
     1963            if (GetFloat(interp, argv[i+1], &xMax) != TCL_OK) {
     1964                return TCL_ERROR;
     1965            }
     1966        } else if (strcmp(argv[i], "xnum") == 0) {
     1967            if (Tcl_GetInt(interp, argv[i+1], &xNum) != TCL_OK) {
     1968                return TCL_ERROR;
     1969            }
     1970            if (xNum <= 0) {
     1971                Tcl_AppendResult(interp, "bad xnum value: must be > 0",
     1972                                 (char *)NULL);
     1973                return TCL_ERROR;
     1974            }
     1975        } else if (strcmp(argv[i], "ymin") == 0) {
     1976            if (GetFloat(interp, argv[i+1], &yMin) != TCL_OK) {
     1977                return TCL_ERROR;
     1978            }
     1979        } else if (strcmp(argv[i], "ymax") == 0) {
     1980            if (GetFloat(interp, argv[i+1], &yMax) != TCL_OK) {
     1981                return TCL_ERROR;
     1982            }
     1983        } else if (strcmp(argv[i], "ynum") == 0) {
     1984            if (Tcl_GetInt(interp, argv[i+1], &yNum) != TCL_OK) {
     1985                return TCL_ERROR;
     1986            }
     1987            if (yNum <= 0) {
     1988                Tcl_AppendResult(interp, "bad ynum value: must be > 0",
     1989                                 (char *)NULL);
     1990                return TCL_ERROR;
     1991            }
     1992        } else if (strcmp(argv[i], "zvalues") == 0) {
     1993            const char **zlist;
     1994
     1995            if (Tcl_SplitList(interp, argv[i+1], &zNum, &zlist) != TCL_OK) {
     1996                return TCL_ERROR;
     1997            }
     1998            int j;
     1999            zValues = new float[zNum];
     2000            for (j = 0; j < zNum; j++) {
     2001                if (GetFloat(interp, zlist[j], zValues + j) != TCL_OK) {
     2002                    Tcl_Free((char *)zlist);
     2003                    return TCL_ERROR;
     2004                }
     2005            }
     2006            Tcl_Free((char *)zlist);
     2007        } else {
     2008            Tcl_AppendResult(interp, "unknown key \"", argv[i],
     2009                "\": should be xmin, xmax, xnum, ymin, ymax, ynum, or zvalues",
     2010                (char *)NULL);
     2011            return TCL_ERROR;
     2012        }
     2013    }
     2014    if (zValues == NULL) {
     2015        Tcl_AppendResult(interp, "missing \"zvalues\" key", (char *)NULL);
     2016        return TCL_ERROR;
     2017    }
     2018    fprintf(stderr, "xnum=%d, ynum=%d, znum=%d\n", xNum, yNum, zNum);
     2019    fflush(stderr);
     2020    if (zNum != (xNum * yNum)) {
     2021        Tcl_AppendResult(interp, "wrong number of z values must be xnum*ynum",
     2022                (char *)NULL);
     2023        return TCL_ERROR;
     2024    }
     2025   
     2026    HeightMap* hMap;
     2027    hMap = new HeightMap();
     2028    hMap->setHeight(xMin, yMin, xMax, yMax, xNum, yNum, zValues);
     2029    hMap->setColorMap(nv_get_transfunc("default"));
     2030    hMap->setVisible(true);
     2031    hMap->setLineContourVisible(true);
     2032    g_heightMap.push_back(hMap);
     2033    delete [] zValues;
     2034    return TCL_OK;
     2035}
     2036
Note: See TracChangeset for help on using the changeset viewer.