source: nanovis/branches/1.1/Volume.h @ 4988

Last change on this file since 4988 was 4904, checked in by ldelgass, 9 years ago

Merge serveral changes from trunk. Does not include threading, world space
changes, etc.

  • Property svn:eol-style set to native
File size: 9.5 KB
RevLine 
[2798]1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
[835]2/*
[4889]3 * Copyright (c) 2004-2013  HUBzero Foundation, LLC
[835]4 *
[4889]5 * Author:
6 *   Wei Qiao <qiaow@purdue.edu>
[835]7 */
[4889]8#ifndef NV_VOLUME_H
9#define NV_VOLUME_H
[835]10
[3492]11#include <cstring>
[835]12#include <string>
13#include <vector>
14
[3492]15#include <vrmath/Vector3f.h>
16
[835]17#include "Texture3D.h"
[929]18#include "AxisRange.h"
[1478]19#include "TransferFunction.h"
[835]20
[4889]21namespace nv {
22
[4904]23class CutPlane {
24public:
25    enum Axis {
26        X_AXIS = 1,
27        Y_AXIS = 2,
28        Z_AXIS = 3
29    };
[835]30
[4904]31    CutPlane(Axis _orient, float _offset) :
[2816]32        orient(_orient),
33        offset(_offset),
[2844]34        enabled(true)
[2816]35    {
[835]36    }
[4904]37
38    Axis orient;
39    float offset;       ///< normalized offset [0,1] in the volume
40    bool enabled;
[835]41};
42
[1478]43class VolumeInterpolator;
[835]44
[2816]45class Volume
46{
[1478]47public:
[2844]48    enum VolumeType {
49        CUBIC,
50        VOLQD,
51        ZINCBLENDE
52    };
[835]53
[2932]54    /**
55     * \brief Volume data constructor
56     *
57     * Represents a 3D regular grid with uniform spacing along
58     * each axis.  Sample spacing may differ between X, Y and Z
59     *
60     * \param x X location
61     * \param y Y location
62     * \param z Z location
63     * \param width Number of samples in X
64     * \param height Number of samples in Y
65     * \param depth Number of samples in Z
66     * \param numComponents Number of components per sample
67     * \param data width * height * depth * numComponent sample array
68     * \param vmin Scalar value minimum
69     * \param vmax Scalar value maximum
70     * \param nonZeroMin Scalar minimum which is greater than zero
71     */
[2844]72    Volume(float x, float y, float z,
73           int width, int height, int depth,
[3362]74           int numComponents,
[2844]75           float *data,
76           double vmin, double vmax,
[2877]77           double nonZeroMin);
[835]78
[2288]79    virtual ~Volume();
[2816]80
[3362]81    int width() const
82    {
83        return _width;
84    }
85
86    int height() const
87    {
88        return _height;
89    }
90
91    int depth() const
92    {
93        return _depth;
94    }
95
[2844]96    void visible(bool value)
97    {
98        _enabled = value;
[1474]99    }
[2844]100
101    bool visible() const
102    {
103        return _enabled;
[1474]104    }
[2844]105
106    int isosurface() const
107    {
[2877]108        return _isosurface;
[1478]109    }
[2844]110
111    void isosurface(int iso)
112    {
[2877]113        _isosurface = iso;
[1478]114    }
[2844]115
[2877]116    int numComponents() const
[2844]117    {
[2877]118        return _numComponents;
[1478]119    }
[2844]120
[2877]121    double nonZeroMin() const
[2844]122    {
[2877]123        return _nonZeroMin;
[1478]124    }
[2844]125
[2877]126    int volumeType() const
[2844]127    {
[2877]128        return _volumeType;
[1478]129    }
[2844]130
[3362]131    const float *data() const
[2844]132    {
133        return _data;
[1478]134    }
[1474]135
[3362]136    const Texture3D *tex() const
[2844]137    {
138        return _tex;
139    }
[3362]140
[2877]141    int numSlices() const
[2844]142    {
[2877]143        return _numSlices;
[1478]144    }
[2844]145
[2877]146    void numSlices(int n)
[2844]147    {
[2877]148        _numSlices = n;
[1478]149    }
[870]150
[2844]151    // methods related to cutplanes
152    /// add a plane and returns its index
[4904]153    int addCutplane(CutPlane::Axis orientation, float location);
[2844]154
[2877]155    void enableCutplane(int index);
[2844]156
[2877]157    void disableCutplane(int index);
[835]158
[4818]159    void cutplanesVisible(bool state)
160    {
161        _cutplanesVisible = state;
162    }
163
164    bool cutplanesVisible() const
165    {
166        return _cutplanesVisible;
167    }
168
[4904]169    void setCutplanePosition(int index, float location);
[2844]170
[2877]171    CutPlane *getCutplane(int index);
[2844]172
173    /// returns the number of cutplanes in the volume
[2877]174    int getCutplaneCount();
[2844]175
176    /// check if a cutplane is enabled
[2877]177    bool isCutplaneEnabled(int index) const;
[2844]178
179    // methods related to shading. These parameters are per volume
[2877]180
[3362]181    /// Get ambient coefficient
182    float ambient() const
[2844]183    {
[3362]184        return _ambient;
[1474]185    }
[2844]186
[3362]187    /// Set ambient coefficient [0,1]
188    void ambient(float value)
[2844]189    {
[2877]190        if (value < 0.0f) value = 0.0f;
[3362]191        if (value > 1.0f) value = 1.0f;
192        _ambient = value;
[1474]193    }
[2844]194
[2877]195    /// Get diffuse coefficient
[2844]196    float diffuse() const
197    {
198        return _diffuse;
[1474]199    }
[2844]200
[2877]201    /// Set diffuse coefficient [0,1]
[2844]202    void diffuse(float value)
203    {
[2877]204        if (value < 0.0f) value = 0.0f;
205        if (value > 1.0f) value = 1.0f;
[2844]206        _diffuse = value;
[1474]207    }
[2844]208
[3362]209    /// Get specular coefficient
210    float specularLevel() const
211    {
212        return _specular;
213    }
214
215    /// Set specular coefficient [0,1]
216    void specularLevel(float value)
217    {
218        if (value < 0.0f) value = 0.0f;
219        if (value > 1.0f) value = 1.0f;
220        _specular = value;
221    }
222
223    /// Get specular exponent
224    float specularExponent() const
225    {
226        return _specularExp;
227    }
228
229    /// Set specular exponent [0,128]
230    void specularExponent(float value)
231    {
232        if (value < 0.0f) value = 0.0f;
233        if (value > 128.0f) value = 128.0f;
234        _specularExp = value;
235    }
236
237    bool twoSidedLighting() const
238    {
239        return _lightTwoSide;
240    }
241
242    void twoSidedLighting(bool value)
243    {
244        _lightTwoSide = value;
245    }
246
[2877]247    float opacityScale() const
[2844]248    {
[2877]249        return _opacityScale;
[1474]250    }
[2844]251
[2877]252    void opacityScale(float value)
[2844]253    {
[2877]254        _opacityScale = value;
[1474]255    }
[2844]256
[2877]257    void dataEnabled(bool value)
[2844]258    {
[2877]259        _dataEnabled = value;
[1474]260    }
[2844]261
[2877]262    bool dataEnabled() const
[2844]263    {
[2877]264        return _dataEnabled;
[1474]265    }
[2844]266
267    void outline(bool value)
268    {
[2877]269        _outlineEnabled = value;
[1474]270    }
[2844]271
272    bool outline()
273    {
[2877]274        return _outlineEnabled;
[1474]275    }
[2844]276
277    TransferFunction *transferFunction()
278    {
[4612]279        return _transferFunc;
[1478]280    }
[2844]281
[4612]282    void transferFunction(TransferFunction *transferFunc)
[2844]283    {
[4612]284        _transferFunc = transferFunc;
[1478]285    }
[2844]286
[2877]287    void setOutlineColor(float *rgb);
[2844]288
[2877]289    void getOutlineColor(float *rgb);
290
[4904]291    void setPosition(const vrmath::Vector3f& pos)
292    {
293        _position = pos;
294    }
295
296    const vrmath::Vector3f& getPosition() const
297    {
298        return _position;
299    }
300
[3492]301    vrmath::Vector3f getPhysicalScaling() const
[3362]302    {
[3492]303        vrmath::Vector3f scale;
[3362]304        scale.x = 1;
305        scale.y = yAxis.length() / xAxis.length();
306        scale.z = zAxis.length() / xAxis.length();
307        return scale;
308    }
[1475]309
[4904]310    void setScale(const vrmath::Vector3f& scale)
311    {
312        _scale = scale;
313    }
314
315    const vrmath::Vector3f& getScale() const
316    {
317        return _scale;
318    }
319
[3492]320    void getWorldSpaceBounds(vrmath::Vector3f& bboxMin,
321                             vrmath::Vector3f& bboxMax) const;
322 
[3362]323    double sampleDistanceX() const
324    {
325        return (xAxis.length() / ((double)_width-1.0));
326    }
[2844]327
[3362]328    double sampleDistanceY() const
329    {
330        return (yAxis.length() / ((double)_height-1.0));
331    }
[2844]332
[3362]333    double sampleDistanceZ() const
334    {
335        if (_depth == 1)
336            return sampleDistanceX();
337        return (zAxis.length() / ((double)_depth-1.0));
338    }
339
[2844]340    const char *name() const
341    {
[3567]342        return _name.c_str();
[1478]343    }
[2844]344
345    void name(const char *name)
346    {
347        _name = name;
[1478]348    }
[2844]349
[3362]350    GLuint textureID() const
351    {
352        return _id;
353    }
[2844]354
[3362]355    AxisRange xAxis, yAxis, zAxis, wAxis;
[2844]356
[3362]357    static bool updatePending;
358    static double valueMin, valueMax;
359
360    friend class VolumeInterpolator;
361
362protected:
363    float *data()
364    {
365        return _data;
366    }
367
368    Texture3D *tex()
369    {
370        return _tex;
371    }
372
373    GLuint _id;         ///< OpenGL textue identifier (==_tex->id)
374
[2844]375    // Width, height and depth are point resolution, NOT physical
376    // units
377    /// The resolution of the data (how many points in X direction)
[3362]378    int _width;
[2844]379    /// The resolution of the data (how many points in Y direction)
[3362]380    int _height;
[2844]381    /// The resolution of the data (how many points in Z direction)
[3362]382    int _depth;
[2844]383
384    /**
385     * This is the designated transfer function to use to
386     * render this volume.
387     */
[4612]388    TransferFunction *_transferFunc;
[2844]389
[3362]390    float _ambient;      ///< Ambient material coefficient
391    float _diffuse;      ///< Diffuse material coefficient
392    float _specular;     ///< Specular level material coefficient
393    float _specularExp;  ///< Specular exponent
394    bool _lightTwoSide;  ///< Two-sided lighting flag
395
[2844]396    /**
397     * The scale multiplied to the opacity assigned by the
[4904]398     * transfer function.
[2844]399     */
[2877]400    float _opacityScale;
[2844]401
[3567]402    std::string _name;
403
[2844]404    float *_data;
405
[2877]406    int _numComponents;
[2844]407
[2877]408    double _nonZeroMin;
[2844]409
[4818]410    bool _cutplanesVisible;
[2844]411    std::vector<CutPlane> _plane; ///< cut planes
412
413    Texture3D *_tex;            ///< OpenGL texture storing the volume
414
[4904]415    vrmath::Vector3f _position;
416    vrmath::Vector3f _scale;
[2844]417
418    /**
419     * Number of slices when rendered. The greater
420     * the better quality, lower speed.
421     */
[2877]422    int _numSlices;
[2844]423    bool _enabled;
[2877]424    bool _dataEnabled;          ///< show/hide cloud of volume data
425    bool _outlineEnabled;       ///< show/hide outline around volume
[3492]426    float _outlineColor[3];     ///< color for outline around volume
[2877]427    int _volumeType;            ///< cubic or zincblende
428    int _isosurface;
[835]429};
430
[2816]431inline int
[4904]432Volume::addCutplane(CutPlane::Axis orientation, float location)
[2816]433{
434    _plane.push_back(CutPlane(orientation, location));
[1478]435    return _plane.size() - 1;
[849]436}
437
[927]438inline void
[2877]439Volume::enableCutplane(int index)
[927]440{
[849]441    //assert(index < plane.size());
[1478]442    _plane[index].enabled = true;
[849]443}
[3362]444
[927]445inline void
[2877]446Volume::disableCutplane(int index)
[927]447{
[849]448    //assert(index < plane.size());
[1478]449    _plane[index].enabled = false;
[849]450}
451
[927]452inline void
[4904]453Volume::setCutplanePosition(int index, float position)
[927]454{
[849]455    //assert(index < plane.size());
[4904]456    _plane[index].offset = position;
[849]457}
458
[2844]459inline CutPlane *
[2877]460Volume::getCutplane(int index)
[927]461{
[849]462    //assert(index < plane.size());
[1478]463    return &_plane[index];
[849]464}
465
[927]466inline int
[2877]467Volume::getCutplaneCount()
[927]468{
[1478]469    return _plane.size();
[849]470}
471
[927]472inline bool
[2877]473Volume::isCutplaneEnabled(int index) const
[927]474{
[849]475    //assert(index < plane.size());
[1478]476    return _plane[index].enabled;
[849]477}
478
[927]479inline void
[2877]480Volume::setOutlineColor(float *rgb)
[927]481{
[3492]482    memcpy(_outlineColor, rgb, sizeof(float)*3);
[849]483}
484
[927]485inline void
[2877]486Volume::getOutlineColor(float *rgb)
[927]487{
[3492]488    memcpy(rgb, _outlineColor, sizeof(float)*3);
[849]489}
490
[4889]491}
492
[835]493#endif
Note: See TracBrowser for help on using the repository browser.