Changeset 445 for trunk/gui


Ignore:
Timestamp:
May 29, 2006 7:55:49 PM (18 years ago)
Author:
mmc
Message:

Created new "transfunc" command for defining transfer functions.
Fixed gradient calculation. Centered volume on origin.

Location:
trunk/gui/vizservers/nanovis
Files:
2 edited

Legend:

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

    r434 r445  
    2222#include <string>
    2323#include <sys/time.h>
     24#include <sys/types.h>
     25#include <unistd.h>
     26#include <fcntl.h>
    2427
    2528#include "nanovis.h"
     29#include "RpField1D.h"
    2630#include "RpFieldRect3D.h"
    2731#include "RpFieldPrism3D.h"
     
    4852
    4953// default transfer function
    50 float def_tf[24] = {
    51   1, 1, 1, 0.5,  // red
    52   1, 1, 0, 0.5,  // yellow
    53   0, 1, 0, 0.5,  // green
    54   0, 1, 1, 0.5,  // cyan
    55   0, 0, 1, 0.5,  // blue
    56   1, 0, 1, 0.5,  // magenta
    57 };
    58 int def_tf_size = 6;
     54char *def_transfunc = "transfunc define default {\n\
     55  0.0  1 1 1  0.5\n\
     56  0.2  1 1 0  0.5\n\
     57  0.4  0 1 0  0.5\n\
     58  0.6  0 1 1  0.5\n\
     59  0.8  0 0 1  0.5\n\
     60  1.0  1 0 1  0.5\n\
     61}";
    5962
    6063#ifdef XINETD
     
    7376void init_particles();
    7477void get_slice_vectors();
     78Rappture::Outcome load_volume_file(int index, char *fname);
     79void load_volume(int index, int width, int height, int depth, int n_component, float* data);
     80TransferFunction* get_transfunc(char *name);
    7581
    7682ParticleSystem* psys;
     
    7985Lic* lic;
    8086
     87//frame buffer for final rendering
    8188unsigned char* screen_buffer = NULL;
    82 NVISid final_fbo, final_color_tex, final_depth_rb;      //frame buffer for final rendering
     89NVISid final_fbo, final_color_tex, final_depth_rb;
    8390
    8491bool advect=false;
     
    8794
    8895int n_volumes = 0;
    89 Volume* volume[MAX_N_VOLUMES];          //pointers to volumes, currently handle up to 10 volumes
    90 TransferFunction* tf[MAX_N_VOLUMES];    //transfer functions, currently handle up to 10 colormaps
    91 Texture2D* plane[10];                   //pointers to 2D planes, currently handle up 10
     96// pointers to volumes, currently handle up to 10 volumes
     97Volume* volume[MAX_N_VOLUMES];
     98// maps transfunc name to TransferFunction object
     99Tcl_HashTable tftable;
     100
     101// pointers to 2D planes, currently handle up 10
     102Texture2D* plane[10];
    92103
    93104PerfQuery* perf;                        //perfromance counter
     
    117128// Tcl interpreter for incoming messages
    118129static Tcl_Interp *interp;
     130static Tcl_DString cmdbuffer;
    119131
    120132static int CameraCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     
    122134static int ClearCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    123135static int ScreenCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    124 static int TransferFunctionNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    125 static int TransferFunctionUpdateCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     136static int TransfuncCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    126137static int VolumeCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    127 static int VolumeNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    128138static int VolumeLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    129139static int VolumeMoveCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    130 static int VolumeEnableCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    131140static int RefreshCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    132141static int PlaneNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     
    281290                    return TCL_ERROR;
    282291                }
    283                 if (ivol < 0 || ivol > n_volumes) {
     292                if (ivol < 0 || ivol >= n_volumes) {
    284293                    Tcl_AppendResult(interp, "bad volume index \"", argv[n],
    285294                        "\": out of range", (char*)NULL);
     
    325334                    return TCL_ERROR;
    326335                }
    327                 if (ivol < 0 || ivol > n_volumes) {
     336                if (ivol < 0 || ivol >= n_volumes) {
    328337                    Tcl_AppendResult(interp, "bad volume index \"", argv[n],
    329338                        "\": out of range", (char*)NULL);
     
    376385}
    377386
    378 void update_transfer_function(int index, float* data);
    379 
    380 //The client sends the first sends the index of the transfer function
    381 //to modify. Then the client sends a chunck of binary floats.
    382 static int
    383 TransferFunctionUpdateCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    384 {
    385   fprintf(stderr, "update transfer function cmd\n");
    386 
    387   double index;
    388 
    389   if (argc != 2) {
    390     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    391                 " tf_index\"", (char*)NULL);
    392     return TCL_ERROR;
    393   }
    394   if (Tcl_GetDouble(interp, argv[1], &index) != TCL_OK) {
    395         return TCL_ERROR;
    396   }
    397 
    398   //Now read 256*4*4 bytes. The server expects the transfer function to be 256 units of (RGBA) floats
    399   char tmp[256*4*4];
    400   bzero(tmp, 256*4*4);
    401   int status = read(0, tmp, 256*4*4);
    402   if (status <= 0) {
    403     exit(0);
    404   }
    405 
    406   update_transfer_function((int)index, (float*)tmp);
    407   return TCL_OK;
    408 }
    409 
    410 
    411 //The client sends the index of the index of the transfer function
    412 //to create. Then the client sends a chunck of binary floats.
    413 static int
    414 TransferFunctionNewCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    415 {
    416   fprintf(stderr, "update transfer function cmd\n");
    417 
    418   double index;
    419 
    420   if (argc != 2) {
    421     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    422                 " tf_index\"", (char*)NULL);
    423     return TCL_ERROR;
    424   }
    425   if (Tcl_GetDouble(interp, argv[1], &index) != TCL_OK) {
    426         return TCL_ERROR;
    427   }
    428 
    429   //Now read 256*4*4 bytes. The server expects the transfer function to be 256 units of (RGBA) floats
    430   char tmp[256*4*4];
    431   bzero(tmp, 256*4*4);
    432   int status = read(0, tmp, 256*4*4);
    433   if (status <= 0) {
    434     exit(0);
    435   }
    436 
    437   tf[(int)index] = new TransferFunction(256, (float*)tmp);
    438   return TCL_OK;
    439 }
    440 
    441 
    442387void set_object(float x, float y, float z){
    443388  live_obj_x = x;
     
    449394 * ----------------------------------------------------------------------
    450395 * CLIENT COMMAND:
     396 *   transfunc define <name> { <v> <r> <g> <b> <w> ... }
     397 *
     398 * Clients send these commands to manipulate the transfer functions.
     399 * ----------------------------------------------------------------------
     400 */
     401static int
     402TransfuncCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     403{
     404        if (argc < 2) {
     405                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     406                        " option arg arg...\"", (char*)NULL);
     407                return TCL_ERROR;
     408    }
     409
     410    char c = *argv[1];
     411        if (c == 'd' && strcmp(argv[1],"define") == 0) {
     412        if (argc < 4) {
     413                    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     414                            argv[1], " option ?arg arg...?\"", (char*)NULL);
     415            return TCL_ERROR;
     416        }
     417
     418        // decode the data and store in a series of fields
     419        Rappture::Field1D rFunc, gFunc, bFunc, wFunc;
     420        int xferc, i, j;
     421        char **xferv;
     422
     423        if (Tcl_SplitList(interp, argv[3], &xferc, &xferv) != TCL_OK) {
     424            return TCL_ERROR;
     425        }
     426        if (xferc % 5 != 0) {
     427            Tcl_Free((char*)xferv);
     428                    Tcl_AppendResult(interp, "missing data in transfunc: should be ",
     429                "{ v r g b w ... }", (char*)NULL);
     430            return TCL_ERROR;
     431        }
     432
     433        for (i=0; i < xferc; i += 5) {
     434            double vals[5];
     435            for (j=0; j < 5; j++) {
     436                if (Tcl_GetDouble(interp, xferv[i+j], &vals[j]) != TCL_OK) {
     437                    Tcl_Free((char*)xferv);
     438                    return TCL_ERROR;
     439                }
     440                if (vals[j] < 0 || vals[j] > 1) {
     441                    Tcl_Free((char*)xferv);
     442                            Tcl_AppendResult(interp, "bad value \"", xferv[i+j],
     443                        "\": should be in the range 0-1", (char*)NULL);
     444                    return TCL_ERROR;
     445                }
     446            }
     447            rFunc.define(vals[0], vals[1]);
     448            gFunc.define(vals[0], vals[2]);
     449            bFunc.define(vals[0], vals[3]);
     450            wFunc.define(vals[0], vals[4]);
     451        }
     452        Tcl_Free((char*)xferv);
     453
     454        // sample the given function into discrete slots
     455        const int nslots = 256;
     456        float data[4*nslots];
     457        for (i=0; i < nslots; i++) {
     458            double xval = double(i)/(nslots-1);
     459            data[4*i]   = rFunc.value(xval);
     460            data[4*i+1] = gFunc.value(xval);
     461            data[4*i+2] = bFunc.value(xval);
     462            data[4*i+3] = wFunc.value(xval);
     463        }
     464
     465        // find or create this transfer function
     466        int newEntry;
     467        Tcl_HashEntry *entryPtr;
     468        TransferFunction *tf;
     469
     470        entryPtr = Tcl_CreateHashEntry(&tftable, argv[2], &newEntry);
     471        if (newEntry) {
     472            tf = new TransferFunction(nslots, data);
     473            Tcl_SetHashValue(entryPtr, (ClientData)tf);
     474        } else {
     475            tf = (TransferFunction*)Tcl_GetHashValue(entryPtr);
     476            tf->update(data);
     477        }
     478
     479        return TCL_OK;
     480    }
     481    Tcl_AppendResult(interp, "bad option \"", argv[1],
     482        "\": should be define", (char*)NULL);
     483    return TCL_ERROR;
     484}
     485
     486/*
     487 * ----------------------------------------------------------------------
     488 * CLIENT COMMAND:
     489 *   volume data state on|off ?<volumeId> ...?
    451490 *   volume outline state on|off ?<volumeId> ...?
    452491 *   volume outline color on|off ?<volumeId> ...?
    453  *   volume data state on|off ?<volumeId> ...?
     492 *   volume shading color <value> ?<volumeId> ...?
     493 *   volume shading diffuse <value> ?<volumeId> ...?
     494 *   volume shading specular <value> ?<volumeId> ...?
     495 *   volume shading opacity <value> ?<volumeId> ...?
     496 *   volume state on|off ?<volumeId> ...?
    454497 *
    455498 * Clients send these commands to manipulate the volumes.
     
    466509
    467510    char c = *argv[1];
    468         if (c == 'o' && strcmp(argv[1],"outline") == 0) {
     511        if (c == 'd' && strcmp(argv[1],"data") == 0) {
     512        if (argc < 3) {
     513                    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     514                            argv[1], " option ?arg arg...?\"", (char*)NULL);
     515                    return TCL_ERROR;
     516        }
     517        c = *argv[2];
     518            if (c == 's' && strcmp(argv[2],"state") == 0) {
     519            if (argc < 4) {
     520                        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     521                                argv[1], " state on|off ?volume ...?\"", (char*)NULL);
     522                        return TCL_ERROR;
     523            }
     524
     525            int state;
     526                if (Tcl_GetBoolean(interp, argv[3], &state) != TCL_OK) {
     527                        return TCL_ERROR;
     528                }
     529
     530            int ivol;
     531            if (argc < 5) {
     532                for (ivol=0; ivol < n_volumes; ivol++) {
     533                    if (state) {
     534                        volume[ivol]->enable_data();
     535                    } else {
     536                        volume[ivol]->disable_data();
     537                    }
     538                }
     539            } else {
     540                for (int n=4; n < argc; n++) {
     541                        if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     542                                return TCL_ERROR;
     543                        }
     544                    if (state) {
     545                        volume[ivol]->enable_data();
     546                    } else {
     547                        volume[ivol]->disable_data();
     548                    }
     549                }
     550            }
     551            return TCL_OK;
     552        }
     553            else if (c == 'f' && strcmp(argv[2],"follows") == 0) {
     554            int nbytes;
     555                if (Tcl_GetInt(interp, argv[3], &nbytes) != TCL_OK) {
     556                        return TCL_ERROR;
     557                }
     558
     559            char fname[64];
     560            sprintf(fname,"/tmp/nv%d.dat",getpid());
     561            std::ofstream dfile(fname);
     562
     563            char buffer[8096];
     564            while (nbytes > 0) {
     565                int chunk = (sizeof(buffer) < nbytes) ? sizeof(buffer) : nbytes;
     566                int status = fread(buffer, 1, chunk, stdin);
     567                if (status > 0) {
     568                    dfile.write(buffer,status);
     569                    nbytes -= status;
     570                } else {
     571                    Tcl_AppendResult(interp, "data unpacking failed in file ",
     572                        fname, (char*)NULL);
     573                    return TCL_ERROR;
     574                }
     575            }
     576            dfile.close();
     577
     578            char cmdstr[512];
     579            sprintf(cmdstr, "mimedecode %s | gunzip -c > /tmp/nv%d.dx", fname, getpid());
     580            if (system(cmdstr) != 0) {
     581                Tcl_AppendResult(interp, "data unpacking failed in file ",
     582                    fname, (char*)NULL);
     583                return TCL_ERROR;
     584            }
     585
     586            sprintf(fname,"/tmp/nv%d.dx",getpid());
     587
     588            int n = n_volumes;
     589            Rappture::Outcome err = load_volume_file(n, fname);
     590
     591            sprintf(cmdstr, "rm -f /tmp/nv%d.dat /tmp/nv%d.dx", getpid(), getpid());
     592            system(cmdstr);
     593
     594            if (err) {
     595                Tcl_AppendResult(interp, err.remark().c_str(), (char*)NULL);
     596                return TCL_ERROR;
     597            }
     598
     599            volume[n]->set_n_slice(512);
     600            volume[n]->disable_cutplane(0);
     601            volume[n]->disable_cutplane(1);
     602            volume[n]->disable_cutplane(2);
     603            vol_render->add_volume(volume[n], get_transfunc("default"));
     604
     605            return TCL_OK;
     606        }
     607        Tcl_AppendResult(interp, "bad option \"", argv[2],
     608            "\": should be follows or state", (char*)NULL);
     609        return TCL_ERROR;
     610    }
     611        else if (c == 'o' && strcmp(argv[1],"outline") == 0) {
    469612        if (argc < 3) {
    470613                    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     
    499642                        return TCL_ERROR;
    500643                    }
    501                     if (ivol < 0 || ivol > n_volumes) {
     644                    if (ivol < 0 || ivol >= n_volumes) {
    502645                        Tcl_AppendResult(interp, "bad volume index \"", argv[n],
    503646                            "\": out of range", (char*)NULL);
     
    535678                        return TCL_ERROR;
    536679                    }
    537                     if (ivol < 0 || ivol > n_volumes) {
     680                    if (ivol < 0 || ivol >= n_volumes) {
    538681                        Tcl_AppendResult(interp, "bad volume index \"", argv[n],
    539682                            "\": out of range", (char*)NULL);
     
    550693        return TCL_ERROR;
    551694    }
    552         else if (c == 's' && strcmp(argv[1],"state") == 0) {
     695        else if (c == 's' && strcmp(argv[1],"shading") == 0) {
    553696        if (argc < 3) {
    554697                    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    555                             " state on|off ?volume ...?\"", (char*)NULL);
     698                            argv[1], " option ?arg arg...?\"", (char*)NULL);
    556699                    return TCL_ERROR;
    557700        }
    558 
    559         int state;
    560             if (Tcl_GetBoolean(interp, argv[2], &state) != TCL_OK) {
    561                     return TCL_ERROR;
    562             }
    563 
    564         int ivol;
    565         for (int n=3; n < argc; n++) {
    566                 if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     701        c = *argv[2];
     702            if (c == 'c' && strcmp(argv[2],"color") == 0) {
     703            if (argc < 4) {
     704                        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     705                                argv[1], " color value ?volume ...?\"", (char*)NULL);
     706                        return TCL_ERROR;
     707            }
     708
     709            float cval[3];
     710                if (GetColor(interp, argv[3], cval) != TCL_OK) {
    567711                        return TCL_ERROR;
    568712                }
    569             if (state) {
    570                 volume[ivol]->enable_data();
     713
     714            int ivol;
     715            if (argc < 5) {
     716                for (ivol=0; ivol < n_volumes; ivol++) {
     717                    //volume[ivol]->set_diffuse((float)dval);
     718                }
    571719            } else {
    572                 volume[ivol]->disable_data();
     720                for (int n=4; n < argc; n++) {
     721                        if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     722                                return TCL_ERROR;
     723                        }
     724                    //volume[ivol]->set_diffuse((float)dval);
     725                }
     726            }
     727            return TCL_OK;
     728        }
     729            else if (c == 'd' && strcmp(argv[2],"diffuse") == 0) {
     730            if (argc < 4) {
     731                        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     732                                argv[1], " diffuse value ?volume ...?\"", (char*)NULL);
     733                        return TCL_ERROR;
     734            }
     735
     736            double dval;
     737                if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) {
     738                        return TCL_ERROR;
     739                }
     740
     741            int ivol;
     742            if (argc < 5) {
     743                for (ivol=0; ivol < n_volumes; ivol++) {
     744                    volume[ivol]->set_diffuse((float)dval);
     745                }
     746            } else {
     747                for (int n=4; n < argc; n++) {
     748                        if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     749                                return TCL_ERROR;
     750                        }
     751                    volume[ivol]->set_diffuse((float)dval);
     752                }
     753            }
     754            return TCL_OK;
     755        }
     756            else if (c == 'o' && strcmp(argv[2],"opacity") == 0) {
     757            if (argc < 4) {
     758                        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     759                                argv[1], " opacity value ?volume ...?\"", (char*)NULL);
     760                        return TCL_ERROR;
     761            }
     762
     763            double dval;
     764                if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) {
     765                        return TCL_ERROR;
     766                }
     767
     768            int ivol;
     769            if (argc < 5) {
     770                for (ivol=0; ivol < n_volumes; ivol++) {
     771                    volume[ivol]->set_opacity_scale((float)dval);
     772                }
     773            } else {
     774                for (int n=4; n < argc; n++) {
     775                        if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     776                                return TCL_ERROR;
     777                        }
     778                    volume[ivol]->set_opacity_scale((float)dval);
     779                }
     780            }
     781            return TCL_OK;
     782        }
     783            else if (c == 's' && strcmp(argv[2],"specular") == 0) {
     784            if (argc < 4) {
     785                        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     786                                argv[1], " specular value ?volume ...?\"", (char*)NULL);
     787                        return TCL_ERROR;
     788            }
     789
     790            double dval;
     791                if (Tcl_GetDouble(interp, argv[3], &dval) != TCL_OK) {
     792                        return TCL_ERROR;
     793                }
     794
     795            int ivol;
     796            if (argc < 5) {
     797                for (ivol=0; ivol < n_volumes; ivol++) {
     798                    volume[ivol]->set_specular((float)dval);
     799                }
     800            } else {
     801                for (int n=4; n < argc; n++) {
     802                        if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     803                                return TCL_ERROR;
     804                        }
     805                    volume[ivol]->set_specular((float)dval);
     806                }
     807            }
     808            return TCL_OK;
     809        }
     810        Tcl_AppendResult(interp, "bad option \"", argv[2],
     811            "\": should be color, diffuse, opacity, or specular", (char*)NULL);
     812        return TCL_ERROR;
     813    }
     814    else if (c == 's' && strcmp(argv[1],"state") == 0) {
     815        if (argc < 3) {
     816            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     817                argv[1], " on|off ?volume...?\"", (char*)NULL);
     818            return TCL_ERROR;
     819        }
     820
     821        int state;
     822        if (Tcl_GetBoolean(interp, argv[2], &state) != TCL_OK) {
     823            return TCL_ERROR;
     824        }
     825
     826        int ivol;
     827        if (argc < 4) {
     828            for (ivol=0; ivol < n_volumes; ivol++) {
     829                if (state) {
     830                    volume[ivol]->enable();
     831                } else {
     832                    volume[ivol]->disable();
     833                }
     834            }
     835        } else {
     836            for (int n=3; n < argc; n++) {
     837                    if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     838                            return TCL_ERROR;
     839                    }
     840                if (state) {
     841                    volume[ivol]->enable();
     842                } else {
     843                    volume[ivol]->disable();
     844                }
    573845            }
    574846        }
     
    577849
    578850    Tcl_AppendResult(interp, "bad option \"", argv[1],
    579         "\": should be state", (char*)NULL);
     851        "\": should be data, outline, shading, or state", (char*)NULL);
    580852    return TCL_ERROR;
    581853}
     
    590862  if (argc != 3) {
    591863    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    592                 " volume_index tf_index \"", (char*)NULL);
     864        " volume_index tf_index \"", (char*)NULL);
    593865    return TCL_ERROR;
    594866  }
     
    600872  }
    601873
    602   vol_render->add_volume(volume[(int)volume_index], tf[(int)tf_index]);
     874  //vol_render->add_volume(volume[(int)volume_index], tf[(int)tf_index]);
    603875
    604876  return TCL_OK;
     
    628900  return TCL_OK;
    629901}
    630 
    631 //Enable a volume.
    632 //Can enable a volume that is not yet added to the volume renderer.
    633 //But it won't be rendered until it's added to the volume renderer using VolumeLinkCmd
    634 //volume_index: the index maintained in the volume renderer.
    635 static int
    636 VolumeEnableCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    637 {
    638   fprintf(stderr, "enabled a volume to render command\n");
    639 
    640   double volume_index, mode;
    641 
    642   if (argc != 3) {
    643     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    644                 " volume_index mode \"", (char*)NULL);
    645     return TCL_ERROR;
    646   }
    647   if (Tcl_GetDouble(interp, argv[1], &volume_index) != TCL_OK) {
    648         return TCL_ERROR;
    649   }
    650   if (Tcl_GetDouble(interp, argv[2], &mode) != TCL_OK) {
    651         return TCL_ERROR;
    652   }
    653 
    654   if(mode==0)
    655     vol_render->disable_volume((int)volume_index);
    656   else
    657     vol_render->enable_volume((int)volume_index);
    658 
    659   return TCL_OK;
    660 }
    661 
    662 
    663 void load_volume(int index, int width, int height, int depth, int n_component, float* data);
    664 
    665 //The client sends the load data command to tell the index of the volume, and the dimensions of the data
    666 //Then the client sends a chunck of binary floats. This call creates a NEW volume
    667 static int
    668 VolumeNewCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    669 {
    670   fprintf(stderr, "load data command\n");
    671 
    672   double index, w, h, d;
    673 
    674   if (argc != 5) {
    675     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    676                 " volume_index w h d \"", (char*)NULL);
    677     return TCL_ERROR;
    678   }
    679   if (Tcl_GetDouble(interp, argv[1], &index) != TCL_OK) {
    680         return TCL_ERROR;
    681   }
    682   if (Tcl_GetDouble(interp, argv[2], &w) != TCL_OK) {
    683         return TCL_ERROR;
    684   }
    685   if (Tcl_GetDouble(interp, argv[3], &h) != TCL_OK) {
    686         return TCL_ERROR;
    687   }
    688   if (Tcl_GetDouble(interp, argv[4], &d) != TCL_OK) {
    689         return TCL_ERROR;
    690   }
    691 
    692   //Now read w*h*d*4*4 bytes. The server expects the volume to be units of 4-float tuples
    693   char* tmp = new char[int(w*h*d*4*4)];
    694   bzero(tmp, w*h*d*4*4);
    695   int status = read(0, tmp, w*h*d*4*4);
    696   if (status <= 0){
    697     exit(0);
    698   }
    699  
    700   load_volume(int(index), int(w), int(h), int(d), 4, (float*) tmp);
    701  
    702   delete[] tmp;
    703   return TCL_OK;
    704 }
    705 
    706902
    707903static int
     
    9061102  }
    9071103
    908   plane_render->add_plane(plane[(int)plane_index], tf[(int)tf_index]);
     1104  //plane_render->add_plane(plane[(int)plane_index], tf[(int)tf_index]);
    9091105
    9101106  return TCL_OK;
     
    10571253
    10581254#ifndef NV40
    1059         nx = pow(2.0, ceil(log10((double)nx)/log10(2.0)));  // must be an even power of 2
    1060         ny = pow(2.0, ceil(log10((double)ny)/log10(2.0)));
    1061         nz = pow(2.0, ceil(log10((double)nz)/log10(2.0)));
     1255        // must be an even power of 2 for older cards
     1256            nx = (int)pow(2.0, ceil(log10((double)nx)/log10(2.0)));
     1257            ny = (int)pow(2.0, ceil(log10((double)ny)/log10(2.0)));
     1258            nz = (int)pow(2.0, ceil(log10((double)nz)/log10(2.0)));
    10621259#endif
    10631260
     
    11101307/* Load a 3D volume from a dx-format file
    11111308 */
    1112 void
     1309Rappture::Outcome
    11131310load_volume_file(int index, char *fname) {
     1311    Rappture::Outcome result;
     1312
    11141313    Rappture::MeshTri2D xymesh;
    11151314    int dummy, nx, ny, nz, nxy, npts;
     
    11401339                }
    11411340
    1142                 std::ofstream ftmp("tmppts");
     1341                char fpts[128];
     1342                sprintf(fpts, "/tmp/tmppts%d", getpid());
     1343                char fcells[128];
     1344                sprintf(fcells, "/tmp/tmpcells%d", getpid());
     1345
     1346                std::ofstream ftmp(fpts);
    11431347                // save corners of bounding box first, to work around meshing
    11441348                // problems in voronoi utility
     
    11561360                ftmp.close();
    11571361
    1158                 if (system("voronoi -t < tmppts > tmpcells") == 0) {
     1362                char cmdstr[512];
     1363                sprintf(cmdstr, "voronoi -t < %s > %s", fpts, fcells);
     1364                if (system(cmdstr) == 0) {
    11591365                    int cx, cy, cz;
    1160                     std::ifstream ftri("tmpcells");
     1366                    std::ifstream ftri(fcells);
    11611367                    while (!ftri.eof()) {
    11621368                        ftri.getline(line,sizeof(line)-1);
     
    11701376                    ftri.close();
    11711377                } else {
    1172                     std::cerr << "WARNING: triangularization failed" << std::endl;
    1173                 }
     1378                    return result.error("triangularization failed");
     1379                }
     1380
     1381                sprintf(cmdstr, "rm -f %s %s", fpts, fcells);
     1382                system(cmdstr);
    11741383            }
    11751384            else if (sscanf(start, "object %d class regulararray count %d", &dummy, &nz) == 2) {
     
    11871396            else if (sscanf(start, "object %d class array type %s rank 0 items %d data follows", &dummy, type, &npts) == 3) {
    11881397                if (isrect && (npts != nx*ny*nz)) {
    1189                     std::cerr << "inconsistent data: expected " << nx*ny*nz << " points but found " << npts << " points" << std::endl;
    1190                     return;
     1398                    char mesg[256];
     1399                    sprintf(mesg,"inconsistent data: expected %d points but found %d points", nx*ny*nz, npts);
     1400                    return result.error(mesg);
    11911401                }
    11921402                else if (!isrect && (npts != nxy*nz)) {
    1193                     std::cerr << "inconsistent data: expected " << nxy*nz << " points but found " << npts << " points" << std::endl;
    1194                     return;
     1403                    char mesg[256];
     1404                    sprintf(mesg,"inconsistent data: expected %d points but found %d points", nxy*nz, npts);
     1405                    return result.error(mesg);
    11951406                }
    11961407                break;
     
    12271438            // make sure that we read all of the expected points
    12281439            if (nread != nx*ny*nz) {
    1229                 std::cerr << "inconsistent data: expected " << nx*ny*nz << " points but found " << nread << " points" << std::endl;
    1230                 return;
     1440                char mesg[256];
     1441                sprintf(mesg,"inconsistent data: expected %d points but found %d points", nx*ny*nz, nread);
     1442                result.error(mesg);
     1443                return result;
    12311444            }
    12321445
     
    12431456
    12441457#ifndef NV40
    1245             nx = pow(2.0, ceil(log10((double)nx)/log10(2.0)));  // must be an even power of 2
    1246             ny = pow(2.0, ceil(log10((double)ny)/log10(2.0)));
    1247             nz = pow(2.0, ceil(log10((double)nz)/log10(2.0)));
     1458            // must be an even power of 2 for older cards
     1459                nx = (int)pow(2.0, ceil(log10((double)nx)/log10(2.0)));
     1460                ny = (int)pow(2.0, ceil(log10((double)ny)/log10(2.0)));
     1461                nz = (int)pow(2.0, ceil(log10((double)nz)/log10(2.0)));
    12481462#endif
    12491463
     
    12531467            double dv = field.valueMax() - field.valueMin();
    12541468            if (dv == 0.0) { dv = 1.0; }
    1255 
    1256             std::cout << "generating " << nx << "x" << ny << "x" << nz << " = " << nx*ny*nz << " points" << std::endl;
    12571469
    12581470            // generate the uniformly sampled data that we need for a volume
     
    12741486                        double oldval = ((ngen/4) % nx == 0) ? 0.0 : data[ngen-4];
    12751487                        oldval = (oldval < 0) ? 0.0 : oldval;
    1276                         data[ngen+1] = (curval-oldval)/dmin;
     1488                        data[ngen+1] = curval-oldval;  // assume dx=1
    12771489
    12781490                        // gradient in y-direction
    12791491                        oldval = (ngen-4*nx >= 0) ? data[ngen-4*nx] : 0.0;
    12801492                        oldval = (oldval < 0) ? 0.0 : oldval;
    1281                         data[ngen+2] = (curval-oldval)/dmin;
     1493                        data[ngen+2] = curval-oldval;  // assume dy=1
    12821494
    12831495                        // gradient in z-direction
    12841496                        oldval = (ngen-4*nx*ny >= 0) ? data[ngen-4*nx*ny] : 0.0;
    12851497                        oldval = (oldval < 0) ? 0.0 : oldval;
    1286                         data[ngen+3] = (curval-oldval)/dmin;
    1287                         ngen += 4;
     1498                        data[ngen+3] = curval-oldval;  // assume dz=1
     1499                        ngen += 4;
    12881500                    }
    12891501                }
    12901502            }
    1291 
    1292             /*
    1293             //hack very first and last yz slice have 0 grad
    1294             for(int iz=0; iz<nz; iz++){
    1295               for(int iy=0; iy<ny; iy++){
    1296                  int index1, index2;
    1297                  int ix1 = 0;
    1298                  int ix2 = 3;
    1299                  index1 = ix1 + iy*nx + iz*nx*ny;
    1300                  index2 = ix2 + iy*nx + iz*nx*ny;
    1301                  data[4*index1 + 1] = data[4*index2 + 1];
    1302                  data[4*index1 + 2] = data[4*index2 + 2];
    1303                  data[4*index1 + 3] = data[4*index2 + 3];
    1304 
    1305                  ix1 = nx-1;
    1306                  ix2 = nx-2;
    1307                  index1 = ix1 + iy*nx + iz*nx*ny;
    1308                  index2 = ix2 + iy*nx + iz*nx*ny;
    1309                  data[4*index1 + 1] = data[4*index2 + 1];
    1310                  data[4*index1 + 2] = data[4*index2 + 2];
    1311                  data[4*index1 + 3] = data[4*index2 + 3];
    1312               }
    1313             }
    1314             */
    13151503
    13161504            load_volume(index, nx, ny, nz, 4, data);
     
    13311519            // make sure that we read all of the expected points
    13321520            if (nread != nxy*nz) {
    1333                 std::cerr << "inconsistent data: expected " << nxy*nz << " points but found " << nread << " points" << std::endl;
    1334                 return;
     1521                char mesg[256];
     1522                sprintf(mesg,"inconsistent data: expected %d points but found %d points", nxy*nz, nread);
     1523                return result.error(mesg);
    13351524            }
    13361525
     
    13461535
    13471536            nx = (int)ceil(dx/dmin);
    1348             nx = pow(2.0, ceil(log10((double)nx)/log10(2.0)));  // must be an even power of 2
    13491537            ny = (int)ceil(dy/dmin);
    1350             ny = pow(2.0, ceil(log10((double)ny)/log10(2.0)));
    13511538            nz = (int)ceil(dz/dmin);
    1352             nz = pow(2.0, ceil(log10((double)nz)/log10(2.0)));
     1539#ifndef NV40
     1540            // must be an even power of 2 for older cards
     1541                nx = (int)pow(2.0, ceil(log10((double)nx)/log10(2.0)));
     1542                ny = (int)pow(2.0, ceil(log10((double)ny)/log10(2.0)));
     1543                nz = (int)pow(2.0, ceil(log10((double)nz)/log10(2.0)));
     1544#endif
    13531545            float *data = new float[4*nx*ny*nz];
    13541546
     
    13561548            double dv = field.valueMax() - field.valueMin();
    13571549            if (dv == 0.0) { dv = 1.0; }
    1358             std::cout << "generating " << nx << "x" << ny << "x" << nz << " = " << nx*ny*nz << " points" << std::endl;
    13591550
    13601551            // generate the uniformly sampled data that we need for a volume
     
    13671558                        double xval = x0 + ix*dmin;
    13681559                        double v = field.value(xval,yval,zval);
    1369                         data[ngen++] = (isnan(v)) ? -1.0 : (v - vmin)/dv;
    1370                         data[ngen++] = 0.0;
    1371                         data[ngen++] = 0.0;
    1372                         data[ngen++] = 0.0;
     1560
     1561                        // scale all values [0-1], -1 => out of bounds
     1562                        v = (isnan(v)) ? -1.0 : (v - vmin)/dv;
     1563                        data[ngen] = v;
     1564
     1565                        // gradient in x-direction
     1566                        double curval = (v < 0) ? 0.0 : v;
     1567                        double oldval = ((ngen/4) % nx == 0) ? 0.0 : data[ngen-4];
     1568                        oldval = (oldval < 0) ? 0.0 : oldval;
     1569                        data[ngen+1] = curval-oldval;  // assume dx=1
     1570
     1571                        // gradient in y-direction
     1572                        oldval = (ngen-4*nx >= 0) ? data[ngen-4*nx] : 0.0;
     1573                        oldval = (oldval < 0) ? 0.0 : oldval;
     1574                        data[ngen+2] = curval-oldval;  // assume dy=1
     1575
     1576                        // gradient in z-direction
     1577                        oldval = (ngen-4*nx*ny >= 0) ? data[ngen-4*nx*ny] : 0.0;
     1578                        oldval = (oldval < 0) ? 0.0 : oldval;
     1579                        data[ngen+3] = curval-oldval;  // assume dz=1
     1580                        ngen += 4;
    13731581                    }
    13741582                }
     
    13781586        }
    13791587    } else {
    1380         std::cerr << "WARNING: data not found in file " << fname << std::endl;
    1381     }
     1588        char mesg[256];
     1589        sprintf(mesg,"data not found in file %s", fname);
     1590        return result.error(mesg);
     1591    }
     1592
     1593    //
     1594    // Center this new volume on the origin.
     1595    //
     1596    float dx0 = -0.5;
     1597    float dy0 = -0.5*dy/dx;
     1598    float dz0 = -0.5*dz/dx;
     1599    volume[index]->move(Vector3(dx0, dy0, dz0));
     1600
     1601    return result;
    13821602}
    13831603
     
    14041624
    14051625
    1406 //load a colormap 1D texture
    1407 void load_transfer_function(int index, int size, float* data){
    1408 
    1409   if(tf[index]!=0){
    1410     delete tf[index];
    1411     tf[index]=0;
    1412   }
    1413 
    1414   tf[index] = new TransferFunction(size, data);
     1626// get a colormap 1D texture by name
     1627TransferFunction*
     1628get_transfunc(char *name) {
     1629    Tcl_HashEntry *entryPtr;
     1630    entryPtr = Tcl_FindHashEntry(&tftable, name);
     1631    if (entryPtr) {
     1632        return (TransferFunction*)Tcl_GetHashValue(entryPtr);
     1633    }
     1634    return NULL;
    14151635}
    14161636
     
    14211641
    14221642  //fprintf(stderr, "tf update\n");
    1423   if(tf[0]==0) return;
     1643  TransferFunction *tf = get_transfunc("default");
     1644  if (tf == NULL) return;
    14241645
    14251646  float data[256*4];
     
    14321653  }
    14331654
    1434   tf[0]->update(data);
     1655  tf->update(data);
    14351656
    14361657#ifdef EVENTLOG
     
    14411662#endif
    14421663}
    1443 
    1444 
    1445 //------------------------------------------
    1446 //update the transfer function in server mode
    1447 //------------------------------------------
    1448 void update_transfer_function(int index, float* data){
    1449   tf[index]->update(data);
    1450 }
    1451 
    14521664
    14531665
     
    16231835
    16241836
    1625 void init_transfer_function(){
    1626   tf[0] = new TransferFunction(def_tf_size, def_tf);
    1627 }
    1628 
    1629 
    16301837//init line integral convolution
    16311838void init_lic(){
     
    17051912   glLightfv(GL_LIGHT1, GL_SPECULAR, white_light);     
    17061913
    1707    //init volume and colormap arrays
     1914   //init volume array
    17081915   for(int i=0; i<MAX_N_VOLUMES; i++){
    17091916     volume[i] = 0;
    1710      tf[i] = 0;
    17111917   }
     1918
     1919   // init table of transfer functions
     1920   Tcl_InitHashTable(&tftable, TCL_STRING_KEYS);
    17121921
    17131922   //check if performance query is supported
     
    17201929   //load_volume_file(0, "./data/nw-AB-Vg=0.000-Vd=1.000-potential.dx");
    17211930   //load_volume_file(0, "./data/test2.dx");
    1722 
    1723    load_volume_file(0, "./data/mu-wire-3d.dx");
     1931   //load_volume_file(0, "./data/mu-wire-3d.dx");
    17241932   //load_volume_file(0, "./data/input_nd_dx_4"); //take a VERY long time?
    17251933   //load_vector_file(1, "./data/J-wire-vec.dx");
     
    17281936   //load_volume_file(4, "./data/mu-wire-3d.dx");
    17291937
    1730    init_transfer_function();   //initialize transfer function
    17311938   init_offscreen_buffer();    //frame buffer object for offscreen rendering
    17321939   init_cg();   //create cg shader context
     
    17341941   //create volume renderer and add volumes to it
    17351942   vol_render = new VolumeRenderer(g_context);
    1736    volume[0]->set_n_slice(512);
    1737    volume[0]->disable_cutplane(0);
    1738    volume[0]->disable_cutplane(1);
    1739    volume[0]->disable_cutplane(2);
    1740    vol_render->add_volume(volume[0], tf[0]);
    1741 
    1742    //volume[1]->move(Vector3(0.42, 0.1, 0.1));
    1743    //vol_render->add_volume(volume[1], tf[0]);
    1744 
    1745    //volume[3]->move(Vector3(0.2, -0.1, -0.1));
    1746    //vol_render->add_volume(volume[3], tf[0]);
    1747    //volume[4]->move(Vector3(0.2,  0.1, -0.1));
    1748    //vol_render->add_volume(volume[4], tf[0]);
    1749 
    17501943
    17511944   //create an 2D plane renderer
     
    17531946   make_test_2D_data();
    17541947
    1755    plane_render->add_plane(plane[0], tf[0]);
    1756 
    1757    
     1948   plane_render->add_plane(plane[0], get_transfunc("default"));
     1949
    17581950   //init_particle_system();
    17591951   //init_lic();
     
    17661958    Tcl_MakeSafe(interp);
    17671959
     1960    Tcl_DStringInit(&cmdbuffer);
     1961
    17681962    // manipulate the viewpoint
    17691963    Tcl_CreateCommand(interp, "camera", CameraCmd,
     
    17781972        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
    17791973
     1974    // manipulate transfer functions
     1975    Tcl_CreateCommand(interp, "transfunc", TransfuncCmd,
     1976        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
     1977
    17801978    // manipulate volume data
    17811979    Tcl_CreateCommand(interp, "volume", VolumeCmd,
    17821980        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
    17831981
    1784   //create new transfer function
    1785   Tcl_CreateCommand(interp, "tf_new", TransferFunctionNewCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    1786   //update an existing transfer function
    1787   Tcl_CreateCommand(interp, "tf_update", TransferFunctionUpdateCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    1788 
    1789 
    1790   //create new volume
    1791   Tcl_CreateCommand(interp, "volume_new", VolumeNewCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
     1982    // create a default transfer function
     1983    if (Tcl_Eval(interp, def_transfunc) != TCL_OK) {
     1984        fprintf(stdin, "WARNING: bad default transfer function\n");
     1985        fprintf(stdin, Tcl_GetStringResult(interp));
     1986    }
     1987
     1988
    17921989  //link an EXISTING volume and transfer function to the volume renderer.
    17931990  //Only after being added, can a volume be rendered. This command does not create a volume nor a transfer function
     
    17951992  //move an volume
    17961993  Tcl_CreateCommand(interp, "volume_move", VolumeMoveCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    1797   //enable or disable an existing volume
    1798   Tcl_CreateCommand(interp, "volume_enable", VolumeEnableCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    17991994  //resize volume
    18001995  Tcl_CreateCommand(interp, "volume_resize", VolumeResizeCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
     
    18682063void xinetd_listen(){
    18692064
    1870     std::string data;
    1871     char tmp[256];
    1872     bzero(tmp, 256);
    1873     int status = read(0, tmp, 256);
    1874     if (status <= 0) {
    1875       exit(0);
    1876     }
    1877     data = tmp;
    1878 
    1879     if (Tcl_Eval(interp, (char*)data.c_str()) != TCL_OK) {
    1880       std::ostringstream errmsg;
    1881       errmsg << "ERROR: " << Tcl_GetStringResult(interp) << std::endl;
    1882       write(0, errmsg.str().c_str(), errmsg.str().size());
    1883       return;
    1884     }
    1885 
     2065    int flags = fcntl(0, F_GETFL, 0);
     2066    fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
     2067
     2068    int status = TCL_OK;
     2069    int npass = 0;
     2070
     2071    //
     2072    //  Read and execute as many commands as we can from stdin...
     2073    //
     2074    while (status == TCL_OK) {
     2075        //
     2076        //  Read the next command from the buffer.  First time through
     2077        //  we block here and wait if necessary until a command comes in.
     2078        //
     2079        //  BE CAREFUL:  Read only one command, up to a newline.
     2080        //  The "volume data follows" command needs to be able to read
     2081        //  the data immediately following the command, and we shouldn't
     2082        //  consume it here.
     2083        //
     2084        while (1) {
     2085            char c = getchar();
     2086            if (c <= 0) {
     2087                if (npass == 0) {
     2088                    exit(0);  // EOF -- we're done!
     2089                } else {
     2090                    break;
     2091                }
     2092            }
     2093            Tcl_DStringAppend(&cmdbuffer, &c, 1);
     2094
     2095            if (c=='\n' && Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer))) {
     2096                break;
     2097            }
     2098        }
     2099
     2100        // no command? then we're done for now
     2101        if (Tcl_DStringLength(&cmdbuffer) == 0) {
     2102            break;
     2103        }
     2104
     2105        // back to original flags during command evaluation...
     2106        fcntl(0, F_SETFL, flags & ~O_NONBLOCK);
     2107
     2108        status = Tcl_Eval(interp, Tcl_DStringValue(&cmdbuffer));
     2109        Tcl_DStringSetLength(&cmdbuffer, 0);
     2110
     2111        // non-blocking for next read -- we might not get anything
     2112        fcntl(0, F_SETFL, flags | O_NONBLOCK);
     2113        npass++;
     2114    }
     2115    fcntl(0, F_SETFL, flags);
     2116
     2117    if (status != TCL_OK) {
     2118        std::ostringstream errmsg;
     2119        errmsg << "ERROR: " << Tcl_GetStringResult(interp) << std::endl;
     2120        write(0, errmsg.str().c_str(), errmsg.str().size());
     2121        return;
     2122    }
     2123
     2124    //
     2125    //  Generate the latest frame and send it back to the client
     2126    //
    18862127    display();
    18872128
     
    19362177    bmp_header_add_int(header, pos, 0);
    19372178
    1938     std::ostringstream buffer;
    1939     buffer << "nv>image -bytes " << fsize << "\n";
    1940     write(0, buffer.str().c_str(), buffer.str().size());
     2179    std::ostringstream result;
     2180    result << "nv>image -bytes " << fsize << "\n";
     2181    write(0, result.str().c_str(), result.str().size());
    19412182
    19422183    write(0, header, sizeof(header));
    19432184    write(0, screen_buffer, win_width * win_height * 3);
    19442185#endif
    1945 
    1946     cerr << "server: serve() image sent" << endl;
    19472186}
    19482187
     
    26432882   glutInit(&argc, argv);
    26442883   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    2645 
    2646    MainTransferFunctionWindow * tf_window;
    2647    tf_window = new MainTransferFunctionWindow();
    2648    tf_window->mainInit();
    26492884   
    26502885   glutInitWindowSize(win_width, win_height);
    26512886   glutInitWindowPosition(10, 10);
    26522887   render_window = glutCreateWindow(argv[0]);
    2653 
    26542888   glutDisplayFunc(display);
     2889
    26552890#ifndef XINETD
     2891   MainTransferFunctionWindow * tf_window;
     2892   tf_window = new MainTransferFunctionWindow();
     2893   tf_window->mainInit();
     2894
    26562895   glutMouseFunc(mouse);
    26572896   glutMotionFunc(motion);
  • trunk/gui/vizservers/nanovis/nanovis.h

    r431 r445  
    113113int    iframe = 0;
    114114int    Npat   = 64;
    115 int    alpha  = (0.12*255);
     115int    alpha  = (int)round(0.12*255);
    116116float  sa;
    117117float  tmax   = NPIX/(SCALE*NPN);
Note: See TracChangeset for help on using the changeset viewer.