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