source: nanovis/branches/1.1/VolumeInterpolator.cpp @ 4874

Last change on this file since 4874 was 4874, checked in by ldelgass, 5 years ago

Add command line options to set I/O file descriptors, merge some refactoring to
prep for merging threading support.

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