/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkRotationFilter.cxx,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkRotationFilter.h" #include "vtkCellData.h" #include "vtkGenericCell.h" #include "vtkIdList.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include "vtkUnstructuredGrid.h" #include "vtkMath.h" #include "vtkTransform.h" vtkCxxRevisionMacro(vtkRotationFilter, "$Revision: 1.9 $"); vtkStandardNewMacro(vtkRotationFilter); //--------------------------------------------------------------------------- vtkRotationFilter::vtkRotationFilter() { this->Axis = 2; this->CopyInput = 0; this->Center[0] = this->Center[1] = this->Center[2] = 0; this->NumberOfCopies = 0; this->Angle = 0; } //--------------------------------------------------------------------------- vtkRotationFilter::~vtkRotationFilter() { } //--------------------------------------------------------------------------- void vtkRotationFilter::PrintSelf(ostream &os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "Axis: " << this->Axis << endl; os << indent << "CopyInput: " << this->CopyInput << endl; os << indent << "Center: (" << this->Center[0] << "," << this->Center[1] << "," << this->Center[2] << ")" << endl; os << indent << "NumberOfCopies: " << this->NumberOfCopies << endl; os << indent << "Angle: " << this->Angle << endl; } //--------------------------------------------------------------------------- int vtkRotationFilter::RequestData( vtkInformation *vtkNotUsed(request), vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // get the info objects vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0); // get the input and ouptut vtkDataSet *input = vtkDataSet::SafeDownCast( inInfo->Get(vtkDataObject::DATA_OBJECT())); vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast( outInfo->Get(vtkDataObject::DATA_OBJECT())); vtkIdType i; vtkPointData *inPD = input->GetPointData(); vtkPointData *outPD = output->GetPointData(); vtkCellData *inCD = input->GetCellData(); vtkCellData *outCD = output->GetCellData(); if (!this->GetNumberOfCopies()) { vtkErrorMacro("No number of copy set!"); return 1; } double tuple[3]; vtkPoints *outPoints; double point[3], center[3], negativCenter[3]; int ptId, cellId, j, k; vtkGenericCell *cell = vtkGenericCell::New(); vtkIdList *ptIds = vtkIdList::New(); outPoints = vtkPoints::New(); vtkIdType numPts = input->GetNumberOfPoints(); vtkIdType numCells = input->GetNumberOfCells(); if (this->CopyInput) { outPoints->Allocate((this->CopyInput + this->GetNumberOfCopies()) * numPts); output->Allocate((this->CopyInput + this->GetNumberOfCopies()) * numPts); } else { outPoints->Allocate( this->GetNumberOfCopies() * numPts); output->Allocate( this->GetNumberOfCopies() * numPts); } outPD->CopyAllocate(inPD); outCD->CopyAllocate(inCD); vtkDataArray *inPtVectors, *outPtVectors, *inPtNormals; vtkDataArray *inCellVectors, *outCellVectors, *inCellNormals; inPtVectors = inPD->GetVectors(); outPtVectors = outPD->GetVectors(); inPtNormals = inPD->GetNormals(); inCellVectors = inCD->GetVectors(); outCellVectors = outCD->GetVectors(); inCellNormals = inCD->GetNormals(); // Copy first points. if (this->CopyInput) { for (i = 0; i < numPts; i++) { input->GetPoint(i, point); ptId = outPoints->InsertNextPoint(point); outPD->CopyData(inPD, i, ptId); } } vtkTransform *localTransform = vtkTransform::New(); // Rotate points. // double angle = this->GetAngle()*vtkMath::DegreesToRadians(); this->GetCenter(center); negativCenter[0] = -center[0]; negativCenter[1] = -center[1]; negativCenter[2] = -center[2]; for (k = 0; k < this->GetNumberOfCopies(); k++) { localTransform->Identity(); localTransform->Translate(center); switch (this->Axis) { case USE_X: localTransform->RotateX((k+1)*this->GetAngle()); break; case USE_Y: localTransform->RotateY((k+1)*this->GetAngle()); break; case USE_Z: localTransform->RotateZ((k+1)*this->GetAngle()); break; } localTransform->Translate(negativCenter); for (i = 0; i < numPts; i++) { input->GetPoint(i, point); localTransform->TransformPoint(point, point); ptId = outPoints->InsertNextPoint(point); outPD->CopyData(inPD, i, ptId); if (inPtVectors) { inPtVectors->GetTuple(i, tuple); outPtVectors->SetTuple(ptId, tuple); } if (inPtNormals) { //inPtNormals->GetTuple(i, tuple); //outPtNormals->SetTuple(ptId, tuple); } } } localTransform->Delete(); int numCellPts, cellType; vtkIdType *newCellPts; vtkIdList *cellPts; // Copy original cells. if (this->CopyInput) { for (i = 0; i < numCells; i++) { input->GetCellPoints(i, ptIds); output->InsertNextCell(input->GetCellType(i), ptIds); outCD->CopyData(inCD, i, i); } } // Generate rotated cells. for (k = 0; k < this->GetNumberOfCopies(); k++) { for (i = 0; i < numCells; i++) { input->GetCellPoints(i, ptIds); input->GetCell(i, cell); numCellPts = cell->GetNumberOfPoints(); cellType = cell->GetCellType(); cellPts = cell->GetPointIds(); // Triangle strips with even number of triangles have // to be handled specially. A degenerate triangle is // introduce to flip all the triangles properly. if (cellType == VTK_TRIANGLE_STRIP && numCellPts % 2 == 0) { vtkErrorMacro(<< "Triangles with bad points"); return 0; } else { vtkDebugMacro(<< "celltype " << cellType << " numCellPts " << numCellPts); newCellPts = new vtkIdType[numCellPts]; //for (j = numCellPts-1; j >= 0; j--) for (j = 0; j < numCellPts; j++) { //newCellPts[numCellPts-1-j] = cellPts->GetId(j) + numPts*k; newCellPts[j] = cellPts->GetId(j) + numPts*k; if (this->CopyInput) { //newCellPts[numCellPts-1-j] += numPts; newCellPts[j] += numPts; } } } cellId = output->InsertNextCell(cellType, numCellPts, newCellPts); delete [] newCellPts; outCD->CopyData(inCD, i, cellId); if (inCellVectors) { inCellVectors->GetTuple(i, tuple); outCellVectors->SetTuple(cellId, tuple); } if (inCellNormals) { //inCellNormals->GetTuple(i, tuple); //outCellNormals->SetTuple(cellId, tuple); } } } cell->Delete(); ptIds->Delete(); output->SetPoints(outPoints); outPoints->Delete(); output->CheckAttributes(); return 1; } int vtkRotationFilter::FillInputPortInformation(int, vtkInformation *info) { info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet"); return 1; }