source: vtkvis/trunk/Image.cpp @ 4635

Last change on this file since 4635 was 4255, checked in by ldelgass, 10 years ago

add method to set snapping to data slices

  • Property svn:eol-style set to native
File size: 7.8 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2004-2013  HUBzero Foundation, LLC
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#include <vtkSmartPointer.h>
9#include <vtkImageData.h>
10#include <vtkImageActor.h>
11#include <vtkImageSlice.h>
12#include <vtkImageProperty.h>
13#include <vtkImageMapper3D.h>
14#include <vtkImageResliceMapper.h>
15#include <vtkLookupTable.h>
16
17#include "Image.h"
18#include "Trace.h"
19
20using namespace VtkVis;
21
22#define USE_RESLICE_MAPPER
23
24Image::Image() :
25    GraphicsObject(),
26    _colorMap(NULL)
27{
28}
29
30Image::~Image()
31{
32    TRACE("Deleting Image");
33}
34
35void Image::initProp()
36{
37    if (_prop == NULL) {
38#ifdef USE_RESLICE_MAPPER
39        _prop = vtkSmartPointer<vtkImageSlice>::New();
40#else
41        _prop = vtkSmartPointer<vtkImageActor>::New();
42#endif
43        vtkImageProperty *property = getImageProperty();
44        property->SetInterpolationTypeToLinear();
45        property->SetBackingColor(_color[0], _color[1], _color[2]);
46        property->BackingOff();
47        if (_dataSet != NULL)
48            _opacity = _dataSet->getOpacity();
49        property->SetOpacity(_opacity);
50
51        if (_dataSet != NULL)
52            setVisibility(_dataSet->getVisibility());
53    }
54}
55
56void Image::update()
57{
58    if (_dataSet == NULL)
59        return;
60
61    TRACE("DataSet: %s", _dataSet->getName().c_str());
62
63    vtkDataSet *ds = _dataSet->getVtkDataSet();
64    vtkImageData *imageData = vtkImageData::SafeDownCast(ds);
65
66    if (imageData == NULL) {
67        ERROR("DataSet is not an image.");
68        return;
69    }
70
71    initProp();
72
73    vtkImageActor *actor = getImageActor();
74    vtkImageMapper3D *mapper = getImageMapper();
75    if (mapper == NULL) {
76        TRACE("Creating mapper");
77        vtkSmartPointer<vtkImageResliceMapper> newMapper = vtkSmartPointer<vtkImageResliceMapper>::New();
78        newMapper->AutoAdjustImageQualityOff();
79        getImageSlice()->SetMapper(newMapper);
80        mapper = getImageMapper();
81        assert(mapper != NULL);
82    }
83    if (actor != NULL) {
84        TRACE("Have actor");
85        actor->SetInputData(imageData);
86        actor->InterpolateOn();
87    } else {
88        TRACE("No actor");
89        mapper->SetInputData(imageData);
90    }
91
92    mapper->SliceAtFocalPointOn();
93    mapper->SliceFacesCameraOn();
94
95    vtkImageResliceMapper *resliceMapper = getImageResliceMapper();
96    if (resliceMapper) {
97        TRACE("Mapper is a vtkImageResliceMapper");
98        resliceMapper->AutoAdjustImageQualityOff();
99        resliceMapper->ResampleToScreenPixelsOff();
100    } else {
101        TRACE("Mapper is a %s", mapper->GetClassName());
102    }
103
104    mapper->Update();
105
106    TRACE("Window: %g Level: %g", getWindow(), getLevel());
107}
108
109void Image::setColor(float color[3])
110{
111    GraphicsObject::setColor(color);
112
113    if (getImageProperty() != NULL) {
114        getImageProperty()->SetBackingColor(color[0], color[1], color[2]);
115    }
116}
117
118/**
119 * \brief Associate a colormap lookup table with the DataSet
120 */
121void Image::setColorMap(ColorMap *cmap)
122{
123    if (cmap == NULL) {
124        _colorMap = NULL;
125        _lut = NULL;
126        if (getImageProperty() != NULL) {
127            getImageProperty()->SetLookupTable(NULL);
128        }
129        return;
130    }
131
132    _colorMap = cmap;
133 
134    if (_lut == NULL) {
135        _lut = vtkSmartPointer<vtkLookupTable>::New();
136        if (getImageProperty() != NULL) {
137            getImageProperty()->UseLookupTableScalarRangeOn();
138            getImageProperty()->SetLookupTable(_lut);
139        }
140        _lut->DeepCopy(cmap->getLookupTable());
141        _lut->SetRange(_dataRange);
142    } else {
143        double range[2];
144        _lut->GetTableRange(range);
145        _lut->DeepCopy(cmap->getLookupTable());
146        _lut->SetRange(range);
147        _lut->Modified();
148    }
149}
150
151void Image::setAspect(double aspect)
152{
153    double bounds[6];
154    vtkDataSet *ds = _dataSet->getVtkDataSet();
155    ds->GetBounds(bounds);
156    double size[3];
157    size[0] = bounds[1] - bounds[0];
158    size[1] = bounds[3] - bounds[2];
159    size[2] = bounds[5] - bounds[4];
160    double scale[3];
161    scale[0] = scale[1] = scale[2] = 1.;
162
163    vtkImageMapper3D *mapper = getImageMapper();
164    if (mapper == NULL)
165        return;
166
167    mapper->Update();
168
169    double normal[3];
170    mapper->GetSlicePlane()->GetNormal(normal);
171
172    Axis sliceAxis = Z_AXIS;
173    if (fabs(normal[0]) == 1.0 &&
174        normal[1] == 0.0 &&
175        normal[2] == 0.0) {
176        sliceAxis = X_AXIS;
177    } else if (normal[0] == 0.0 &&
178               fabs(normal[1]) == 1.0 &&
179               normal[2] == 0.0) {
180        sliceAxis = Y_AXIS;
181    } else if (normal[0] == 0.0 &&
182               normal[1] == 0.0 &&
183               fabs(normal[2]) == 1.0) {
184        sliceAxis = Z_AXIS;
185    } else {
186        TRACE("Non orthogonal slice plane, setting native aspect");
187        aspect = 0.0;
188    }
189
190    if (aspect == 1.0) {
191        // Square
192        switch (sliceAxis) {
193        case X_AXIS: {
194            if (size[1] > size[2] && size[2] > 0.0) {
195                scale[2] = size[1] / size[2];
196            } else if (size[2] > size[1] && size[1] > 0.0) {
197                scale[1] = size[2] / size[1];
198            }
199        }
200            break;
201        case Y_AXIS: {
202            if (size[0] > size[2] && size[2] > 0.0) {
203                scale[2] = size[0] / size[2];
204            } else if (size[2] > size[0] && size[0] > 0.0) {
205                scale[0] = size[2] / size[0];
206            }
207        }
208            break;
209        case Z_AXIS: {
210            if (size[0] > size[1] && size[1] > 0.0) {
211                scale[1] = size[0] / size[1];
212            } else if (size[1] > size[0] && size[0] > 0.0) {
213                scale[0] = size[1] / size[0];
214            }
215        }
216            break;
217        }
218    } else if (aspect != 0.0) {
219        switch (sliceAxis) {
220        case X_AXIS: {
221            if (aspect > 1.0) {
222                if (size[2] > size[1] && size[1] > 0.0) {
223                    scale[1] = (size[2] / aspect) / size[1];
224                } else if (size[2] > 0.0) {
225                    scale[2] = (size[1] * aspect) / size[2];
226                }
227            } else {
228                if (size[1] > size[2] && size[2] > 0.0) {
229                    scale[2] = (size[1] * aspect) / size[2];
230                } else if (size[1] > 0.0) {
231                    scale[1] = (size[2] / aspect) / size[1];
232                }
233            }
234        }
235            break;
236        case Y_AXIS: {
237            if (aspect > 1.0) {
238                if (size[0] > size[2] && size[2] > 0.0) {
239                    scale[2] = (size[0] / aspect) / size[2];
240                } else if (size[0] > 0.0) {
241                    scale[0] = (size[2] * aspect) / size[0];
242                }
243            } else {
244                if (size[2] > size[0] && size[0] > 0.0) {
245                    scale[0] = (size[2] * aspect) / size[0];
246                } else if (size[2] > 0.0) {
247                    scale[2] = (size[0] / aspect) / size[2];
248                }
249            }
250        }
251            break;
252        case Z_AXIS: {
253            if (aspect > 1.0) {
254                if (size[0] > size[1] && size[1] > 0.0) {
255                    scale[1] = (size[0] / aspect) / size[1];
256                } else if (size[0] > 0.0) {
257                    scale[0] = (size[1] * aspect) / size[0];
258                }
259            } else {
260                if (size[1] > size[0] && size[0] > 0.0) {
261                    scale[0] = (size[1] * aspect) / size[0];
262                } else if (size[1] > 0.0) {
263                    scale[1] = (size[0] / aspect) / size[1];
264                }
265            }
266        }
267            break;
268        }
269    }
270
271    TRACE("%s dims %g,%g,%g", _dataSet->getName().c_str(),
272          size[0], size[1], size[2]);
273    TRACE("Setting scale to %g,%g,%g", scale[0], scale[1], scale[2]);
274    setScale(scale);
275    mapper->Modified();
276    mapper->Update();
277}
278
279void Image::setClippingPlanes(vtkPlaneCollection *planes)
280{
281    vtkImageMapper3D *mapper = getImageMapper();
282    if (mapper != NULL) {
283        mapper->SetClippingPlanes(planes);
284    }
285}
Note: See TracBrowser for help on using the repository browser.