1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkRotationFilter.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 "vtkRotationFilter.h"
16
17 #include "vtkCellData.h"
18 #include "vtkGenericCell.h"
19 #include "vtkIdList.h"
20 #include "vtkInformation.h"
21 #include "vtkInformationVector.h"
22 #include "vtkMath.h"
23 #include "vtkObjectFactory.h"
24 #include "vtkPointData.h"
25 #include "vtkTransform.h"
26 #include "vtkUnstructuredGrid.h"
27
28 vtkStandardNewMacro(vtkRotationFilter);
29
30 //------------------------------------------------------------------------------
vtkRotationFilter()31 vtkRotationFilter::vtkRotationFilter()
32 {
33 this->Axis = 2;
34 this->CopyInput = 0;
35 this->Center[0] = this->Center[1] = this->Center[2] = 0;
36 this->NumberOfCopies = 0;
37 this->Angle = 0;
38 }
39
40 //------------------------------------------------------------------------------
41 vtkRotationFilter::~vtkRotationFilter() = default;
42
43 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)44 void vtkRotationFilter::PrintSelf(ostream& os, vtkIndent indent)
45 {
46 this->Superclass::PrintSelf(os, indent);
47
48 os << indent << "Axis: " << this->Axis << endl;
49 os << indent << "CopyInput: " << this->CopyInput << endl;
50 os << indent << "Center: (" << this->Center[0] << "," << this->Center[1] << "," << this->Center[2]
51 << ")" << endl;
52 os << indent << "NumberOfCopies: " << this->NumberOfCopies << endl;
53 os << indent << "Angle: " << this->Angle << endl;
54 }
55
56 //------------------------------------------------------------------------------
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)57 int vtkRotationFilter::RequestData(vtkInformation* vtkNotUsed(request),
58 vtkInformationVector** inputVector, vtkInformationVector* outputVector)
59 {
60 // get the info objects
61 vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
62 vtkInformation* outInfo = outputVector->GetInformationObject(0);
63
64 // get the input and output
65 vtkDataSet* input = vtkDataSet::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
66 vtkUnstructuredGrid* output =
67 vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
68
69 vtkPointData* inPD = input->GetPointData();
70 vtkPointData* outPD = output->GetPointData();
71 vtkCellData* inCD = input->GetCellData();
72 vtkCellData* outCD = output->GetCellData();
73
74 if (!this->GetNumberOfCopies())
75 {
76 vtkErrorMacro("No number of copy set!");
77 return 1;
78 }
79
80 double tuple[3];
81 vtkPoints* outPoints;
82 double point[3], center[3], negativCenter[3];
83 vtkIdType ptId, cellId;
84 vtkGenericCell* cell = vtkGenericCell::New();
85 vtkIdList* ptIds = vtkIdList::New();
86
87 outPoints = vtkPoints::New();
88
89 vtkIdType numPts = input->GetNumberOfPoints();
90 vtkIdType numCells = input->GetNumberOfCells();
91
92 if (this->CopyInput)
93 {
94 outPoints->Allocate((this->CopyInput + this->GetNumberOfCopies()) * numPts);
95 output->Allocate((this->CopyInput + this->GetNumberOfCopies()) * numPts);
96 }
97 else
98 {
99 outPoints->Allocate(this->GetNumberOfCopies() * numPts);
100 output->Allocate(this->GetNumberOfCopies() * numPts);
101 }
102
103 outPD->CopyAllocate(inPD);
104 outCD->CopyAllocate(inCD);
105
106 vtkDataArray *inPtVectors, *outPtVectors;
107 vtkDataArray *inCellVectors, *outCellVectors;
108
109 inPtVectors = inPD->GetVectors();
110 outPtVectors = outPD->GetVectors();
111 inCellVectors = inCD->GetVectors();
112 outCellVectors = outCD->GetVectors();
113
114 // Copy first points.
115 if (this->CopyInput)
116 {
117 for (vtkIdType i = 0; i < numPts; ++i)
118 {
119 input->GetPoint(i, point);
120 ptId = outPoints->InsertNextPoint(point);
121 outPD->CopyData(inPD, i, ptId);
122 }
123 }
124 vtkTransform* localTransform = vtkTransform::New();
125 // Rotate points.
126 this->GetCenter(center);
127 negativCenter[0] = -center[0];
128 negativCenter[1] = -center[1];
129 negativCenter[2] = -center[2];
130
131 for (int k = 0; k < this->GetNumberOfCopies(); ++k)
132 {
133 localTransform->Identity();
134 localTransform->Translate(center);
135 switch (this->Axis)
136 {
137 case USE_X:
138 localTransform->RotateX((k + 1) * this->GetAngle());
139 break;
140
141 case USE_Y:
142 localTransform->RotateY((k + 1) * this->GetAngle());
143 break;
144
145 case USE_Z:
146 localTransform->RotateZ((k + 1) * this->GetAngle());
147 break;
148 }
149 localTransform->Translate(negativCenter);
150 for (vtkIdType i = 0; i < numPts; ++i)
151 {
152 input->GetPoint(i, point);
153 localTransform->TransformPoint(point, point);
154 ptId = outPoints->InsertNextPoint(point);
155 outPD->CopyData(inPD, i, ptId);
156 if (inPtVectors)
157 {
158 inPtVectors->GetTuple(i, tuple);
159 outPtVectors->SetTuple(ptId, tuple);
160 }
161 }
162 }
163
164 localTransform->Delete();
165
166 // Copy original cells.
167 if (this->CopyInput)
168 {
169 for (vtkIdType i = 0; i < numCells; ++i)
170 {
171 input->GetCellPoints(i, ptIds);
172 output->InsertNextCell(input->GetCellType(i), ptIds);
173 outCD->CopyData(inCD, i, i);
174 }
175 }
176
177 vtkIdType* newCellPts;
178 vtkIdList* cellPts;
179
180 // Generate rotated cells.
181 for (int k = 0; k < this->GetNumberOfCopies(); ++k)
182 {
183 for (vtkIdType i = 0; i < numCells; ++i)
184 {
185 input->GetCellPoints(i, ptIds);
186 input->GetCell(i, cell);
187 vtkIdType numCellPts = cell->GetNumberOfPoints();
188 int cellType = cell->GetCellType();
189 cellPts = cell->GetPointIds();
190
191 vtkDebugMacro(<< "celltype " << cellType << " numCellPts " << numCellPts);
192 newCellPts = new vtkIdType[numCellPts];
193 for (vtkIdType j = 0; j < numCellPts; ++j)
194 {
195 newCellPts[j] = cellPts->GetId(j) + numPts * k;
196 if (this->CopyInput)
197 {
198 newCellPts[j] += numPts;
199 }
200 }
201
202 cellId = output->InsertNextCell(cellType, numCellPts, newCellPts);
203 delete[] newCellPts;
204 outCD->CopyData(inCD, i, cellId);
205 if (inCellVectors)
206 {
207 inCellVectors->GetTuple(i, tuple);
208 outCellVectors->SetTuple(cellId, tuple);
209 }
210 }
211 }
212
213 cell->Delete();
214 ptIds->Delete();
215 output->SetPoints(outPoints);
216 outPoints->Delete();
217 output->CheckAttributes();
218
219 return 1;
220 }
221
FillInputPortInformation(int,vtkInformation * info)222 int vtkRotationFilter::FillInputPortInformation(int, vtkInformation* info)
223 {
224 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
225 return 1;
226 }
227