source: trunk/packages/vizservers/nanovis/VolumeInterpolator.cpp @ 2892

Last change on this file since 2892 was 2877, checked in by ldelgass, 12 years ago

Some minor refactoring, also add some more fine grained config.h defines
(e.g. replace NV40 define with feature defines). Add tests for some required
OpenGL extensions (should always check for extensions or base version before
calling entry points from the extension). Also, clamp diffuse and specular
values on input and warn when they are out of range.

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2#include <string.h>
3#include <memory.h>
4#include <time.h>
5#include <sys/time.h>
6#include <math.h>
7#include <stdlib.h>
8
9#include "VolumeInterpolator.h"
10#include "Volume.h"
11#include "Vector3.h"
12#include "Trace.h"
13
14VolumeInterpolator::VolumeInterpolator() :
15    _volume(0),
16    _interval(8.0),
17    _started(false),
18    _numBytes(0),
19    _dataCount(0),
20    _numComponents(0),
21    _referenceOfVolume(0)
22{
23}
24
25void VolumeInterpolator::start()
26{
27    if (_volumes.size() > 0) {
28        TRACE("\tVolume Interpolation Started\n");
29        _started = true;
30    } else {
31        TRACE("\tVolume Interpolation did not get started\n");
32        _started = false;
33    }
34    struct timeval clock;
35    gettimeofday(&clock, NULL);
36    _startTime = clock.tv_sec + clock.tv_usec/1000000.0;
37    TRACE("End Start - VolumeInterpolator\n");
38}
39
40void VolumeInterpolator::stop()
41{
42    _started = false;
43}
44
45Volume *VolumeInterpolator::update(float fraction)
46{
47    int key1, key2;
48    float interp;
49
50    computeKeys(fraction, _volumes.size(), &interp, &key1, &key2);
51
52    if (interp == 0.0f) {
53        memcpy(_volume->data(), _volumes[key1]->data(), _numBytes);
54        _volume->tex()->update(_volume->data());
55    } else {
56        float *data1 = _volumes[key1]->data();
57        float *data2 = _volumes[key2]->data();
58        float *result = _volume->data();
59
60        Vector3 normal1, normal2, normal;
61        for (unsigned int i = 0; i < _dataCount; ++i) {
62            *result = interp * (*data2 - *data1) + *data1;
63            normal1 = (*(Vector3*)(data1 + 1) - 0.5) * 2;
64            normal2 = (*(Vector3*)(data2 + 1) - 0.5) * 2;
65            normal = (normal2 - normal2) * interp + normal1;
66            normal = normal.normalize();
67            normal = normal * 0.5 + 0.5;
68            *((Vector3*)(result + 1)) = normal;
69
70            result += _numComponents;
71            data1 += _numComponents;
72            data2 += _numComponents;
73        }
74
75        _volume->tex()->update(_volume->data());
76    }
77
78    return _volume;
79}
80
81void
82VolumeInterpolator::computeKeys(float fraction, int count, float *interp,
83                                int *key1, int *key2)
84{
85    int limit = (int) count - 1;
86    if (fraction <= 0) {
87        *key1 = *key2 = 0;
88        *interp = 0.0f;
89    } else if (fraction >= 1.0f) {
90        *key1 = *key2 = limit;
91        *interp = 0.0f;
92    } else {
93        int n;
94        for (n = 0; n < limit; n++){
95            if (fraction >= (n / (count - 1.0f)) &&
96                fraction < ((n+1)/(count-1.0f))) {
97                break;
98            }
99        }
100
101        TRACE("n = %d count = %d\n", n, count);
102        if (n >= limit) {
103            *key1 = *key2 = limit;
104            *interp = 0.0f;
105        } else {
106            *key1 = n;
107            *key2 = n+1;
108            *interp = (fraction - (n / (count -1.0f))) / ((n + 1) / (count - 1.0f) - n / (count - 1.0f));
109            //*ret = inter * (keyValue[n + 1] - keyValue[n]) + keyValue[n];
110        }
111    }
112}
113
114void
115VolumeInterpolator::clearAll()
116{
117    _volumes.clear();
118}
119
120void
121VolumeInterpolator::addVolume(Volume *refPtr)
122{
123    if (_volumes.size() != 0) {
124        if (_volumes[0]->width != refPtr->width ||
125            _volumes[0]->height != refPtr->height ||   
126            _volumes[0]->depth != refPtr->depth ||
127            _volumes[0]->numComponents() != refPtr->numComponents()) {
128            TRACE("The volume should be the same width, height, number of components\n");
129            return;
130        }
131    } else {
132        _dataCount = refPtr->width * refPtr->height * refPtr->depth;
133        _numComponents = refPtr->numComponents();
134        _numBytes = _dataCount * _numComponents * sizeof(float);
135        Vector3 loc = refPtr->location();
136        _volume = new Volume(loc.x, loc.y, loc.z,
137                             refPtr->width, refPtr->height, refPtr->depth,
138                             refPtr->size,
139                             refPtr->numComponents(),
140                             refPtr->data(),
141                             refPtr->wAxis.min(),
142                             refPtr->wAxis.max(),
143                             refPtr->nonZeroMin());
144        /*
145        _referenceOfVolume = refPtr->dataID();
146        */
147        _volume->numSlices(256-1);
148        _volume->disableCutplane(0);
149        _volume->disableCutplane(1);
150        _volume->disableCutplane(2);
151        _volume->visible(true);
152        _volume->dataEnabled(true);
153        _volume->specular(refPtr->specular());
154        _volume->diffuse(refPtr->diffuse());
155        _volume->opacityScale(refPtr->opacityScale());
156        _volume->isosurface(0);
157        TRACE("VOL : location %f %f %f\n\tid : %s\n", loc.x, loc.y, loc.z,
158               refPtr->name());
159    }
160    _volumes.push_back(_volume);
161    TRACE("a Volume[%s] is added to VolumeInterpolator\n", refPtr->name());
162}
163
164Volume *VolumeInterpolator::getVolume()
165{
166    return _volume;
167    //return _volumes[0];
168}
Note: See TracBrowser for help on using the repository browser.