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

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

Remove unused global origin, make default transfer function a bit more
sensible (used to have full opacity at 0). Fix HeightMap? dtor to use delete[]
instead of free() on array allocated with new[]. Document data response in
protocol.

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