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

Last change on this file since 3597 was 3597, checked in by ldelgass, 11 years ago

More refactoring in nanovis flows: Rename FlowCmd? to Flow and move to separate
implementation module. Move statis NanoVis? methods to nanovis.cpp from
FlowCmd?.cpp, remove more unused classes and code.

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