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