forked from Kitware/VTK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vtkEncodedGradientEstimator.h
259 lines (209 loc) · 7.81 KB
/
vtkEncodedGradientEstimator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/*=========================================================================
Program: Visualization Toolkit
Module: vtkEncodedGradientEstimator.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/**
* @class vtkEncodedGradientEstimator
* @brief Superclass for gradient estimation
*
* vtkEncodedGradientEstimator is an abstract superclass for gradient
* estimation. It takes a scalar input of vtkImageData, computes
* a gradient value for every point, and encodes this value into a
* three byte value (2 for direction, 1 for magnitude) using the
* vtkDirectionEncoder. The direction encoder is defaulted to a
* vtkRecursiveSphereDirectionEncoder, but can be overridden with the
* SetDirectionEncoder method. The scale and the bias values for the gradient
* magnitude are used to convert it into a one byte value according to
* v = m*scale + bias where m is the magnitude and v is the resulting
* one byte value.
* @sa
* vtkFiniteDifferenceGradientEstimator vtkDirectionEncoder
*/
#ifndef vtkEncodedGradientEstimator_h
#define vtkEncodedGradientEstimator_h
#include "vtkRenderingVolumeModule.h" // For export macro
#include "vtkObject.h"
class vtkImageData;
class vtkDirectionEncoder;
class vtkMultiThreader;
class VTKRENDERINGVOLUME_EXPORT vtkEncodedGradientEstimator : public vtkObject
{
public:
vtkTypeMacro(vtkEncodedGradientEstimator,vtkObject);
void PrintSelf( ostream& os, vtkIndent indent ) override;
//@{
/**
* Set/Get the scalar input for which the normals will be
* calculated. Note that this call does not setup a pipeline
* connection. vtkEncodedGradientEstimator is not an algorithm
* and does not update its input. If you are directly using this
* class, you may need to manually update the algorithm that produces
* this data object.
*/
virtual void SetInputData(vtkImageData*);
vtkGetObjectMacro( InputData, vtkImageData );
//@}
//@{
/**
* Set/Get the scale and bias for the gradient magnitude
*/
vtkSetMacro( GradientMagnitudeScale, float );
vtkGetMacro( GradientMagnitudeScale, float );
vtkSetMacro( GradientMagnitudeBias, float );
vtkGetMacro( GradientMagnitudeBias, float );
//@}
//@{
/**
* Turn on / off the bounding of the normal computation by
* the this->Bounds bounding box
*/
vtkSetClampMacro( BoundsClip, int, 0, 1 );
vtkGetMacro( BoundsClip, int );
vtkBooleanMacro( BoundsClip, int );
//@}
//@{
/**
* Set / Get the bounds of the computation (used if
* this->ComputationBounds is 1.) The bounds are specified
* xmin, xmax, ymin, ymax, zmin, zmax.
*/
vtkSetVector6Macro( Bounds, int );
vtkGetVectorMacro( Bounds, int, 6 );
//@}
/**
* Recompute the encoded normals and gradient magnitudes.
*/
void Update( void );
/**
* Get the encoded normals.
*/
unsigned short *GetEncodedNormals( void );
//@{
/**
* Get the encoded normal at an x,y,z location in the volume
*/
int GetEncodedNormalIndex( vtkIdType xyz_index );
int GetEncodedNormalIndex( int x_index, int y_index, int z_index );
//@}
/**
* Get the gradient magnitudes
*/
unsigned char *GetGradientMagnitudes(void);
//@{
/**
* Get/Set the number of threads to create when encoding normals
* This defaults to the number of available processors on the machine
*/
vtkSetClampMacro( NumberOfThreads, int, 1, VTK_MAX_THREADS );
vtkGetMacro( NumberOfThreads, int );
//@}
//@{
/**
* Set / Get the direction encoder used to encode normal directions
* to fit within two bytes
*/
void SetDirectionEncoder( vtkDirectionEncoder *direnc );
vtkGetObjectMacro( DirectionEncoder, vtkDirectionEncoder );
//@}
//@{
/**
* If you don't want to compute gradient magnitudes (but you
* do want normals for shading) this can be used. Be careful - if
* if you a non-constant gradient magnitude transfer function and
* you turn this on, it may crash
*/
vtkSetMacro( ComputeGradientMagnitudes, int );
vtkGetMacro( ComputeGradientMagnitudes, int );
vtkBooleanMacro( ComputeGradientMagnitudes, int );
//@}
//@{
/**
* If the data in each slice is only contained within a circle circumscribed
* within the slice, and the slice is square, then don't compute anything
* outside the circle. This circle through the slices forms a cylinder.
*/
vtkSetMacro( CylinderClip, int );
vtkGetMacro( CylinderClip, int );
vtkBooleanMacro( CylinderClip, int );
//@}
//@{
/**
* Get the time required for the last update in seconds or cpu seconds
*/
vtkGetMacro( LastUpdateTimeInSeconds, float );
vtkGetMacro( LastUpdateTimeInCPUSeconds, float );
//@}
vtkGetMacro( UseCylinderClip, int );
int *GetCircleLimits() { return this->CircleLimits; };
//@{
/**
* Set / Get the ZeroNormalThreshold - this defines the minimum magnitude
* of a gradient that is considered sufficient to define a
* direction. Gradients with magnitudes at or less than this value are given
* a "zero normal" index. These are handled specially in the shader,
* and you can set the intensity of light for these zero normals in
* the gradient shader.
*/
void SetZeroNormalThreshold( float v );
vtkGetMacro( ZeroNormalThreshold, float );
//@}
//@{
/**
* Assume that the data value outside the volume is zero when
* computing normals.
*/
vtkSetClampMacro( ZeroPad, int, 0, 1 );
vtkGetMacro( ZeroPad, int );
vtkBooleanMacro( ZeroPad, int );
//@}
// These variables should be protected but are being
// made public to be accessible to the templated function.
// We used to have the templated function as a friend, but
// this does not work with all compilers
// The input scalar data on which the normals are computed
vtkImageData *InputData;
// The encoded normals (2 bytes) and the size of the encoded normals
unsigned short *EncodedNormals;
int EncodedNormalsSize[3];
// The magnitude of the gradient array and the size of this array
unsigned char *GradientMagnitudes;
// The time at which the normals were last built
vtkTimeStamp BuildTime;
vtkGetVectorMacro( InputSize, int, 3 );
vtkGetVectorMacro( InputAspect, float, 3 );
protected:
vtkEncodedGradientEstimator();
~vtkEncodedGradientEstimator() override;
void ReportReferences(vtkGarbageCollector*) override;
// The number of threads to use when encoding normals
int NumberOfThreads;
vtkMultiThreader *Threader;
vtkDirectionEncoder *DirectionEncoder;
virtual void UpdateNormals( void ) = 0;
float GradientMagnitudeScale;
float GradientMagnitudeBias;
float LastUpdateTimeInSeconds;
float LastUpdateTimeInCPUSeconds;
float ZeroNormalThreshold;
int CylinderClip;
int *CircleLimits;
int CircleLimitsSize;
int UseCylinderClip;
void ComputeCircleLimits( int size );
int BoundsClip;
int Bounds[6];
int InputSize[3];
float InputAspect[3];
int ComputeGradientMagnitudes;
int ZeroPad;
private:
vtkEncodedGradientEstimator(const vtkEncodedGradientEstimator&) = delete;
void operator=(const vtkEncodedGradientEstimator&) = delete;
};
#endif