Index: /nanovis/branches/1.1/Command.cpp
===================================================================
--- /nanovis/branches/1.1/Command.cpp	(revision 4611)
+++ /nanovis/branches/1.1/Command.cpp	(revision 4612)
@@ -26,12 +26,6 @@
  *        o Use Tcl command option parser to reduce size of procedures, remove
  *          lots of extra error checking code. (almost there)
- *        o Convert GetVolumeIndices to GetVolumes.  Goal is to remove
- *          all references of Nanovis::volume[] from this file.  Don't
- *          want to know how volumes are stored. Same for heightmaps.
- *        o Rationalize volume id scheme. Right now it's the index in
- *          the vector. 1) Use a list instead of a vector. 2) carry
- *          an id field that's a number that gets incremented each new volume.
  *        o Add bookkeeping for volumes, heightmaps, flows, etc. to track
- *          1) id #  2) simulation # 3) include/exclude.  The include/exclude
+ *          1) simulation # 2) include/exclude.  The include/exclude
  *          is to indicate whether the item should contribute to the overall
  *          limits of the axes.
@@ -45,6 +39,4 @@
 
 #include <RpField1D.h>
-#include <RpFieldRect3D.h>
-#include <RpFieldPrism3D.h>
 #include <RpEncode.h>
 #include <RpOutcome.h>
@@ -55,4 +47,5 @@
 #include "nanovis.h"
 #include "CmdProc.h"
+#include "FlowCmd.h"
 #include "Trace.h"
 #ifdef USE_POINTSET_RENDERER
@@ -109,17 +102,4 @@
 }";
 
-static Tcl_ObjCmdProc AxisCmd;
-static Tcl_ObjCmdProc CameraCmd;
-static Tcl_ObjCmdProc CutplaneCmd;
-extern Tcl_AppInitProc FlowCmdInitProc;
-static Tcl_ObjCmdProc GridCmd;
-static Tcl_ObjCmdProc LegendCmd;
-static Tcl_ObjCmdProc ScreenCmd;
-static Tcl_ObjCmdProc SnapshotCmd;
-static Tcl_ObjCmdProc TransfuncCmd;
-static Tcl_ObjCmdProc Unirect2dCmd;
-static Tcl_ObjCmdProc UpCmd;
-static Tcl_ObjCmdProc VolumeCmd;
-
 bool
 GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, bool *boolPtr)
@@ -2228,4 +2208,2 @@
     return interp;
 }
-
-
Index: /nanovis/branches/1.1/Command.h
===================================================================
--- /nanovis/branches/1.1/Command.h	(revision 4612)
+++ /nanovis/branches/1.1/Command.h	(revision 4612)
@@ -0,0 +1,37 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (c) 2004-2013  HUBzero Foundation, LLC
+ *
+ * Authors:
+ *   Wei Qiao <qiaow@purdue.edu>
+ *   Insoo Woo <iwoo@purdue.edu>
+ *   George A. Howlett <gah@purdue.edu>
+ *   Leif Delgass <ldelgass@purdue.edu>
+ */
+#ifndef COMMAND_H
+#define COMMAND_H
+
+#include <tcl.h>
+
+namespace Rappture {
+class Buffer;
+}
+class Volume;
+
+extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+                          int *axisVal);
+
+extern int GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+                             bool *boolVal);
+
+extern int GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes);
+
+extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+                           float *floatVal);
+
+extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+                            Volume **volume);
+
+extern Tcl_Interp *initTcl();
+
+#endif
Index: /nanovis/branches/1.1/Doxyfile.in
===================================================================
--- /nanovis/branches/1.1/Doxyfile.in	(revision 4611)
+++ /nanovis/branches/1.1/Doxyfile.in	(revision 4612)
@@ -599,5 +599,5 @@
 # subdirectory from a directory tree whose root is specified with the INPUT tag.
 
-EXCLUDE                = @srcdir@/newmat11 @srcdir@/CircularQueue.h @srcdir@/ParticleEmitter.h @srcdir@/ParticleEmitter.cpp @srcdir@/ParticleSystem.h @srcdir@/ParticleSystem.cpp @srcdir@/ParticleSystemFactory.h @srcdir@/ParticleSystemFactory.cpp @srcdir@/BucketSort.h @srcdir@/BucketSort.cpp @srcdir@/PCASplit.h @srcdir@/PCASplit.cpp @srcdir@/PointSet.h @srcdir@/PointSet.cpp @srcdir@/PointSetRenderer.h @srcdir@/PointSetRenderer.cpp @srcdir@/PointShader.h @srcdir@/PointShader.cpp @srcdir@/NvVectorField.h @srcdir@/NvVectorField.cpp @srcdir@/NvFlowVisRenderer.h @srcdir@/NvFlowVisRenderer.cpp
+EXCLUDE                = @srcdir@/newmat11 @srcdir@/CircularQueue.h @srcdir@/ParticleEmitter.h @srcdir@/ParticleEmitter.cpp @srcdir@/ParticleSystem.h @srcdir@/ParticleSystem.cpp @srcdir@/ParticleSystemFactory.h @srcdir@/ParticleSystemFactory.cpp @srcdir@/BucketSort.h @srcdir@/BucketSort.cpp @srcdir@/PCASplit.h @srcdir@/PCASplit.cpp @srcdir@/PointSet.h @srcdir@/PointSet.cpp @srcdir@/PointSetRenderer.h @srcdir@/PointSetRenderer.cpp @srcdir@/PointShader.h @srcdir@/PointShader.cpp
 
 # The EXCLUDE_SYMLINKS tag can be used select whether or not files or
Index: /nanovis/branches/1.1/Flow.cpp
===================================================================
--- /nanovis/branches/1.1/Flow.cpp	(revision 4612)
+++ /nanovis/branches/1.1/Flow.cpp	(revision 4612)
@@ -0,0 +1,441 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (c) 2004-2013  HUBzero Foundation, LLC
+ *
+ * Authors:
+ *   Wei Qiao <qiaow@purdue.edu>
+ *   Insoo Woo <iwoo@purdue.edu>
+ *   George A. Howlett <gah@purdue.edu>
+ *   Leif Delgass <ldelgass@purdue.edu>
+ */
+
+#include <tcl.h>
+
+#include <vrmath/Vector3f.h>
+
+#include "nanovis.h"
+#include "Flow.h"
+#include "FlowCmd.h"
+#include "FlowTypes.h"
+#include "FlowParticles.h"
+#include "FlowBox.h"
+#include "NvLIC.h"
+#include "VelocityArrowsSlice.h"
+#include "NvParticleRenderer.h"
+#include "Switch.h"
+#include "Unirect.h"
+#include "Volume.h"
+#include "Trace.h"
+#include "TransferFunction.h"
+
+using namespace vrmath;
+
+Flow::Flow(Tcl_Interp *interp, const char *name) :
+    _interp(interp),
+    _name(name),
+    _data(NULL),
+    _volume(NULL)
+{
+    memset(&_sv, 0, sizeof(FlowValues));
+    _sv.sliceVisible = 1;
+    _sv.transferFunction = NanoVis::getTransferFunction("default");
+
+    _cmdToken = Tcl_CreateObjCommand(_interp, (char *)name, 
+                                     (Tcl_ObjCmdProc *)FlowInstObjCmd,
+                                     this, FlowInstDeleteProc);
+}
+
+Flow::~Flow()
+{
+    TRACE("Enter");
+
+    Rappture::FreeSwitches(_switches, &_sv, 0);
+
+    if (_data != NULL) {
+        delete _data;
+    }
+    if (_volume != NULL) {
+        NanoVis::removeVolume(_volume);
+        _volume = NULL;
+    }
+    for (BoxHashmap::iterator itr = _boxTable.begin();
+         itr != _boxTable.end(); ++itr) {
+        delete itr->second;
+    }
+    _boxTable.clear();
+    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
+         itr != _particlesTable.end(); ++itr) {
+        delete itr->second;
+    }
+    _particlesTable.clear();
+}
+
+void
+Flow::getBounds(Vector3f& min,
+                Vector3f& max,
+                bool onlyVisible)
+{
+    TRACE("Enter");
+
+    if (onlyVisible && !visible())
+        return;
+
+#if 0  // Using volume bounds instead of these
+    if (isDataLoaded()) {
+        Vector3f umin, umax;
+        Rappture::Unirect3d *unirect = data();
+        unirect->getWorldSpaceBounds(umin, umax);
+        if (min.x > umin.x) {
+            min.x = umin.x;
+        }
+        if (max.x < umax.x) {
+            max.x = umax.x;
+        }
+        if (min.y > umin.y) {
+            min.y = umin.y;
+        }
+        if (max.y < umax.y) {
+            max.y = umax.y;
+        }
+        if (min.z > umin.z) {
+            min.z = umin.z;
+        }
+        if (max.z < umax.z) {
+            max.z = umax.z;
+        }
+    }
+#endif
+    for (BoxHashmap::iterator itr = _boxTable.begin();
+         itr != _boxTable.end(); ++itr) {
+        FlowBox *box = itr->second;
+        if (!onlyVisible || box->visible()) {
+            Vector3f fbmin, fbmax;
+            box->getWorldSpaceBounds(fbmin, fbmax,
+                                     getVolume());
+            if (min.x > fbmin.x) {
+                min.x = fbmin.x;
+            }
+            if (max.x < fbmax.x) {
+                max.x = fbmax.x;
+            }
+            if (min.y > fbmin.y) {
+                min.y = fbmin.y;
+            }
+            if (max.y < fbmax.y) {
+                max.y = fbmax.y;
+            }
+            if (min.z > fbmin.z) {
+                min.z = fbmin.z;
+            }
+            if (max.z < fbmax.z) {
+                max.z = fbmax.z;
+            }
+        }
+    }
+}
+
+float
+Flow::getRelativePosition(FlowPosition *position)
+{
+    if (position->flags == RELPOS) {
+        return position->value;
+    }
+    switch (position->axis) {
+    case AXIS_X:  
+        return (position->value - NanoVis::xMin) / 
+            (NanoVis::xMax - NanoVis::xMin); 
+    case AXIS_Y:  
+        return (position->value - NanoVis::yMin) / 
+            (NanoVis::yMax - NanoVis::yMin); 
+    case AXIS_Z:  
+        return (position->value - NanoVis::zMin) / 
+            (NanoVis::zMax - NanoVis::zMin); 
+    }
+    return 0.0;
+}
+
+float
+Flow::getRelativePosition() 
+{
+    return getRelativePosition(&_sv.slicePos);
+}
+
+void
+Flow::resetParticles()
+{
+    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
+         itr != _particlesTable.end(); ++itr) {
+        itr->second->reset();
+    }
+}
+
+void
+Flow::advect()
+{
+    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
+         itr != _particlesTable.end(); ++itr) {
+        if (itr->second->visible()) {
+            itr->second->advect();
+        }
+    }
+}
+
+void
+Flow::render()
+{
+    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
+         itr != _particlesTable.end(); ++itr) {
+        if (itr->second->visible()) {
+            itr->second->render();
+        }
+    }
+    renderBoxes();
+}
+
+FlowParticles *
+Flow::createParticles(const char *particlesName)
+{
+    ParticlesHashmap::iterator itr = _particlesTable.find(particlesName);
+    if (itr != _particlesTable.end()) {
+        TRACE("Deleting existing particle injection plane '%s'", particlesName);
+        delete itr->second;
+        _particlesTable.erase(itr);
+    }
+    FlowParticles *particles = new FlowParticles(particlesName);
+    _particlesTable[particlesName] = particles;
+    return particles;
+}
+
+FlowParticles *
+Flow::getParticles(const char *particlesName)
+{
+    ParticlesHashmap::iterator itr;
+    itr = _particlesTable.find(particlesName);
+    if (itr == _particlesTable.end()) {
+        TRACE("Can't find particle injection plane '%s' in '%s'", particlesName, name());
+        return NULL;
+    }
+    return itr->second;
+}
+
+void
+Flow::deleteParticles(const char *particlesName)
+{
+    ParticlesHashmap::iterator itr = _particlesTable.find(particlesName);
+    if (itr == _particlesTable.end()) {
+        TRACE("Can't find particle injection plane '%s' in '%s'", particlesName, name());
+        return;
+    }
+    delete itr->second;
+    _particlesTable.erase(itr);
+}
+
+void
+Flow::getParticlesNames(std::vector<std::string>& names)
+{
+    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
+         itr != _particlesTable.end(); ++itr) {
+        names.push_back(std::string(itr->second->name()));
+    }
+}
+
+FlowBox *
+Flow::createBox(const char *boxName)
+{
+    BoxHashmap::iterator itr = _boxTable.find(boxName);
+    if (itr != _boxTable.end()) {
+        TRACE("Deleting existing box '%s'", boxName);
+        delete itr->second;
+        _boxTable.erase(itr);
+    }
+    FlowBox *box = new FlowBox(boxName);
+    _boxTable[boxName] = box;
+    return box;
+}
+
+FlowBox *
+Flow::getBox(const char *boxName)
+{
+    BoxHashmap::iterator itr = _boxTable.find(boxName);
+    if (itr == _boxTable.end()) {
+        TRACE("Can't find box '%s' in '%s'", boxName, name());
+        return NULL;
+    }
+    return itr->second;
+}
+
+void
+Flow::deleteBox(const char *boxName)
+{
+    BoxHashmap::iterator itr = _boxTable.find(boxName);
+    if (itr == _boxTable.end()) {
+        TRACE("Can't find box '%s' in '%s'", boxName, name());
+        return;
+    }
+    delete itr->second;
+    _boxTable.erase(itr);
+}
+
+void Flow::getBoxNames(std::vector<std::string>& names)
+{
+    for (BoxHashmap::iterator itr = _boxTable.begin();
+         itr != _boxTable.end(); ++itr) {
+        names.push_back(std::string(itr->second->name()));
+    }
+}
+
+void
+Flow::initializeParticles()
+{
+    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
+         itr != _particlesTable.end(); ++itr) {
+        itr->second->initialize();
+    }
+}
+
+bool
+Flow::scaleVectorField()
+{
+    if (_volume != NULL) {
+        TRACE("Removing existing volume: %s", _volume->name());
+        NanoVis::removeVolume(_volume);
+        _volume = NULL;
+    }
+    float *vdata = getScaledVector();
+    if (vdata == NULL) {
+        return false;
+    }
+    Volume *volume = makeVolume(vdata);
+    delete [] vdata;
+    if (volume == NULL) {
+        return false;
+    }
+    _volume = volume;
+
+    Vector3f scale = volume->getPhysicalScaling();
+    Vector3f location = _volume->location();
+
+    if (NanoVis::licRenderer != NULL) {
+        NanoVis::licRenderer->
+            setVectorField(_volume->textureID(),
+                           location,
+                           scale.x,
+                           scale.y,
+                           scale.z,
+                           _volume->wAxis.max());
+        setCurrentPosition();
+        setAxis();
+        setActive();
+    }
+
+    if (NanoVis::velocityArrowsSlice != NULL) {
+        NanoVis::velocityArrowsSlice->
+            setVectorField(_volume->textureID(),
+                           location,
+                           scale.x,
+                           scale.y,
+                           scale.z,
+                           _volume->wAxis.max());
+        NanoVis::velocityArrowsSlice->axis(_sv.slicePos.axis);
+        NanoVis::velocityArrowsSlice->slicePos(_sv.slicePos.value);
+        NanoVis::velocityArrowsSlice->enabled(_sv.showArrows);
+    }
+
+    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
+         itr != _particlesTable.end(); ++itr) {
+        itr->second->setVectorField(_volume,
+                                    location,
+                                    scale.x,
+                                    scale.y,
+                                    scale.z,
+                                    _volume->wAxis.max());
+    }
+    return true;
+}
+
+void
+Flow::renderBoxes()
+{
+    for (BoxHashmap::iterator itr = _boxTable.begin();
+         itr != _boxTable.end(); ++itr) {
+        if (itr->second->visible()) {
+            itr->second->render(_volume);
+        }
+    }
+}
+
+float *
+Flow::getScaledVector()
+{
+    assert(_data->nComponents() == 3);
+    size_t n = _data->nValues() / _data->nComponents() * 4;
+    float *data = new float[n];
+    if (data == NULL) {
+        return NULL;
+    }
+    memset(data, 0, sizeof(float) * n);
+    float *dest = data;
+    const float *values = _data->values();
+    for (size_t iz = 0; iz < _data->zNum(); iz++) {
+        for (size_t iy = 0; iy < _data->yNum(); iy++) {
+            for (size_t ix = 0; ix < _data->xNum(); ix++) {
+                double vx, vy, vz, vm;
+                vx = values[0];
+                vy = values[1];
+                vz = values[2];
+                vm = sqrt(vx*vx + vy*vy + vz*vz);
+                dest[0] = vm / NanoVis::magMax;
+                dest[1] = vx /(2.0*NanoVis::magMax) + 0.5;
+                dest[2] = vy /(2.0*NanoVis::magMax) + 0.5;
+                dest[3] = vz /(2.0*NanoVis::magMax) + 0.5;
+                values += 3;
+                dest += 4;
+            }
+        }
+    }
+    return data;
+}
+
+Volume *
+Flow::makeVolume(float *data)
+{
+    Volume *volume =
+        NanoVis::loadVolume(_name.c_str(),
+                            _data->xNum(),
+                            _data->yNum(), 
+                            _data->zNum(),
+                            4, data, 
+                            NanoVis::magMin, NanoVis::magMax, 0);
+    volume->xAxis.setRange(_data->xMin(), _data->xMax());
+    volume->yAxis.setRange(_data->yMin(), _data->yMax());
+    volume->zAxis.setRange(_data->zMin(), _data->zMax());
+
+    TRACE("min=%g %g %g max=%g %g %g mag=%g %g",
+          NanoVis::xMin, NanoVis::yMin, NanoVis::zMin,
+          NanoVis::xMax, NanoVis::yMax, NanoVis::zMax,
+          NanoVis::magMin, NanoVis::magMax);
+
+    volume->disableCutplane(0);
+    volume->disableCutplane(1);
+    volume->disableCutplane(2);
+
+    /* Initialize the volume with the previously configured values. */
+    volume->transferFunction(_sv.transferFunction);
+    volume->dataEnabled(_sv.showVolume);
+    volume->twoSidedLighting(_sv.twoSidedLighting);
+    volume->outline(_sv.showOutline);
+    volume->opacityScale(_sv.opacity);
+    volume->ambient(_sv.ambient);
+    volume->diffuse(_sv.diffuse);
+    volume->specularLevel(_sv.specular);
+    volume->specularExponent(_sv.specularExp);
+    volume->visible(_sv.showVolume);
+
+    Vector3f volScaling = volume->getPhysicalScaling();
+    Vector3f loc(volScaling);
+    loc *= -0.5;
+    volume->location(loc);
+
+    Volume::updatePending = true;
+    return volume;
+}
Index: /nanovis/branches/1.1/Flow.h
===================================================================
--- /nanovis/branches/1.1/Flow.h	(revision 4612)
+++ /nanovis/branches/1.1/Flow.h	(revision 4612)
@@ -0,0 +1,255 @@
+/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (c) 2004-2013  HUBzero Foundation, LLC
+ *
+ * Authors:
+ *   Wei Qiao <qiaow@purdue.edu>
+ *   Insoo Woo <iwoo@purdue.edu>
+ *   George A. Howlett <gah@purdue.edu>
+ *   Leif Delgass <ldelgass@purdue.edu>
+ */
+
+#ifndef FLOW_H
+#define FLOW_H
+
+#include <tr1/unordered_map>
+#include <vector>
+#include <string>
+
+#include <tcl.h>
+
+#include <vrmath/Vector3f.h>
+
+#include "Switch.h"
+#include "FlowTypes.h"
+#include "FlowParticles.h"
+#include "FlowBox.h"
+#include "NvLIC.h"
+#include "NvParticleRenderer.h"
+#include "Unirect.h"
+#include "Volume.h"
+#include "TransferFunction.h"
+
+struct FlowValues {
+    TransferFunction *transferFunction;
+    FlowPosition slicePos;
+    int showArrows;
+    int sliceVisible;
+    int showVolume;
+    int showOutline;
+    int isHidden;
+    int twoSidedLighting;
+    float ambient;     ///< Ambient volume shading
+    float diffuse;     ///< Diffuse volume shading
+    float specular;    ///< Specular level volume shading
+    float specularExp; ///< Specular exponent volume shading
+    float opacity;     ///< Volume opacity scaling
+};
+
+class Flow
+{
+public:
+    enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
+
+    Flow(Tcl_Interp *interp, const char *name);
+
+    ~Flow();
+
+    void getBounds(vrmath::Vector3f& min,
+                   vrmath::Vector3f& max,
+                   bool onlyVisible);
+
+    FlowParticles *createParticles(const char *particlesName);
+
+    FlowParticles *getParticles(const char *particlesName);
+
+    void deleteParticles(const char *particlesName);
+
+    void getParticlesNames(std::vector<std::string>& names);
+
+    void render();
+
+    void advect();
+
+    void resetParticles();
+
+    void initializeParticles();
+
+    FlowBox *createBox(const char *boxName);
+
+    FlowBox *getBox(const char *boxName);
+
+    void deleteBox(const char *boxName);
+
+    void getBoxNames(std::vector<std::string>& names);
+
+    float *getScaledVector();
+
+    Volume *makeVolume(float *data);
+
+    bool scaleVectorField();
+
+    bool visible()
+    {
+        return !_sv.isHidden;
+    }
+
+    const char *name() const
+    {
+        return _name.c_str();
+    }
+
+    bool isDataLoaded()
+    {
+        return (_data != NULL);
+    }
+
+    Rappture::Unirect3d *data()
+    {
+        return _data;
+    }
+
+    void data(Rappture::Unirect3d *data)
+    {
+        if (_data != NULL) {
+            delete _data;
+        }
+        _data = data;
+    }
+#if 0
+    void activateSlice()
+    {
+        /* Must set axis before offset or position goes to wrong axis. */
+        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
+        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
+        NanoVis::licRenderer->active(true);
+    }
+
+    void deactivateSlice()
+    {
+        NanoVis::licRenderer->active(false);
+    }
+#endif
+    SliceAxis getAxis()
+    {
+        return (SliceAxis)_sv.slicePos.axis;
+    }
+
+    TransferFunction *getTransferFunction()
+    {
+        return _sv.transferFunction;
+    }
+
+    float getRelativePosition();
+
+    void setAxis()
+    {
+        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
+    }
+
+    void setAxis(Flow::SliceAxis axis)
+    {
+        _sv.slicePos.axis = axis;
+        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
+    }
+
+    void setCurrentPosition(float position)
+    {
+        _sv.slicePos.value = position;
+        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
+    }
+
+    void setCurrentPosition()
+    {
+        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
+    }
+
+    void setActive(bool state)
+    {
+        _sv.sliceVisible = state;
+        NanoVis::licRenderer->active(state);
+    }
+
+    void setActive()
+    {
+        NanoVis::licRenderer->active(_sv.sliceVisible);
+    }
+
+    const Volume *getVolume() const
+    {
+        return _volume;
+    }
+
+    int parseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
+    {
+        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
+                                    SWITCH_DEFAULTS) < 0) {
+            return TCL_ERROR;
+        }
+        return TCL_OK;
+    }
+
+    Tcl_Command getCommandToken()
+    {
+        return _cmdToken;
+    }
+
+    static float getRelativePosition(FlowPosition *pos);
+
+private:
+    typedef std::string ParticlesId;
+    typedef std::string BoxId;
+    typedef std::tr1::unordered_map<ParticlesId, FlowParticles *> ParticlesHashmap;
+    typedef std::tr1::unordered_map<BoxId, FlowBox *> BoxHashmap;
+
+    void configure();
+
+    void renderBoxes();
+
+    Tcl_Interp *_interp;
+    /**
+     * Name of the flow.  This may differ
+     * from the name of the command
+     * associated with the flow, if the
+     * command was renamed. */
+    std::string _name;
+
+    /**
+     * Command associated with the flow.
+     * When the command is deleted, so is
+     * the flow. */
+    Tcl_Command _cmdToken;
+
+    /**
+     * Uniform rectangular data
+     * representing the mesh and vector
+     * field values.  These values are
+     * kept to regenerate the volume
+     * associated with the flow. */
+    Rappture::Unirect3d *_data;
+
+    /**
+     * The volume associated with the
+     * flow.  This isn't the same thing as
+     * a normal volume displayed. */
+    Volume *_volume;
+
+    /**
+     * For each field there can be one or
+     * more particle injection planes
+     * where the particles are injected
+     * into the flow. */
+    ParticlesHashmap _particlesTable;
+
+    /**
+     * A table of boxes.  There maybe
+     * zero or more boxes associated
+     * with each field. */
+    BoxHashmap _boxTable;
+
+    FlowValues _sv;
+
+    static Rappture::SwitchSpec _switches[];
+};
+
+#endif
Index: /nanovis/branches/1.1/FlowCmd.cpp
===================================================================
--- /nanovis/branches/1.1/FlowCmd.cpp	(revision 4611)
+++ /nanovis/branches/1.1/FlowCmd.cpp	(revision 4612)
@@ -16,9 +16,7 @@
 #include <unistd.h>
 #include <poll.h>
+
 #include <tcl.h>
 
-#include <RpField1D.h>
-#include <RpFieldRect3D.h>
-#include <RpFieldPrism3D.h>
 #include <RpOutcome.h>
 
@@ -29,6 +27,8 @@
 #include "nanovis.h"
 #include "CmdProc.h"
+#include "Command.h"
 #include "FlowCmd.h"
 #include "FlowTypes.h"
+#include "Flow.h"
 #include "FlowBox.h"
 #include "FlowParticles.h"
@@ -36,8 +36,8 @@
 #include "TransferFunction.h"
 #include "NvLIC.h"
-#include "Trace.h"
 #include "Unirect.h"
 #include "VelocityArrowsSlice.h"
 #include "Volume.h"
+#include "Trace.h"
 
 using namespace vrmath;
@@ -68,5 +68,5 @@
 };
 
-Rappture::SwitchSpec FlowCmd::_switches[] = {
+Rappture::SwitchSpec Flow::_switches[] = {
     {Rappture::SWITCH_FLOAT, "-ambient", "value",
      offsetof(FlowValues, ambient), 0},
@@ -128,414 +128,4 @@
 };
 
-static Tcl_ObjCmdProc FlowInstObjCmd;
-static Tcl_CmdDeleteProc FlowInstDeleteProc;
-
-FlowCmd::FlowCmd(Tcl_Interp *interp, const char *name) :
-    _interp(interp),
-    _name(name),
-    _data(NULL),
-    _volume(NULL),
-    _field(NULL)
-{
-    memset(&_sv, 0, sizeof(FlowValues));
-    _sv.sliceVisible = 1;
-    _sv.transferFunction = NanoVis::getTransferFunction("default");
-
-    _cmdToken = Tcl_CreateObjCommand(_interp, (char *)name, 
-                                     (Tcl_ObjCmdProc *)FlowInstObjCmd,
-                                     this, FlowInstDeleteProc);
-}
-
-FlowCmd::~FlowCmd()
-{
-    TRACE("Enter");
-
-    Rappture::FreeSwitches(_switches, &_sv, 0);
-    if (_field != NULL) {
-        delete _field;
-    }
-    if (_data != NULL) {
-        delete _data;
-    }
-    if (_volume != NULL) {
-        NanoVis::removeVolume(_volume);
-        _volume = NULL;
-    }
-    for (BoxHashmap::iterator itr = _boxTable.begin();
-         itr != _boxTable.end(); ++itr) {
-        delete itr->second;
-    }
-    _boxTable.clear();
-    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
-         itr != _particlesTable.end(); ++itr) {
-        delete itr->second;
-    }
-    _particlesTable.clear();
-}
-
-void
-FlowCmd::getBounds(Vector3f& min,
-                   Vector3f& max,
-                   bool onlyVisible)
-{
-    TRACE("Enter");
-
-    if (onlyVisible && !visible())
-        return;
-
-#if 0  // Using volume bounds instead of these
-    if (isDataLoaded()) {
-        Vector3f umin, umax;
-        Rappture::Unirect3d *unirect = data();
-        unirect->getWorldSpaceBounds(umin, umax);
-        if (min.x > umin.x) {
-            min.x = umin.x;
-        }
-        if (max.x < umax.x) {
-            max.x = umax.x;
-        }
-        if (min.y > umin.y) {
-            min.y = umin.y;
-        }
-        if (max.y < umax.y) {
-            max.y = umax.y;
-        }
-        if (min.z > umin.z) {
-            min.z = umin.z;
-        }
-        if (max.z < umax.z) {
-            max.z = umax.z;
-        }
-    }
-#endif
-    for (BoxHashmap::iterator itr = _boxTable.begin();
-         itr != _boxTable.end(); ++itr) {
-        FlowBox *box = itr->second;
-        if (!onlyVisible || box->visible()) {
-            Vector3f fbmin, fbmax;
-            box->getWorldSpaceBounds(fbmin, fbmax,
-                                     getVolume());
-            if (min.x > fbmin.x) {
-                min.x = fbmin.x;
-            }
-            if (max.x < fbmax.x) {
-                max.x = fbmax.x;
-            }
-            if (min.y > fbmin.y) {
-                min.y = fbmin.y;
-            }
-            if (max.y < fbmax.y) {
-                max.y = fbmax.y;
-            }
-            if (min.z > fbmin.z) {
-                min.z = fbmin.z;
-            }
-            if (max.z < fbmax.z) {
-                max.z = fbmax.z;
-            }
-        }
-    }
-}
-
-void
-FlowCmd::resetParticles()
-{
-    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
-         itr != _particlesTable.end(); ++itr) {
-        itr->second->reset();
-    }
-}
-
-void
-FlowCmd::advect()
-{
-    NvVectorField *fieldPtr = getVectorField();
-    fieldPtr->active(true);
-    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
-         itr != _particlesTable.end(); ++itr) {
-        if (itr->second->visible()) {
-            itr->second->advect();
-        }
-    }
-}
-
-void
-FlowCmd::render()
-{
-    _field->active(true);
-    _field->render();
-    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
-         itr != _particlesTable.end(); ++itr) {
-        if (itr->second->visible()) {
-            itr->second->render();
-        }
-    }
-    renderBoxes();
-}
-
-FlowParticles *
-FlowCmd::createParticles(const char *particlesName)
-{
-    ParticlesHashmap::iterator itr = _particlesTable.find(particlesName);
-    if (itr != _particlesTable.end()) {
-        TRACE("Deleting existing particle injection plane '%s'", particlesName);
-        delete itr->second;
-        _particlesTable.erase(itr);
-    }
-    FlowParticles *particles = new FlowParticles(particlesName);
-    _particlesTable[particlesName] = particles;
-    return particles;
-}
-
-FlowParticles *
-FlowCmd::getParticles(const char *particlesName)
-{
-    ParticlesHashmap::iterator itr;
-    itr = _particlesTable.find(particlesName);
-    if (itr == _particlesTable.end()) {
-        TRACE("Can't find particle injection plane '%s' in '%s'", particlesName, name());
-        return NULL;
-    }
-    return itr->second;
-}
-
-void
-FlowCmd::deleteParticles(const char *particlesName)
-{
-    ParticlesHashmap::iterator itr = _particlesTable.find(particlesName);
-    if (itr == _particlesTable.end()) {
-        TRACE("Can't find particle injection plane '%s' in '%s'", particlesName, name());
-        return;
-    }
-    delete itr->second;
-    _particlesTable.erase(itr);
-}
-
-void
-FlowCmd::getParticlesNames(std::vector<std::string>& names)
-{
-    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
-         itr != _particlesTable.end(); ++itr) {
-        names.push_back(std::string(itr->second->name()));
-    }
-}
-
-FlowBox *
-FlowCmd::createBox(const char *boxName)
-{
-    BoxHashmap::iterator itr = _boxTable.find(boxName);
-    if (itr != _boxTable.end()) {
-        TRACE("Deleting existing box '%s'", boxName);
-        delete itr->second;
-        _boxTable.erase(itr);
-    }
-    FlowBox *box = new FlowBox(boxName);
-    _boxTable[boxName] = box;
-    return box;
-}
-
-FlowBox *
-FlowCmd::getBox(const char *boxName)
-{
-    BoxHashmap::iterator itr = _boxTable.find(boxName);
-    if (itr == _boxTable.end()) {
-        TRACE("Can't find box '%s' in '%s'", boxName, name());
-        return NULL;
-    }
-    return itr->second;
-}
-
-void
-FlowCmd::deleteBox(const char *boxName)
-{
-    BoxHashmap::iterator itr = _boxTable.find(boxName);
-    if (itr == _boxTable.end()) {
-        TRACE("Can't find box '%s' in '%s'", boxName, name());
-        return;
-    }
-    delete itr->second;
-    _boxTable.erase(itr);
-}
-
-void FlowCmd::getBoxNames(std::vector<std::string>& names)
-{
-    for (BoxHashmap::iterator itr = _boxTable.begin();
-         itr != _boxTable.end(); ++itr) {
-        names.push_back(std::string(itr->second->name()));
-    }
-}
-
-void
-FlowCmd::initializeParticles()
-{
-    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
-         itr != _particlesTable.end(); ++itr) {
-        itr->second->initialize();
-    }
-}
-
-bool
-FlowCmd::scaleVectorField()
-{
-    if (_volume != NULL) {
-        TRACE("Removing existing volume: %s", _volume->name());
-        NanoVis::removeVolume(_volume);
-        _volume = NULL;
-    }
-    float *vdata = getScaledVector();
-    if (vdata == NULL) {
-        return false;
-    }
-    Volume *volume = makeVolume(vdata);
-    delete [] vdata;
-    if (volume == NULL) {
-        return false;
-    }
-    _volume = volume;
-
-    // Remove the associated vector field.
-    if (_field != NULL) {
-        delete _field;
-    }
-    _field = new NvVectorField();
-    if (_field == NULL) {
-        return false;
-    }
-
-    Vector3f scale = volume->getPhysicalScaling();
-    Vector3f location = _volume->location();
-
-    _field->setVectorField(_volume,
-                           location,
-                           scale.x,
-                           scale.y,
-                           scale.z,
-                           NanoVis::magMax);
-
-    if (NanoVis::licRenderer != NULL) {
-        NanoVis::licRenderer->
-            setVectorField(_volume->textureID(),
-                           location,
-                           scale.x,
-                           scale.y,
-                           scale.z,
-                           _volume->wAxis.max());
-        setCurrentPosition();
-        setAxis();
-        setActive();
-    }
-
-    if (NanoVis::velocityArrowsSlice != NULL) {
-        NanoVis::velocityArrowsSlice->
-            setVectorField(_volume->textureID(),
-                           location,
-                           scale.x,
-                           scale.y,
-                           scale.z,
-                           _volume->wAxis.max());
-        NanoVis::velocityArrowsSlice->axis(_sv.slicePos.axis);
-        NanoVis::velocityArrowsSlice->slicePos(_sv.slicePos.value);
-        NanoVis::velocityArrowsSlice->enabled(_sv.showArrows);
-    }
-
-    for (ParticlesHashmap::iterator itr = _particlesTable.begin();
-         itr != _particlesTable.end(); ++itr) {
-        itr->second->setVectorField(_volume,
-                                    location,
-                                    scale.x,
-                                    scale.y,
-                                    scale.z,
-                                    _volume->wAxis.max());
-    }
-    return true;
-}
-
-void
-FlowCmd::renderBoxes()
-{
-    for (BoxHashmap::iterator itr = _boxTable.begin();
-         itr != _boxTable.end(); ++itr) {
-        if (itr->second->visible()) {
-            itr->second->render(_volume);
-        }
-    }
-}
-
-float *
-FlowCmd::getScaledVector()
-{
-    assert(_data->nComponents() == 3);
-    size_t n = _data->nValues() / _data->nComponents() * 4;
-    float *data = new float[n];
-    if (data == NULL) {
-        return NULL;
-    }
-    memset(data, 0, sizeof(float) * n);
-    float *destPtr = data;
-    const float *values = _data->values();
-    for (size_t iz = 0; iz < _data->zNum(); iz++) {
-        for (size_t iy = 0; iy < _data->yNum(); iy++) {
-            for (size_t ix = 0; ix < _data->xNum(); ix++) {
-                double vx, vy, vz, vm;
-                vx = values[0];
-                vy = values[1];
-                vz = values[2];
-                vm = sqrt(vx*vx + vy*vy + vz*vz);
-                destPtr[0] = vm / NanoVis::magMax;
-                destPtr[1] = vx /(2.0*NanoVis::magMax) + 0.5;
-                destPtr[2] = vy /(2.0*NanoVis::magMax) + 0.5;
-                destPtr[3] = vz /(2.0*NanoVis::magMax) + 0.5;
-                values += 3;
-                destPtr += 4;
-            }
-        }
-    }
-    return data;
-}
-
-Volume *
-FlowCmd::makeVolume(float *data)
-{
-    Volume *volume =
-        NanoVis::loadVolume(_name.c_str(),
-                            _data->xNum(),
-                            _data->yNum(), 
-                            _data->zNum(),
-                            4, data, 
-                            NanoVis::magMin, NanoVis::magMax, 0);
-    volume->xAxis.setRange(_data->xMin(), _data->xMax());
-    volume->yAxis.setRange(_data->yMin(), _data->yMax());
-    volume->zAxis.setRange(_data->zMin(), _data->zMax());
-
-    TRACE("min=%g %g %g max=%g %g %g mag=%g %g",
-          NanoVis::xMin, NanoVis::yMin, NanoVis::zMin,
-          NanoVis::xMax, NanoVis::yMax, NanoVis::zMax,
-          NanoVis::magMin, NanoVis::magMax);
-
-    volume->disableCutplane(0);
-    volume->disableCutplane(1);
-    volume->disableCutplane(2);
-
-    /* Initialize the volume with the previously configured values. */
-    volume->transferFunction(_sv.transferFunction);
-    volume->dataEnabled(_sv.showVolume);
-    volume->twoSidedLighting(_sv.twoSidedLighting);
-    volume->outline(_sv.showOutline);
-    volume->opacityScale(_sv.opacity);
-    volume->ambient(_sv.ambient);
-    volume->diffuse(_sv.diffuse);
-    volume->specularLevel(_sv.specular);
-    volume->specularExponent(_sv.specularExp);
-    volume->visible(_sv.showVolume);
-
-    Vector3f volScaling = volume->getPhysicalScaling();
-    Vector3f loc(volScaling);
-    loc *= -0.5;
-    volume->location(loc);
-
-    Volume::updatePending = true;
-    return volume;
-}
-
 static int
 FlowDataFileOp(ClientData clientData, Tcl_Interp *interp, int objc,
@@ -566,5 +156,5 @@
     Rappture::Unirect3d *dataPtr;
     dataPtr = new Rappture::Unirect3d(nComponents);
-    FlowCmd *flowPtr = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     size_t length = buf.size();
     char *bytes = (char *)buf.bytes();
@@ -603,5 +193,5 @@
         return TCL_ERROR;
     }
-    flowPtr->data(dataPtr);
+    flow->data(dataPtr);
     NanoVis::eventuallyRedraw(NanoVis::MAP_FLOWS);
     return TCL_OK;
@@ -649,5 +239,5 @@
     dataPtr = new Rappture::Unirect3d(nComponents);
 
-    FlowCmd *flowPtr = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     size_t length = buf.size();
     char *bytes = (char *)buf.bytes();
@@ -699,5 +289,5 @@
     TRACE("magMin = %lg magMax = %lg",
           dataPtr->magMin(), dataPtr->magMax());
-    flowPtr->data(dataPtr);
+    flow->data(dataPtr);
     {
         char info[1024];
@@ -706,5 +296,5 @@
 
         length = sprintf(info, "nv>data tag %s min %g max %g\n",
-                         flowPtr->name(), dataPtr->magMin(), dataPtr->magMax());
+                         flow->name(), dataPtr->magMin(), dataPtr->magMax());
         nWritten  = write(1, info, length);
         assert(nWritten == (ssize_t)strlen(info));
@@ -732,217 +322,4 @@
     }
     return (*proc) (clientData, interp, objc, objv);
-}
-
-float
-FlowCmd::getRelativePosition(FlowPosition *posPtr)
-{
-    if (posPtr->flags == RELPOS) {
-        return posPtr->value;
-    }
-    switch (posPtr->axis) {
-    case AXIS_X:  
-        return (posPtr->value - NanoVis::xMin) / 
-            (NanoVis::xMax - NanoVis::xMin); 
-    case AXIS_Y:  
-        return (posPtr->value - NanoVis::yMin) / 
-            (NanoVis::yMax - NanoVis::yMin); 
-    case AXIS_Z:  
-        return (posPtr->value - NanoVis::zMin) / 
-            (NanoVis::zMax - NanoVis::zMin); 
-    }
-    return 0.0;
-}
-
-float
-FlowCmd::getRelativePosition() 
-{
-    return FlowCmd::getRelativePosition(&_sv.slicePos);
-}
-
-/* Static NanoVis class commands. */
-
-FlowCmd *
-NanoVis::getFlow(const char *name)
-{
-    FlowHashmap::iterator itr = flowTable.find(name);
-    if (itr == flowTable.end()) {
-        TRACE("Can't find flow '%s'", name);
-        return NULL;
-    }
-    return itr->second;
-}
-
-FlowCmd *
-NanoVis::createFlow(Tcl_Interp *interp, const char *name)
-{
-    FlowHashmap::iterator itr = flowTable.find(name);
-    if (itr != flowTable.end()) {
-        ERROR("Flow '%s' already exists", name);
-        return NULL;
-    }
-    FlowCmd *flow = new FlowCmd(interp, name);
-    flowTable[name] = flow;
-    return flow;
-}
-
-/**
- * \brief Delete flow object and hash table entry
- *
- * This is called by the flow command instance delete callback
- */
-void
-NanoVis::deleteFlow(const char *name)
-{
-    FlowHashmap::iterator itr = flowTable.find(name);
-    if (itr != flowTable.end()) {
-        delete itr->second;
-        flowTable.erase(itr);
-    }
-}
-
-/**
- * \brief Delete all flow object commands
- *
- * This will also delete the flow objects and hash table entries
- */
-void
-NanoVis::deleteFlows(Tcl_Interp *interp)
-{
-    FlowHashmap::iterator itr;
-    for (itr = flowTable.begin();
-         itr != flowTable.end(); ++itr) {
-        Tcl_DeleteCommandFromToken(interp, itr->second->getCommandToken());
-    }
-    flowTable.clear();
-}
-
-bool
-NanoVis::mapFlows()
-{
-    TRACE("Enter");
-
-    flags &= ~MAP_FLOWS;
-
-    /* 
-     * Step 1. Get the overall min and max magnitudes of all the 
-     *         flow vectors.
-     */
-    magMin = DBL_MAX, magMax = -DBL_MAX;
-
-    for (FlowHashmap::iterator itr = flowTable.begin();
-         itr != flowTable.end(); ++itr) {
-        FlowCmd *flow = itr->second;
-        double min, max;
-        if (!flow->isDataLoaded()) {
-            continue;
-        }
-        Rappture::Unirect3d *data = flow->data();
-        min = data->magMin();
-        max = data->magMax();
-        if (min < magMin) {
-            magMin = min;
-        } 
-        if (max > magMax) {
-            magMax = max;
-        }
-        if (data->xMin() < xMin) {
-            xMin = data->xMin();
-        }
-        if (data->yMin() < yMin) {
-            yMin = data->yMin();
-        }
-        if (data->zMin() < zMin) {
-            zMin = data->zMin();
-        }
-        if (data->xMax() > xMax) {
-            xMax = data->xMax();
-        }
-        if (data->yMax() > yMax) {
-            yMax = data->yMax();
-        }
-        if (data->zMax() > zMax) {
-            zMax = data->zMax();
-        }
-    }
-
-    TRACE("magMin=%g magMax=%g", NanoVis::magMin, NanoVis::magMax);
-
-    /* 
-     * Step 2. Generate the vector field from each data set. 
-     */
-    for (FlowHashmap::iterator itr = flowTable.begin();
-         itr != flowTable.end(); ++itr) {
-        FlowCmd *flow = itr->second;
-        if (!flow->isDataLoaded()) {
-            continue; // Flow exists, but no data has been loaded yet.
-        }
-        if (flow->visible()) {
-            flow->initializeParticles();
-        }
-        if (!flow->scaleVectorField()) {
-            return false;
-        }
-        // FIXME: This doesn't work when there is more than one flow.
-        licRenderer->setOffset(flow->getRelativePosition());
-        velocityArrowsSlice->slicePos(flow->getRelativePosition());
-    }
-    advectFlows();
-    return true;
-}
-
-void
-NanoVis::getFlowBounds(Vector3f& min,
-                       Vector3f& max,
-                       bool onlyVisible)
-{
-    TRACE("Enter");
-
-    min.set(FLT_MAX, FLT_MAX, FLT_MAX);
-    max.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
-
-    for (FlowHashmap::iterator itr = flowTable.begin();
-         itr != flowTable.end(); ++itr) {
-        itr->second->getBounds(min, max, onlyVisible);
-    }
-}
-
-void
-NanoVis::renderFlows()
-{
-    for (FlowHashmap::iterator itr = flowTable.begin();
-         itr != flowTable.end(); ++itr) {
-        FlowCmd *flow = itr->second;
-        if (flow->isDataLoaded() && flow->visible()) {
-            flow->render();
-        }
-    }
-    flags &= ~REDRAW_PENDING;
-}
-
-void
-NanoVis::resetFlows()
-{
-    if (licRenderer->active()) {
-        NanoVis::licRenderer->reset();
-    }
-    for (FlowHashmap::iterator itr = flowTable.begin();
-         itr != flowTable.end(); ++itr) {
-        FlowCmd *flow = itr->second;
-        if (flow->isDataLoaded() && flow->visible()) {
-            flow->resetParticles();
-        }
-    }
-}    
-
-void
-NanoVis::advectFlows()
-{
-    for (FlowHashmap::iterator itr = flowTable.begin();
-         itr != flowTable.end(); ++itr) {
-        FlowCmd *flow = itr->second;
-        if (flow->isDataLoaded() && flow->visible()) {
-            flow->advect();
-        }
-    }
 }
 
@@ -969,15 +346,15 @@
     const char *string = Tcl_GetString(objPtr);
     if (string[1] == '\0') {
-        FlowCmd::SliceAxis *axisPtr = (FlowCmd::SliceAxis *)(record + offset);
+        Flow::SliceAxis *axisPtr = (Flow::SliceAxis *)(record + offset);
         char c;
         c = tolower((unsigned char)string[0]);
         if (c == 'x') {
-            *axisPtr = FlowCmd::AXIS_X;
+            *axisPtr = Flow::AXIS_X;
             return TCL_OK;
         } else if (c == 'y') {
-            *axisPtr = FlowCmd::AXIS_Y;
+            *axisPtr = Flow::AXIS_Y;
             return TCL_OK;
         } else if (c == 'z') {
-            *axisPtr = FlowCmd::AXIS_Z;
+            *axisPtr = Flow::AXIS_Z;
             return TCL_OK;
         }
@@ -1175,7 +552,7 @@
                 Tcl_Obj *const *objv)
 {
-    FlowCmd *flowPtr = (FlowCmd *)clientData;
-
-    if (flowPtr->parseSwitches(interp, objc - 2, objv + 2) != TCL_OK) {
+    Flow *flow = (Flow *)clientData;
+
+    if (flow->parseSwitches(interp, objc - 2, objv + 2) != TCL_OK) {
         return TCL_ERROR;
     }
@@ -1188,5 +565,5 @@
                    Tcl_Obj *const *objv)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     const char *particlesName = Tcl_GetString(objv[3]);
     FlowParticles *particles = flow->createParticles(particlesName);
@@ -1212,5 +589,5 @@
                          Tcl_Obj *const *objv)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     const char *particlesName = Tcl_GetString(objv[3]);
     FlowParticles *particles = flow->getParticles(particlesName);
@@ -1233,5 +610,5 @@
                       Tcl_Obj *const *objv)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     for (int i = 3; i < objc; i++) {
         flow->deleteParticles(Tcl_GetString(objv[i]));
@@ -1245,5 +622,5 @@
                      Tcl_Obj *const *objv)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     Tcl_Obj *listObjPtr;
     listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
@@ -1288,9 +665,9 @@
         return TCL_ERROR;
     }
-    FlowCmd *flowPtr = (FlowCmd *)clientData;
-    Tcl_Preserve(flowPtr);
+    Flow *flow = (Flow *)clientData;
+    Tcl_Preserve(flow);
     int result;
     result = (*proc) (clientData, interp, objc, objv);
-    Tcl_Release(flowPtr);
+    Tcl_Release(flow);
     return result;
 }
@@ -1300,5 +677,5 @@
              Tcl_Obj *const *objv)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     const char *boxName = Tcl_GetString(objv[3]);
     FlowBox *box = flow->createBox(boxName);
@@ -1322,5 +699,5 @@
                    Tcl_Obj *const *objv)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     const char *boxName = Tcl_GetString(objv[3]);
     FlowBox *box = flow->getBox(boxName);
@@ -1341,5 +718,5 @@
                 Tcl_Obj *const *objv)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     for (int i = 3; i < objc; i++) {
         flow->deleteBox(Tcl_GetString(objv[i]));
@@ -1353,5 +730,5 @@
                Tcl_Obj *const *objv)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     Tcl_Obj *listObjPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL);
     std::vector<std::string> names;
@@ -1393,9 +770,9 @@
         return TCL_ERROR;
     }
-    FlowCmd *flowPtr = (FlowCmd *)clientData;
-    Tcl_Preserve(flowPtr);
+    Flow *flow = (Flow *)clientData;
+    Tcl_Preserve(flow);
     int result;
     result = (*proc) (clientData, interp, objc, objv);
-    Tcl_Release(flowPtr);
+    Tcl_Release(flow);
     return result;
 }
@@ -1414,9 +791,9 @@
              Tcl_Obj *const *objv)
 {
-    FlowCmd *flowPtr = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     
     const char *string = Tcl_GetString(objv[1]);
     TransferFunction *tf;
-    tf = flowPtr->getTransferFunction();
+    tf = flow->getTransferFunction();
     if (tf == NULL) {
         Tcl_AppendResult(interp, "unknown transfer function \"", string, "\"",
@@ -1455,5 +832,5 @@
  * \return A standard Tcl result.
  */
-static int
+int
 FlowInstObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, 
                Tcl_Obj *const *objv)
@@ -1466,5 +843,5 @@
     }
     assert(CheckGL(AT));
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     Tcl_Preserve(flow);
     int result = (*proc) (clientData, interp, objc, objv);
@@ -1478,8 +855,8 @@
  * This is called only when the command associated with the flow is destroyed.
  */
-static void
+void
 FlowInstDeleteProc(ClientData clientData)
 {
-    FlowCmd *flow = (FlowCmd *)clientData;
+    Flow *flow = (Flow *)clientData;
     NanoVis::deleteFlow(flow->name());
 }
@@ -1496,5 +873,5 @@
         return TCL_ERROR;
     }
-    FlowCmd *flow = NanoVis::createFlow(interp, name);
+    Flow *flow = NanoVis::createFlow(interp, name);
     if (flow == NULL) {
         Tcl_AppendResult(interp, "Flow \"", name, "\" already exists",
@@ -1516,5 +893,5 @@
 {
     for (int i = 2; i < objc; i++) {
-        FlowCmd *flow = NanoVis::getFlow(Tcl_GetString(objv[i]));
+        Flow *flow = NanoVis::getFlow(Tcl_GetString(objv[i]));
         if (flow != NULL) {
             Tcl_DeleteCommandFromToken(interp, flow->getCommandToken());
@@ -1530,5 +907,5 @@
 {
     bool value = false;
-    FlowCmd *flow = NanoVis::getFlow(Tcl_GetString(objv[2]));
+    Flow *flow = NanoVis::getFlow(Tcl_GetString(objv[2]));
     if (flow != NULL) {
         value = true;
@@ -1577,5 +954,5 @@
     for (NanoVis::FlowHashmap::iterator itr = NanoVis::flowTable.begin();
          itr != NanoVis::flowTable.end(); ++itr) {
-        FlowCmd *flow = itr->second;
+        Flow *flow = itr->second;
         Tcl_Obj *objPtr = Tcl_NewStringObj(flow->name(), -1);
         Tcl_ListObjAppendElement(interp, listObjPtr, objPtr);
@@ -1668,5 +1045,5 @@
 };
 
-Rappture::SwitchSpec FlowCmd::videoSwitches[] = {
+static Rappture::SwitchSpec flowVideoSwitches[] = {
     {Rappture::SWITCH_INT, "-bitrate", "value",
      offsetof(FlowVideoSwitches, bitRate), 0},
@@ -1872,5 +1249,5 @@
     switches.formatObjPtr = Tcl_NewStringObj("mpeg1video", 10);
     Tcl_IncrRefCount(switches.formatObjPtr);
-    if (Rappture::ParseSwitches(interp, FlowCmd::videoSwitches, 
+    if (Rappture::ParseSwitches(interp, flowVideoSwitches, 
                 objc - 3, objv + 3, &switches, SWITCH_DEFAULTS) < 0) {
         return TCL_ERROR;
@@ -1918,5 +1295,5 @@
     tmpFileName[length] = '\0';
     rmdir(tmpFileName);
-    Rappture::FreeSwitches(FlowCmd::videoSwitches, &switches, 0);
+    Rappture::FreeSwitches(flowVideoSwitches, &switches, 0);
     return result;
 }
Index: /nanovis/branches/1.1/FlowCmd.h
===================================================================
--- /nanovis/branches/1.1/FlowCmd.h	(revision 4611)
+++ /nanovis/branches/1.1/FlowCmd.h	(revision 4612)
@@ -25,286 +25,9 @@
 #define FLOWCMD_H
 
-#include <tr1/unordered_map>
-#include <vector>
-#include <string>
-
 #include <tcl.h>
 
-#include <vrmath/Vector3f.h>
-
-#include "Switch.h"
-#include "FlowTypes.h"
-#include "FlowParticles.h"
-#include "FlowBox.h"
-#include "NvLIC.h"
-#include "NvParticleRenderer.h"
-#include "NvVectorField.h"
-#include "Unirect.h"
-#include "Volume.h"
-#include "TransferFunction.h"
-
-struct FlowValues {
-    TransferFunction *transferFunction;
-    FlowPosition slicePos;
-    int showArrows;
-    int sliceVisible;
-    int showVolume;
-    int showOutline;
-    int isHidden;
-    int twoSidedLighting;
-    float ambient;     ///< Ambient volume shading
-    float diffuse;     ///< Diffuse volume shading
-    float specular;    ///< Specular level volume shading
-    float specularExp; ///< Specular exponent volume shading
-    float opacity;     ///< Volume opacity scaling
-};
-
-class FlowCmd
-{
-public:
-    enum SliceAxis { AXIS_X, AXIS_Y, AXIS_Z };
-
-    FlowCmd(Tcl_Interp *interp, const char *name);
-
-    ~FlowCmd();
-
-    void getBounds(vrmath::Vector3f& min,
-                   vrmath::Vector3f& max,
-                   bool onlyVisible);
-
-    FlowParticles *createParticles(const char *particlesName);
-
-    FlowParticles *getParticles(const char *particlesName);
-
-    void deleteParticles(const char *particlesName);
-
-    void getParticlesNames(std::vector<std::string>& names);
-
-    void render();
-
-    void advect();
-
-    void resetParticles();
-
-    void initializeParticles();
-
-    FlowBox *createBox(const char *boxName);
-
-    FlowBox *getBox(const char *boxName);
-
-    void deleteBox(const char *boxName);
-
-    void getBoxNames(std::vector<std::string>& names);
-
-    float *getScaledVector();
-
-    Volume *makeVolume(float *data);
-    
-    void initVectorField();
-
-    NvVectorField *getVectorField()
-    {
-        return _field;
-    }
-
-    bool scaleVectorField();
-
-    bool visible()
-    {
-        return !_sv.isHidden;
-    }
-
-    const char *name() const
-    {
-        return _name.c_str();
-    }
-
-    bool isDataLoaded()
-    {
-        return (_data != NULL);
-    }
-
-    Rappture::Unirect3d *data()
-    {
-        return _data;
-    }
-
-    void data(Rappture::Unirect3d *data)
-    {
-        if (_data != NULL) {
-            delete _data;
-        }
-        _data = data;
-    }
-
-    void activateSlice()
-    {
-        /* Must set axis before offset or position goes to wrong axis. */
-        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
-        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
-        NanoVis::licRenderer->active(true);
-    }
-
-    void ceactivateSlice()
-    {
-        NanoVis::licRenderer->active(false);
-    }
-
-    SliceAxis getAxis()
-    {
-        return (SliceAxis)_sv.slicePos.axis;
-    }
-
-    TransferFunction *getTransferFunction()
-    {
-        return _sv.transferFunction;
-    }
-
-    float getRelativePosition();
-
-    void setAxis()
-    {
-        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
-    }
-
-    void setAxis(FlowCmd::SliceAxis axis)
-    {
-        _sv.slicePos.axis = axis;
-        NanoVis::licRenderer->setAxis(_sv.slicePos.axis);
-    }
-
-    void setCurrentPosition(float position)
-    {
-        _sv.slicePos.value = position;
-        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
-    }
-
-    void setCurrentPosition()
-    {
-        NanoVis::licRenderer->setOffset(_sv.slicePos.value);
-    }
-
-    void setActive(bool state)
-    {
-        _sv.sliceVisible = state;
-        NanoVis::licRenderer->active(state);
-    }
-
-    void setActive()
-    {
-        NanoVis::licRenderer->active(_sv.sliceVisible);
-    }
-
-    void setVectorField(NvVectorField *field)
-    {
-        deleteVectorField();
-        _field = field;
-    }
-
-    void deleteVectorField()
-    {
-        if (_field != NULL) {
-            delete _field;
-            _field = NULL;
-        }
-    }
-
-    const Volume *getVolume() const
-    {
-        return _volume;
-    }
-
-    int parseSwitches(Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
-    {
-        if (Rappture::ParseSwitches(interp, _switches, objc, objv, &_sv,
-                                    SWITCH_DEFAULTS) < 0) {
-            return TCL_ERROR;
-        }
-        return TCL_OK;
-    }
-
-    Tcl_Command getCommandToken()
-    {
-        return _cmdToken;
-    }
-
-    static float getRelativePosition(FlowPosition *pos);
-
-    static Rappture::SwitchSpec videoSwitches[];
-
-private:
-    typedef std::string ParticlesId;
-    typedef std::string BoxId;
-    typedef std::tr1::unordered_map<ParticlesId, FlowParticles *> ParticlesHashmap;
-    typedef std::tr1::unordered_map<BoxId, FlowBox *> BoxHashmap;
-
-    void configure();
-
-    void renderBoxes();
-
-    Tcl_Interp *_interp;
-    /**
-     * Name of the flow.  This may differ
-     * from the name of the command
-     * associated with the flow, if the
-     * command was renamed. */
-    std::string _name;
-
-    /**
-     * Command associated with the flow.
-     * When the command is deleted, so is
-     * the flow. */
-    Tcl_Command _cmdToken;
-
-    /**
-     * Uniform rectangular data
-     * representing the mesh and vector
-     * field values.  These values are
-     * kept to regenerate the volume
-     * associated with the flow. */
-    Rappture::Unirect3d *_data;
-
-    /**
-     * The volume associated with the
-     * flow.  This isn't the same thing as
-     * a normal volume displayed. */
-    Volume *_volume;
-
-    /**
-     * Vector field generated from the 
-     * above volume */
-    NvVectorField *_field;
-
-    /**
-     * For each field there can be one or
-     * more particle injection planes
-     * where the particles are injected
-     * into the flow. */
-    ParticlesHashmap _particlesTable;
-
-    /**
-     * A table of boxes.  There maybe
-     * zero or more boxes associated
-     * with each field. */
-    BoxHashmap _boxTable;
-
-    FlowValues _sv;
-
-    static Rappture::SwitchSpec _switches[];
-};
-
-extern int GetDataStream(Tcl_Interp *interp, Rappture::Buffer &buf, int nBytes);
-
-extern int GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
-                             bool *boolVal);
-
-extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
-                           float *floatVal);
-
-extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
-                          int *axisVal);
-
-extern int GetVolumeFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
-                            Volume **volume);
+extern Tcl_AppInitProc FlowCmdInitProc;
+extern Tcl_ObjCmdProc FlowInstObjCmd;
+extern Tcl_CmdDeleteProc FlowInstDeleteProc;
 
 #endif
Index: /nanovis/branches/1.1/FlowParticles.cpp
===================================================================
--- /nanovis/branches/1.1/FlowParticles.cpp	(revision 4611)
+++ /nanovis/branches/1.1/FlowParticles.cpp	(revision 4612)
@@ -16,5 +16,5 @@
 #include "nanovis.h"        // For NMESH
 #include "FlowParticles.h"
-#include "FlowCmd.h"
+#include "Flow.h"
 #include "Trace.h"
 
@@ -48,7 +48,7 @@
     TRACE("Particles '%s' axis: %d pos: %g rel pos: %g",
           _name.c_str(), _sv.position.axis, _sv.position.value,
-          FlowCmd::getRelativePosition(&_sv.position));
+          Flow::getRelativePosition(&_sv.position));
 
-    _renderer->setPos(FlowCmd::getRelativePosition(&_sv.position));
+    _renderer->setPos(Flow::getRelativePosition(&_sv.position));
     _renderer->setAxis(_sv.position.axis);
     assert(_renderer->active());
@@ -59,5 +59,5 @@
 FlowParticles::configure() 
 {
-    _renderer->setPos(FlowCmd::getRelativePosition(&_sv.position));
+    _renderer->setPos(Flow::getRelativePosition(&_sv.position));
     _renderer->setColor(Vector4f(_sv.color.r,
                                  _sv.color.g,
Index: /nanovis/branches/1.1/FlowParticles.h
===================================================================
--- /nanovis/branches/1.1/FlowParticles.h	(revision 4611)
+++ /nanovis/branches/1.1/FlowParticles.h	(revision 4612)
@@ -12,4 +12,5 @@
 #define FLOWPARTICLES_H
 
+#include <cassert>
 #include <string>
 
Index: /nanovis/branches/1.1/HeightMap.cpp
===================================================================
--- /nanovis/branches/1.1/HeightMap.cpp	(revision 4611)
+++ /nanovis/branches/1.1/HeightMap.cpp	(revision 4612)
@@ -23,16 +23,16 @@
 
 HeightMap::HeightMap() : 
-    _vertexBufferObjectID(0), 
-    _texcoordBufferObjectID(0), 
-    _vertexCount(0), 
-    _contour(0), 
-    _tfPtr(0), 
+    _vertexBufferObjectID(0),
+    _texcoordBufferObjectID(0),
+    _vertexCount(0),
+    _contour(NULL),
+    _transferFunc(NULL),
     _opacity(0.5f),
-    _indexBuffer(0), 
-    _indexCount(0), 
-    _contourColor(1.0f, 0.0f, 0.0f), 
-    _contourVisible(false), 
+    _indexBuffer(NULL),
+    _indexCount(0),
+    _contourColor(1.0f, 0.0f, 0.0f),
+    _contourVisible(false),
     _visible(false),
-    _scale(1.0f, 1.0f, 1.0f), 
+    _scale(1.0f, 1.0f, 1.0f),
     _centerPoint(0.0f, 0.0f, 0.0f),
     _heights(NULL)
@@ -93,14 +93,14 @@
         glDisableClientState(GL_NORMAL_ARRAY);
 
-        if (_tfPtr) {
+        if (_transferFunc) {
             // PUT vertex program here
             //
             //
             _shader->bind();
-            _shader->setFPTextureParameter("tf", _tfPtr->id());
+            _shader->setFPTextureParameter("tf", _transferFunc->id());
             _shader->setFPParameter1f("opacity", _opacity);
 
             glEnable(GL_TEXTURE_1D);
-            _tfPtr->getTexture()->activate();
+            _transferFunc->getTexture()->activate();
  
             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
@@ -125,6 +125,6 @@
 
         glDisableClientState(GL_VERTEX_ARRAY);
-        if (_tfPtr != NULL) {
-            _tfPtr->getTexture()->deactivate();
+        if (_transferFunc != NULL) {
+            _transferFunc->getTexture()->deactivate();
             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
@@ -384,5 +384,5 @@
     }
     ContourLineFilter lineFilter;
-    //lineFilter.transferFunction(_tfPtr);
+    //lineFilter.transferFunction(_transferFunc);
     _contour = lineFilter.create(0.0f, 1.0f, 10, map, xNum, yNum);
 
@@ -398,6 +398,6 @@
     Vector3f* vertices = new Vector3f[xNum * yNum];
 
-    Vector3f* dstDataPtr = vertices;
-    float* srcDataPtr = height;
+    Vector3f* dstData = vertices;
+    float* srcData = height;
     
     for (int y = 0; y < yNum; ++y) {
@@ -409,8 +409,8 @@
 
             xCoord = xMin + ((xMax - xMin) * x) / (xNum - 1); 
-            dstDataPtr->set(xCoord, *srcDataPtr, yCoord);
-
-            ++dstDataPtr;
-            ++srcDataPtr;
+            dstData->set(xCoord, *srcData, yCoord);
+
+            ++dstData;
+            ++srcData;
         }
     }
@@ -422,5 +422,5 @@
  */
 void 
-HeightMap::mapToGrid(Grid *gridPtr)
+HeightMap::mapToGrid(Grid *grid)
 {
     int count = _xNum * _yNum;
@@ -432,9 +432,9 @@
     // this surface's y-values (heights) into the grid's axis coordinates.
 
-    float yScale = 1.0 / (gridPtr->yAxis.max() - gridPtr->yAxis.min());
+    float yScale = 1.0 / (grid->yAxis.max() - grid->yAxis.min());
     float *p, *q, *pend;
     float *normHeights = new float[count];
     for (p = _heights, pend = p + count, q = normHeights; p < pend; p++, q++) {
-	*q = (*p - gridPtr->yAxis.min()) * yScale;
+	*q = (*p - grid->yAxis.min()) * yScale;
     }
     Vector3f *t, *texcoord;
@@ -450,10 +450,10 @@
     float xMin, xMax, zMin, zMax;
 
-    xScale = 1.0 / (gridPtr->xAxis.max() - gridPtr->xAxis.min());
-    xMin = (xAxis.min() - gridPtr->xAxis.min()) * xScale;
-    xMax = (xAxis.max() - gridPtr->xAxis.min()) * xScale;
-    zScale = 1.0 / (gridPtr->zAxis.max() - gridPtr->zAxis.min());
-    zMin = (zAxis.min() - gridPtr->zAxis.min()) * zScale;
-    zMax = (zAxis.max() - gridPtr->zAxis.min()) * zScale;
+    xScale = 1.0 / (grid->xAxis.max() - grid->xAxis.min());
+    xMin = (xAxis.min() - grid->xAxis.min()) * xScale;
+    xMax = (xAxis.max() - grid->xAxis.min()) * xScale;
+    zScale = 1.0 / (grid->zAxis.max() - grid->zAxis.min());
+    zMin = (zAxis.min() - grid->zAxis.min()) * zScale;
+    zMax = (zAxis.max() - grid->zAxis.min()) * zScale;
 
     Vector3f* vertices;
@@ -477,5 +477,5 @@
     }
     ContourLineFilter lineFilter;
-    //lineFilter.transferFunction(_tfPtr);
+    //lineFilter.transferFunction(_transferFunc);
     _contour = lineFilter.create(0.0f, 1.0f, 10, vertices, _xNum, _yNum);
     
Index: /nanovis/branches/1.1/HeightMap.h
===================================================================
--- /nanovis/branches/1.1/HeightMap.h	(revision 4611)
+++ /nanovis/branches/1.1/HeightMap.h	(revision 4612)
@@ -49,12 +49,12 @@
     void setHeight(int xCount, int yCount, vrmath::Vector3f *heights);
 #endif
-    void mapToGrid(Grid *gridPtr);
+    void mapToGrid(Grid *grid);
 
     /**
      *@brief Define a color map for color shading of heightmap
      */
-    void transferFunction(TransferFunction *tfPtr)
+    void transferFunction(TransferFunction *transferFunc)
     {
-        _tfPtr = tfPtr;
+        _transferFunc = transferFunc;
     }
 
@@ -64,5 +64,5 @@
     TransferFunction *transferFunction()
     {
-        return _tfPtr;
+        return _transferFunc;
     }
 
@@ -128,5 +128,5 @@
     int _vertexCount;
     nv::graphics::Geometry *_contour;
-    TransferFunction *_tfPtr;
+    TransferFunction *_transferFunc;
     float _opacity;
     NvShader *_shader;
Index: /nanovis/branches/1.1/Makefile.in
===================================================================
--- /nanovis/branches/1.1/Makefile.in	(revision 4611)
+++ /nanovis/branches/1.1/Makefile.in	(revision 4612)
@@ -111,4 +111,5 @@
 		ContourLineFilter.o \
 		ConvexPolygon.o \
+		Flow.o \
 		FlowBox.o \
 		FlowCmd.o \
@@ -125,5 +126,4 @@
 		NvShader.o \
 		NvStdVertexShader.o \
-		NvVectorField.o \
 		NvVolumeShader.o \
 		NvZincBlendeReconstructor.o \
@@ -174,6 +174,5 @@
 
 ifdef NOTDEF
-OBJS +=		NvFlowVisRenderer.o \
-		ParticleEmitter.o \
+OBJS +=		ParticleEmitter.o \
 		ParticleSystem.o \
 		ParticleSystemFactory.o
@@ -274,9 +273,10 @@
 Chain.o: Chain.cpp Chain.h
 CmdProc.o: CmdProc.cpp CmdProc.h
-Command.o: Command.cpp nanovis.h $(AUXSRC) CmdProc.h Trace.h PlaneRenderer.h PointSet.h dxReader.h Grid.h HeightMap.h NvCamera.h NvZincBlendeReconstructor.h Unirect.h Volume.h VolumeRenderer.h
+Command.o: Command.cpp nanovis.h $(AUXSRC) FlowCmd.h CmdProc.h Trace.h PlaneRenderer.h PointSet.h dxReader.h Grid.h HeightMap.h NvCamera.h NvZincBlendeReconstructor.h Unirect.h Volume.h VolumeRenderer.h
 ContourLineFilter.o: ContourLineFilter.cpp ContourLineFilter.h
 ConvexPolygon.o: ConvexPolygon.cpp ConvexPolygon.h $(VRMATH_DIR)/include/vrmath/Vector4f.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h Plane.h
+Flow.o: Flow.h FlowCmd.h FlowTypes.h FlowBox.h FlowParticles.h Switch.h Trace.h
 FlowBox.o: FlowBox.h FlowTypes.h Switch.h Trace.h Volume.h $(VRMATH_DIR)/include/vrmath/Vector3f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h
-FlowCmd.o: FlowCmd.cpp FlowCmd.h FlowParticles.h FlowBox.h FlowTypes.h Switch.h Trace.h TransferFunction.h nanovis.h CmdProc.h NvLIC.h Unirect.h Volume.h VelocityArrowsSlice.h $(VRMATH_DIR)/include/vrmath/Vector3f.h
+FlowCmd.o: FlowCmd.cpp FlowCmd.h FlowParticles.h FlowBox.h FlowTypes.h Command.h Switch.h Trace.h TransferFunction.h nanovis.h CmdProc.h NvLIC.h Unirect.h Volume.h VelocityArrowsSlice.h $(VRMATH_DIR)/include/vrmath/Vector3f.h
 FlowParticles.o: FlowParticles.h FlowTypes.h FlowCmd.h Switch.h Trace.h NvParticleRenderer.h Volume.h $(VRMATH_DIR)/include/vrmath/Vector3f.h $(VRMATH_DIR)/include/vrmath/Vector4f.h
 GradientFilter.o: GradientFilter.cpp GradientFilter.h
@@ -285,5 +285,4 @@
 NvCamera.o: NvCamera.cpp NvCamera.h config.h $(VRMATH_DIR)/include/vrmath/Matrix4x4d.h
 NvColorTableShader.o: NvColorTableShader.cpp NvColorTableShader.h NvShader.h
-NvFlowVisRenderer.o: NvFlowVisRenderer.cpp NvFlowVisRenderer.h
 NvLIC.o: NvLIC.cpp NvLIC.h
 NvParticleAdvectionShader.o: NvParticleAdvectionShader.cpp NvParticleAdvectionShader.h NvShader.h
@@ -292,5 +291,4 @@
 NvShader.o: NvShader.cpp NvShader.h
 NvStdVertexShader.o: NvStdVertexShader.cpp NvStdVertexShader.h NvShader.h
-NvVectorField.o: NvVectorField.cpp NvVectorField.h NvParticleRenderer.h
 NvVolumeShader.o: NvVolumeShader.cpp NvVolumeShader.h NvShader.h
 NvZincBlendeReconstructor.o: NvZincBlendeReconstructor.cpp NvZincBlendeReconstructor.h ZincBlendeVolume.h Volume.h $(VRMATH_DIR)/include/vrmath/Vector3f.h
@@ -314,5 +312,5 @@
 Trace.o: Trace.cpp Trace.h
 TransferFunction.o: TransferFunction.cpp
-Unirect.o: Unirect.cpp Unirect.h Trace.h
+Unirect.o: Unirect.cpp Unirect.h Command.h Trace.h
 VelocityArrowsSlice.o: VelocityArrowsSlice.cpp VelocityArrowsSlice.h
 Volume.o: Volume.cpp Volume.h $(AUXSRC)
@@ -322,4 +320,4 @@
 ZincBlendeVolume.o: ZincBlendeVolume.cpp ZincBlendeVolume.h $(AUXSRC)
 dxReader.o: dxReader.cpp ReaderCommon.h config.h nanovis.h Unirect.h ZincBlendeVolume.h NvZincBlendeReconstructor.h
-nanovis.o: nanovis.cpp nanovis.h $(AUXSRC) FlowCmd.h Grid.h HeightMap.h NvCamera.h NvFlowVisRenderer.h NvLIC.h NvZincBlendeReconstructor.h PerfQuery.h PlaneRenderer.h PointSetRenderer.h PointSet.h Switch.h Trace.h Unirect.h VelocityArrowsSlice.h VolumeInterpolator.h VolumeRenderer.h ZincBlendeVolume.h Axis.h Chain.h
+nanovis.o: nanovis.cpp nanovis.h $(AUXSRC) Command.h Flow.h Grid.h HeightMap.h NvCamera.h NvLIC.h NvZincBlendeReconstructor.h PerfQuery.h PlaneRenderer.h PointSetRenderer.h PointSet.h Switch.h Trace.h Unirect.h VelocityArrowsSlice.h VolumeInterpolator.h VolumeRenderer.h ZincBlendeVolume.h Axis.h Chain.h
 md5.o: md5.h
Index: novis/branches/1.1/NvFlowVisRenderer.cpp
===================================================================
--- /nanovis/branches/1.1/NvFlowVisRenderer.cpp	(revision 4611)
+++ 	(revision )
@@ -1,268 +1,0 @@
-/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * ----------------------------------------------------------------------
- * NvFlowVisRenderer.cpp: particle system class
- *
- * ======================================================================
- *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
- *           Purdue Rendering and Perceptualization Lab (PURPL)
- *
- *  Copyright (c) 2004-2013  HUBzero Foundation, LLC
- *
- *  See the file "license.terms" for information on usage and
- *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- * ======================================================================
- */
-
-#include <vrmath/Vector3f.h>
-
-#include "NvFlowVisRenderer.h"
-
-using namespace vrmath;
-
-#define NV_32
-
-NvFlowVisRenderer::NvFlowVisRenderer(int w, int h) :
-    _activated(true)
-{
-    _psys_width = w;
-    _psys_height = h;
-}
-
-NvFlowVisRenderer::~NvFlowVisRenderer()
-{
-    std::map<std::string, NvVectorField *>::iterator iter;
-    for (iter = _vectorFieldMap.begin(); iter != _vectorFieldMap.end(); ++iter) {
-        delete (*iter).second;
-    }
-}
-
-void 
-NvFlowVisRenderer::initialize()
-{
-    std::map<std::string, NvVectorField *>::iterator iter;
-    for (iter = _vectorFieldMap.begin(); iter != _vectorFieldMap.end(); ++iter) {
-        (*iter).second->initialize();
-    }
-}
-
-void 
-NvFlowVisRenderer::reset()
-{
-    std::map<std::string, NvVectorField *>::iterator iter;
-    for (iter = _vectorFieldMap.begin(); iter != _vectorFieldMap.end(); ++iter) {
-        (*iter).second->reset();
-    }
-}
-
-void 
-NvFlowVisRenderer::initialize(const std::string& vfName)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-        if ((*iter).second) {
-            (*iter).second->initialize();
-        }
-    }
-}
-
-void 
-NvFlowVisRenderer::advect()
-{
-    std::map<std::string, NvVectorField *>::iterator iter;
-    for (iter = _vectorFieldMap.begin(); iter != _vectorFieldMap.end(); ++iter) {
-        if ((*iter).second && (*iter).second->active())
-            (*iter).second->advect();
-    }
-}
-
-void 
-NvFlowVisRenderer::render()
-{ 
-    std::map<std::string, NvVectorField *>::iterator iter;
-    for (iter = _vectorFieldMap.begin(); iter != _vectorFieldMap.end(); ++iter) {
-        if ((*iter).second && (*iter).second->active())
-            (*iter).second->render();
-    }
-}
-
-void 
-NvFlowVisRenderer::addVectorField(const std::string& vfName, Volume* volPtr,
-                                  const Vector3f& ori,
-                                  float scaleX, float scaleY, float scaleZ, float max)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second) {
-	    ((*iter).second)->setVectorField(volPtr, ori, scaleX, scaleY, scaleZ, max);
-	} else {
-	    NvVectorField *vf = new NvVectorField();
-	    _vectorFieldMap[vfName] = vf;
-	    vf->setVectorField(volPtr, ori, scaleX, scaleY, scaleZ, max);
-	}
-    } else {
-	NvVectorField *vf = new NvVectorField();
-	_vectorFieldMap[vfName] = vf;
-	vf->setVectorField(volPtr, ori, scaleX, scaleY, scaleZ, max);
-    }
-}
-
-void 
-NvFlowVisRenderer::activateVectorField(const std::string& vfName)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->active(true);
-    }
-}
-
-void 
-NvFlowVisRenderer::deactivateVectorField(const std::string& vfName)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->active(false);
-    }
-}
-
-void 
-NvFlowVisRenderer::activatePlane(const std::string& vfName, const std::string& name)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-        if ((*iter).second)
-            (*iter).second->activatePlane(name);
-    }
-}
-
-void 
-NvFlowVisRenderer::deactivatePlane(const std::string& vfName, const std::string& name)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-        if ((*iter).second)
-            (*iter).second->deactivatePlane(name);
-    }
-}
-
-void
-NvFlowVisRenderer::setPlaneAxis(const std::string& vfName, const std::string& planeName, int axis)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->setPlaneAxis(planeName, axis);
-    }
-}
-
-void
-NvFlowVisRenderer::setPlanePos(const std::string& vfName, const std::string& name, float pos)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->setPlanePos(name, pos);
-    }
-}
-
-void
-NvFlowVisRenderer::setParticleColor(const std::string& vfName, const std::string& name, const Vector4& color)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->setParticleColor(name, color);
-    }
-}
-
-void 
-NvFlowVisRenderer::removeVectorField(const std::string& vfName)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	delete (*iter).second;
-	_vectorFieldMap.erase(iter);
-    }
-}
-
-void 
-NvFlowVisRenderer::addPlane(const std::string& vfName, const std::string& name)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->addPlane(name);
-    }
-}
-
-void 
-NvFlowVisRenderer::removePlane(const std::string& vfName, const std::string& name)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->removePlane(name);
-    }
-}
-
-void 
-NvFlowVisRenderer::activateDeviceShape(const std::string& vfName, const std::string& name)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->activateDeviceShape(name);
-    }
-}
-
-void 
-NvFlowVisRenderer::deactivateDeviceShape(const std::string& vfName, const std::string& name)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->deactivateDeviceShape(name);
-    }
-}
-
-void 
-NvFlowVisRenderer::activateDeviceShape(const std::string& vfName)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->activateDeviceShape();
-    }
-}
-
-void 
-NvFlowVisRenderer::deactivateDeviceShape(const std::string& vfName)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->deactivateDeviceShape();
-    }
-}
-
-void 
-NvFlowVisRenderer::addDeviceShape(const std::string& vfName, const std::string& name, const NvDeviceShape& shape)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->addDeviceShape(name, shape);
-    }
-}
-
-void 
-NvFlowVisRenderer::removeDeviceShape(const std::string& vfName, const std::string& name)
-{
-    std::map<std::string, NvVectorField *>::iterator iter = _vectorFieldMap.find(vfName);
-    if (iter != _vectorFieldMap.end()) {
-	if ((*iter).second)
-            (*iter).second->removeDeviceShape(name);
-    }
-}
Index: novis/branches/1.1/NvFlowVisRenderer.h
===================================================================
--- /nanovis/branches/1.1/NvFlowVisRenderer.h	(revision 4611)
+++ 	(revision )
@@ -1,101 +1,0 @@
-/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * Copyright (c) 2004-2013  HUBzero Foundation, LLC
- *
- */
-#ifndef NVFLOWVISRENDERER_H
-#define NVFLOWVISRENDERER_H
-
-#include <map>
-#include <string>
-
-#include <vrmath/Vector3f.h>
-#include <vrmath/Vector4f.h>
-
-#include "NvVectorField.h"
-
-class NvParticleRenderer;
-
-class NvFlowVisRenderer
-{
-public:
-    NvFlowVisRenderer(int w, int h);
-
-    ~NvFlowVisRenderer();
-
-    void initialize();
-
-    void initialize(const std::string& vfName);
-
-    void advect();
-
-    void reset();
-
-    void render();
-
-    void addVectorField(Volume *volPtr, const vrmath::Vector3f& ori, float scaleX, 
-                        float scaleY, float scaleZ, float max);
-
-    void addVectorField(const std::string& vfName, Volume *volPtr, const vrmath::Vector3f& ori,
-                        float scaleX, float scaleY, float scaleZ, float max);
-
-    void removeVectorField(const std::string& vfName);
-
-    void addPlane(const std::string& vfName, const std::string& name);
-
-    void removePlane(const std::string& vfName, const std::string& name);
-
-    /** 
-     * @brief Specify the axis of the index plane
-     */
-    void setPlaneAxis(const std::string& vfName, const std::string& name, int axis);
-
-    /**
-     * @param pos Specify the position of slice
-     */
-    void setPlanePos(const std::string& vfName, const std::string& name, float pos);
-
-    void setParticleColor(const std::string& vfName, const std::string& name, const vrmath::Vector4f& color);
-
-    void activatePlane(const std::string& vfName, const std::string& name);
-
-    void deactivatePlane(const std::string& vfName, const std::string& name);
-
-    void activateVectorField(const std::string& vfName);
-
-    void deactivateVectorField(const std::string& vfName);
-
-    ////////////////////
-    // DEVICE SHAPE
-    void addDeviceShape(const std::string& vfName, const std::string& name, const NvDeviceShape& shape);
-
-    void removeDeviceShape(const std::string& vfName, const std::string& name);
-
-    void activateDeviceShape(const std::string& vfName);
-
-    void deactivateDeviceShape(const std::string& vfName);
-
-    void activateDeviceShape(const std::string& vfName, const std::string& name);
-
-    void deactivateDeviceShape(const std::string& vfName, const std::string& name);
-
-    bool active()
-    {
-	return _activated;
-    }
-
-    void active(bool state)
-    {
-	_activated = state;
-    }
-
-private:
-    int _psys_width;
-    int _psys_height;
-
-    std::map<std::string, NvVectorField *> _vectorFieldMap;
-
-    bool _activated;
-};
-
-#endif
Index: novis/branches/1.1/NvVectorField.cpp
===================================================================
--- /nanovis/branches/1.1/NvVectorField.cpp	(revision 4611)
+++ 	(revision )
@@ -1,296 +1,0 @@
-/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * Copyright (c) 2004-2013  HUBzero Foundation, LLC
- *
- */
-#include "nanovis.h"
-
-#include <vrmath/Vector3f.h>
-#include <vrmath/Vector4f.h>
-
-#include "NvVectorField.h"
-#include "NvParticleRenderer.h"
-
-using namespace vrmath;
-
-NvVectorField::NvVectorField() :
-    _vectorFieldId(0),
-    _volPtr(NULL),
-    _activated(true),
-    _origin(0, 0, 0),
-    _scaleX(1),
-    _scaleY(1),
-    _scaleZ(1),
-    _max(1),
-    _deviceVisible(false)
-{
-}
-
-NvVectorField::~NvVectorField()
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter;
-    for (iter = _particleRendererMap.begin(); 
-	 iter != _particleRendererMap.end(); iter++) {
-	delete (*iter).second;
-    }
-}
-
-void 
-NvVectorField::setVectorField(Volume *volPtr, const Vector3f& origin, 
-			      float scaleX, float scaleY, float scaleZ, 
-			      float max)
-{
-    _volPtr = volPtr;
-    _origin = origin;
-    _scaleX = scaleX;
-    _scaleY = scaleY;
-    _scaleZ = scaleZ;
-    _max = max;
-    _vectorFieldId = volPtr->textureID();
-}
-
-void 
-NvVectorField::addDeviceShape(const std::string& name, 
-			      const NvDeviceShape& shape)
-{
-    _shapeMap[name] = shape;
-}
-
-void NvVectorField::removeDeviceShape(const std::string& name)
-{
-    std::map<std::string, NvDeviceShape>::iterator iter = _shapeMap.find(name);
-    if (iter != _shapeMap.end()) _shapeMap.erase(iter);
-}
-
-void NvVectorField::initialize()
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter;
-    for (iter = _particleRendererMap.begin(); 
-	 iter != _particleRendererMap.end(); iter++) {
-	if ((*iter).second) (*iter).second->initialize();
-    }
-}
-
-void NvVectorField::reset()
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter;
-    for (iter = _particleRendererMap.begin(); 
-	 iter != _particleRendererMap.end(); iter++) {
-	if ((*iter).second) (*iter).second->reset();
-    }
-}
-
-void NvVectorField::setPlaneAxis(const std::string& name, int axis)
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter = _particleRendererMap.find(name);
-    if (iter != _particleRendererMap.end()) {
-	(*iter).second->setAxis(axis);
-    }
-    
-}
-
-void NvVectorField::setPlanePos(const std::string& name, float pos)
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter = _particleRendererMap.find(name);
-    if (iter != _particleRendererMap.end()) {
-	(*iter).second->setPos(pos);
-    }
-}
-
-void NvVectorField::addPlane(const std::string& name)
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter = _particleRendererMap.find(name);
-    NvParticleRenderer *renderer = NULL;
-    if (iter != _particleRendererMap.end()) {
-	if ((*iter).second != 0) {
-	    renderer = (*iter).second;
-	} else {
-	    renderer = (*iter).second = new NvParticleRenderer(NMESH, NMESH);
-	}
-    } else {
-	renderer = new NvParticleRenderer(NMESH, NMESH);
-	_particleRendererMap[name] = renderer;
-    }
-
-    renderer->setVectorField(_vectorFieldId, _origin, _scaleX, _scaleY, _scaleZ, _max);
-    if (renderer) {
-	renderer->initialize();
-    }
-}
-
-void NvVectorField::removePlane(const std::string& name)
-{
-    std::map<std::string, NvParticleRenderer* >::iterator iter = _particleRendererMap.find(name);
-    if (iter != _particleRendererMap.end()) {
-	delete (*iter).second;
-	_particleRendererMap.erase(iter);
-    }
-}
-
-void NvVectorField::activatePlane(const std::string& name)
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter = _particleRendererMap.find(name);
-    if (iter != _particleRendererMap.end()) {
-	(*iter).second->active(true);
-    }
-}
-
-void NvVectorField::deactivatePlane(const std::string& name)
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter = _particleRendererMap.find(name);
-    if (iter != _particleRendererMap.end()) {
-	(*iter).second->active(false);
-    }
-}
-
-void NvVectorField::setParticleColor(const std::string& name, const vrmath::Vector4f& color)
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter = _particleRendererMap.find(name);
-    if (iter != _particleRendererMap.end()) {
-	(*iter).second->setColor(color);
-    }
-}
-
-void NvVectorField::setParticleColor(const std::string& name, float r, float g, float b, float a)
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter = _particleRendererMap.find(name);
-    if (iter != _particleRendererMap.end()) {
-	if ((*iter).second) (*iter).second->setColor(vrmath::Vector4f(r,g,b,a));
-    }
-}
-
-void NvVectorField::advect()
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter;
-    for (iter = _particleRendererMap.begin(); 
-	 iter != _particleRendererMap.end(); ++iter) {
-	if ((*iter).second && (*iter).second->active()) 
-	    (*iter).second->advect();
-    }
-}
-
-void NvVectorField::render()
-{
-    std::map<std::string, NvParticleRenderer *>::iterator iter;
-    for (iter = _particleRendererMap.begin(); 
-	 iter != _particleRendererMap.end(); ++iter) {
-	if ((*iter).second && (*iter).second->active()) {
-	    (*iter).second->render();
-	}
-    }
-    if (_deviceVisible) {
-	drawDeviceShape();
-    }
-}
-
-void 
-NvVectorField::drawDeviceShape()
-{
-    glPushAttrib(GL_ENABLE_BIT);
-
-    glEnable(GL_DEPTH_TEST);
-    glDisable(GL_TEXTURE_2D);
-    glDisable(GL_BLEND);
-
-    glMatrixMode(GL_MODELVIEW);
-    glPushMatrix();
-
-    Vector3f origin = _volPtr->location();
-    glTranslatef(origin.x, origin.y, origin.z);
-
-    Vector3f scale = _volPtr->getPhysicalScaling();
-    glScaled(scale.x, scale.y, scale.z);
-
-    Vector3f min, max;
-    min.x = _volPtr->xAxis.min();
-    min.y = _volPtr->yAxis.min();
-    min.z = _volPtr->zAxis.min();
-    max.x = _volPtr->xAxis.max();
-    max.y = _volPtr->yAxis.max();
-    max.z = _volPtr->zAxis.max();
-
-    std::map<std::string, NvDeviceShape>::iterator iterShape;
-
-    for (iterShape = _shapeMap.begin(); iterShape != _shapeMap.end(); 
-	 ++iterShape) {
-	NvDeviceShape& shape = (*iterShape).second;
-
-	if (!shape.visible) continue;
-
-        float x0, y0, z0, x1, y1, z1;
-        x0 = y0 = z0 = 0.0f;
-        x1 = y1 = z1 = 0.0f;
-        if (max.x > min.x) {
-            x0 = (shape.min.x - min.x) / (max.x - min.x);
-            x1 = (shape.max.x - min.x) / (max.x - min.x);
-        }
-        if (max.y > min.y) {
-            y0 = (shape.min.y - min.y) / (max.y - min.y);
-            y1 = (shape.max.y - min.y) / (max.y - min.y);
-        }
-        if (max.z > min.z) {
-            z0 = (shape.min.z - min.z) / (max.z - min.z);
-            z1 = (shape.max.z - min.z) / (max.z - min.z);
-        }
-
-        TRACE("rendering box %g,%g %g,%g %g,%g", x0, x1, y0, y1, z0, z1);
-
-	glColor4d(shape.color.x, shape.color.y, shape.color.z, shape.color.w);
-	glLineWidth(1.2);
-	glBegin(GL_LINE_LOOP); 
-	{
-	    glVertex3d(x0, y0, z0);
-	    glVertex3d(x1, y0, z0);
-	    glVertex3d(x1, y1, z0);
-	    glVertex3d(x0, y1, z0);
-	}
-	glEnd();
-	glBegin(GL_LINE_LOOP);
-	{
-	    glVertex3d(x0, y0, z1);
-	    glVertex3d(x1, y0, z1);
-	    glVertex3d(x1, y1, z1);
-	    glVertex3d(x0, y1, z1);
-	}
-	glEnd();
-	
-	glBegin(GL_LINE_LOOP);
-	{
-	    glVertex3d(x0, y0, z0);
-	    glVertex3d(x0, y0, z1);
-	    glVertex3d(x0, y1, z1);
-	    glVertex3d(x0, y1, z0);
-	}
-	glEnd();
-	
-	glBegin(GL_LINE_LOOP);
-	{
-	    glVertex3d(x1, y0, z0);
-	    glVertex3d(x1, y0, z1);
-	    glVertex3d(x1, y1, z1);
-	    glVertex3d(x1, y1, z0);
-	}
-	glEnd();
-    }
-    
-    glPopMatrix();
-    glPopAttrib();
-}
-
-void 
-NvVectorField::activateDeviceShape(const std::string& name)
-{
-    std::map<std::string, NvDeviceShape>::iterator iter = _shapeMap.find(name);
-    if (iter != _shapeMap.end()) {
-	(*iter).second.visible = true;
-    }
-}
-
-void 
-NvVectorField::deactivateDeviceShape(const std::string& name)
-{
-    std::map<std::string, NvDeviceShape>::iterator iter = _shapeMap.find(name);
-    if (iter != _shapeMap.end()) {
-	(*iter).second.visible = false;
-    }
-}
Index: novis/branches/1.1/NvVectorField.h
===================================================================
--- /nanovis/branches/1.1/NvVectorField.h	(revision 4611)
+++ 	(revision )
@@ -1,116 +1,0 @@
-/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/*
- * Copyright (c) 2004-2013  HUBzero Foundation, LLC
- *
- */
-#ifndef NV_VECTOR_FIELD_H
-#define NV_VECTOR_FIELD_H
-
-#include <string>
-#include <map>
-
-#include <vrmath/Vector3f.h>
-#include <vrmath/Vector4f.h>
-
-#include "Volume.h"
-#include "NvParticleRenderer.h"
-
-class NvDeviceShape
-{
-public:
-    NvDeviceShape() :
-        visible(true)
-    {
-    }
-
-    vrmath::Vector3f min;
-    vrmath::Vector3f max;
-    vrmath::Vector4f color;
-    bool visible;
-};
-
-class NvVectorField
-{
-public :
-    NvVectorField();
-
-    ~NvVectorField();
-
-    void setVectorField(Volume *vol, const vrmath::Vector3f& origin,
-                        float scaleX, float scaleY, float scaleZ, float max);
-
-    bool active()
-    {
-	return _activated;
-    }
-
-    void active(bool state)
-    {
-	_activated = state;
-    }
-
-    void activateDeviceShape()
-    {
-	_deviceVisible = true;
-    }
-
-    void deactivateDeviceShape()
-    {
-	_deviceVisible = false;
-    }
-
-    void addDeviceShape(const std::string& name, const NvDeviceShape& shape);
-
-    void removeDeviceShape(const std::string& name);
-
-    void activateDeviceShape(const std::string& name);
-
-    void deactivateDeviceShape(const std::string& name);
-
-    void initialize();
-
-    void reset();
-    
-    void addPlane(const std::string& name);
-
-    void removePlane(const std::string& name);
-    
-    void advect();
-
-    void render();
-    
-    void drawDeviceShape();
-
-    void activatePlane(const std::string& name);
-
-    void deactivatePlane(const std::string& name);
-
-    void setPlaneAxis(const std::string& name, int axis);
-
-    void setPlanePos(const std::string& name, float pos);
-
-    void setParticleColor(const std::string& name, float r, float g, float b, float a);
-
-    void setParticleColor(const std::string& name, const vrmath::Vector4f& color);
-
-private:
-    GLuint _vectorFieldId;
-    Volume *_volPtr;
-    std::map<std::string, NvParticleRenderer *> _particleRendererMap;
-    std::map<std::string, NvDeviceShape> _shapeMap;
-
-    /**
-     * @brief Specify the visibility
-     */
-    bool _activated;
-
-    vrmath::Vector3f _origin;
-    float _scaleX;
-    float _scaleY;
-    float _scaleZ;
-    float _max;
-
-    bool _deviceVisible;
-};
-
-#endif
Index: /nanovis/branches/1.1/PlaneRenderer.cpp
===================================================================
--- /nanovis/branches/1.1/PlaneRenderer.cpp	(revision 4611)
+++ /nanovis/branches/1.1/PlaneRenderer.cpp	(revision 4612)
@@ -37,10 +37,10 @@
 
 int 
-PlaneRenderer::addPlane(Texture2D *p, TransferFunction *tfPtr)
+PlaneRenderer::addPlane(Texture2D *planeTexture, TransferFunction *tf)
 {
     int ret = _numPlanes;
 
-    _plane.push_back(p);
-    _tf.push_back(tfPtr);
+    _plane.push_back(planeTexture);
+    _tf.push_back(tf);
 
     if (ret == 0)
Index: /nanovis/branches/1.1/Trace.cpp
===================================================================
--- /nanovis/branches/1.1/Trace.cpp	(revision 4611)
+++ /nanovis/branches/1.1/Trace.cpp	(revision 4612)
@@ -45,8 +45,8 @@
 
 bool
-CheckFBO(GLenum *statusPtr) 
+CheckFBO(GLenum *status) 
 {
-    *statusPtr = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
-    return (*statusPtr == GL_FRAMEBUFFER_COMPLETE_EXT);
+    *status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+    return (*status == GL_FRAMEBUFFER_COMPLETE_EXT);
 }
 
Index: /nanovis/branches/1.1/Trace.h
===================================================================
--- /nanovis/branches/1.1/Trace.h	(revision 4611)
+++ /nanovis/branches/1.1/Trace.h	(revision 4612)
@@ -30,5 +30,5 @@
 #define INFO(...)	LogMessage(LOG_INFO, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__)
 
-extern bool CheckFBO(GLenum *statusPtr);
+extern bool CheckFBO(GLenum *status);
 extern void PrintFBOStatus(GLenum status, const char *prefix);
 extern bool CheckGL(const char *prefix);
Index: /nanovis/branches/1.1/Unirect.cpp
===================================================================
--- /nanovis/branches/1.1/Unirect.cpp	(revision 4611)
+++ /nanovis/branches/1.1/Unirect.cpp	(revision 4612)
@@ -6,4 +6,5 @@
  */
 #include <float.h>
+
 #include <tcl.h>
 
@@ -11,11 +12,7 @@
 #include <RpFieldRect3D.h>
 
+#include "Command.h"
 #include "Unirect.h"
 #include "Trace.h"
-
-extern int GetFloatFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, 
-                           float *valuePtr);
-
-extern int GetAxisFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *indexPtr);
 
 static inline char *
Index: /nanovis/branches/1.1/Volume.cpp
===================================================================
--- /nanovis/branches/1.1/Volume.cpp	(revision 4611)
+++ /nanovis/branches/1.1/Volume.cpp	(revision 4612)
@@ -38,5 +38,5 @@
     _height(h),
     _depth(d),
-    _tfPtr(NULL),
+    _transferFunc(NULL),
     _ambient(0.6f),
     _diffuse(0.4f),
Index: /nanovis/branches/1.1/Volume.h
===================================================================
--- /nanovis/branches/1.1/Volume.h	(revision 4611)
+++ /nanovis/branches/1.1/Volume.h	(revision 4612)
@@ -277,10 +277,10 @@
     TransferFunction *transferFunction()
     {
-        return _tfPtr;
-    }
-
-    void transferFunction(TransferFunction *tfPtr)
-    {
-        _tfPtr = tfPtr;
+        return _transferFunc;
+    }
+
+    void transferFunction(TransferFunction *transferFunc)
+    {
+        _transferFunc = transferFunc;
     }
 
@@ -366,5 +366,5 @@
      * render this volume.
      */
-    TransferFunction *_tfPtr;
+    TransferFunction *_transferFunc;
 
     float _ambient;      ///< Ambient material coefficient
Index: /nanovis/branches/1.1/VolumeInterpolator.cpp
===================================================================
--- /nanovis/branches/1.1/VolumeInterpolator.cpp	(revision 4611)
+++ /nanovis/branches/1.1/VolumeInterpolator.cpp	(revision 4612)
@@ -125,28 +125,28 @@
 
 void
-VolumeInterpolator::addVolume(Volume *refPtr)
+VolumeInterpolator::addVolume(Volume *volume)
 {
     if (_volumes.size() != 0) {
-        if (_volumes[0]->width() != refPtr->width() || 
-            _volumes[0]->height() != refPtr->height() ||   
-            _volumes[0]->depth() != refPtr->depth() || 
-            _volumes[0]->numComponents() != refPtr->numComponents()) {
+        if (_volumes[0]->width() != volume->width() || 
+            _volumes[0]->height() != volume->height() ||   
+            _volumes[0]->depth() != volume->depth() || 
+            _volumes[0]->numComponents() != volume->numComponents()) {
             TRACE("The volume should be the same width, height, number of components");
             return;
         }
     } else {
-        _dataCount = refPtr->width() * refPtr->height() * refPtr->depth();
-        _numComponents = refPtr->numComponents();
+        _dataCount = volume->width() * volume->height() * volume->depth();
+        _numComponents = volume->numComponents();
         _numBytes = _dataCount * _numComponents * sizeof(float);
-        Vector3f loc = refPtr->location();
+        Vector3f loc = volume->location();
         _volume = new Volume(loc.x, loc.y, loc.z,
-                             refPtr->width(),
-                             refPtr->height(),
-                             refPtr->depth(), 
-                             refPtr->numComponents(), 
-                             refPtr->data(), 
-                             refPtr->wAxis.min(), 
-                             refPtr->wAxis.max(), 
-                             refPtr->nonZeroMin());
+                             volume->width(),
+                             volume->height(),
+                             volume->depth(), 
+                             volume->numComponents(), 
+                             volume->data(), 
+                             volume->wAxis.min(), 
+                             volume->wAxis.max(), 
+                             volume->nonZeroMin());
 
         _volume->numSlices(256-1);
@@ -156,15 +156,15 @@
         _volume->visible(true);
         _volume->dataEnabled(true);
-        _volume->ambient(refPtr->ambient());
-        _volume->diffuse(refPtr->diffuse());
-        _volume->specularLevel(refPtr->specularLevel());
-        _volume->specularExponent(refPtr->specularExponent());
-        _volume->opacityScale(refPtr->opacityScale());
+        _volume->ambient(volume->ambient());
+        _volume->diffuse(volume->diffuse());
+        _volume->specularLevel(volume->specularLevel());
+        _volume->specularExponent(volume->specularExponent());
+        _volume->opacityScale(volume->opacityScale());
         _volume->isosurface(0);
         TRACE("VOL : location %f %f %f\n\tid : %s", loc.x, loc.y, loc.z, 
-               refPtr->name());
+               volume->name());
     }
     _volumes.push_back(_volume);
-    TRACE("a Volume[%s] is added to VolumeInterpolator", refPtr->name());
+    TRACE("a Volume[%s] is added to VolumeInterpolator", volume->name());
 }
 
Index: /nanovis/branches/1.1/VolumeRenderer.cpp
===================================================================
--- /nanovis/branches/1.1/VolumeRenderer.cpp	(revision 4611)
+++ /nanovis/branches/1.1/VolumeRenderer.cpp	(revision 4612)
@@ -132,10 +132,10 @@
     TRACE("start loop %d", volumes.size());
     for (size_t i = 0; i < volumes.size(); i++) {
-        Volume *volPtr = volumes[i];
+        Volume *volume = volumes[i];
         polys[i] = NULL;
         actual_slices[i] = 0;
 
-        int n_slices = volPtr->numSlices();
-        if (volPtr->isosurface()) {
+        int n_slices = volume->numSlices();
+        if (volume->isosurface()) {
             // double the number of slices
             n_slices <<= 1;
@@ -143,6 +143,6 @@
 
         //volume start location
-        Vector3f volPos = volPtr->location();
-        Vector3f volScaling = volPtr->getPhysicalScaling();
+        Vector3f volPos = volume->location();
+        Vector3f volScaling = volume->getPhysicalScaling();
 
         TRACE("VOL POS: %g %g %g",
@@ -196,7 +196,7 @@
         //draw volume bounding box with translation (the correct location in
         //space)
-        if (volPtr->outline()) {
+        if (volume->outline()) {
             float olcolor[3];
-            volPtr->getOutlineColor(olcolor);
+            volume->getOutlineColor(olcolor);
             drawBoundingBox(x0, y0, z0, x0+1, y0+1, z0+1,
                 (double)olcolor[0], (double)olcolor[1], (double)olcolor[2],
@@ -222,5 +222,5 @@
         size_t n_actual_slices;
 
-        if (volPtr->dataEnabled()) {
+        if (volume->dataEnabled()) {
             if (z_step == 0.0f)
                 n_actual_slices = 1;
@@ -244,10 +244,10 @@
         // vice versa.
 
-        for (int j = 0; j < volPtr->getCutplaneCount(); j++) {
-            if (!volPtr->isCutplaneEnabled(j)) {
+        for (int j = 0; j < volume->getCutplaneCount(); j++) {
+            if (!volume->isCutplaneEnabled(j)) {
                 continue;
             }
-            float offset = volPtr->getCutplane(j)->offset;
-            int axis = volPtr->getCutplane(j)->orient;
+            float offset = volume->getCutplane(j)->offset;
+            int axis = volume->getCutplane(j)->orient;
 
             switch (axis) {
@@ -279,6 +279,6 @@
 
             _cutplaneShader->bind();
-            _cutplaneShader->setFPTextureParameter("volume", volPtr->textureID());
-            _cutplaneShader->setFPTextureParameter("tf", volPtr->transferFunction()->id());
+            _cutplaneShader->setFPTextureParameter("volume", volume->textureID());
+            _cutplaneShader->setFPTextureParameter("tf", volume->transferFunction()->id());
 
             glPushMatrix();
@@ -383,5 +383,5 @@
 
     for (size_t i = 0; i < total_rendered_slices; i++) {
-        Volume *volPtr = NULL;
+        Volume *volume = NULL;
 
         int volume_index = slices[i].volumeId;
@@ -390,7 +390,7 @@
         float z_step = z_steps[volume_index];
 
-        volPtr = volumes[volume_index];
-
-        Vector3f volScaling = volPtr->getPhysicalScaling();
+        volume = volumes[volume_index];
+
+        Vector3f volScaling = volume->getPhysicalScaling();
 
         glPushMatrix();
@@ -398,14 +398,14 @@
 
         // FIXME: compute view-dependent volume sample distance
-        double avgSampleDistance = 1.0 / pow(volPtr->width() * volScaling.x * 
-                                             volPtr->height() * volScaling.y * 
-                                             volPtr->depth() * volScaling.z, 1.0/3.0);
+        double avgSampleDistance = 1.0 / pow(volume->width() * volScaling.x * 
+                                             volume->height() * volScaling.y * 
+                                             volume->depth() * volScaling.z, 1.0/3.0);
         float sampleRatio = z_step / avgSampleDistance;
 
 #ifdef notdef
         TRACE("shading slice: volume %s addr=%x slice=%d, volume=%d z_step=%g avgSD=%g", 
-              volPtr->name(), volPtr, slice_index, volume_index, z_step, avgSampleDistance);
+              volume->name(), volume, slice_index, volume_index, z_step, avgSampleDistance);
 #endif
-        activateVolumeShader(volPtr, false, sampleRatio);
+        activateVolumeShader(volume, false, sampleRatio);
         glPopMatrix();
 
@@ -493,14 +493,14 @@
 
 void 
-VolumeRenderer::activateVolumeShader(Volume *volPtr, bool sliceMode,
+VolumeRenderer::activateVolumeShader(Volume *volume, bool sliceMode,
                                      float sampleRatio)
 {
     //vertex shader
     _stdVertexShader->bind();
-    TransferFunction *tfPtr  = volPtr->transferFunction();
-    if (volPtr->volumeType() == Volume::CUBIC) {
-        _regularVolumeShader->bind(tfPtr->id(), volPtr, sliceMode, sampleRatio);
-    } else if (volPtr->volumeType() == Volume::ZINCBLENDE) {
-        _zincBlendeShader->bind(tfPtr->id(), volPtr, sliceMode, sampleRatio);
+    TransferFunction *transferFunc  = volume->transferFunction();
+    if (volume->volumeType() == Volume::CUBIC) {
+        _regularVolumeShader->bind(transferFunc->id(), volume, sliceMode, sampleRatio);
+    } else if (volume->volumeType() == Volume::ZINCBLENDE) {
+        _zincBlendeShader->bind(transferFunc->id(), volume, sliceMode, sampleRatio);
     }
 }
Index: /nanovis/branches/1.1/VtkReader.cpp
===================================================================
--- /nanovis/branches/1.1/VtkReader.cpp	(revision 4611)
+++ /nanovis/branches/1.1/VtkReader.cpp	(revision 4612)
@@ -342,5 +342,5 @@
     lz = (nz - 1) * dz;
 
-    Volume *volPtr = NULL;
+    Volume *volume = NULL;
     double vmin = DBL_MAX;
     double nzero_min = DBL_MAX;
@@ -477,10 +477,10 @@
           vmin, vmax, nzero_min);
 
-    volPtr = NanoVis::loadVolume(tag, nx, ny, nz, 4, data,
+    volume = NanoVis::loadVolume(tag, nx, ny, nz, 4, data,
                                  vmin, vmax, nzero_min);
-    volPtr->xAxis.setRange(x0, x0 + lx);
-    volPtr->yAxis.setRange(y0, y0 + ly);
-    volPtr->zAxis.setRange(z0, z0 + lz);
-    volPtr->updatePending = true;
+    volume->xAxis.setRange(x0, x0 + lx);
+    volume->yAxis.setRange(y0, y0 + ly);
+    volume->zAxis.setRange(z0, z0 + lz);
+    volume->updatePending = true;
 
     delete [] data;
@@ -492,8 +492,8 @@
     float dy0 = -0.5*ly/lx;
     float dz0 = -0.5*lz/lx;
-    if (volPtr) {
-        volPtr->location(vrmath::Vector3f(dx0, dy0, dz0));
+    if (volume) {
+        volume->location(vrmath::Vector3f(dx0, dy0, dz0));
         TRACE("Set volume location to %g %g %g", dx0, dy0, dz0);
     }
-    return volPtr;
-}
+    return volume;
+}
Index: /nanovis/branches/1.1/dxReader.cpp
===================================================================
--- /nanovis/branches/1.1/dxReader.cpp	(revision 4611)
+++ /nanovis/branches/1.1/dxReader.cpp	(revision 4612)
@@ -225,5 +225,5 @@
         return NULL;
     }
-    Volume *volPtr = NULL;
+    Volume *volume = NULL;
     float *data = NULL;
     double vmin = DBL_MAX;
@@ -481,19 +481,19 @@
           vmin, vmax, nzero_min);
 
-    volPtr = NanoVis::loadVolume(tag, nx, ny, nz, 4, data,
+    volume = NanoVis::loadVolume(tag, nx, ny, nz, 4, data,
                                  vmin, vmax, nzero_min);
-    volPtr->xAxis.setRange(x0, x0 + lx);
-    volPtr->yAxis.setRange(y0, y0 + ly);
-    volPtr->zAxis.setRange(z0, z0 + lz);
-    volPtr->updatePending = true;
+    volume->xAxis.setRange(x0, x0 + lx);
+    volume->yAxis.setRange(y0, y0 + ly);
+    volume->zAxis.setRange(z0, z0 + lz);
+    volume->updatePending = true;
 
     // TBD..
 #if 0 && defined(USE_POINTSET_RENDERER)
     PointSet *pset = new PointSet();
-    pset->initialize(volPtr, (float*)data);
+    pset->initialize(volume, (float*)data);
     pset->setVisible(true);
     NanoVis::pointSet.push_back(pset);
     updateColor(pset);
-    volPtr->pointsetIndex = NanoVis::pointSet.size() - 1;
+    volume->pointsetIndex = NanoVis::pointSet.size() - 1;
 #endif
     delete [] data;
@@ -505,8 +505,8 @@
     float dy0 = -0.5*ly/lx;
     float dz0 = -0.5*lz/lx;
-    if (volPtr) {
-        volPtr->location(vrmath::Vector3f(dx0, dy0, dz0));
+    if (volume) {
+        volume->location(vrmath::Vector3f(dx0, dy0, dz0));
         TRACE("Set volume location to %g %g %g", dx0, dy0, dz0);
     }
-    return volPtr;
+    return volume;
 }
Index: /nanovis/branches/1.1/nanovis.cpp
===================================================================
--- /nanovis/branches/1.1/nanovis.cpp	(revision 4611)
+++ /nanovis/branches/1.1/nanovis.cpp	(revision 4612)
@@ -59,10 +59,10 @@
 #include "define.h"
 
-#include "FlowCmd.h"
+#include "Command.h"
+#include "Flow.h"
 #include "Grid.h"
 #include "HeightMap.h"
 #include "NvCamera.h"
 #include "NvShader.h"
-#include "NvFlowVisRenderer.h"
 #include "NvLIC.h"
 #include "NvZincBlendeReconstructor.h"
@@ -82,4 +82,5 @@
 using namespace nv::graphics;
 using namespace nv::util;
+using namespace vrmath;
 
 #define SIZEOF_BMP_HEADER   54
@@ -141,10 +142,7 @@
 float NanoVis::wMin = FLT_MAX;
 float NanoVis::wMax = -FLT_MAX;
-vrmath::Vector3f NanoVis::sceneMin, NanoVis::sceneMax;
+Vector3f NanoVis::sceneMin, NanoVis::sceneMax;
 
 VolumeRenderer *NanoVis::volRenderer = NULL;
-#ifdef notdef
-NvFlowVisRenderer *NanoVis::flowVisRenderer = NULL;
-#endif
 VelocityArrowsSlice *NanoVis::velocityArrowsSlice = NULL;
 NvLIC *NanoVis::licRenderer = NULL;
@@ -167,7 +165,4 @@
 GLuint NanoVis::_finalDepthRb = 0;
 
-// in Command.cpp
-extern Tcl_Interp *initTcl();
-
 // Default camera location.
 float def_eye_x = 0.0f;
@@ -199,10 +194,4 @@
         delete legendTexture;
     }
-#ifdef notdef
-    if (flowVisRenderer != NULL) {
-        TRACE("Deleting flowVisRenderer");
-        delete flowVisRenderer;
-    }
-#endif
     TRACE("Deleting flows");
     deleteFlows(interp);
@@ -570,13 +559,21 @@
 /** \brief Load a 3D volume
  *
- * \param n_component the number of scalars for each space point. All component 
+ * \param name Volume ID
+ * \param width Number of samples in X direction
+ * \param height Number of samples in Y direction
+ * \param depth Number of samples in Z direction
+ * \param numComponents the number of scalars for each space point. All component 
  * scalars for a point are placed consequtively in data array
  * width, height and depth: number of points in each dimension
+ * \param data Array of floats
+ * \param vmin Min value of field
+ * \param vmax Max value of field
+ * \param nonZeroMin Minimum non-zero value of field
  * \param data pointer to an array of floats.
  */
 Volume *
 NanoVis::loadVolume(const char *name, int width, int height, int depth, 
-                    int n_component, float *data, double vmin, double vmax, 
-                    double nzero_min)
+                    int numComponents, float *data, double vmin, double vmax, 
+                    double nonZeroMin)
 {
     VolumeHashmap::iterator itr = volumeTable.find(name);
@@ -588,6 +585,6 @@
     Volume *volume = new Volume(0.f, 0.f, 0.f,
                                 width, height, depth,
-                                n_component,
-                                data, vmin, vmax, nzero_min);
+                                numComponents,
+                                data, vmin, vmax, nonZeroMin);
     Volume::updatePending = true;
     volume->name(name);
@@ -884,9 +881,5 @@
     fonts->setFont("verdana");
 
-#ifdef notdef
-    flowVisRenderer = new NvFlowVisRenderer(NMESH, NMESH);
-#endif
     velocityArrowsSlice = new VelocityArrowsSlice;
-
     licRenderer = new NvLIC(NMESH, NPIX, NPIX, _licAxis, _licSlice);
 
@@ -936,5 +929,5 @@
     initOffscreenBuffer();    //frame buffer object for offscreen rendering
 
-    //create volume renderer and add volumes to it
+    //create volume renderer
     volRenderer = new VolumeRenderer();
 
@@ -949,42 +942,4 @@
     TRACE("leaving initGL");
 }
-
-#ifdef DO_RLE
-char rle[512*512*3];
-int rleSize;
-
-short offsets[512*512*3];
-int offsetsSize;
-
-static void 
-doRle()
-{
-    int len = NanoVis::winWidth*NanoVis::winHeight*3;
-    rleSize = 0;
-    offsetsSize = 0;
-
-    int i = 0;
-    while (i < len) {
-        if (NanoVis::screenBuffer[i] == 0) {
-            int pos = i+1;
-            while ( (pos < len) && (NanoVis::screenBuffer[pos] == 0)) {
-                pos++;
-            }
-            offsets[offsetsSize++] = -(pos - i);
-            i = pos;
-        }
-
-        else {
-            int pos;
-            for (pos = i; (pos < len) && (NanoVis::screenBuffer[pos] != 0); pos++){
-                rle[rleSize++] = NanoVis::screenBuffer[pos];
-            }
-            offsets[offsetsSize++] = (pos - i);
-            i = pos;
-        }
-
-    }
-}
-#endif
 
 // used internally to build up the BMP file header
@@ -1525,5 +1480,5 @@
             continue;
 
-        vrmath::Vector3f bmin, bmax;
+        Vector3f bmin, bmax;
         volume->getWorldSpaceBounds(bmin, bmax);
         if (bmin.x > bmax.x)
@@ -1557,5 +1512,5 @@
             continue;
 
-        vrmath::Vector3f bmin, bmax;
+        Vector3f bmin, bmax;
         heightMap->getWorldSpaceBounds(bmin, bmax);
         if (bmin.x > bmax.x)
@@ -1582,5 +1537,5 @@
     }
 
-    vrmath::Vector3f flowMin, flowMax;
+    Vector3f flowMin, flowMax;
     getFlowBounds(flowMin, flowMax, onlyVisible);
     if (flowMin.x < flowMax.x) {
@@ -1622,4 +1577,189 @@
     TRACE("Setting bgcolor to %g %g %g", color[0], color[1], color[2]);
     glClearColor(color[0], color[1], color[2], 1);
+}
+
+Flow *
+NanoVis::getFlow(const char *name)
+{
+    FlowHashmap::iterator itr = flowTable.find(name);
+    if (itr == flowTable.end()) {
+        TRACE("Can't find flow '%s'", name);
+        return NULL;
+    }
+    return itr->second;
+}
+
+Flow *
+NanoVis::createFlow(Tcl_Interp *interp, const char *name)
+{
+    FlowHashmap::iterator itr = flowTable.find(name);
+    if (itr != flowTable.end()) {
+        ERROR("Flow '%s' already exists", name);
+        return NULL;
+    }
+    Flow *flow = new Flow(interp, name);
+    flowTable[name] = flow;
+    return flow;
+}
+
+/**
+ * \brief Delete flow object and hash table entry
+ *
+ * This is called by the flow command instance delete callback
+ */
+void
+NanoVis::deleteFlow(const char *name)
+{
+    FlowHashmap::iterator itr = flowTable.find(name);
+    if (itr != flowTable.end()) {
+        delete itr->second;
+        flowTable.erase(itr);
+    }
+}
+
+/**
+ * \brief Delete all flow object commands
+ *
+ * This will also delete the flow objects and hash table entries
+ */
+void
+NanoVis::deleteFlows(Tcl_Interp *interp)
+{
+    FlowHashmap::iterator itr;
+    for (itr = flowTable.begin();
+         itr != flowTable.end(); ++itr) {
+        Tcl_DeleteCommandFromToken(interp, itr->second->getCommandToken());
+    }
+    flowTable.clear();
+}
+
+bool
+NanoVis::mapFlows()
+{
+    TRACE("Enter");
+
+    flags &= ~MAP_FLOWS;
+
+    /* 
+     * Step 1. Get the overall min and max magnitudes of all the 
+     *         flow vectors.
+     */
+    magMin = DBL_MAX, magMax = -DBL_MAX;
+
+    for (FlowHashmap::iterator itr = flowTable.begin();
+         itr != flowTable.end(); ++itr) {
+        Flow *flow = itr->second;
+        double min, max;
+        if (!flow->isDataLoaded()) {
+            continue;
+        }
+        Rappture::Unirect3d *data = flow->data();
+        min = data->magMin();
+        max = data->magMax();
+        if (min < magMin) {
+            magMin = min;
+        } 
+        if (max > magMax) {
+            magMax = max;
+        }
+        if (data->xMin() < xMin) {
+            xMin = data->xMin();
+        }
+        if (data->yMin() < yMin) {
+            yMin = data->yMin();
+        }
+        if (data->zMin() < zMin) {
+            zMin = data->zMin();
+        }
+        if (data->xMax() > xMax) {
+            xMax = data->xMax();
+        }
+        if (data->yMax() > yMax) {
+            yMax = data->yMax();
+        }
+        if (data->zMax() > zMax) {
+            zMax = data->zMax();
+        }
+    }
+
+    TRACE("magMin=%g magMax=%g", NanoVis::magMin, NanoVis::magMax);
+
+    /* 
+     * Step 2. Generate the vector field from each data set. 
+     */
+    for (FlowHashmap::iterator itr = flowTable.begin();
+         itr != flowTable.end(); ++itr) {
+        Flow *flow = itr->second;
+        if (!flow->isDataLoaded()) {
+            continue; // Flow exists, but no data has been loaded yet.
+        }
+        if (flow->visible()) {
+            flow->initializeParticles();
+        }
+        if (!flow->scaleVectorField()) {
+            return false;
+        }
+        // FIXME: This doesn't work when there is more than one flow.
+        licRenderer->setOffset(flow->getRelativePosition());
+        velocityArrowsSlice->slicePos(flow->getRelativePosition());
+    }
+    advectFlows();
+    return true;
+}
+
+void
+NanoVis::getFlowBounds(Vector3f& min,
+                       Vector3f& max,
+                       bool onlyVisible)
+{
+    TRACE("Enter");
+
+    min.set(FLT_MAX, FLT_MAX, FLT_MAX);
+    max.set(-FLT_MAX, -FLT_MAX, -FLT_MAX);
+
+    for (FlowHashmap::iterator itr = flowTable.begin();
+         itr != flowTable.end(); ++itr) {
+        itr->second->getBounds(min, max, onlyVisible);
+    }
+}
+
+void
+NanoVis::renderFlows()
+{
+    for (FlowHashmap::iterator itr = flowTable.begin();
+         itr != flowTable.end(); ++itr) {
+        Flow *flow = itr->second;
+        if (flow->isDataLoaded() && flow->visible()) {
+            flow->render();
+        }
+    }
+    flags &= ~REDRAW_PENDING;
+}
+
+void
+NanoVis::resetFlows()
+{
+    if (licRenderer->active()) {
+        NanoVis::licRenderer->reset();
+    }
+    for (FlowHashmap::iterator itr = flowTable.begin();
+         itr != flowTable.end(); ++itr) {
+        Flow *flow = itr->second;
+        if (flow->isDataLoaded() && flow->visible()) {
+            flow->resetParticles();
+        }
+    }
+}    
+
+void
+NanoVis::advectFlows()
+{
+    for (FlowHashmap::iterator itr = flowTable.begin();
+         itr != flowTable.end(); ++itr) {
+        Flow *flow = itr->second;
+        if (flow->isDataLoaded() && flow->visible()) {
+            flow->advect();
+        }
+    }
 }
 
@@ -1652,7 +1792,7 @@
     bindOffscreenBuffer();
 
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear screen
-
-    //3D rendering mode
+    //clear screen
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
     glEnable(GL_DEPTH_TEST);
     glEnable(GL_COLOR_MATERIAL);
@@ -1701,9 +1841,4 @@
         velocityArrowsSlice->render();
     }
-#ifdef notdef
-    if ((flowVisRenderer != NULL) && (flowVisRenderer->active())) {
-        flowVisRenderer->render();
-    }
-#endif
     if (!flowTable.empty()) {
         renderFlows();
@@ -1826,14 +1961,7 @@
         exitService(90);
     }
-#ifdef DO_RLE
-    doRle();
-    int sizes[2] = {  offsets_size*sizeof(offsets[0]), rle_size };
-    TRACE("Writing %d,%d", sizes[0], sizes[1]); 
-    write(1, &sizes, sizeof(sizes));
-    write(1, offsets, offsets_size*sizeof(offsets[0]));
-    write(1, rle, rle_size);    //unsigned byte
-#else
+
     ppmWrite("nv>image -type image -bytes");
-#endif
+
     TRACE("Leave");
 }
Index: /nanovis/branches/1.1/nanovis.h
===================================================================
--- /nanovis/branches/1.1/nanovis.h	(revision 4611)
+++ /nanovis/branches/1.1/nanovis.h	(revision 4612)
@@ -51,5 +51,4 @@
 class PointSetRenderer;
 class NvParticleRenderer;
-class NvFlowVisRenderer;
 class PlaneRenderer;
 class VelocityArrowsSlice;
@@ -58,10 +57,9 @@
 class Texture2D;
 class HeightMap;
-class NvVectorField;
 class Grid;
 class NvCamera;
 class TransferFunction;
 class Volume;
-class FlowCmd;
+class Flow;
 
 class NanoVis
@@ -88,5 +86,5 @@
     typedef std::tr1::unordered_map<TransferFunctionId, TransferFunction *> TransferFunctionHashmap;
     typedef std::tr1::unordered_map<VolumeId, Volume *> VolumeHashmap;
-    typedef std::tr1::unordered_map<FlowId, FlowCmd *> FlowHashmap;
+    typedef std::tr1::unordered_map<FlowId, Flow *> FlowHashmap;
     typedef std::tr1::unordered_map<HeightMapId, HeightMap *> HeightMapHashmap;
 
@@ -134,8 +132,8 @@
 
     static Volume *loadVolume(const char *tag, int width, int height, int depth,
-                              int n, float* data, double vmin, double vmax, 
+                              int numComponents, float *data, double vmin, double vmax, 
                               double nonZeroMin);
 
-    static void removeVolume(Volume *volPtr);
+    static void removeVolume(Volume *volume);
 
     static void readScreen()
@@ -149,6 +147,6 @@
     }
 
-    static FlowCmd *getFlow(const char *name);
-    static FlowCmd *createFlow(Tcl_Interp *interp, const char *name);
+    static Flow *getFlow(const char *name);
+    static Flow *createFlow(Tcl_Interp *interp, const char *name);
     static void deleteFlow(const char *name);
     static void deleteFlows(Tcl_Interp *interp);
@@ -190,7 +188,4 @@
 
     static VolumeRenderer *volRenderer;
-#ifdef notdef
-    static NvFlowVisRenderer *flowVisRenderer;
-#endif
     static VelocityArrowsSlice *velocityArrowsSlice;
     static NvLIC *licRenderer;
