Ignore:
Timestamp:
Apr 1, 2011 12:28:21 AM (13 years ago)
Author:
ldelgass
Message:

Fix pan/zoom for VTK contours, add command to control data range mapping for
multiple datasets. Still need to fix 3D panning, allow absolute rotation/
orientation of the camera.

Location:
trunk/packages/vizservers/vtkvis
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/packages/vizservers/vtkvis/ColorMap.cpp

    r2113 r2194  
    2727}
    2828
     29/**
     30 * \brief Return the name/ID of the ColorMap
     31 */
    2932const std::string& ColorMap::getName()
    3033{
     
    3235}
    3336
     37/**
     38 * \brief Build and return the vtkLookupTable from the transfer function
     39 */
    3440vtkLookupTable *ColorMap::getLookupTable()
    3541{
     
    3945}
    4046
     47/**
     48 * \brief Insert a new RGB control point into the transfer function
     49 */
    4150void ColorMap::addControlPoint(ControlPoint& cp)
    4251{
     
    6574}
    6675
     76/**
     77 * \brief Insert a new opacity/alpha control point into the transfer function
     78 */
    6779void ColorMap::addOpacityControlPoint(OpacityControlPoint& cp)
    6880{
     
    109121}
    110122
     123/**
     124 * \brief Build the lookup table from the control points in the transfer
     125 * function
     126 */
    111127void ColorMap::build()
    112128{
     
    193209}
    194210
     211/**
     212 * \brief Remove all control points and lookup table
     213 */
    195214void ColorMap::clear()
    196215{
     
    200219}
    201220
     221/**
     222 * \brief Create a default ColorMap with a blue-cyan-green-yellow-red ramp
     223 */
    202224ColorMap * ColorMap::createDefault()
    203225{
  • trunk/packages/vizservers/vtkvis/ColorMap.h

    r2112 r2194  
    2727public:
    2828    /**
    29      * \brief RGBA inflection point in a transfer function
     29     * \brief RGB inflection point in a transfer function
    3030     */
    3131    struct ControlPoint {
     
    5252        double color[3]; ///< RGB color
    5353    };
     54
     55    /**
     56     * \brief Opacity(alpha) inflection point in a transfer function
     57     */
    5458    struct OpacityControlPoint {
    5559        OpacityControlPoint() :
  • trunk/packages/vizservers/vtkvis/RpContour2D.cpp

    r2137 r2194  
    2121    _opacity(1.0)
    2222{
     23    _dataRange[0] = 0;
     24    _dataRange[1] = 1;
    2325    _edgeColor[0] = 0;
    2426    _edgeColor[1] = 0;
     
    4345    if (_dataSet != dataSet) {
    4446        _dataSet = dataSet;
     47
     48        if (_dataSet != NULL) {
     49            double dataRange[2];
     50            _dataSet->getDataRange(dataRange);
     51            _dataRange[0] = dataRange[0];
     52            _dataRange[1] = dataRange[1];
     53        }
     54
    4555        update();
    4656    }
     
    90100
    91101    // Contour filter to generate isolines
    92     vtkSmartPointer<vtkContourFilter> contourFilter = vtkSmartPointer<vtkContourFilter>::New();
    93     contourFilter->SetInput(_dataSet->getVtkDataSet());
    94 
    95     contourFilter->ComputeNormalsOff();
    96     contourFilter->ComputeGradientsOff();
     102    if (_contourFilter == NULL) {
     103        _contourFilter = vtkSmartPointer<vtkContourFilter>::New();
     104    }
     105
     106    _contourFilter->SetInput(_dataSet->getVtkDataSet());
     107
     108    _contourFilter->ComputeNormalsOff();
     109    _contourFilter->ComputeGradientsOff();
    97110
    98111    // Speed up multiple contour computation at cost of extra memory use
    99112    if (_numContours > 1) {
    100         contourFilter->UseScalarTreeOn();
     113        _contourFilter->UseScalarTreeOn();
    101114    } else {
    102         contourFilter->UseScalarTreeOff();
    103     }
     115        _contourFilter->UseScalarTreeOff();
     116    }
     117
     118    _contourFilter->SetNumberOfContours(_numContours);
     119
    104120    if (_contours.empty()) {
    105121        // Evenly spaced isovalues
    106         double dataRange[2];
    107         _dataSet->getDataRange(dataRange);
    108         contourFilter->GenerateValues(_numContours, dataRange[0], dataRange[1]);
     122        _contourFilter->GenerateValues(_numContours, _dataRange[0], _dataRange[1]);
    109123    } else {
    110124        // User-supplied isovalues
    111         for (int i = 0; i < (int)_contours.size(); i++) {
    112             contourFilter->SetValue(i, _contours[i]);
     125        for (int i = 0; i < _numContours; i++) {
     126            _contourFilter->SetValue(i, _contours[i]);
    113127        }
    114128    }
     
    117131        _contourMapper->SetResolveCoincidentTopologyToPolygonOffset();
    118132        _contourActor->SetMapper(_contourMapper);
    119     }
    120 
    121     _contourMapper->SetInput(contourFilter->GetOutput());
     133        _contourMapper->SetInput(_contourFilter->GetOutput());
     134    }
    122135}
    123136
     
    132145    _numContours = numContours;
    133146
     147    if (_dataSet != NULL) {
     148        double dataRange[2];
     149        _dataSet->getDataRange(dataRange);
     150        _dataRange[0] = dataRange[0];
     151        _dataRange[1] = dataRange[1];
     152    }
     153
    134154    update();
    135155}
    136156
    137157/**
     158 * \brief Specify number of evenly spaced contour lines to render
     159 * between the given range (including range endpoints)
     160 *
     161 * Will override any existing contours
     162 */
     163void Contour2D::setContours(int numContours, double range[2])
     164{
     165    _contours.clear();
     166    _numContours = numContours;
     167
     168    _dataRange[0] = range[0];
     169    _dataRange[1] = range[1];
     170
     171    update();
     172}
     173
     174/**
    138175 * \brief Specify an explicit list of contour isovalues
    139176 *
     
    143180{
    144181    _contours = contours;
    145     _numContours = _contours.size();
     182    _numContours = (int)_contours.size();
    146183
    147184    update();
     185}
     186
     187/**
     188 * \brief Get the number of contours
     189 */
     190int Contour2D::getNumContours() const
     191{
     192    return _numContours;
     193}
     194
     195/**
     196 * \brief Get the contour list (may be empty if number of contours
     197 * was specified in place of a list)
     198 */
     199const std::vector<double>& Contour2D::getContourList() const
     200{
     201    return _contours;
    148202}
    149203
     
    163217 * \return Is contour set visible?
    164218 */
    165 bool Contour2D::getVisibility()
     219bool Contour2D::getVisibility() const
    166220{
    167221    if (_contourActor == NULL) {
  • trunk/packages/vizservers/vtkvis/RpContour2D.h

    r2137 r2194  
    1010
    1111#include <vtkSmartPointer.h>
     12#include <vtkContourFilter.h>
    1213#include <vtkPolyDataMapper.h>
    1314#include <vtkActor.h>
     
    3738    void setContours(int numContours);
    3839
     40    void setContours(int numContours, double range[2]);
     41
    3942    void setContourList(const std::vector<double>& contours);
     43
     44    int getNumContours() const;
     45
     46    const std::vector<double>& getContourList() const;
    4047
    4148    void setVisibility(bool state);
    4249
    43     bool getVisibility();
     50    bool getVisibility() const;
    4451
    4552    void setOpacity(double opacity);
     
    6168    int _numContours;
    6269    std::vector<double> _contours;
     70    double _dataRange[2];
    6371
    6472    float _edgeColor[3];
    6573    float _edgeWidth;
    6674    double _opacity;
     75    vtkSmartPointer<vtkContourFilter> _contourFilter;
    6776    vtkSmartPointer<vtkPolyDataMapper> _contourMapper;
    6877    vtkSmartPointer<vtkActor> _contourActor;
  • trunk/packages/vizservers/vtkvis/RpPseudoColor.cpp

    r2146 r2194  
    144144    }
    145145
    146     double dataRange[2];
    147     if (_dataSet != NULL) {
    148         _dataSet->getDataRange(dataRange);
    149         _lut->SetRange(dataRange);
    150 #ifdef notdef
    151         if (_dataSet->getVtkDataSet()->GetPointData() &&
    152             _dataSet->getVtkDataSet()->GetPointData()->GetScalars() &&
    153             _dataSet->getVtkDataSet()->GetPointData()->GetScalars()->GetLookupTable()) {
    154             TRACE("Change scalar table: %p %p\n",
    155                   _dataSet->getVtkDataSet()->GetPointData()->GetScalars()->GetLookupTable(),
    156                   _lut.GetPointer());
    157             _dataSet->getVtkDataSet()->GetPointData()->GetScalars()->SetLookupTable(_lut);
    158             TRACE("Scalar Table: %p\n", _dataSet->getVtkDataSet()->GetPointData()->GetScalars()->GetLookupTable());
    159         }
    160 #endif
    161     }
    162146    if (_dsMapper != NULL) {
    163147        _dsMapper->UseLookupTableScalarRangeOn();
  • trunk/packages/vizservers/vtkvis/RpVtkDataSet.cpp

    r2121 r2194  
    1818using namespace Rappture::VtkVis;
    1919
    20 DataSet::DataSet(const std::string& name)
     20DataSet::DataSet(const std::string& name) :
     21    _name(name),
     22    _visible(true)
    2123{
    2224    _name = name;
    23     _dataRange[0] = 0.0;
    24     _dataRange[1] = 1.0;
     25    _dataRange[0] = 0;
     26    _dataRange[1] = 1;
     27    for (int i = 0; i < 6; i++) {
     28        _bounds[i] = 0;
     29    }
    2530}
    2631
    2732DataSet::~DataSet()
    2833{
     34}
     35
     36/**
     37 * \brief Set visibility flag in DataSet
     38 *
     39 * This method is used for record-keeping.  The renderer controls
     40 * the visibility of related graphics objects.
     41 */
     42void DataSet::setVisibility(bool state)
     43{
     44    _visible = state;
     45}
     46
     47/**
     48 * \brief Get visibility flag in DataSet
     49 *
     50 * This method is used for record-keeping.  The renderer controls
     51 * the visibility of related graphics objects.
     52 */
     53bool DataSet::getVisibility() const
     54{
     55    return _visible;
    2956}
    3057
     
    76103    _dataSet->Update();
    77104    _dataSet->GetScalarRange(_dataRange);
     105    _dataSet->GetBounds(_bounds);
    78106
    79107    TRACE("Scalar Range: %.12e, %.12e", _dataRange[0], _dataRange[1]);
     
    82110
    83111/**
     112 * \brief Does DataSet lie in the XY plane (z = 0)
     113 */
     114bool DataSet::is2D() const
     115{
     116    return (_bounds[4] == 0. && _bounds[4] == _bounds[5]);
     117}
     118
     119/**
    84120 * \brief Get the name/id of this dataset
    85121 */
    86 const std::string& DataSet::getName()
     122const std::string& DataSet::getName() const
    87123{
    88124    return _name;
  • trunk/packages/vizservers/vtkvis/RpVtkDataSet.h

    r2121 r2194  
    3535    bool setDataFile(const char *filename);
    3636
    37     const std::string& getName();
     37    bool is2D() const;
     38
     39    const std::string& getName() const;
    3840
    3941    vtkDataSet *getVtkDataSet();
     
    4345    double getDataValue(double x, double y, double z);
    4446
     47    void setVisibility(bool state);
     48
     49    bool getVisibility() const;
     50
    4551private:
    4652    DataSet();
     
    4955    vtkSmartPointer<vtkDataSet> _dataSet;
    5056    double _dataRange[2];
     57    double _bounds[6];
     58    bool _visible;
    5159};
    5260
  • trunk/packages/vizservers/vtkvis/RpVtkRenderServer.cpp

    r2100 r2194  
    99#include <cstring>
    1010#include <cstdlib>
     11#include <string>
     12#include <sstream>
    1113#include <unistd.h>
    1214#include <signal.h>
     
    3234{
    3335#ifdef DEBUG
     36    if (g_renderer->getCameraMode() == Renderer::IMAGE) {
     37        double xywh[4];
     38        g_renderer->getScreenWorldCoords(xywh);
     39        TRACE("Image bbox: %g %g %g %g",
     40              xywh[0],
     41              (xywh[1] + xywh[3]),
     42              (xywh[0] + xywh[2]),
     43              xywh[1]);
     44    }
     45
    3446    writeTGAFile("/tmp/frame.tga",
    3547                 imgData->GetPointer(0),
     
    3749                 g_renderer->getWindowHeight());
    3850#else
    39     writePPM(fd, "nv>image -type image -bytes",
    40              imgData->GetPointer(0),
    41              g_renderer->getWindowWidth(),
    42              g_renderer->getWindowHeight());
     51    if (g_renderer->getCameraMode() == Renderer::IMAGE) {
     52        double xywh[4];
     53        g_renderer->getScreenWorldCoords(xywh);
     54        std::ostringstream oss;
     55        oss.precision(12);
     56        // Send upper left and lower right corners as bbox
     57        oss << "nv>image -type image -bbox {"
     58            << std::scientific
     59            << xywh[0] << " "
     60            << (xywh[1] + xywh[3]) << " "
     61            << (xywh[0] + xywh[2]) << " "
     62            << xywh[1] << "} -bytes";
     63
     64        writePPM(fd, oss.str().c_str(),
     65                 imgData->GetPointer(0),
     66                 g_renderer->getWindowWidth(),
     67                 g_renderer->getWindowHeight());
     68    } else {
     69        writePPM(fd, "nv>image -type image -bytes",
     70                 imgData->GetPointer(0),
     71                 g_renderer->getWindowWidth(),
     72                 g_renderer->getWindowHeight());
     73    }
    4374#endif
    4475}
  • trunk/packages/vizservers/vtkvis/RpVtkRenderer.cpp

    r2146 r2194  
    77
    88#include <cfloat>
     9#include <cstring>
     10#include <cassert>
    911
    1012#include <vtkCamera.h>
     
    3941    _windowWidth(320),
    4042    _windowHeight(320),
    41     _useCumulativeRanges(true)
     43    _cameraZoomRatio(1),
     44    _useCumulativeRange(true),
     45    _cumulativeRangeOnlyVisible(false)
    4246{
    4347    _bgColor[0] = 0;
    4448    _bgColor[1] = 0;
    4549    _bgColor[2] = 0;
     50    _cameraPan[0] = 0;
     51    _cameraPan[1] = 0;
    4652    _cumulativeDataRange[0] = 0.0;
    4753    _cumulativeDataRange[1] = 1.0;
     
    268274        TRACE("After deleting graphics objects");
    269275
    270         // Update cumulative data range
    271         collectDataRanges(_cumulativeDataRange);
    272 
    273276        delete itr->second;
    274277        _dataSets.erase(itr);
    275278    } while (doAll && ++itr != _dataSets.end());
     279
     280    // Update cumulative data range
     281    collectDataRanges(_cumulativeDataRange, _cumulativeRangeOnlyVisible);
     282    updateRanges(_useCumulativeRange);
    276283
    277284    _needsRedraw = true;
     
    301308    if (ds) {
    302309        bool ret = ds->setDataFile(filename);
    303         collectDataRanges(_cumulativeDataRange);
    304         updateRanges(_useCumulativeRanges);
     310        collectDataRanges(_cumulativeDataRange, _cumulativeRangeOnlyVisible);
     311        updateRanges(_useCumulativeRange);
    305312        _needsRedraw = true;
    306313        return ret;
     
    317324    if (ds) {
    318325        bool ret = ds->setData(data, nbytes);
    319         collectDataRanges(_cumulativeDataRange);
    320         updateRanges(_useCumulativeRanges);
     326        collectDataRanges(_cumulativeDataRange, _cumulativeRangeOnlyVisible);
     327        updateRanges(_useCumulativeRange);
    321328        _needsRedraw = true;
    322329        return ret;
    323330    } else
    324331        return false;
     332}
     333
     334/**
     335 * \brief Control whether the cumulative data range of datasets is used for
     336 * colormapping and contours
     337 */
     338void Renderer::setUseCumulativeDataRange(bool state, bool onlyVisible)
     339{
     340    if (state != _useCumulativeRange) {
     341        _useCumulativeRange = state;
     342        _cumulativeRangeOnlyVisible = onlyVisible;
     343        collectDataRanges(_cumulativeDataRange, _cumulativeRangeOnlyVisible);
     344        updateRanges(_useCumulativeRange);
     345        _needsRedraw = true;
     346    }
    325347}
    326348
     
    384406    _cubeAxesActor2D->ScalingOff();
    385407    //_cubeAxesActor2D->SetShowActualBounds(0);
    386     _cubeAxesActor2D->SetFontFactor(2);
     408    _cubeAxesActor2D->SetFontFactor(1.25);
    387409    // Use "nice" range and number of ticks/labels
    388410    _cubeAxesActor2D->GetXAxisActor2D()->AdjustLabelsOn();
     
    744766        pc->setDataSet(ds);
    745767
     768        // Use the default color map
     769        vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
     770        ColorMap *cmap = getColorMap("default");
     771        lut->DeepCopy(cmap->getLookupTable());
     772        if (_useCumulativeRange) {
     773            lut->SetRange(_cumulativeDataRange);
     774        } else {
     775            double range[2];
     776            ds->getDataRange(range);
     777            lut->SetRange(range);
     778        }
     779
     780        pc->setLookupTable(lut);
     781
    746782        _renderer->AddActor(pc->getActor());
    747783    } while (doAll && ++itr != _dataSets.end());
     
    802838        lut->DeepCopy(cmap->getLookupTable());
    803839
     840        if (_useCumulativeRange) {
     841            lut->SetRange(_cumulativeDataRange);
     842        } else {
     843            if (itr->second->getDataSet() != NULL) {
     844                double range[2];
     845                itr->second->getDataSet()->getDataRange(range);
     846                lut->SetRange(range);
     847            }
     848        }
     849
    804850        itr->second->setLookupTable(lut);
    805851    } while (doAll && ++itr != _pseudoColors.end());
     
    10681114
    10691115    do {
    1070         itr->second->setContours(numContours);
     1116        if (_useCumulativeRange) {
     1117            itr->second->setContours(numContours, _cumulativeDataRange);
     1118        } else {
     1119            itr->second->setContours(numContours);
     1120        }
    10711121    } while (doAll && ++itr != _contours.end());
    10721122
     
    15201570    _windowHeight = height;
    15211571    _renderWindow->SetSize(_windowWidth, _windowHeight);
    1522 #ifdef notdef
    1523     setCameraZoomRegion(_imgWorldOrigin[0], _imgWorldOrigin[1],
    1524                         _imgWorldDims[0], _imgWorldDims[1]);
    1525 #endif
     1572    if (_cameraMode == IMAGE) {
     1573        setCameraZoomRegion(_imgWorldOrigin[0], _imgWorldOrigin[1],
     1574                            _imgWorldDims[0], _imgWorldDims[1]);
     1575    }
    15261576    _needsRedraw = true;
    15271577}
     
    15771627}
    15781628
     1629/**
     1630 * \brief Get the current camera mode
     1631 */
     1632Renderer::CameraMode Renderer::getCameraMode() const
     1633{
     1634    return _cameraMode;
     1635}
     1636
    15791637void Renderer::storeCameraOrientation()
    15801638{
     
    16141672        _renderer->ResetCamera();
    16151673        _renderer->ResetCameraClippingRange();
    1616     }
     1674        computeScreenWorldCoords();
     1675    }
     1676    _cameraZoomRatio = 1;
     1677    _cameraPan[0] = 0;
     1678    _cameraPan[1] = 0;
    16171679    _needsRedraw = true;
    16181680}
     
    16351697    _renderer->ResetCameraClippingRange();
    16361698    storeCameraOrientation();
    1637     _needsRedraw = true;
    1638 }
    1639 
    1640 /**
    1641  * \brief Perform a relative 2D translation of the camera
    1642  *
    1643  * \param[in] x World coordinate horizontal panning
    1644  * \param[in] y World coordinate vertical panning
    1645  */
    1646 void Renderer::panCamera(double x, double y)
    1647 {
     1699    computeScreenWorldCoords();
     1700    _needsRedraw = true;
     1701}
     1702
     1703/**
     1704 * \brief Perform a 2D translation of the camera
     1705 *
     1706 * \param[in] x [0,1] Viewport coordinate horizontal panning
     1707 * \param[in] y [0,1] Viewport coordinate vertical panning (with origin at top)
     1708 * \param[in] absolute Control if pan amount is relative to current or absolute
     1709 */
     1710void Renderer::panCamera(double x, double y, bool absolute)
     1711{
     1712    // Reverse x rather than y, since we are panning the camera, and client
     1713    // expects to be panning/moving the object
     1714    x = -x * _screenWorldCoords[2];
     1715    y = y * _screenWorldCoords[3];
     1716
     1717    if (absolute) {
     1718        double panAbs[2];
     1719        panAbs[0] = x;
     1720        panAbs[1] = y;
     1721        x -= _cameraPan[0];
     1722        y -= _cameraPan[1];
     1723        _cameraPan[0] = panAbs[0];
     1724        _cameraPan[1] = panAbs[1];
     1725    } else {
     1726        _cameraPan[0] += x;
     1727        _cameraPan[1] += y;
     1728    }
    16481729    if (_cameraMode == IMAGE) {
    16491730        _imgWorldOrigin[0] += x;
     
    16511732        setCameraZoomRegion(_imgWorldOrigin[0], _imgWorldOrigin[1],
    16521733                            _imgWorldDims[0], _imgWorldDims[1]);
    1653         _needsRedraw = true;
    1654         return;
    1655     }
    1656     vtkSmartPointer<vtkCamera> camera = _renderer->GetActiveCamera();
    1657     vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
    1658     trans->Translate(x, y, 0);
    1659     camera->ApplyTransform(trans);
    1660     _renderer->ResetCameraClippingRange();
    1661     storeCameraOrientation();
     1734    } else {
     1735        vtkSmartPointer<vtkCamera> camera = _renderer->GetActiveCamera();
     1736        vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
     1737        trans->Translate(x, y, 0);
     1738        camera->ApplyTransform(trans);
     1739        _renderer->ResetCameraClippingRange();
     1740        storeCameraOrientation();
     1741        computeScreenWorldCoords();
     1742    }
    16621743    _needsRedraw = true;
    16631744}
     
    16671748 *
    16681749 * \param[in] z Ratio to change zoom (greater than 1 is zoom in, less than 1 is zoom out)
    1669  */
    1670 void Renderer::zoomCamera(double z)
    1671 {
     1750 * \param[in] absolute Control if zoom factor is relative to current setting or absolute
     1751 */
     1752void Renderer::zoomCamera(double z, bool absolute)
     1753{
     1754    if (absolute) {
     1755        assert(_cameraZoomRatio > 0.0);
     1756        double zAbs = z;
     1757        z *= 1.0/_cameraZoomRatio;
     1758        _cameraZoomRatio = zAbs;
     1759    } else {
     1760        _cameraZoomRatio *= z;
     1761    }
    16721762    if (_cameraMode == IMAGE) {
    16731763        double dx = _imgWorldDims[0];
     
    16811771        setCameraZoomRegion(_imgWorldOrigin[0], _imgWorldOrigin[1],
    16821772                            _imgWorldDims[0], _imgWorldDims[1]);
    1683         _needsRedraw = true;
    1684         return;
    1685     }
    1686     vtkSmartPointer<vtkCamera> camera = _renderer->GetActiveCamera();
    1687     camera->Zoom(z); // Change perspective FOV angle or ortho parallel scale
    1688     //camera->Dolly(z); // Move camera forward/back
    1689     _renderer->ResetCameraClippingRange();
    1690     storeCameraOrientation();
     1773    } else {
     1774        vtkSmartPointer<vtkCamera> camera = _renderer->GetActiveCamera();
     1775        camera->Zoom(z); // Change perspective FOV angle or ortho parallel scale
     1776        //camera->Dolly(z); // Move camera forward/back
     1777        _renderer->ResetCameraClippingRange();
     1778        storeCameraOrientation();
     1779    }
    16911780    _needsRedraw = true;
    16921781}
     
    17041793    double camPos[2];
    17051794
    1706     int pxOffsetX = 75;
     1795    int pxOffsetX = 85;
    17071796    int pxOffsetY = 75;
    17081797    int outerGutter = 15;
    17091798
    17101799    int imgHeightPx = _windowHeight - pxOffsetY - outerGutter;
    1711     double pxToWorld = height / imgHeightPx;
     1800    int imgWidthPx = _windowWidth - pxOffsetX - outerGutter;
     1801    double pxToWorld;
     1802    if (height > width)
     1803        pxToWorld = height / imgHeightPx;
     1804    else
     1805        pxToWorld = width / imgWidthPx;
    17121806    double offsetX = pxOffsetX * pxToWorld;
    17131807    double offsetY = pxOffsetY * pxToWorld;
     
    17491843                                _imgWorldOrigin[1], _imgWorldOrigin[1] + _imgWorldDims[1], 0, 0);
    17501844
     1845    // Compute screen world coordinates
     1846    computeScreenWorldCoords();
     1847
    17511848#ifdef DEBUG
    17521849    printCameraInfo(camera);
     
    17561853}
    17571854
     1855void Renderer::computeScreenWorldCoords()
     1856{
     1857    // Start with viewport coords [-1,1]
     1858    double x0 = -1;
     1859    double y0 = -1;
     1860    double z0 = 0;
     1861    double x1 = 1;
     1862    double y1 = 1;
     1863    double z1 = 0;
     1864
     1865    vtkMatrix4x4 *mat = vtkMatrix4x4::New();
     1866    double result[4];
     1867
     1868    // get the perspective transformation from the active camera
     1869    mat->DeepCopy(_renderer->GetActiveCamera()->
     1870                  GetCompositeProjectionTransformMatrix(_renderer->GetTiledAspectRatio(),0,1));
     1871
     1872    // use the inverse matrix
     1873    mat->Invert();
     1874
     1875    // Transform point to world coordinates
     1876    result[0] = x0;
     1877    result[1] = y0;
     1878    result[2] = z0;
     1879    result[3] = 1.0;
     1880
     1881    mat->MultiplyPoint(result, result);
     1882
     1883    // Get the transformed vector & set WorldPoint
     1884    // while we are at it try to keep w at one
     1885    if (result[3]) {
     1886        x0 = result[0] / result[3];
     1887        y0 = result[1] / result[3];
     1888        z0 = result[2] / result[3];
     1889    }
     1890
     1891    result[0] = x1;
     1892    result[1] = y1;
     1893    result[2] = z1;
     1894    result[3] = 1.0;
     1895
     1896    mat->MultiplyPoint(result, result);
     1897
     1898    if (result[3]) {
     1899        x1 = result[0] / result[3];
     1900        y1 = result[1] / result[3];
     1901        z1 = result[2] / result[3];
     1902    }
     1903
     1904    mat->Delete();
     1905
     1906    _screenWorldCoords[0] = x0;
     1907    _screenWorldCoords[1] = y0;
     1908    _screenWorldCoords[2] = x1 - x0;
     1909    _screenWorldCoords[3] = y1 - y0;
     1910}
     1911
     1912/**
     1913 * \brief Get the world coordinates of the image camera plot area
     1914 *
     1915 * \param[out] xywh Array to hold x,y,width,height world coordinates
     1916 */
     1917void Renderer::getCameraZoomRegion(double xywh[4]) const
     1918{
     1919    xywh[0] = _imgWorldOrigin[0];
     1920    xywh[1] = _imgWorldOrigin[1];
     1921    xywh[2] = _imgWorldDims[0];
     1922    xywh[3] = _imgWorldDims[1];
     1923}
     1924
     1925/**
     1926 * \brief Get the world origin and dimensions of the screen
     1927 *
     1928 * \param[out] xywh Array to hold x,y,width,height world coordinates
     1929 */
     1930void Renderer::getScreenWorldCoords(double xywh[4]) const
     1931{
     1932    memcpy(xywh, _screenWorldCoords, sizeof(double)*4);
     1933}
     1934
     1935/**
     1936 * \brief Compute bounding box containing the two input bounding boxes
     1937 *
     1938 * \param[out] boundsDest Union of the two input bounding boxes
     1939 * \param[in] bounds1 Input bounding box
     1940 * \param[in] bounds2 Input bounding box
     1941 */
    17581942void Renderer::mergeBounds(double *boundsDest,
    17591943                           const double *bounds1, const double *bounds2)
     
    18091993
    18101994/**
    1811  * \brief Update data ranges for color-mapping
     1995 * \brief Update data ranges for color-mapping and contours
    18121996 *
    18131997 * \param[in] useCumulative Use cumulative range of all DataSets
     
    18302014        }
    18312015    }
     2016    for (Contour2DHashmap::iterator itr = _contours.begin();
     2017         itr != _contours.end(); ++itr) {
     2018        // Only need to update range if using evenly spaced contours
     2019        if (itr->second->getContourList().empty()) {
     2020            if (useCumulative) {
     2021                itr->second->setContours(itr->second->getNumContours(), _cumulativeDataRange);
     2022            } else {
     2023                itr->second->setContours(itr->second->getNumContours());
     2024            }
     2025        }
     2026    }
    18322027}
    18332028
     
    18362031 *
    18372032 * \param[inout] range Data range of all DataSets
    1838  */
    1839 void Renderer::collectDataRanges(double *range)
     2033 * \param[in] onlyVisible Only collect range of visible DataSets
     2034 */
     2035void Renderer::collectDataRanges(double *range, bool onlyVisible)
    18402036{
    18412037    range[0] = DBL_MAX;
     
    18442040    for (DataSetHashmap::iterator itr = _dataSets.begin();
    18452041         itr != _dataSets.end(); ++itr) {
    1846         double r[2];
    1847         itr->second->getDataRange(r);
    1848         range[0] = min2(range[0], r[0]);
    1849         range[1] = max2(range[1], r[1]);
     2042        if (!onlyVisible || itr->second->getVisibility()) {
     2043            double r[2];
     2044            itr->second->getDataRange(r);
     2045            range[0] = min2(range[0], r[0]);
     2046            range[1] = max2(range[1], r[1]);
     2047        }
    18502048    }
    18512049    if (range[0] == DBL_MAX)
     
    18752073    _imgWorldDims[0] = bounds[1] - bounds[0];
    18762074    _imgWorldDims[1] = bounds[3] - bounds[2];
     2075    _cameraPan[0] = 0;
     2076    _cameraPan[1] = 0;
     2077    _cameraZoomRatio = 1;
    18772078
    18782079    if (_cameraMode == IMAGE) {
     
    18852086        resetAxes();
    18862087        _renderer->ResetCamera();
     2088        computeScreenWorldCoords();
    18872089    } else if (_cameraMode == PERSPECTIVE) {
    18882090        _renderer->GetActiveCamera()->ParallelProjectionOff();
    18892091        resetAxes();
    18902092        _renderer->ResetCamera();
     2093        computeScreenWorldCoords();
    18912094    }
    18922095}
     
    19332136void Renderer::setVisibility(const DataSetId& id, bool state)
    19342137{
     2138    DataSetHashmap::iterator itr;
     2139
     2140    bool doAll = false;
     2141
     2142    if (id.compare("all") == 0) {
     2143        itr = _dataSets.begin();
     2144        doAll = true;
     2145    } else {
     2146        itr = _dataSets.find(id);
     2147    }
     2148    if (itr == _dataSets.end()) {
     2149        ERROR("Unknown dataset %s", id.c_str());
     2150        return;
     2151    }
     2152
     2153    do {
     2154        itr->second->setVisibility(state);
     2155    } while (doAll && ++itr != _dataSets.end());
     2156
    19352157    setPseudoColorVisibility(id, state);
    19362158    setContourVisibility(id, state);
     
    20142236    double *worldCoords = coord->GetComputedWorldValue(_renderer);
    20152237
    2016 #ifdef DEBUG
    20172238    TRACE("Pixel coords: %d, %d\nWorld coords: %.12e, %.12e, %12e", x, y,
    20182239          worldCoords[0],
    20192240          worldCoords[1],
    20202241          worldCoords[2]);
    2021 #endif
    20222242
    20232243    return getDataValue(id, worldCoords[0], worldCoords[1], worldCoords[2]);
  • trunk/packages/vizservers/vtkvis/RpVtkRenderer.h

    r2146 r2194  
    8484    void setVisibility(const DataSetId& id, bool state);
    8585
     86    void setUseCumulativeDataRange(bool state, bool onlyVisible = false);
     87
    8688    // Render window
    8789
     
    9698    void setCameraMode(CameraMode mode);
    9799
     100    CameraMode getCameraMode() const;
     101
    98102    void resetCamera(bool resetOrientation = true);
    99103
    100104    void setCameraZoomRegion(double x, double y, double width, double height);
    101105
     106    void getCameraZoomRegion(double xywh[4]) const;
     107
     108    void getScreenWorldCoords(double xywh[4]) const;
     109
    102110    void rotateCamera(double yaw, double pitch, double roll);
    103111
    104     void panCamera(double x, double y);
    105 
    106     void zoomCamera(double z);
     112    void panCamera(double x, double y, bool absolute = true);
     113
     114    void zoomCamera(double z, bool absolute = true);
    107115
    108116    // Rendering an image
     
    228236    void collectBounds(double *bounds, bool onlyVisible);
    229237
    230     void collectDataRanges(double *range);
     238    void collectDataRanges(double *range, bool onlyVisible);
    231239
    232240    void updateRanges(bool useCumulative);
     241
     242    void computeScreenWorldCoords();
    233243
    234244    void storeCameraOrientation();
     
    242252    double _imgWorldOrigin[2];
    243253    double _imgWorldDims[2];
     254    double _screenWorldCoords[4];
    244255    double _cameraPos[3];
    245256    double _cameraFocalPoint[3];
    246257    double _cameraUp[3];
     258    double _cameraZoomRatio;
     259    double _cameraPan[2];
    247260    float _bgColor[3];
    248     bool _useCumulativeRanges;
     261    bool _useCumulativeRange;
     262    bool _cumulativeRangeOnlyVisible;
    249263    double _cumulativeDataRange[2];
    250264
  • trunk/packages/vizservers/vtkvis/RpVtkRendererCmd.cpp

    r2146 r2194  
    782782
    783783static int
     784DataSetMapRangeOp(ClientData clientData, Tcl_Interp *interp, int objc,
     785                  Tcl_Obj *const *objv)
     786{
     787    const char *value = Tcl_GetString(objv[2]);
     788    if (strcmp(value, "all") == 0) {
     789        g_renderer->setUseCumulativeDataRange(true);
     790    } else if (strcmp(value, "visible") == 0) {
     791        g_renderer->setUseCumulativeDataRange(true, true);
     792    } else if (strcmp(value, "separate") == 0) {
     793        g_renderer->setUseCumulativeDataRange(false);
     794    } else {
     795        return TCL_ERROR;
     796    }
     797    return TCL_OK;
     798}
     799
     800static int
    784801DataSetVisibleOp(ClientData clientData, Tcl_Interp *interp, int objc,
    785802                 Tcl_Obj *const *objv)
     
    802819    {"delete", 1, DataSetDeleteOp, 2, 3, "?name?"},
    803820    {"getvalue", 1, DataSetGetValueOp, 6, 7, "oper x y ?z? name"},
     821    {"maprange", 1, DataSetMapRangeOp, 3, 3, "value"},
    804822    {"opacity", 1, DataSetOpacityOp, 3, 4, "value ?name?"},
    805823    {"visible", 1, DataSetVisibleOp, 3, 4, "bool ?name?"}
  • trunk/packages/vizservers/vtkvis/protocol.txt

    r2146 r2194  
    4444dataset getvalue pixel <x> <y> <datasetName>
    4545        Use pixel for image camera mode
     46dataset maprange <val>
     47        <val> = all|visible|separate
     48        Controls if data range for colormapping and contours is based on
     49        cumulative range of all datasets ("all"), only visible datasets
     50        ("visible") or each individual dataset ("separate").  Defaults to
     51        "all"
    4652dataset opacity <val> <?datasetName?>
    4753dataset visible <bool> <?datasetName?>
     
    5864
    5965contour2d add numcontours <n> <?datasetName?>
     66          Generate evenly spaced contours including range endpoints.  See also
     67          'dataset maprange' command.
    6068contour2d add contourlist <list> <?datasetName?>
    6169          list = {isoval1 isoval2 isoval3...}
     
    8391nv>image -type image -bytes <nbytes>
    8492  <binary RGB data>
     93nv>image -type image -bbox {x1 y1 x2 y2} -bytes <nbytes>
     94  <binary RGB data>
     95  Note: in this form, the bbox is the upper left and lower right screen corners
     96  in world coordinates.  This form is currently used only if the camera mode is
     97  set to 'image'.
    8598nv>legend <colormapName> <nbytes>
    8699  <binary RGB data>
Note: See TracChangeset for help on using the changeset viewer.