source: branches/blt4/packages/vizservers/vtkvis/RpVolume.cpp @ 2681

Last change on this file since 2681 was 2681, checked in by gah, 12 years ago
File size: 5.1 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2011, Purdue Research Foundation
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#include <cassert>
9
10#include <vtkDataSet.h>
11#include <vtkPointData.h>
12#include <vtkImageData.h>
13#include <vtkVolumeProperty.h>
14#include <vtkGPUVolumeRayCastMapper.h>
15#include <vtkVolumeTextureMapper3D.h>
16#include <vtkUnstructuredGrid.h>
17#include <vtkCellType.h>
18#include <vtkUnstructuredGridVolumeMapper.h>
19#include <vtkUnstructuredGridVolumeRayCastMapper.h>
20#include <vtkProjectedTetrahedraMapper.h>
21#include <vtkDataSetTriangleFilter.h>
22
23#include "RpVolume.h"
24#include "Trace.h"
25
26using namespace Rappture::VtkVis;
27
28Volume::Volume() :
29    VtkGraphicsObject(),
30    _colorMap(NULL)
31{
32}
33
34Volume::~Volume()
35{
36#ifdef WANT_TRACE
37    if (_dataSet != NULL)
38        TRACE("Deleting Volume for %s", _dataSet->getName().c_str());
39    else
40        TRACE("Deleting Volume with NULL DataSet");
41#endif
42}
43
44/**
45 * \brief Create and initialize a VTK Prop to render the Volume
46 */
47void Volume::initProp()
48{
49    if (_prop == NULL) {
50        _prop = vtkSmartPointer<vtkVolume>::New();
51        getVolume()->GetProperty()->SetInterpolationTypeToLinear();
52    }
53}
54
55/**
56 * \brief Internal method to set up pipeline after a state change
57 */
58void Volume::update()
59{
60    if (_dataSet == NULL)
61        return;
62
63    vtkDataSet *ds = _dataSet->getVtkDataSet();
64
65    if (vtkImageData::SafeDownCast(ds) != NULL) {
66        // Image data required for these mappers
67#ifdef USE_GPU_RAYCAST_MAPPER
68        _volumeMapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
69#else
70        _volumeMapper = vtkSmartPointer<vtkVolumeTextureMapper3D>::New();
71#endif
72        _volumeMapper->SetInput(ds);
73        vtkVolumeMapper::SafeDownCast(_volumeMapper)->SetBlendModeToComposite();       
74    } else if (vtkUnstructuredGrid::SafeDownCast(ds) != NULL) {
75        vtkUnstructuredGrid *ugrid = vtkUnstructuredGrid::SafeDownCast(ds);
76        // DataSet is unstructured grid
77        // Only works if cells are all tetrahedra
78        _volumeMapper = vtkSmartPointer<vtkProjectedTetrahedraMapper>::New();
79        // Software raycast rendering - requires all tetrahedra
80        //_volumeMapper = vtkSmartPointer<vtkUnstructuredGridVolumeRayCastMapper>::New();
81        if (ugrid->GetCellType(0) == VTK_TETRA &&
82            ugrid->IsHomogeneous()) {
83            _volumeMapper->SetInput(ds);
84        } else {
85            // Decompose to tetrahedra
86            vtkSmartPointer<vtkDataSetTriangleFilter> filter =
87                vtkSmartPointer<vtkDataSetTriangleFilter>::New();
88            filter->SetInput(ugrid);
89            filter->TetrahedraOnlyOn();
90            _volumeMapper->SetInputConnection(filter->GetOutputPort());
91        }
92
93        vtkUnstructuredGridVolumeMapper::SafeDownCast(_volumeMapper)->
94            SetBlendModeToComposite();
95    } else {
96        ERROR("Unsupported DataSet type: %s", _dataSet->getVtkType());
97        _dataSet = NULL;
98        return;
99    }
100
101    TRACE("Using mapper type: %s", _volumeMapper->GetClassName());
102
103    initProp();
104
105    if (ds->GetPointData() == NULL ||
106        ds->GetPointData()->GetScalars() == NULL) {
107        WARN("No scalar point data in dataset %s", _dataSet->getName().c_str());
108    }
109
110    if (_colorMap == NULL) {
111        setColorMap(ColorMap::getVolumeDefault());
112    }
113
114    getVolume()->SetMapper(_volumeMapper);
115    _volumeMapper->Update();
116}
117
118void Volume::updateRanges(Renderer *renderer)
119{
120    VtkGraphicsObject::updateRanges(renderer);
121
122    if (getVolume() != NULL) {
123        getVolume()->GetProperty()->SetColor(_colorMap->getColorTransferFunction(_dataRange));
124        getVolume()->GetProperty()->SetScalarOpacity(_colorMap->getOpacityTransferFunction(_dataRange));
125    }
126}
127
128void Volume::updateColorMap()
129{
130    setColorMap(_colorMap);
131}
132
133/**
134 * \brief Assign a color map (transfer function) to use in rendering the Volume
135 */
136void Volume::setColorMap(ColorMap *cmap)
137{
138    if (cmap == NULL)
139        return;
140
141    _colorMap = cmap;
142
143    if (getVolume() != NULL) {
144        getVolume()->GetProperty()->SetColor(_colorMap->getColorTransferFunction(_dataRange));
145        getVolume()->GetProperty()->SetScalarOpacity(_colorMap->getOpacityTransferFunction(_dataRange));
146    }
147}
148
149/**
150 * \brief Return the ColorMap assigned to this Volume
151 */
152ColorMap *Volume::getColorMap()
153{
154    return _colorMap;
155}
156
157/**
158 * \brief Set opacity scaling used to render the Volume
159 */
160void Volume::setOpacity(double opacity)
161{
162    _opacity = opacity;
163    // FIXME: There isn't really a good opacity scaling option that works
164    // across the different mappers/algorithms.  This only works with the
165    // 3D texture mapper, not the GPU raycast mapper
166    if (getVolume() != NULL) {
167        if (opacity < 1.0e-6)
168            opacity = 1.0e-6;
169        getVolume()->GetProperty()->SetScalarOpacityUnitDistance(1.0/opacity);
170    }
171}
172
173/**
174 * \brief Set a group of world coordinate planes to clip rendering
175 *
176 * Passing NULL for planes will remove all cliping planes
177 */
178void Volume::setClippingPlanes(vtkPlaneCollection *planes)
179{
180    if (_volumeMapper != NULL) {
181        _volumeMapper->SetClippingPlanes(planes);
182    }
183}
Note: See TracBrowser for help on using the repository browser.