1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkImageSinusoidSource.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkImageSinusoidSource.h"
16
17 #include "vtkImageData.h"
18 #include "vtkInformation.h"
19 #include "vtkInformationVector.h"
20 #include "vtkMath.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkStreamingDemandDrivenPipeline.h"
23
24 #include <cmath>
25
26 vtkStandardNewMacro(vtkImageSinusoidSource);
27
28 //------------------------------------------------------------------------------
vtkImageSinusoidSource()29 vtkImageSinusoidSource::vtkImageSinusoidSource()
30 {
31 this->Direction[0] = 1.0;
32 this->Direction[1] = 0.0;
33 this->Direction[2] = 0.0;
34
35 this->Amplitude = 255.0;
36 this->Phase = 0.0;
37 this->Period = 20.0;
38
39 this->WholeExtent[0] = 0;
40 this->WholeExtent[1] = 255;
41 this->WholeExtent[2] = 0;
42 this->WholeExtent[3] = 255;
43 this->WholeExtent[4] = 0;
44 this->WholeExtent[5] = 0;
45
46 this->SetNumberOfInputPorts(0);
47 }
48
SetDirection(double v[3])49 void vtkImageSinusoidSource::SetDirection(double v[3])
50 {
51 this->SetDirection(v[0], v[1], v[2]);
52 }
53
SetDirection(double v0,double v1,double v2)54 void vtkImageSinusoidSource::SetDirection(double v0, double v1, double v2)
55 {
56 double sum;
57
58 sum = v0 * v0 + v1 * v1 + v2 * v2;
59
60 if (sum == 0.0)
61 {
62 vtkErrorMacro("Zero direction vector");
63 return;
64 }
65
66 // normalize
67 sum = 1.0 / sqrt(sum);
68 v0 *= sum;
69 v1 *= sum;
70 v2 *= sum;
71
72 if (this->Direction[0] == v0 && this->Direction[1] == v1 && this->Direction[2] == v2)
73 {
74 return;
75 }
76
77 this->Direction[0] = v0;
78 this->Direction[1] = v1;
79 this->Direction[2] = v2;
80
81 this->Modified();
82 }
83
84 //------------------------------------------------------------------------------
SetWholeExtent(int xMin,int xMax,int yMin,int yMax,int zMin,int zMax)85 void vtkImageSinusoidSource::SetWholeExtent(
86 int xMin, int xMax, int yMin, int yMax, int zMin, int zMax)
87 {
88 int modified = 0;
89
90 if (this->WholeExtent[0] != xMin)
91 {
92 modified = 1;
93 this->WholeExtent[0] = xMin;
94 }
95 if (this->WholeExtent[1] != xMax)
96 {
97 modified = 1;
98 this->WholeExtent[1] = xMax;
99 }
100 if (this->WholeExtent[2] != yMin)
101 {
102 modified = 1;
103 this->WholeExtent[2] = yMin;
104 }
105 if (this->WholeExtent[3] != yMax)
106 {
107 modified = 1;
108 this->WholeExtent[3] = yMax;
109 }
110 if (this->WholeExtent[4] != zMin)
111 {
112 modified = 1;
113 this->WholeExtent[4] = zMin;
114 }
115 if (this->WholeExtent[5] != zMax)
116 {
117 modified = 1;
118 this->WholeExtent[5] = zMax;
119 }
120 if (modified)
121 {
122 this->Modified();
123 }
124 }
125
126 //------------------------------------------------------------------------------
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector)127 int vtkImageSinusoidSource::RequestInformation(vtkInformation* vtkNotUsed(request),
128 vtkInformationVector** vtkNotUsed(inputVector), vtkInformationVector* outputVector)
129 {
130 // get the info objects
131 vtkInformation* outInfo = outputVector->GetInformationObject(0);
132
133 outInfo->Set(vtkDataObject::SPACING(), 1.0, 1.0, 1.0);
134 outInfo->Set(vtkDataObject::ORIGIN(), 0.0, 0.0, 0.0);
135 outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), this->WholeExtent, 6);
136 vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_DOUBLE, 1);
137 return 1;
138 }
139
140 //------------------------------------------------------------------------------
ExecuteDataWithInformation(vtkDataObject * output,vtkInformation * outInfo)141 void vtkImageSinusoidSource::ExecuteDataWithInformation(
142 vtkDataObject* output, vtkInformation* outInfo)
143 {
144 vtkImageData* data = this->AllocateOutputData(output, outInfo);
145 double* outPtr;
146 int idxX, idxY, idxZ;
147 int maxX, maxY, maxZ;
148 vtkIdType outIncX, outIncY, outIncZ;
149 int* outExt;
150 double sum;
151 double yContrib, zContrib, xContrib;
152 unsigned long count = 0;
153 unsigned long target;
154
155 if (data->GetScalarType() != VTK_DOUBLE)
156 {
157 vtkErrorMacro("Execute: This source only outputs doubles");
158 }
159
160 outExt = data->GetExtent();
161
162 // find the region to loop over
163 maxX = outExt[1] - outExt[0];
164 maxY = outExt[3] - outExt[2];
165 maxZ = outExt[5] - outExt[4];
166
167 // Get increments to march through data
168 data->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
169 outPtr = static_cast<double*>(data->GetScalarPointer(outExt[0], outExt[2], outExt[4]));
170
171 target = static_cast<unsigned long>((maxZ + 1) * (maxY + 1) / 50.0);
172 target++;
173
174 // Loop through output pixels
175 for (idxZ = 0; idxZ <= maxZ; idxZ++)
176 {
177 zContrib = this->Direction[2] * (idxZ + outExt[4]);
178 for (idxY = 0; !this->AbortExecute && idxY <= maxY; idxY++)
179 {
180 if (!(count % target))
181 {
182 this->UpdateProgress(count / (50.0 * target));
183 }
184 count++;
185 yContrib = this->Direction[1] * (idxY + outExt[2]);
186 for (idxX = 0; idxX <= maxX; idxX++)
187 {
188 xContrib = this->Direction[0] * static_cast<double>(idxX + outExt[0]);
189 // find dot product
190 sum = zContrib + yContrib + xContrib;
191
192 *outPtr = this->Amplitude * cos((2.0 * vtkMath::Pi() * sum / this->Period) - this->Phase);
193 outPtr++;
194 }
195 outPtr += outIncY;
196 }
197 outPtr += outIncZ;
198 }
199 }
200
201 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)202 void vtkImageSinusoidSource::PrintSelf(ostream& os, vtkIndent indent)
203 {
204 this->Superclass::PrintSelf(os, indent);
205
206 os << indent << "Period: " << this->Period << "\n";
207 os << indent << "Phase: " << this->Phase << "\n";
208 os << indent << "Amplitude: " << this->Amplitude << "\n";
209 os << indent << "Direction: ( " << this->Direction[0] << ", " << this->Direction[1] << ", "
210 << this->Direction[2] << " )\n";
211 }
212