Ignore:
Timestamp:
Jun 22, 2011 3:39:41 PM (13 years ago)
Author:
ldelgass
Message:
  • Add contour3d (isosurface geometry) command to vtkvis
  • Use depth peeling algorithm (order independent transparency) by default, add 'renderer depthpeel' command to toggle.
  • Use tri strips in some geometry generators for better performance
  • Heightmap: 2D slice resampling of non-image 3D datasets (e.g. points, ugrids) Set a default scaling based on data range. Still some problems where images from resampling have zero values in out-of-bounds pixels (probe filter creates a mask array that could be used). Still need a method/heuristic to select image resolution when resampling.
Location:
trunk/packages/vizservers/vtkvis
Files:
2 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/vizservers/vtkvis/Makefile.in

    r2269 r2290  
    7676                PPMWriter.cpp \
    7777                RpContour2D.cpp \
     78                RpContour3D.cpp \
    7879                RpGlyphs.cpp \
    7980                RpHeightMap.cpp \
     
    126127PPMWriter.o: PPMWriter.h Trace.h
    127128RpContour2D.o: RpContour2D.h RpVtkDataSet.h Trace.h
     129RpContour3D.o: RpContour3D.h RpVtkDataSet.h Trace.h
    128130RpPolyData.o: RpPolyData.h RpVtkDataSet.h Trace.h
    129131RpGlyphs.o: RpGlyphs.h RpVtkDataSet.h ColorMap.h Trace.h
  • trunk/packages/vizservers/vtkvis/RpContour2D.cpp

    r2270 r2290  
    115115    }
    116116
     117    vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
     118
    117119    if (ds->GetPointData() == NULL ||
    118120        ds->GetPointData()->GetScalars() == NULL) {
     
    120122        if (ds->GetCellData() != NULL &&
    121123            ds->GetCellData()->GetScalars() != NULL) {
    122             vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
    123124            cellToPtData =
    124125                vtkSmartPointer<vtkCellDataToPointData>::New();
  • trunk/packages/vizservers/vtkvis/RpGlyphs.cpp

    r2271 r2290  
    147147    setGlyphShape(_glyphShape);
    148148
     149    vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
     150
    149151    if (ds->GetPointData() == NULL ||
    150152        ds->GetPointData()->GetScalars() == NULL) {
     
    152154        if (ds->GetCellData() != NULL &&
    153155            ds->GetCellData()->GetScalars() != NULL) {
    154             vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
    155156            cellToPtData =
    156157                vtkSmartPointer<vtkCellDataToPointData>::New();
  • trunk/packages/vizservers/vtkvis/RpHeightMap.cpp

    r2270 r2290  
    2020#include <vtkDelaunay2D.h>
    2121#include <vtkDelaunay3D.h>
     22#include <vtkProbeFilter.h>
    2223#include <vtkGaussianSplatter.h>
    2324#include <vtkExtractVOI.h>
     
    3233using namespace Rappture::VtkVis;
    3334
    34 //#define MESH_POINTS
     35#define MESH_POINT_CLOUDS
    3536
    3637HeightMap::HeightMap() :
     
    4142    _opacity(1.0),
    4243    _warpScale(1.0),
     44    _sliceAxis(Z_AXIS),
    4345    _pipelineInitialized(false)
    4446{
     
    7880            _dataRange[0] = dataRange[0];
    7981            _dataRange[1] = dataRange[1];
     82
     83            // Compute a data scaling factor to make maximum
     84            // height (at default _warpScale) equivalent to
     85            // largest dimension of data set
     86            double bounds[6];
     87            double boundsRange = 0.0;
     88            _dataSet->getBounds(bounds);
     89            for (int i = 0; i < 6; i+=2) {
     90                double r = bounds[i+1] - bounds[i];
     91                if (r > boundsRange)
     92                    boundsRange = r;
     93            }
     94            double datRange = _dataRange[1] - _dataRange[0];
     95            if (datRange < 1.0e-10) {
     96                _dataScale = 1.0;
     97            } else {
     98                _dataScale = boundsRange / datRange;
     99            }
     100            TRACE("Bounds range: %g data range: %g scaling: %g",
     101                  boundsRange, datRange, _dataScale);
    80102        }
    81103
     
    115137
    116138    if (!_pipelineInitialized) {
     139        vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
     140
    117141        if (ds->GetPointData() == NULL ||
    118142            ds->GetPointData()->GetScalars() == NULL) {
     
    120144            if (ds->GetCellData() != NULL &&
    121145                ds->GetCellData()->GetScalars() != NULL) {
    122                 vtkSmartPointer<vtkCellDataToPointData> cellToPtData;
    123146                cellToPtData =
    124147                    vtkSmartPointer<vtkCellDataToPointData>::New();
     
    141164                // DataSet is a point cloud
    142165                if (_dataSet->is2D()) {
    143 #ifdef MESH_POINTS
     166#ifdef MESH_POINT_CLOUDS
     167                    // Result of Delaunay2D is a PolyData
    144168                    vtkSmartPointer<vtkDelaunay2D> mesher = vtkSmartPointer<vtkDelaunay2D>::New();
    145169                    mesher->SetInput(pd);
     
    169193                    _volumeSlicer->SetSampleRate(1, 1, 1);
    170194                    vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
     195                    gf->UseStripsOn();
    171196                    gf->SetInputConnection(_volumeSlicer->GetOutputPort());
    172197                    vtkAlgorithmOutput *warpOutput = initWarp(gf->GetOutputPort());
     
    175200#endif
    176201                } else {
    177 #ifdef MESH_POINTS
     202#ifdef MESH_POINT_CLOUDS
     203                    // Data Set is a 3D point cloud
     204                    // Result of Delaunay3D mesher is unstructured grid
    178205                    vtkSmartPointer<vtkDelaunay3D> mesher = vtkSmartPointer<vtkDelaunay3D>::New();
    179206                    mesher->SetInput(pd);
     207                    // Run the mesher
     208                    mesher->Update();
     209                    // Get bounds of resulting grid
     210                    double bounds[6];
     211                    mesher->GetOutput()->GetBounds(bounds);
     212                    // Sample a plane within the grid bounding box
     213                    if (_probeFilter == NULL)
     214                        _probeFilter = vtkSmartPointer<vtkProbeFilter>::New();
     215                    _probeFilter->SetSourceConnection(mesher->GetOutputPort());
     216                    vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::New();
     217                    int xdim = 256;
     218                    int ydim = 256;
     219                    int zdim = 1;
     220                    imageData->SetDimensions(xdim, ydim, zdim);
     221                    imageData->SetOrigin(bounds[0], bounds[2], bounds[4] + (bounds[5]-bounds[4])/2.);
     222                    imageData->SetSpacing((bounds[1]-bounds[0])/((double)(xdim-1)),
     223                                          (bounds[3]-bounds[2])/((double)(ydim-1)),
     224                                          0);
     225                    _probeFilter->SetInput(imageData);
    180226                    vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
    181                     gf->SetInputConnection(mesher->GetOutputPort());
     227                    gf->UseStripsOn();
     228                    gf->SetInputConnection(_probeFilter->GetOutputPort());
    182229#else
    183230                    if (_pointSplatter == NULL)
     
    202249                    _volumeSlicer->SetSampleRate(1, 1, 1);
    203250                    vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
     251                    gf->UseStripsOn();
    204252                    gf->SetInputConnection(_volumeSlicer->GetOutputPort());
    205253#endif
     
    223271            // Can be: image/volume/uniform grid, structured grid, unstructured grid, rectilinear grid
    224272            vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
     273            gf->UseStripsOn();
    225274            vtkImageData *imageData = vtkImageData::SafeDownCast(ds);
    226275            if (!_dataSet->is2D() && imageData != NULL) {
     
    235284                _volumeSlicer->SetSampleRate(1, 1, 1);
    236285                gf->SetInputConnection(_volumeSlicer->GetOutputPort());
     286            } else if (imageData == NULL) {
     287                // structured grid, unstructured grid, or rectilinear grid
     288                double bounds[6];
     289                ds->GetBounds(bounds);
     290                // Sample a plane within the grid bounding box
     291                if (_probeFilter == NULL)
     292                    _probeFilter = vtkSmartPointer<vtkProbeFilter>::New();
     293                _probeFilter->SetSource(ds);
     294                vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::New();
     295                int xdim = 256;
     296                int ydim = 256;
     297                int zdim = 1;
     298                imageData->SetDimensions(xdim, ydim, zdim);
     299                imageData->SetOrigin(bounds[0], bounds[2], bounds[4] + (bounds[5]-bounds[4])/2.);
     300                imageData->SetSpacing((bounds[1]-bounds[0])/((double)(xdim-1)),
     301                                      (bounds[3]-bounds[2])/((double)(ydim-1)),
     302                                      0);
     303                _probeFilter->SetInput(imageData);
     304                gf->SetInputConnection(_probeFilter->GetOutputPort());
    237305            } else {
    238                 // 2D image data, structured grid, unstructured grid, or rectilinear grid
     306                // 2D image data
    239307                gf->SetInput(ds);
    240308            }
     
    269337    initProp();
    270338
     339    _dsMapper->SetColorModeToMapScalars();
    271340    _dsMapper->UseLookupTableScalarRangeOn();
    272341    _dsMapper->SetLookupTable(_lut);
     
    325394        if (_warp == NULL)
    326395            _warp = vtkSmartPointer<vtkWarpScalar>::New();
    327         _warp->SetNormal(0, 0, 1);
     396        switch (_sliceAxis) {
     397        case X_AXIS:
     398            _warp->SetNormal(1, 0, 0);
     399            break;
     400        case Y_AXIS:
     401            _warp->SetNormal(0, 1, 0);
     402            break;
     403        default:
     404            _warp->SetNormal(0, 0, 1);
     405        }
    328406        _warp->UseNormalOn();
    329         _warp->SetScaleFactor(_warpScale);
     407        _warp->SetScaleFactor(_warpScale * _dataScale);
    330408        _warp->SetInputConnection(input);
    331409        return _warp->GetOutputPort();
     
    345423        if (_warp == NULL)
    346424            _warp = vtkSmartPointer<vtkWarpScalar>::New();
    347         _warp->SetNormal(0, 0, 1);
     425        switch (_sliceAxis) {
     426        case X_AXIS:
     427            _warp->SetNormal(1, 0, 0);
     428            break;
     429        case Y_AXIS:
     430            _warp->SetNormal(0, 1, 0);
     431            break;
     432        default:
     433            _warp->SetNormal(0, 0, 1);
     434        }
    348435        _warp->UseNormalOn();
    349         _warp->SetScaleFactor(_warpScale);
     436        _warp->SetScaleFactor(_warpScale * _dataScale);
    350437        _warp->SetInput(pdInput);
    351438        return _warp->GetOutputPort();
     
    369456        _warp = NULL;
    370457    } else {
    371         _warp->SetScaleFactor(_warpScale);
     458        _warp->SetScaleFactor(_warpScale * _dataScale);
    372459    }
    373460
     
    385472    }
    386473
    387     if (_warp == NULL ||
    388         _volumeSlicer == NULL) {
     474    if (_volumeSlicer == NULL &&
     475         _probeFilter == NULL) {
    389476        WARN("Called before update() or DataSet is not a volume");
    390477        return;
     
    392479
    393480    int dims[3];
    394     int voi[6];
    395481
    396482    if (_pointSplatter != NULL) {
     
    399485        vtkImageData *imageData = vtkImageData::SafeDownCast(_dataSet->getVtkDataSet());
    400486        if (imageData == NULL) {
    401             ERROR("Not a volume data set");
     487            if (_probeFilter != NULL) {
     488                imageData = vtkImageData::SafeDownCast(_probeFilter->GetInput());
     489                if (imageData == NULL) {
     490                    ERROR("Couldn't get probe filter input image");
     491                    return;
     492                }
     493            } else {
     494                ERROR("Not a volume data set");
     495                return;
     496            }
     497        }
     498        imageData->GetDimensions(dims);
     499    }
     500
     501    _sliceAxis = axis;
     502    if (_warp != NULL) {
     503        switch (axis) {
     504        case X_AXIS:
     505            _warp->SetNormal(1, 0, 0);
     506            break;
     507        case Y_AXIS:
     508            _warp->SetNormal(0, 1, 0);
     509            break;
     510        case Z_AXIS:
     511            _warp->SetNormal(0, 0, 1);
     512            break;
     513        default:
     514            ERROR("Invalid Axis");
    402515            return;
    403516        }
    404         imageData->GetDimensions(dims);
    405     }
    406 
    407     switch (axis) {
    408     case X_AXIS:
    409         voi[0] = voi[1] = (int)((dims[0]-1) * ratio);
    410         voi[2] = 0;
    411         voi[3] = dims[1]-1;
    412         voi[4] = 0;
    413         voi[5] = dims[2]-1;
    414         _warp->SetNormal(1, 0, 0);
    415         break;
    416     case Y_AXIS:
    417         voi[2] = voi[3] = (int)((dims[1]-1) * ratio);
    418         voi[0] = 0;
    419         voi[1] = dims[0]-1;
    420         voi[4] = 0;
    421         voi[5] = dims[2]-1;
    422         _warp->SetNormal(0, 1, 0);
    423         break;
    424     case Z_AXIS:
    425         voi[4] = voi[5] = (int)((dims[2]-1) * ratio);
    426         voi[0] = 0;
    427         voi[1] = dims[0]-1;
    428         voi[2] = 0;
    429         voi[3] = dims[1]-1;
    430         _warp->SetNormal(0, 0, 1);
    431         break;
    432     default:
    433         ERROR("Invalid Axis");
    434         return;
    435     }
    436 
    437     _volumeSlicer->SetVOI(voi[0], voi[1], voi[2], voi[3], voi[4], voi[5]);
     517    }
     518
     519    if (_probeFilter != NULL) {
     520        vtkImageData *imageData = vtkImageData::SafeDownCast(_probeFilter->GetInput());
     521        double bounds[6];
     522        assert(vtkDataSet::SafeDownCast(_probeFilter->GetSource()) != NULL);
     523        vtkDataSet::SafeDownCast(_probeFilter->GetSource())->GetBounds(bounds);
     524        int dim = 256;
     525
     526        switch (axis) {
     527        case X_AXIS:
     528            imageData->SetDimensions(1, dim, dim);
     529            imageData->SetOrigin(bounds[0] + (bounds[1]-bounds[0])*ratio, bounds[2], bounds[4]);
     530            imageData->SetSpacing(0,
     531                                  (bounds[3]-bounds[2])/((double)(dim-1)),
     532                                  (bounds[5]-bounds[4])/((double)(dim-1)));
     533            break;
     534        case Y_AXIS:
     535            imageData->SetDimensions(dim, 1, dim);
     536            imageData->SetOrigin(bounds[0], bounds[2] + (bounds[3]-bounds[2])*ratio, bounds[4]);
     537            imageData->SetSpacing((bounds[1]-bounds[0])/((double)(dim-1)),
     538                                  0,
     539                                  (bounds[5]-bounds[4])/((double)(dim-1)));
     540            break;
     541        case Z_AXIS:
     542            imageData->SetDimensions(dim, dim, 1);
     543            imageData->SetOrigin(bounds[0], bounds[2], bounds[4] + (bounds[5]-bounds[4])*ratio);
     544            imageData->SetSpacing((bounds[1]-bounds[0])/((double)(dim-1)),
     545                                  (bounds[3]-bounds[2])/((double)(dim-1)),
     546                                  0);
     547            break;
     548        default:
     549            ERROR("Invalid Axis");
     550            return;
     551        }
     552    } else {
     553        int voi[6];
     554
     555        switch (axis) {
     556        case X_AXIS:
     557            voi[0] = voi[1] = (int)((dims[0]-1) * ratio);
     558            voi[2] = 0;
     559            voi[3] = dims[1]-1;
     560            voi[4] = 0;
     561            voi[5] = dims[2]-1;
     562            break;
     563        case Y_AXIS:
     564            voi[2] = voi[3] = (int)((dims[1]-1) * ratio);
     565            voi[0] = 0;
     566            voi[1] = dims[0]-1;
     567            voi[4] = 0;
     568            voi[5] = dims[2]-1;
     569            break;
     570        case Z_AXIS:
     571            voi[4] = voi[5] = (int)((dims[2]-1) * ratio);
     572            voi[0] = 0;
     573            voi[1] = dims[0]-1;
     574            voi[2] = 0;
     575            voi[3] = dims[1]-1;
     576            break;
     577        default:
     578            ERROR("Invalid Axis");
     579            return;
     580        }
     581
     582        _volumeSlicer->SetVOI(voi[0], voi[1], voi[2], voi[3], voi[4], voi[5]);
     583    }
     584
    438585    if (_dsMapper != NULL)
    439586        _dsMapper->Update();
  • trunk/packages/vizservers/vtkvis/RpHeightMap.h

    r2270 r2290  
    1212#include <vtkAlgorithmOutput.h>
    1313#include <vtkContourFilter.h>
     14#include <vtkProbeFilter.h>
    1415#include <vtkLookupTable.h>
    1516#include <vtkDataSetMapper.h>
     
    107108    double _opacity;
    108109    double _warpScale;
     110    double _dataScale;
     111    Axis _sliceAxis;
    109112    bool _pipelineInitialized;
    110113
     
    114117    vtkSmartPointer<vtkPolyDataMapper> _contourMapper;
    115118    vtkSmartPointer<vtkGaussianSplatter> _pointSplatter;
     119    vtkSmartPointer<vtkProbeFilter> _probeFilter;
    116120    vtkSmartPointer<vtkExtractVOI> _volumeSlicer;
    117121    vtkSmartPointer<vtkWarpScalar> _warp;
  • trunk/packages/vizservers/vtkvis/RpPseudoColor.cpp

    r2270 r2290  
    2424#include "Trace.h"
    2525
     26#define MESH_POINT_CLOUDS
     27
    2628using namespace Rappture::VtkVis;
    2729
     
    9395            // DataSet is a point cloud
    9496            if (_dataSet->is2D()) {
    95 #if 0
     97#ifdef MESH_POINT_CLOUDS
    9698                vtkSmartPointer<vtkDelaunay2D> mesher = vtkSmartPointer<vtkDelaunay2D>::New();
    9799                mesher->SetInput(pd);
    98                 _dsMapper->SetInputConnection(mesher->GetOutputPort());
     100                vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
     101                gf->SetInputConnection(mesher->GetOutputPort());
     102                _dsMapper->SetInputConnection(gf->GetOutputPort());
    99103#else
    100104                vtkSmartPointer<vtkGaussianSplatter> splatter = vtkSmartPointer<vtkGaussianSplatter>::New();
     
    117121                slicer->SetSampleRate(1, 1, 1);
    118122                vtkSmartPointer<vtkDataSetSurfaceFilter> gf = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
     123                gf->UseStripsOn();
    119124                gf->SetInputConnection(slicer->GetOutputPort());
    120125                _dsMapper->SetInputConnection(gf->GetOutputPort());
     
    158163    _lut->SetRange(dataRange);
    159164
     165    _dsMapper->SetColorModeToMapScalars();
    160166    _dsMapper->UseLookupTableScalarRangeOn();
    161167    _dsMapper->SetLookupTable(_lut);
  • trunk/packages/vizservers/vtkvis/RpVtkDataSet.cpp

    r2270 r2290  
    124124    TRACE("DataSet class: %s", _dataSet->GetClassName());
    125125    TRACE("Scalar Range: %.12e, %.12e", _dataRange[0], _dataRange[1]);
     126    TRACE("DataSet bounds: %g %g %g %g %g %g",
     127          _bounds[0], _bounds[1],
     128          _bounds[2], _bounds[3],
     129          _bounds[4], _bounds[5]);
    126130    return true;
    127131}
     
    141145    TRACE("DataSet class: %s", _dataSet->GetClassName());
    142146    TRACE("Scalar Range: %.12e, %.12e", _dataRange[0], _dataRange[1]);
     147    TRACE("DataSet bounds: %g %g %g %g %g %g",
     148          _bounds[0], _bounds[1],
     149          _bounds[2], _bounds[3],
     150          _bounds[4], _bounds[5]);
    143151    return true;
    144152}
     
    217225void DataSet::getDataRange(double minmax[2])
    218226{
    219     minmax[0] = _dataRange[0];
    220     minmax[1] = _dataRange[1];
     227    memcpy(minmax, _dataRange, sizeof(double)*2);
     228}
     229
     230/**
     231 * \brief Get the bounds the DataSet
     232 */
     233void DataSet::getBounds(double bounds[6])
     234{
     235    memcpy(bounds, _bounds, sizeof(double)*6);
    221236}
    222237
  • trunk/packages/vizservers/vtkvis/RpVtkDataSet.h

    r2270 r2290  
    4747    void getDataRange(double minmax[2]);
    4848
     49    void getBounds(double bounds[6]);
     50
    4951    double getDataValue(double x, double y, double z);
    5052
  • trunk/packages/vizservers/vtkvis/RpVtkRenderer.cpp

    r2277 r2290  
    104104#endif
    105105    _renderWindow->SetSize(_windowWidth, _windowHeight);
     106    // Next 2 options needed to support depth peeling
     107    _renderWindow->SetAlphaBitPlanes(1);
     108    _renderWindow->SetMultiSamples(0);
     109    _renderer->SetMaximumNumberOfPeels(100);
     110    _renderer->SetUseDepthPeeling(1);
    106111    _renderWindow->AddRenderer(_renderer);
    107112    addColorMap("default", ColorMap::getDefault());
     
    112117{
    113118    TRACE("Enter");
    114     TRACE("Deleting Contours");
    115     for (Contour2DHashmap::iterator itr = _contours.begin();
    116              itr != _contours.end(); ++itr) {
     119    TRACE("Deleting Contour2Ds");
     120    for (Contour2DHashmap::iterator itr = _contour2Ds.begin();
     121             itr != _contour2Ds.end(); ++itr) {
    117122        delete itr->second;
    118123    }
    119     _contours.clear();
     124    _contour2Ds.clear();
     125    TRACE("Deleting Contour3Ds");
     126    for (Contour3DHashmap::iterator itr = _contour3Ds.begin();
     127             itr != _contour3Ds.end(); ++itr) {
     128        delete itr->second;
     129    }
     130    _contour3Ds.clear();
    120131    TRACE("Deleting Glyphs");
    121132    for (GlyphsHashmap::iterator itr = _glyphs.begin();
     
    169180 *
    170181 * This just adds the DataSet to the Renderer's list of data sets.
    171  * In order to render the data, a PseudoColor or Contour2D must
    172  * be added to the Renderer.
     182 * In order to render the data, a graphics object using the data
     183 * set must be added to the Renderer.
    173184 */
    174185void Renderer::addDataSet(const DataSetId& id)
     
    193204
    194205    if (id.compare("all") == 0) {
    195         itr = _contours.begin();
    196         doAll = true;
    197     } else {
    198         itr = _contours.find(id);
    199     }
    200     if (itr == _contours.end()) {
     206        itr = _contour2Ds.begin();
     207        doAll = true;
     208    } else {
     209        itr = _contour2Ds.find(id);
     210    }
     211    if (itr == _contour2Ds.end()) {
    201212        ERROR("Contour2D not found: %s", id.c_str());
    202213        return;
     
    211222        delete contour;
    212223
    213         itr = _contours.erase(itr);
    214     } while (doAll && itr != _contours.end());
     224        itr = _contour2Ds.erase(itr);
     225    } while (doAll && itr != _contour2Ds.end());
     226
     227    _needsRedraw = true;
     228}
     229
     230/**
     231 * \brief Remove the Contour3D isosurfaces for the specified DataSet
     232 *
     233 * The underlying Contour3D is deleted, freeing its memory
     234 */
     235void Renderer::deleteContour3D(const DataSetId& id)
     236{
     237    Contour3DHashmap::iterator itr;
     238
     239    bool doAll = false;
     240
     241    if (id.compare("all") == 0) {
     242        itr = _contour3Ds.begin();
     243        doAll = true;
     244    } else {
     245        itr = _contour3Ds.find(id);
     246    }
     247    if (itr == _contour3Ds.end()) {
     248        ERROR("Contour3D not found: %s", id.c_str());
     249        return;
     250    }
     251
     252    TRACE("Deleting Contour3Ds for %s", id.c_str());
     253
     254    do {
     255        Contour3D *contour = itr->second;
     256        if (contour->getProp())
     257            _renderer->RemoveViewProp(contour->getProp());
     258        delete contour;
     259
     260        itr = _contour3Ds.erase(itr);
     261    } while (doAll && itr != _contour3Ds.end());
    215262
    216263    _needsRedraw = true;
     
    424471
    425472        deleteContour2D(itr->second->getName());
     473        deleteContour3D(itr->second->getName());
    426474        deleteGlyphs(itr->second->getName());
    427475        deleteHeightMap(itr->second->getName());
     
    9821030
    9831031        Contour2D *contour = new Contour2D();
    984         _contours[dsID] = contour;
     1032        _contour2Ds[dsID] = contour;
    9851033
    9861034        contour->setDataSet(ds);
     
    9981046Contour2D *Renderer::getContour2D(const DataSetId& id)
    9991047{
    1000     Contour2DHashmap::iterator itr = _contours.find(id);
    1001 
    1002     if (itr == _contours.end()) {
     1048    Contour2DHashmap::iterator itr = _contour2Ds.find(id);
     1049
     1050    if (itr == _contour2Ds.end()) {
    10031051        TRACE("Contour2D not found: %s", id.c_str());
    10041052        return NULL;
     
    10101058 * \brief Set the number of equally spaced contour isolines for the given DataSet
    10111059 */
    1012 void Renderer::setContours(const DataSetId& id, int numContours)
     1060void Renderer::setContour2DContours(const DataSetId& id, int numContours)
    10131061{
    10141062    Contour2DHashmap::iterator itr;
     
    10171065
    10181066    if (id.compare("all") == 0) {
    1019         itr = _contours.begin();
    1020         doAll = true;
    1021     } else {
    1022         itr = _contours.find(id);
    1023     }
    1024     if (itr == _contours.end()) {
     1067        itr = _contour2Ds.begin();
     1068        doAll = true;
     1069    } else {
     1070        itr = _contour2Ds.find(id);
     1071    }
     1072    if (itr == _contour2Ds.end()) {
    10251073        ERROR("Contour2D not found: %s", id.c_str());
    10261074        return;
     
    10331081            itr->second->setContours(numContours);
    10341082        }
    1035     } while (doAll && ++itr != _contours.end());
     1083    } while (doAll && ++itr != _contour2Ds.end());
    10361084
    10371085    _needsRedraw = true;
     
    10411089 * \brief Set a list of isovalues for the given DataSet
    10421090 */
    1043 void Renderer::setContourList(const DataSetId& id, const std::vector<double>& contours)
     1091void Renderer::setContour2DContourList(const DataSetId& id, const std::vector<double>& contours)
    10441092{
    10451093    Contour2DHashmap::iterator itr;
     
    10481096
    10491097    if (id.compare("all") == 0) {
    1050         itr = _contours.begin();
    1051         doAll = true;
    1052     } else {
    1053         itr = _contours.find(id);
    1054     }
    1055     if (itr == _contours.end()) {
     1098        itr = _contour2Ds.begin();
     1099        doAll = true;
     1100    } else {
     1101        itr = _contour2Ds.find(id);
     1102    }
     1103    if (itr == _contour2Ds.end()) {
    10561104        ERROR("Contour2D not found: %s", id.c_str());
    10571105        return;
     
    10601108    do {
    10611109        itr->second->setContourList(contours);
    1062     } while (doAll && ++itr != _contours.end());
     1110    } while (doAll && ++itr != _contour2Ds.end());
    10631111
    10641112     _needsRedraw = true;
     
    10681116 * \brief Set opacity of contour lines for the given DataSet
    10691117 */
    1070 void Renderer::setContourOpacity(const DataSetId& id, double opacity)
     1118void Renderer::setContour2DOpacity(const DataSetId& id, double opacity)
    10711119{
    10721120    Contour2DHashmap::iterator itr;
     
    10751123
    10761124    if (id.compare("all") == 0) {
    1077         itr = _contours.begin();
    1078         doAll = true;
    1079     } else {
    1080         itr = _contours.find(id);
    1081     }
    1082     if (itr == _contours.end()) {
     1125        itr = _contour2Ds.begin();
     1126        doAll = true;
     1127    } else {
     1128        itr = _contour2Ds.find(id);
     1129    }
     1130    if (itr == _contour2Ds.end()) {
    10831131        ERROR("Contour2D not found: %s", id.c_str());
    10841132        return;
     
    10871135    do {
    10881136        itr->second->setOpacity(opacity);
    1089     } while (doAll && ++itr != _contours.end());
     1137    } while (doAll && ++itr != _contour2Ds.end());
    10901138
    10911139    _needsRedraw = true;
     
    10951143 * \brief Turn on/off rendering contour lines for the given DataSet
    10961144 */
    1097 void Renderer::setContourVisibility(const DataSetId& id, bool state)
     1145void Renderer::setContour2DVisibility(const DataSetId& id, bool state)
    10981146{
    10991147    Contour2DHashmap::iterator itr;
     
    11021150
    11031151    if (id.compare("all") == 0) {
    1104         itr = _contours.begin();
    1105         doAll = true;
    1106     } else {
    1107         itr = _contours.find(id);
    1108     }
    1109     if (itr == _contours.end()) {
     1152        itr = _contour2Ds.begin();
     1153        doAll = true;
     1154    } else {
     1155        itr = _contour2Ds.find(id);
     1156    }
     1157    if (itr == _contour2Ds.end()) {
    11101158        ERROR("Contour2D not found: %s", id.c_str());
    11111159        return;
     
    11141162    do {
    11151163        itr->second->setVisibility(state);
    1116     } while (doAll && ++itr != _contours.end());
     1164    } while (doAll && ++itr != _contour2Ds.end());
    11171165
    11181166    _needsRedraw = true;
     
    11221170 * \brief Set the RGB isoline color for the specified DataSet
    11231171 */
    1124 void Renderer::setContourEdgeColor(const DataSetId& id, float color[3])
     1172void Renderer::setContour2DEdgeColor(const DataSetId& id, float color[3])
    11251173{
    11261174    Contour2DHashmap::iterator itr;
     
    11291177
    11301178    if (id.compare("all") == 0) {
    1131         itr = _contours.begin();
    1132         doAll = true;
    1133     } else {
    1134         itr = _contours.find(id);
    1135     }
    1136     if (itr == _contours.end()) {
     1179        itr = _contour2Ds.begin();
     1180        doAll = true;
     1181    } else {
     1182        itr = _contour2Ds.find(id);
     1183    }
     1184    if (itr == _contour2Ds.end()) {
    11371185        ERROR("Contour2D not found: %s", id.c_str());
    11381186        return;
     
    11411189    do {
    11421190        itr->second->setEdgeColor(color);
    1143     } while (doAll && ++itr != _contours.end());
     1191    } while (doAll && ++itr != _contour2Ds.end());
    11441192
    11451193    _needsRedraw = true;
     
    11521200 * this function may not have an effect.
    11531201 */
    1154 void Renderer::setContourEdgeWidth(const DataSetId& id, float edgeWidth)
     1202void Renderer::setContour2DEdgeWidth(const DataSetId& id, float edgeWidth)
    11551203{
    11561204    Contour2DHashmap::iterator itr;
     
    11591207
    11601208    if (id.compare("all") == 0) {
    1161         itr = _contours.begin();
    1162         doAll = true;
    1163     } else {
    1164         itr = _contours.find(id);
    1165     }
    1166     if (itr == _contours.end()) {
     1209        itr = _contour2Ds.begin();
     1210        doAll = true;
     1211    } else {
     1212        itr = _contour2Ds.find(id);
     1213    }
     1214    if (itr == _contour2Ds.end()) {
    11671215        ERROR("Contour2D not found: %s", id.c_str());
    11681216        return;
     
    11711219    do {
    11721220        itr->second->setEdgeWidth(edgeWidth);
    1173     } while (doAll && ++itr != _contours.end());
     1221    } while (doAll && ++itr != _contour2Ds.end());
    11741222
    11751223    _needsRedraw = true;
     
    11791227 * \brief Turn contour lighting on/off for the specified DataSet
    11801228 */
    1181 void Renderer::setContourLighting(const DataSetId& id, bool state)
     1229void Renderer::setContour2DLighting(const DataSetId& id, bool state)
    11821230{
    11831231    Contour2DHashmap::iterator itr;
     
    11861234
    11871235    if (id.compare("all") == 0) {
    1188         itr = _contours.begin();
    1189         doAll = true;
    1190     } else {
    1191         itr = _contours.find(id);
    1192     }
    1193     if (itr == _contours.end()) {
     1236        itr = _contour2Ds.begin();
     1237        doAll = true;
     1238    } else {
     1239        itr = _contour2Ds.find(id);
     1240    }
     1241    if (itr == _contour2Ds.end()) {
    11941242        ERROR("Contour2D not found: %s", id.c_str());
    11951243        return;
     
    11981246    do {
    11991247        itr->second->setLighting(state);
    1200     } while (doAll && ++itr != _contours.end());
     1248    } while (doAll && ++itr != _contour2Ds.end());
     1249    _needsRedraw = true;
     1250}
     1251
     1252/**
     1253 * \brief Create a new Contour3D and associate it with the named DataSet
     1254 */
     1255void Renderer::addContour3D(const DataSetId& id)
     1256{
     1257    DataSetHashmap::iterator itr;
     1258
     1259    bool doAll = false;
     1260
     1261    if (id.compare("all") == 0) {
     1262        itr = _dataSets.begin();
     1263    } else {
     1264        itr = _dataSets.find(id);
     1265    }
     1266    if (itr == _dataSets.end()) {
     1267        ERROR("Unknown dataset %s", id.c_str());
     1268        return;
     1269    }
     1270
     1271    do {
     1272        DataSet *ds = itr->second;
     1273        const DataSetId& dsID = ds->getName();
     1274
     1275        if (getContour3D(dsID)) {
     1276            WARN("Replacing existing contour3d %s", dsID.c_str());
     1277            deleteContour3D(dsID);
     1278        }
     1279
     1280        Contour3D *contour = new Contour3D();
     1281        _contour3Ds[dsID] = contour;
     1282
     1283        contour->setDataSet(ds);
     1284
     1285        // Use the default color map
     1286        vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
     1287        ColorMap *cmap = getColorMap("default");
     1288        lut->DeepCopy(cmap->getLookupTable());
     1289        if (_useCumulativeRange) {
     1290            lut->SetRange(_cumulativeDataRange);
     1291        } else {
     1292            double range[2];
     1293            ds->getDataRange(range);
     1294            lut->SetRange(range);
     1295        }
     1296
     1297        contour->setLookupTable(lut);
     1298
     1299        _renderer->AddViewProp(contour->getProp());
     1300    } while (doAll && ++itr != _dataSets.end());
     1301
     1302    if (_cameraMode == IMAGE)
     1303        setCameraMode(PERSPECTIVE);
     1304    initCamera();
     1305    _needsRedraw = true;
     1306}
     1307
     1308/**
     1309 * \brief Get the Contour3D associated with a named DataSet
     1310 */
     1311Contour3D *Renderer::getContour3D(const DataSetId& id)
     1312{
     1313    Contour3DHashmap::iterator itr = _contour3Ds.find(id);
     1314
     1315    if (itr == _contour3Ds.end()) {
     1316        TRACE("Contour3D not found: %s", id.c_str());
     1317        return NULL;
     1318    } else
     1319        return itr->second;
     1320}
     1321
     1322/**
     1323 * \brief Set the number of equally spaced isosurfaces for the given DataSet
     1324 */
     1325void Renderer::setContour3DContours(const DataSetId& id, int numContours)
     1326{
     1327    Contour3DHashmap::iterator itr;
     1328
     1329    bool doAll = false;
     1330
     1331    if (id.compare("all") == 0) {
     1332        itr = _contour3Ds.begin();
     1333        doAll = true;
     1334    } else {
     1335        itr = _contour3Ds.find(id);
     1336    }
     1337    if (itr == _contour3Ds.end()) {
     1338        ERROR("Contour3D not found: %s", id.c_str());
     1339        return;
     1340    }
     1341
     1342    do {
     1343        if (_useCumulativeRange) {
     1344            itr->second->setContours(numContours, _cumulativeDataRange);
     1345        } else {
     1346            itr->second->setContours(numContours);
     1347        }
     1348    } while (doAll && ++itr != _contour3Ds.end());
     1349
     1350    initCamera();
     1351    _needsRedraw = true;
     1352}
     1353
     1354/**
     1355 * \brief Set a list of isovalues for the given DataSet
     1356 */
     1357void Renderer::setContour3DContourList(const DataSetId& id, const std::vector<double>& contours)
     1358{
     1359    Contour3DHashmap::iterator itr;
     1360
     1361    bool doAll = false;
     1362
     1363    if (id.compare("all") == 0) {
     1364        itr = _contour3Ds.begin();
     1365        doAll = true;
     1366    } else {
     1367        itr = _contour3Ds.find(id);
     1368    }
     1369    if (itr == _contour3Ds.end()) {
     1370        ERROR("Contour3D not found: %s", id.c_str());
     1371        return;
     1372    }
     1373
     1374    do {
     1375        itr->second->setContourList(contours);
     1376    } while (doAll && ++itr != _contour3Ds.end());
     1377
     1378    initCamera();
     1379     _needsRedraw = true;
     1380}
     1381
     1382/**
     1383 * \brief Set opacity of isosurfaces for the given DataSet
     1384 */
     1385void Renderer::setContour3DOpacity(const DataSetId& id, double opacity)
     1386{
     1387    Contour3DHashmap::iterator itr;
     1388
     1389    bool doAll = false;
     1390
     1391    if (id.compare("all") == 0) {
     1392        itr = _contour3Ds.begin();
     1393        doAll = true;
     1394    } else {
     1395        itr = _contour3Ds.find(id);
     1396    }
     1397    if (itr == _contour3Ds.end()) {
     1398        ERROR("Contour3D not found: %s", id.c_str());
     1399        return;
     1400    }
     1401
     1402    do {
     1403        itr->second->setOpacity(opacity);
     1404    } while (doAll && ++itr != _contour3Ds.end());
     1405
     1406    _needsRedraw = true;
     1407}
     1408
     1409/**
     1410 * \brief Turn on/off rendering isosurfaces for the given DataSet
     1411 */
     1412void Renderer::setContour3DVisibility(const DataSetId& id, bool state)
     1413{
     1414    Contour3DHashmap::iterator itr;
     1415
     1416    bool doAll = false;
     1417
     1418    if (id.compare("all") == 0) {
     1419        itr = _contour3Ds.begin();
     1420        doAll = true;
     1421    } else {
     1422        itr = _contour3Ds.find(id);
     1423    }
     1424    if (itr == _contour3Ds.end()) {
     1425        ERROR("Contour3D not found: %s", id.c_str());
     1426        return;
     1427    }
     1428
     1429    do {
     1430        itr->second->setVisibility(state);
     1431    } while (doAll && ++itr != _contour3Ds.end());
     1432
     1433    _needsRedraw = true;
     1434}
     1435
     1436/**
     1437 * \brief Associate an existing named color map with a Contour3D for the given
     1438 * DataSet
     1439 */
     1440void Renderer::setContour3DColorMap(const DataSetId& id, const ColorMapId& colorMapId)
     1441{
     1442    Contour3DHashmap::iterator itr;
     1443
     1444    bool doAll = false;
     1445
     1446    if (id.compare("all") == 0) {
     1447        itr = _contour3Ds.begin();
     1448        doAll = true;
     1449    } else {
     1450        itr = _contour3Ds.find(id);
     1451    }
     1452
     1453    if (itr == _contour3Ds.end()) {
     1454        ERROR("Contour3D not found: %s", id.c_str());
     1455        return;
     1456    }
     1457
     1458    ColorMap *cmap = getColorMap(colorMapId);
     1459    if (cmap == NULL) {
     1460        ERROR("Unknown colormap: %s", colorMapId.c_str());
     1461        return;
     1462    }
     1463
     1464    do {
     1465        TRACE("Set Contour3D color map: %s for dataset %s", colorMapId.c_str(),
     1466              itr->second->getDataSet()->getName().c_str());
     1467
     1468        // Make a copy of the generic colormap lookup table, so
     1469        // data range can be set in the copy table to match the
     1470        // dataset being plotted
     1471        vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
     1472        lut->DeepCopy(cmap->getLookupTable());
     1473
     1474        if (_useCumulativeRange) {
     1475            lut->SetRange(_cumulativeDataRange);
     1476        } else {
     1477            if (itr->second->getDataSet() != NULL) {
     1478                double range[2];
     1479                itr->second->getDataSet()->getDataRange(range);
     1480                lut->SetRange(range);
     1481            }
     1482        }
     1483
     1484        itr->second->setLookupTable(lut);
     1485    } while (doAll && ++itr != _contour3Ds.end());
     1486
     1487    _needsRedraw = true;
     1488}
     1489
     1490/**
     1491 * \brief Set the RGB isosurface color for the specified DataSet
     1492 */
     1493void Renderer::setContour3DColor(const DataSetId& id, float color[3])
     1494{
     1495    Contour3DHashmap::iterator itr;
     1496
     1497    bool doAll = false;
     1498
     1499    if (id.compare("all") == 0) {
     1500        itr = _contour3Ds.begin();
     1501        doAll = true;
     1502    } else {
     1503        itr = _contour3Ds.find(id);
     1504    }
     1505    if (itr == _contour3Ds.end()) {
     1506        ERROR("Contour3D not found: %s", id.c_str());
     1507        return;
     1508    }
     1509
     1510    do {
     1511        itr->second->setColor(color);
     1512    } while (doAll && ++itr != _contour3Ds.end());
     1513    _needsRedraw = true;
     1514}
     1515
     1516/**
     1517 * \brief Turn on/off rendering isosurface edges for the given DataSet
     1518 */
     1519void Renderer::setContour3DEdgeVisibility(const DataSetId& id, bool state)
     1520{
     1521    Contour3DHashmap::iterator itr;
     1522
     1523    bool doAll = false;
     1524
     1525    if (id.compare("all") == 0) {
     1526        itr = _contour3Ds.begin();
     1527        doAll = true;
     1528    } else {
     1529        itr = _contour3Ds.find(id);
     1530    }
     1531    if (itr == _contour3Ds.end()) {
     1532        ERROR("Contour3D not found: %s", id.c_str());
     1533        return;
     1534    }
     1535
     1536    do {
     1537        itr->second->setEdgeVisibility(state);
     1538    } while (doAll && ++itr != _contour3Ds.end());
     1539
     1540    _needsRedraw = true;
     1541}
     1542
     1543/**
     1544 * \brief Set the RGB isosurface edge color for the specified DataSet
     1545 */
     1546void Renderer::setContour3DEdgeColor(const DataSetId& id, float color[3])
     1547{
     1548    Contour3DHashmap::iterator itr;
     1549
     1550    bool doAll = false;
     1551
     1552    if (id.compare("all") == 0) {
     1553        itr = _contour3Ds.begin();
     1554        doAll = true;
     1555    } else {
     1556        itr = _contour3Ds.find(id);
     1557    }
     1558    if (itr == _contour3Ds.end()) {
     1559        ERROR("Contour3D not found: %s", id.c_str());
     1560        return;
     1561    }
     1562
     1563    do {
     1564        itr->second->setEdgeColor(color);
     1565    } while (doAll && ++itr != _contour3Ds.end());
     1566
     1567    _needsRedraw = true;
     1568}
     1569
     1570/**
     1571 * \brief Set the isosurface edge width for the specified DataSet (may be a no-op)
     1572 *
     1573 * If the OpenGL implementation/hardware does not support wide lines,
     1574 * this function may not have an effect.
     1575 */
     1576void Renderer::setContour3DEdgeWidth(const DataSetId& id, float edgeWidth)
     1577{
     1578    Contour3DHashmap::iterator itr;
     1579
     1580    bool doAll = false;
     1581
     1582    if (id.compare("all") == 0) {
     1583        itr = _contour3Ds.begin();
     1584        doAll = true;
     1585    } else {
     1586        itr = _contour3Ds.find(id);
     1587    }
     1588    if (itr == _contour3Ds.end()) {
     1589        ERROR("Contour3D not found: %s", id.c_str());
     1590        return;
     1591    }
     1592
     1593    do {
     1594        itr->second->setEdgeWidth(edgeWidth);
     1595    } while (doAll && ++itr != _contour3Ds.end());
     1596
     1597    _needsRedraw = true;
     1598}
     1599
     1600/**
     1601 * \brief Set wireframe rendering for the specified DataSet
     1602 */
     1603void Renderer::setContour3DWireframe(const DataSetId& id, bool state)
     1604{
     1605    Contour3DHashmap::iterator itr;
     1606
     1607    bool doAll = false;
     1608
     1609    if (id.compare("all") == 0) {
     1610        itr = _contour3Ds.begin();
     1611        doAll = true;
     1612    } else {
     1613        itr = _contour3Ds.find(id);
     1614    }
     1615    if (itr == _contour3Ds.end()) {
     1616        ERROR("Contour3D not found: %s", id.c_str());
     1617        return;
     1618    }
     1619
     1620    do {
     1621        itr->second->setWireframe(state);
     1622    } while (doAll && ++itr != _contour3Ds.end());
     1623
     1624    _needsRedraw = true;
     1625}
     1626
     1627/**
     1628 * \brief Turn contour lighting on/off for the specified DataSet
     1629 */
     1630void Renderer::setContour3DLighting(const DataSetId& id, bool state)
     1631{
     1632    Contour3DHashmap::iterator itr;
     1633
     1634    bool doAll = false;
     1635
     1636    if (id.compare("all") == 0) {
     1637        itr = _contour3Ds.begin();
     1638        doAll = true;
     1639    } else {
     1640        itr = _contour3Ds.find(id);
     1641    }
     1642    if (itr == _contour3Ds.end()) {
     1643        ERROR("Contour3D not found: %s", id.c_str());
     1644        return;
     1645    }
     1646
     1647    do {
     1648        itr->second->setLighting(state);
     1649    } while (doAll && ++itr != _contour3Ds.end());
    12011650    _needsRedraw = true;
    12021651}
     
    34023851    bounds[5] = -DBL_MAX;
    34033852
    3404     for (Contour2DHashmap::iterator itr = _contours.begin();
    3405              itr != _contours.end(); ++itr) {
     3853    for (Contour2DHashmap::iterator itr = _contour2Ds.begin();
     3854             itr != _contour2Ds.end(); ++itr) {
     3855        if (!onlyVisible || itr->second->getVisibility())
     3856            mergeBounds(bounds, bounds, itr->second->getProp()->GetBounds());
     3857    }
     3858    for (Contour3DHashmap::iterator itr = _contour3Ds.begin();
     3859             itr != _contour3Ds.end(); ++itr) {
    34063860        if (!onlyVisible || itr->second->getVisibility())
    34073861            mergeBounds(bounds, bounds, itr->second->getProp()->GetBounds());
     
    34573911void Renderer::updateRanges(bool useCumulative)
    34583912{
    3459     for (Contour2DHashmap::iterator itr = _contours.begin();
    3460          itr != _contours.end(); ++itr) {
     3913    for (Contour2DHashmap::iterator itr = _contour2Ds.begin();
     3914         itr != _contour2Ds.end(); ++itr) {
     3915        // Only need to update range if using evenly spaced contours
     3916        if (itr->second->getContourList().empty()) {
     3917            if (useCumulative) {
     3918                itr->second->setContours(itr->second->getNumContours(), _cumulativeDataRange);
     3919            } else {
     3920                itr->second->setContours(itr->second->getNumContours());
     3921            }
     3922        }
     3923    }
     3924    for (Contour3DHashmap::iterator itr = _contour3Ds.begin();
     3925         itr != _contour3Ds.end(); ++itr) {
    34613926        // Only need to update range if using evenly spaced contours
    34623927        if (itr->second->getContourList().empty()) {
     
    36564121{
    36574122    if (id.compare("all") == 0 || getContour2D(id) != NULL)
    3658         setContourOpacity(id, opacity);
     4123        setContour2DOpacity(id, opacity);
     4124    if (id.compare("all") == 0 || getContour3D(id) != NULL)
     4125        setContour3DOpacity(id, opacity);
    36594126    if (id.compare("all") == 0 || getGlyphs(id) != NULL)
    36604127        setGlyphsOpacity(id, opacity);
     
    36944161
    36954162    if (id.compare("all") == 0 || getContour2D(id) != NULL)
    3696         setContourVisibility(id, state);
     4163        setContour2DVisibility(id, state);
     4164    if (id.compare("all") == 0 || getContour3D(id) != NULL)
     4165        setContour3DVisibility(id, state);
    36974166    if (id.compare("all") == 0 || getGlyphs(id) != NULL)
    36984167        setGlyphsVisibility(id, state);
     
    37324201     * Mappers already using the PlaneCollection
    37334202     */
    3734     for (Contour2DHashmap::iterator itr = _contours.begin();
    3735          itr != _contours.end(); ++itr) {
     4203    for (Contour2DHashmap::iterator itr = _contour2Ds.begin();
     4204         itr != _contour2Ds.end(); ++itr) {
     4205        itr->second->setClippingPlanes(_activeClipPlanes);
     4206    }
     4207    for (Contour3DHashmap::iterator itr = _contour3Ds.begin();
     4208         itr != _contour3Ds.end(); ++itr) {
    37364209        itr->second->setClippingPlanes(_activeClipPlanes);
    37374210    }
     
    37564229        itr->second->setClippingPlanes(_activeClipPlanes);
    37574230    }
     4231}
     4232
     4233/**
     4234 * \brief Control the use of the depth peeling algorithm for transparency
     4235 */
     4236void Renderer::setUseDepthPeeling(bool state)
     4237{
     4238    _renderer->SetUseDepthPeeling(state ? 1 : 0);
     4239    _needsRedraw = true;
    37584240}
    37594241
  • trunk/packages/vizservers/vtkvis/RpVtkRenderer.h

    r2270 r2290  
    2828#include "RpVtkDataSet.h"
    2929#include "RpContour2D.h"
     30#include "RpContour3D.h"
    3031#include "RpGlyphs.h"
    3132#include "RpHeightMap.h"
     
    7677    typedef std::tr1::unordered_map<ColorMapId, ColorMap *> ColorMapHashmap;
    7778    typedef std::tr1::unordered_map<DataSetId, Contour2D *> Contour2DHashmap;
     79    typedef std::tr1::unordered_map<DataSetId, Contour3D *> Contour3DHashmap;
    7880    typedef std::tr1::unordered_map<DataSetId, Glyphs *> GlyphsHashmap;
    7981    typedef std::tr1::unordered_map<DataSetId, HeightMap *> HeightMapHashmap;
     
    146148    void setBackgroundColor(float color[3]);
    147149
     150    void setUseDepthPeeling(bool state);
     151
    148152    bool render();
    149153
     
    182186                        vtkUnsignedCharArray *imgData);
    183187
    184     // Contour plots
     188    // 2D Contour plots
    185189
    186190    void addContour2D(const DataSetId& id);
     
    190194    Contour2D *getContour2D(const DataSetId& id);
    191195
    192     void setContours(const DataSetId& id, int numContours);
    193 
    194     void setContourList(const DataSetId& id, const std::vector<double>& contours);
    195 
    196     void setContourOpacity(const DataSetId& id, double opacity);
    197 
    198     void setContourVisibility(const DataSetId& id, bool state);
    199 
    200     void setContourEdgeColor(const DataSetId& id, float color[3]);
    201 
    202     void setContourEdgeWidth(const DataSetId& id, float edgeWidth);
    203 
    204     void setContourLighting(const DataSetId& id, bool state);
     196    void setContour2DContours(const DataSetId& id, int numContours);
     197
     198    void setContour2DContourList(const DataSetId& id, const std::vector<double>& contours);
     199
     200    void setContour2DOpacity(const DataSetId& id, double opacity);
     201
     202    void setContour2DVisibility(const DataSetId& id, bool state);
     203
     204    void setContour2DEdgeColor(const DataSetId& id, float color[3]);
     205
     206    void setContour2DEdgeWidth(const DataSetId& id, float edgeWidth);
     207
     208    void setContour2DLighting(const DataSetId& id, bool state);
     209
     210    // 3D Contour (isosurface) plots
     211
     212    void addContour3D(const DataSetId& id);
     213
     214    void deleteContour3D(const DataSetId& id);
     215
     216    Contour3D *getContour3D(const DataSetId& id);
     217
     218    void setContour3DContours(const DataSetId& id, int numContours);
     219
     220    void setContour3DContourList(const DataSetId& id, const std::vector<double>& contours);
     221
     222    void setContour3DColorMap(const DataSetId& id, const ColorMapId& colorMapId);
     223
     224    void setContour3DOpacity(const DataSetId& id, double opacity);
     225
     226    void setContour3DVisibility(const DataSetId& id, bool state);
     227
     228    void setContour3DColor(const DataSetId& id, float color[3]);
     229
     230    void setContour3DEdgeVisibility(const DataSetId& id, bool state);
     231
     232    void setContour3DEdgeColor(const DataSetId& id, float color[3]);
     233
     234    void setContour3DEdgeWidth(const DataSetId& id, float edgeWidth);
     235
     236    void setContour3DWireframe(const DataSetId& id, bool state);
     237
     238    void setContour3DLighting(const DataSetId& id, bool state);
    205239
    206240    // Glyphs
     
    376410    ColorMapHashmap _colorMaps;
    377411    DataSetHashmap _dataSets;
    378     Contour2DHashmap _contours;
     412    Contour2DHashmap _contour2Ds;
     413    Contour3DHashmap _contour3Ds;
    379414    GlyphsHashmap _glyphs;
    380415    HeightMapHashmap _heightMaps;
  • trunk/packages/vizservers/vtkvis/RpVtkRendererCmd.cpp

    r2278 r2290  
    551551        const char *name = Tcl_GetString(objv[4]);
    552552        g_renderer->addContour2D(name);
    553         g_renderer->setContourList(name, contourList);
     553        g_renderer->setContour2DContourList(name, contourList);
    554554    } else {
    555555        g_renderer->addContour2D("all");
    556         g_renderer->setContourList("all", contourList);
     556        g_renderer->setContour2DContourList("all", contourList);
    557557    }
    558558    return TCL_OK;
     
    570570        const char *name = Tcl_GetString(objv[4]);
    571571        g_renderer->addContour2D(name);
    572         g_renderer->setContours(name, numContours);
     572        g_renderer->setContour2DContours(name, numContours);
    573573    } else {
    574574        g_renderer->addContour2D("all");
    575         g_renderer->setContours("all", numContours);
     575        g_renderer->setContour2DContours("all", numContours);
    576576    }
    577577    return TCL_OK;
     
    621621    if (objc == 4) {
    622622        const char *name = Tcl_GetString(objv[3]);
    623         g_renderer->setContourLighting(name, state);
    624     } else {
    625         g_renderer->setContourLighting("all", state);
     623        g_renderer->setContour2DLighting(name, state);
     624    } else {
     625        g_renderer->setContour2DLighting("all", state);
    626626    }
    627627    return TCL_OK;
     
    640640    if (objc == 6) {
    641641        const char *name = Tcl_GetString(objv[5]);
    642         g_renderer->setContourEdgeColor(name, color);
    643     } else {
    644         g_renderer->setContourEdgeColor("all", color);
     642        g_renderer->setContour2DEdgeColor(name, color);
     643    } else {
     644        g_renderer->setContour2DEdgeColor("all", color);
    645645    }
    646646    return TCL_OK;
     
    657657    if (objc == 4) {
    658658        const char *name = Tcl_GetString(objv[3]);
    659         g_renderer->setContourEdgeWidth(name, width);
    660     } else {
    661         g_renderer->setContourEdgeWidth("all", width);
     659        g_renderer->setContour2DEdgeWidth(name, width);
     660    } else {
     661        g_renderer->setContour2DEdgeWidth("all", width);
    662662    }
    663663    return TCL_OK;
     
    674674    if (objc == 4) {
    675675        const char *name = Tcl_GetString(objv[3]);
    676         g_renderer->setContourOpacity(name, opacity);
    677     } else {
    678         g_renderer->setContourOpacity("all", opacity);
     676        g_renderer->setContour2DOpacity(name, opacity);
     677    } else {
     678        g_renderer->setContour2DOpacity("all", opacity);
    679679    }
    680680    return TCL_OK;
     
    691691    if (objc == 4) {
    692692        const char *name = Tcl_GetString(objv[3]);
    693         g_renderer->setContourVisibility(name, state);
    694     } else {
    695         g_renderer->setContourVisibility("all", state);
     693        g_renderer->setContour2DVisibility(name, state);
     694    } else {
     695        g_renderer->setContour2DVisibility("all", state);
    696696    }
    697697    return TCL_OK;
     
    724724
    725725static int
     726Contour3DAddContourListOp(ClientData clientData, Tcl_Interp *interp, int objc,
     727                          Tcl_Obj *const *objv)
     728{
     729    std::vector<double> contourList;
     730
     731    int clistc;
     732    Tcl_Obj **clistv;
     733
     734    if (Tcl_ListObjGetElements(interp, objv[3], &clistc, &clistv) != TCL_OK) {
     735        return TCL_ERROR;
     736    }
     737
     738    for (int i = 0; i < clistc; i++) {
     739        double val;
     740        if (Tcl_GetDoubleFromObj(interp, clistv[i], &val) != TCL_OK) {
     741            return TCL_ERROR;
     742        }
     743        contourList.push_back(val);
     744    }
     745
     746    if (objc == 5) {
     747        const char *name = Tcl_GetString(objv[4]);
     748        g_renderer->addContour3D(name);
     749        g_renderer->setContour3DContourList(name, contourList);
     750    } else {
     751        g_renderer->addContour3D("all");
     752        g_renderer->setContour3DContourList("all", contourList);
     753    }
     754    return TCL_OK;
     755}
     756
     757static int
     758Contour3DAddNumContoursOp(ClientData clientData, Tcl_Interp *interp, int objc,
     759                          Tcl_Obj *const *objv)
     760{
     761    int numContours;
     762    if (Tcl_GetIntFromObj(interp, objv[3], &numContours) != TCL_OK) {
     763        return TCL_ERROR;
     764    }
     765    if (objc == 5) {
     766        const char *name = Tcl_GetString(objv[4]);
     767        g_renderer->addContour3D(name);
     768        g_renderer->setContour3DContours(name, numContours);
     769    } else {
     770        g_renderer->addContour3D("all");
     771        g_renderer->setContour3DContours("all", numContours);
     772    }
     773    return TCL_OK;
     774}
     775
     776static Rappture::CmdSpec contour3dAddOps[] = {
     777    {"contourlist", 1, Contour3DAddContourListOp, 4, 5, "contourList ?dataSetName?"},
     778    {"numcontours", 1, Contour3DAddNumContoursOp, 4, 5, "numContours ?dataSetName?"}
     779};
     780static int nContour3dAddOps = NumCmdSpecs(contour3dAddOps);
     781
     782static int
     783Contour3DAddOp(ClientData clientData, Tcl_Interp *interp, int objc,
     784               Tcl_Obj *const *objv)
     785{
     786    Tcl_ObjCmdProc *proc;
     787
     788    proc = Rappture::GetOpFromObj(interp, nContour3dAddOps, contour3dAddOps,
     789                                  Rappture::CMDSPEC_ARG2, objc, objv, 0);
     790    if (proc == NULL) {
     791        return TCL_ERROR;
     792    }
     793    return (*proc) (clientData, interp, objc, objv);
     794}
     795
     796static int
     797Contour3DColorOp(ClientData clientData, Tcl_Interp *interp, int objc,
     798                 Tcl_Obj *const *objv)
     799{
     800    float color[3];
     801    if (GetFloatFromObj(interp, objv[2], &color[0]) != TCL_OK ||
     802        GetFloatFromObj(interp, objv[3], &color[1]) != TCL_OK ||
     803        GetFloatFromObj(interp, objv[4], &color[2]) != TCL_OK) {
     804        return TCL_ERROR;
     805    }
     806    if (objc == 6) {
     807        const char *name = Tcl_GetString(objv[5]);
     808        g_renderer->setContour3DColor(name, color);
     809    } else {
     810        g_renderer->setContour3DColor("all", color);
     811    }
     812    return TCL_OK;
     813}
     814
     815static int
     816Contour3DColorMapOp(ClientData clientData, Tcl_Interp *interp, int objc,
     817                    Tcl_Obj *const *objv)
     818{
     819    const char *colorMapName = Tcl_GetString(objv[2]);
     820    if (objc == 4) {
     821        const char *dataSetName = Tcl_GetString(objv[3]);
     822        g_renderer->setContour3DColorMap(dataSetName, colorMapName);
     823    } else {
     824        g_renderer->setContour3DColorMap("all", colorMapName);
     825    }
     826    return TCL_OK;
     827}
     828
     829static int
     830Contour3DDeleteOp(ClientData clientData, Tcl_Interp *interp, int objc,
     831                  Tcl_Obj *const *objv)
     832{
     833    if (objc == 3) {
     834        const char *name = Tcl_GetString(objv[2]);
     835        g_renderer->deleteContour3D(name);
     836    } else {
     837        g_renderer->deleteContour3D("all");
     838    }
     839    return TCL_OK;
     840}
     841
     842static int
     843Contour3DEdgeVisibilityOp(ClientData clientData, Tcl_Interp *interp, int objc,
     844                          Tcl_Obj *const *objv)
     845{
     846    bool state;
     847    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     848        return TCL_ERROR;
     849    }
     850    if (objc == 4) {
     851        const char *name = Tcl_GetString(objv[3]);
     852        g_renderer->setContour3DEdgeVisibility(name, state);
     853    } else {
     854        g_renderer->setContour3DEdgeVisibility("all", state);
     855    }
     856    return TCL_OK;
     857}
     858
     859static int
     860Contour3DLightingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     861                    Tcl_Obj *const *objv)
     862{
     863    bool state;
     864    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     865        return TCL_ERROR;
     866    }
     867    if (objc == 4) {
     868        const char *name = Tcl_GetString(objv[3]);
     869        g_renderer->setContour3DLighting(name, state);
     870    } else {
     871        g_renderer->setContour3DLighting("all", state);
     872    }
     873    return TCL_OK;
     874}
     875
     876static int
     877Contour3DLineColorOp(ClientData clientData, Tcl_Interp *interp, int objc,
     878                     Tcl_Obj *const *objv)
     879{
     880    float color[3];
     881    if (GetFloatFromObj(interp, objv[2], &color[0]) != TCL_OK ||
     882        GetFloatFromObj(interp, objv[3], &color[1]) != TCL_OK ||
     883        GetFloatFromObj(interp, objv[4], &color[2]) != TCL_OK) {
     884        return TCL_ERROR;
     885    }
     886    if (objc == 6) {
     887        const char *name = Tcl_GetString(objv[5]);
     888        g_renderer->setContour3DEdgeColor(name, color);
     889    } else {
     890        g_renderer->setContour3DEdgeColor("all", color);
     891    }
     892    return TCL_OK;
     893}
     894
     895static int
     896Contour3DLineWidthOp(ClientData clientData, Tcl_Interp *interp, int objc,
     897                     Tcl_Obj *const *objv)
     898{
     899    float width;
     900    if (GetFloatFromObj(interp, objv[2], &width) != TCL_OK) {
     901        return TCL_ERROR;
     902    }
     903    if (objc == 4) {
     904        const char *name = Tcl_GetString(objv[3]);
     905        g_renderer->setContour3DEdgeWidth(name, width);
     906    } else {
     907        g_renderer->setContour3DEdgeWidth("all", width);
     908    }
     909    return TCL_OK;
     910}
     911
     912static int
     913Contour3DOpacityOp(ClientData clientData, Tcl_Interp *interp, int objc,
     914                   Tcl_Obj *const *objv)
     915{
     916    double opacity;
     917    if (Tcl_GetDoubleFromObj(interp, objv[2], &opacity) != TCL_OK) {
     918        return TCL_ERROR;
     919    }
     920    if (objc == 4) {
     921        const char *name = Tcl_GetString(objv[3]);
     922        g_renderer->setContour3DOpacity(name, opacity);
     923    } else {
     924        g_renderer->setContour3DOpacity("all", opacity);
     925    }
     926    return TCL_OK;
     927}
     928
     929static int
     930Contour3DVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
     931                   Tcl_Obj *const *objv)
     932{
     933    bool state;
     934    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     935        return TCL_ERROR;
     936    }
     937    if (objc == 4) {
     938        const char *name = Tcl_GetString(objv[3]);
     939        g_renderer->setContour3DVisibility(name, state);
     940    } else {
     941        g_renderer->setContour3DVisibility("all", state);
     942    }
     943    return TCL_OK;
     944}
     945
     946static int
     947Contour3DWireframeOp(ClientData clientData, Tcl_Interp *interp, int objc,
     948                     Tcl_Obj *const *objv)
     949{
     950    bool state;
     951    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     952        return TCL_ERROR;
     953    }
     954    if (objc == 4) {
     955        const char *name = Tcl_GetString(objv[3]);
     956        g_renderer->setContour3DWireframe(name, state);
     957    } else {
     958        g_renderer->setContour3DWireframe("all", state);
     959    }
     960    return TCL_OK;
     961}
     962
     963static Rappture::CmdSpec contour3dOps[] = {
     964    {"add",       1, Contour3DAddOp, 4, 5, "oper value ?dataSetName?"},
     965    {"color",     6, Contour3DColorOp, 5, 6, "r g b ?dataSetName?"},
     966    {"colormap",  6, Contour3DColorMapOp, 3, 4, "colorMapName ?dataSetName?"},
     967    {"delete",    1, Contour3DDeleteOp, 2, 3, "?dataSetName?"},
     968    {"edges",     1, Contour3DEdgeVisibilityOp, 3, 4, "bool ?dataSetName?"},
     969    {"lighting",  3, Contour3DLightingOp, 3, 4, "bool ?dataSetName?"},
     970    {"linecolor", 5, Contour3DLineColorOp, 5, 6, "r g b ?dataSetName?"},
     971    {"linewidth", 5, Contour3DLineWidthOp, 3, 4, "width ?dataSetName?"},
     972    {"opacity",   1, Contour3DOpacityOp, 3, 4, "value ?dataSetName?"},
     973    {"visible",   1, Contour3DVisibleOp, 3, 4, "bool ?dataSetName?"},
     974    {"wireframe", 1, Contour3DWireframeOp, 3, 4, "bool ?dataSetName?"}
     975};
     976static int nContour3dOps = NumCmdSpecs(contour3dOps);
     977
     978static int
     979Contour3DCmd(ClientData clientData, Tcl_Interp *interp, int objc,
     980             Tcl_Obj *const *objv)
     981{
     982    Tcl_ObjCmdProc *proc;
     983
     984    proc = Rappture::GetOpFromObj(interp, nContour3dOps, contour3dOps,
     985                                  Rappture::CMDSPEC_ARG1, objc, objv, 0);
     986    if (proc == NULL) {
     987        return TCL_ERROR;
     988    }
     989    return (*proc) (clientData, interp, objc, objv);
     990}
     991
     992static int
    726993DataSetAddOp(ClientData clientData, Tcl_Interp *interp, int objc,
    727994             Tcl_Obj *const *objv)
     
    7581025    TRACE("bytesRead: %d", ofs);
    7591026    if (bytesRead < 0) {
     1027        free(data);
    7601028        return TCL_ERROR;
    7611029    }
     
    7641032    TRACE("bytesRead: %d '%c'", bytesRead, data[0]);
    7651033    if (bytesRead < (size_t)nbytes) {
     1034        free(data);
    7661035        return TCL_ERROR;
    7671036    }
     
    18862155
    18872156    proc = Rappture::GetOpFromObj(interp, nPolyDataOps, polyDataOps,
     2157                                  Rappture::CMDSPEC_ARG1, objc, objv, 0);
     2158    if (proc == NULL) {
     2159        return TCL_ERROR;
     2160    }
     2161    return (*proc) (clientData, interp, objc, objv);
     2162}
     2163
     2164static int
     2165RendererDepthPeelingOp(ClientData clientData, Tcl_Interp *interp, int objc,
     2166                       Tcl_Obj *const *objv)
     2167{
     2168    bool state;
     2169    if (GetBooleanFromObj(interp, objv[2], &state) != TCL_OK) {
     2170        return TCL_ERROR;
     2171    }
     2172    g_renderer->setUseDepthPeeling(state);
     2173    return TCL_OK;
     2174}
     2175
     2176static Rappture::CmdSpec rendererOps[] = {
     2177    {"depthpeel", 1, RendererDepthPeelingOp, 3, 3, "bool"}
     2178};
     2179static int nRendererOps = NumCmdSpecs(rendererOps);
     2180
     2181static int
     2182RendererCmd(ClientData clientData, Tcl_Interp *interp, int objc,
     2183            Tcl_Obj *const *objv)
     2184{
     2185    Tcl_ObjCmdProc *proc;
     2186
     2187    proc = Rappture::GetOpFromObj(interp, nRendererOps, rendererOps,
    18882188                                  Rappture::CMDSPEC_ARG1, objc, objv, 0);
    18892189    if (proc == NULL) {
     
    22322532    Tcl_CreateObjCommand(interp, "colormap",    ColorMapCmd,    NULL, NULL);
    22332533    Tcl_CreateObjCommand(interp, "contour2d",   Contour2DCmd,   NULL, NULL);
     2534    Tcl_CreateObjCommand(interp, "contour3d",   Contour3DCmd,   NULL, NULL);
    22342535    Tcl_CreateObjCommand(interp, "dataset",     DataSetCmd,     NULL, NULL);
    22352536    Tcl_CreateObjCommand(interp, "glyphs",      GlyphsCmd,      NULL, NULL);
     
    22382539    Tcl_CreateObjCommand(interp, "polydata",    PolyDataCmd,    NULL, NULL);
    22392540    Tcl_CreateObjCommand(interp, "pseudocolor", PseudoColorCmd, NULL, NULL);
     2541    Tcl_CreateObjCommand(interp, "renderer",    RendererCmd,    NULL, NULL);
    22402542    Tcl_CreateObjCommand(interp, "screen",      ScreenCmd,      NULL, NULL);
    22412543    Tcl_CreateObjCommand(interp, "volume",      VolumeCmd,      NULL, NULL);
     
    22542556    Tcl_DeleteCommand(interp, "colormap");
    22552557    Tcl_DeleteCommand(interp, "contour2d");
     2558    Tcl_DeleteCommand(interp, "contour3d");
    22562559    Tcl_DeleteCommand(interp, "dataset");
    22572560    Tcl_DeleteCommand(interp, "glyphs");
     
    22602563    Tcl_DeleteCommand(interp, "polydata");
    22612564    Tcl_DeleteCommand(interp, "pseudocolor");
     2565    Tcl_DeleteCommand(interp, "renderer");
    22622566    Tcl_DeleteCommand(interp, "screen");
    22632567    Tcl_DeleteCommand(interp, "volume");
  • trunk/packages/vizservers/vtkvis/protocol.txt

    r2269 r2290  
    77screen bgcolor <r> <g> <b>
    88screen size <width> <height>
     9
     10renderer depthpeel <bool>
     11         Set use of depth peeling algorithm for transparency
    912
    1013axis color <r> <g> <b>
     
    7376contour2d opacity <val> <?datasetName?>
    7477contour2d visible <bool> <?datasetName?>
     78
     79contour3d add numcontours <n> <?datasetName?>
     80          Generate evenly spaced contours including range endpoints.  See also
     81          'dataset maprange' command.
     82contour3d add contourlist <list> <?datasetName?>
     83          list = {isoval1 isoval2 isoval3...}
     84contour3d color r g b <?datasetName?>
     85contour3d colormap <colorMapName> <?dataSetName?>
     86contour3d delete <?datasetName?>
     87contour3d edges <bool> <?datasetName?>
     88contour3d lighting <bool> <?datasetName?>
     89contour3d linecolor <r> <g> <b> <?datasetName?>
     90contour3d linewidth <val> <?datasetName?>
     91contour3d opacity <val> <?datasetName?>
     92contour3d visible <bool> <?datasetName?>
     93contour3d wireframe <bool> <?datasetName?>
    7594
    7695glyphs add <?dataSetName?>
Note: See TracChangeset for help on using the changeset viewer.