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 "vtkMath.h"
18 #include "vtkImageData.h"
19 #include "vtkInformation.h"
20 #include "vtkInformationVector.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkStreamingDemandDrivenPipeline.h"
23 
24 #include <math.h>
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;  this->WholeExtent[1] = 255;
40   this->WholeExtent[2] = 0;  this->WholeExtent[3] = 255;
41   this->WholeExtent[4] = 0;  this->WholeExtent[5] = 0;
42 
43   this->SetNumberOfInputPorts(0);
44 }
45 
SetDirection(double v[3])46 void vtkImageSinusoidSource::SetDirection(double v[3])
47 {
48   this->SetDirection(v[0],v[1],v[2]);
49 }
50 
SetDirection(double v0,double v1,double v2)51 void vtkImageSinusoidSource::SetDirection(double v0, double v1, double v2)
52 {
53   double sum;
54 
55   sum = v0*v0 + v1*v1 + v2*v2;
56 
57   if (sum == 0.0)
58     {
59     vtkErrorMacro("Zero direction vector");
60     return;
61     }
62 
63   // normalize
64   sum = 1.0 / sqrt(sum);
65   v0 *= sum;
66   v1 *= sum;
67   v2 *= sum;
68 
69   if (this->Direction[0] == v0 && this->Direction[1] == v1
70       && this->Direction[2] == v2)
71     {
72     return;
73     }
74 
75   this->Direction[0] = v0;
76   this->Direction[1] = v1;
77   this->Direction[2] = v2;
78 
79   this->Modified();
80 }
81 
82 //----------------------------------------------------------------------------
SetWholeExtent(int xMin,int xMax,int yMin,int yMax,int zMin,int zMax)83 void vtkImageSinusoidSource::SetWholeExtent(int xMin, int xMax,
84                                             int yMin, int yMax,
85                                             int zMin, int zMax)
86 {
87   int modified = 0;
88 
89   if (this->WholeExtent[0] != xMin)
90     {
91     modified = 1;
92     this->WholeExtent[0] = xMin ;
93     }
94   if (this->WholeExtent[1] != xMax)
95     {
96     modified = 1;
97     this->WholeExtent[1] = xMax ;
98     }
99   if (this->WholeExtent[2] != yMin)
100     {
101     modified = 1;
102     this->WholeExtent[2] = yMin ;
103     }
104   if (this->WholeExtent[3] != yMax)
105     {
106     modified = 1;
107     this->WholeExtent[3] = yMax ;
108     }
109   if (this->WholeExtent[4] != zMin)
110     {
111     modified = 1;
112     this->WholeExtent[4] = zMin ;
113     }
114   if (this->WholeExtent[5] != zMax)
115     {
116     modified = 1;
117     this->WholeExtent[5] = zMax ;
118     }
119   if (modified)
120     {
121     this->Modified();
122     }
123 }
124 
125 //----------------------------------------------------------------------------
RequestInformation(vtkInformation * vtkNotUsed (request),vtkInformationVector ** vtkNotUsed (inputVector),vtkInformationVector * outputVector)126 int vtkImageSinusoidSource::RequestInformation (
127   vtkInformation * vtkNotUsed(request),
128   vtkInformationVector** vtkNotUsed( inputVector ),
129   vtkInformationVector *outputVector)
130 {
131   // get the info objects
132   vtkInformation* outInfo = outputVector->GetInformationObject(0);
133 
134   outInfo->Set(vtkDataObject::SPACING(), 1.0, 1.0, 1.0);
135   outInfo->Set(vtkDataObject::ORIGIN(),  0.0, 0.0, 0.0);
136   outInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
137                this->WholeExtent,6);
138   vtkDataObject::SetPointDataActiveScalarInfo(outInfo, VTK_DOUBLE, 1);
139   return 1;
140 }
141 
142 //----------------------------------------------------------------------------
ExecuteDataWithInformation(vtkDataObject * output,vtkInformation * outInfo)143 void vtkImageSinusoidSource::ExecuteDataWithInformation(vtkDataObject *output,
144                                                         vtkInformation* outInfo)
145 {
146   vtkImageData *data = this->AllocateOutputData(output, outInfo);
147   double *outPtr;
148   int idxX, idxY, idxZ;
149   int maxX, maxY, maxZ;
150   vtkIdType outIncX, outIncY, outIncZ;
151   int *outExt;
152   double sum;
153   double yContrib, zContrib, xContrib;
154   unsigned long count = 0;
155   unsigned long target;
156 
157   if (data->GetScalarType() != VTK_DOUBLE)
158     {
159     vtkErrorMacro("Execute: This source only outputs doubles");
160     }
161 
162   outExt = data->GetExtent();
163 
164   // find the region to loop over
165   maxX = outExt[1] - outExt[0];
166   maxY = outExt[3] - outExt[2];
167   maxZ = outExt[5] - outExt[4];
168 
169   // Get increments to march through data
170   data->GetContinuousIncrements(outExt, outIncX, outIncY, outIncZ);
171   outPtr = static_cast<double *>(
172     data->GetScalarPointer(outExt[0],outExt[2],outExt[4]));
173 
174   target = static_cast<unsigned long>((maxZ+1)*(maxY+1)/50.0);
175   target++;
176 
177   // Loop through output pixels
178   for (idxZ = 0; idxZ <= maxZ; idxZ++)
179     {
180     zContrib = this->Direction[2] * (idxZ + outExt[4]);
181     for (idxY = 0; !this->AbortExecute && idxY <= maxY; idxY++)
182       {
183       if (!(count%target))
184         {
185         this->UpdateProgress(count/(50.0*target));
186         }
187       count++;
188       yContrib = this->Direction[1] * (idxY + outExt[2]);
189       for (idxX = 0; idxX <= maxX; idxX++)
190         {
191         xContrib = this->Direction[0] * static_cast<double>(idxX + outExt[0]);
192         // find dot product
193         sum = zContrib + yContrib + xContrib;
194 
195         *outPtr = this->Amplitude *
196           cos((2.0 * vtkMath::Pi() * sum / this->Period) - this->Phase);
197         outPtr++;
198         }
199       outPtr += outIncY;
200       }
201     outPtr += outIncZ;
202     }
203 }
204 
205 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)206 void vtkImageSinusoidSource::PrintSelf(ostream& os, vtkIndent indent)
207 {
208   this->Superclass::PrintSelf(os,indent);
209 
210   os << indent << "Period: " << this->Period << "\n";
211   os << indent << "Phase: " << this->Phase << "\n";
212   os << indent << "Amplitude: " << this->Amplitude << "\n";
213   os << indent << "Direction: ( "
214      << this->Direction[0] << ", "
215      << this->Direction[1] << ", "
216      << this->Direction[2] << " )\n";
217 
218 }
219 
220