source: branches/vtkvis_threaded/RpVolume.cpp @ 2549

Last change on this file since 2549 was 2402, checked in by ldelgass, 13 years ago
  • Let graphics objects handle DataSet? cumulative range changes, track vectors as well as scalars, also supply cumulative ranges in setDataSet()
  • Be more consistent about naming enums and commands for vectors
  • Add constructor arguments to some graphics objects to speed initialization (eliminates some pipeline changes)
  • Apply a scale factor to glyphs based on cell sizes
  • Add line glyph shape
  • Don't delete ColorMaps? in use
  • Update graphics objects when a ColorMap? is edited
  • Property svn:eol-style set to native
File size: 5.3 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(bool useCumulative,
119                          double scalarRange[2],
120                          double vectorMagnitudeRange[2],
121                          double vectorComponentRange[3][2])
122{
123    if (useCumulative) {
124        _dataRange[0] = scalarRange[0];
125        _dataRange[1] = scalarRange[1];
126    } else if (_dataSet != NULL) {
127        _dataSet->getScalarRange(_dataRange);
128    }
129
130    if (getVolume() != NULL) {
131        getVolume()->GetProperty()->SetColor(_colorMap->getColorTransferFunction(_dataRange));
132        getVolume()->GetProperty()->SetScalarOpacity(_colorMap->getOpacityTransferFunction(_dataRange));
133    }
134}
135void Volume::updateColorMap()
136{
137    setColorMap(_colorMap);
138}
139
140/**
141 * \brief Assign a color map (transfer function) to use in rendering the Volume
142 */
143void Volume::setColorMap(ColorMap *cmap)
144{
145    _colorMap = cmap;
146
147    if (getVolume() != NULL) {
148        getVolume()->GetProperty()->SetColor(_colorMap->getColorTransferFunction(_dataRange));
149        getVolume()->GetProperty()->SetScalarOpacity(_colorMap->getOpacityTransferFunction(_dataRange));
150    }
151}
152
153/**
154 * \brief Return the ColorMap assigned to this Volume
155 */
156ColorMap *Volume::getColorMap()
157{
158    return _colorMap;
159}
160
161/**
162 * \brief Set opacity scaling used to render the Volume
163 */
164void Volume::setOpacity(double opacity)
165{
166    _opacity = opacity;
167    // FIXME: There isn't really a good opacity scaling option that works
168    // across the different mappers/algorithms.  This only works with the
169    // 3D texture mapper, not the GPU raycast mapper
170    if (getVolume() != NULL) {
171        if (opacity < 1.0e-6)
172            opacity = 1.0e-6;
173        getVolume()->GetProperty()->SetScalarOpacityUnitDistance(1.0/opacity);
174    }
175}
176
177/**
178 * \brief Set a group of world coordinate planes to clip rendering
179 *
180 * Passing NULL for planes will remove all cliping planes
181 */
182void Volume::setClippingPlanes(vtkPlaneCollection *planes)
183{
184    if (_volumeMapper != NULL) {
185        _volumeMapper->SetClippingPlanes(planes);
186    }
187}
Note: See TracBrowser for help on using the repository browser.