1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkTransformTextureCoords.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 "vtkTransformTextureCoords.h"
16 
17 #include "vtkDataSet.h"
18 #include "vtkFloatArray.h"
19 #include "vtkInformation.h"
20 #include "vtkInformationVector.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkPointData.h"
23 #include "vtkTransform.h"
24 
25 vtkStandardNewMacro(vtkTransformTextureCoords);
26 
27 // Create instance with Origin (0.5,0.5,0.5); Position (0,0,0); and Scale
28 // set to (1,1,1). Rotation of the texture coordinates is turned off.
vtkTransformTextureCoords()29 vtkTransformTextureCoords::vtkTransformTextureCoords()
30 {
31   this->Origin[0] = this->Origin[1] = this->Origin[2] = 0.5;
32   this->Position[0] = this->Position[1] = this->Position[2] = 0.0;
33   this->Scale[0] = this->Scale[1] = this->Scale[2] = 1.0;
34 
35   this->FlipR = 0;
36   this->FlipS = 0;
37   this->FlipT = 0;
38 }
39 
40 // Incrementally change the position of the texture map (i.e., does a
41 // translate or shift of the texture coordinates).
AddPosition(double dPX,double dPY,double dPZ)42 void vtkTransformTextureCoords::AddPosition (double dPX, double dPY, double dPZ)
43 {
44   double position[3];
45 
46   position[0] = this->Position[0] + dPX;
47   position[1] = this->Position[1] + dPY;
48   position[2] = this->Position[2] + dPZ;
49 
50   this->SetPosition(position);
51 }
52 
AddPosition(double deltaPosition[3])53 void vtkTransformTextureCoords::AddPosition(double deltaPosition[3])
54 {
55   this->AddPosition (deltaPosition[0], deltaPosition[1], deltaPosition[2]);
56 }
57 
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)58 int vtkTransformTextureCoords::RequestData(
59   vtkInformation *vtkNotUsed(request),
60   vtkInformationVector **inputVector,
61   vtkInformationVector *outputVector)
62 {
63   // get the info objects
64   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
65   vtkInformation *outInfo = outputVector->GetInformationObject(0);
66 
67   // get the input and output
68   vtkDataSet *input = vtkDataSet::SafeDownCast(
69     inInfo->Get(vtkDataObject::DATA_OBJECT()));
70   vtkDataSet *output = vtkDataSet::SafeDownCast(
71     outInfo->Get(vtkDataObject::DATA_OBJECT()));
72 
73   vtkDataArray *inTCoords=input->GetPointData()->GetTCoords();
74   vtkDataArray *newTCoords;
75   vtkIdType numPts=input->GetNumberOfPoints(), ptId;
76   int i, j, texDim;
77   vtkTransform *transform;
78   vtkMatrix4x4 *matrix;
79   double TC[3], newTC[3];
80 
81   vtkDebugMacro(<<"Transforming texture coordinates...");
82 
83   // First, copy the input to the output as a starting point
84   output->CopyStructure( input );
85 
86   if ( inTCoords == NULL || numPts < 1 )
87     {
88     vtkErrorMacro(<<"No texture coordinates to transform");
89     return 1;
90     }
91   transform = vtkTransform::New();
92   matrix = vtkMatrix4x4::New();
93 
94   // create same type as input
95   texDim = inTCoords->GetNumberOfComponents();
96   newTCoords = inTCoords->NewInstance();
97   newTCoords->SetNumberOfComponents(inTCoords->GetNumberOfComponents());
98   newTCoords->Allocate(numPts*texDim);
99 
100   // just pretend texture coordinate is 3D point and use transform object to
101   // manipulate
102   transform->PostMultiply();
103   // shift back to origin
104   transform->Translate(-this->Origin[0], -this->Origin[1], -this->Origin[2]);
105 
106   // scale
107   transform->Scale(this->Scale[0], this->Scale[1], this->Scale[2]);
108 
109   // rotate about z, then x, then y
110   if ( this->FlipT )
111     {
112     transform->RotateZ(180.0);
113     }
114   if ( this->FlipR )
115     {
116     transform->RotateX(180.0);
117     }
118   if ( this->FlipS )
119     {
120     transform->RotateY(180.0);
121     }
122 
123   // move back from origin and translate
124   transform->Translate(this->Origin[0] + this->Position[0],
125                       this->Origin[1] + this->Position[1],
126                       this->Origin[2] + this->Position[2]);
127 
128   matrix->DeepCopy(transform->GetMatrix());
129 
130   newTC[0] = newTC[1] = newTC[2] = 0.0;
131   newTC[0] = newTC[1] = newTC[2] = 0.0;
132 
133   int abort=0;
134   int progressInterval = numPts/20+1;
135 
136   for (ptId=0; ptId < numPts && !abort; ptId++)
137     {
138     if ( !(ptId % progressInterval) )
139       {
140       this->UpdateProgress((double)ptId/numPts);
141       abort = this->GetAbortExecute();
142       }
143 
144     inTCoords->GetTuple(ptId, TC);
145     for (i=0; i<texDim; i++)
146       {
147       newTC[i] = matrix->Element[i][3];
148       for (j=0; j<texDim; j++)
149         {
150         newTC[i] += matrix->Element[i][j] * TC[j];
151         }
152       }
153 
154     newTCoords->InsertTuple(ptId,newTC);
155     }
156 
157   // Update self
158   //
159   output->GetPointData()->CopyTCoordsOff();
160   output->GetPointData()->PassData(input->GetPointData());
161 
162   output->GetPointData()->SetTCoords(newTCoords);
163   newTCoords->Delete();
164   matrix->Delete();
165   transform->Delete();
166 
167   return 1;
168 }
169 
PrintSelf(ostream & os,vtkIndent indent)170 void vtkTransformTextureCoords::PrintSelf(ostream& os, vtkIndent indent)
171 {
172   this->Superclass::PrintSelf(os,indent);
173 
174   os << indent << "Scale: ("
175      << this->Scale[0] << ", "
176      << this->Scale[1] << ", "
177      << this->Scale[2] << ")\n";
178 
179   os << indent << "Position: ("
180      << this->Position[0] << ", "
181      << this->Position[1] << ", "
182      << this->Position[2] << ")\n";
183 
184   os << indent << "Origin: ("
185      << this->Origin[0] << ", "
186      << this->Origin[1] << ", "
187      << this->Origin[2] << ")\n";
188 
189   os << indent << "FlipR: " << (this->FlipR ? "On\n" : "Off\n");
190   os << indent << "FlipS: " << (this->FlipS ? "On\n" : "Off\n");
191   os << indent << "FlipT: " << (this->FlipT ? "On\n" : "Off\n");
192 }
193