/*========================================================================= medInria Copyright (c) INRIA 2013 - 2020. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "vtkVectorOrienter.h" #include "vtkCellData.h" #include "vtkImageData.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkObjectFactory.h" #include "vtkStreamingDemandDrivenPipeline.h" #include "vtkPointData.h" #include "vtkAssignAttribute.h" #include "vtkDoubleArray.h" #include "vtkMatrix4x4.h" #include "vtkMath.h" #include "vtkPlane.h" #include "vtkSmartPointer.h" vtkStandardNewMacro(vtkVectorOrienter) vtkVectorOrienter::vtkVectorOrienter() { this->VOI[0] = this->VOI[2] = this->VOI[4] = 0; this->VOI[1] = this->VOI[3] = this->VOI[5] = VTK_INT_MAX; this->Projection = false; } int vtkVectorOrienter::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 output vtkImageData *input = vtkImageData::SafeDownCast( inInfo->Get(vtkDataObject::DATA_OBJECT())); vtkImageData *output = vtkImageData::SafeDownCast( outInfo->Get(vtkDataObject::DATA_OBJECT())); vtkPointData *pd=input->GetPointData(); vtkPointData *outPD=output->GetPointData(); vtkDataArray *inVectors; double inV[4]; vtkIdType ptId, numPts; vtkDoubleArray *newVectors = nullptr; // First, copy the input to the output as a starting point output->CopyStructure( input ); // build transposed Matrix vtkMatrix4x4 *matrixT = vtkMatrix4x4::New(); vtkMatrix4x4::Transpose(Matrix, matrixT); inVectors = pd->GetVectors(); numPts = input->GetNumberOfPoints(); newVectors = vtkDoubleArray::New(); newVectors->SetNumberOfComponents (3); newVectors->SetNumberOfTuples (numPts); if ( !inVectors || numPts < 1 ) { vtkErrorMacro(<<"No data to orient!"); return 1; } outPD->CopyAllOn(); outPD->PassData(pd); for (ptId=0; ptId < numPts; ptId++) { inVectors->GetTuple(ptId, inV); inV[3] = 0; // As Actor->SetUserMatrix() also applies the matrix to the vectors (expressed in world coordinates) // we need to apply matrixT before, so that there are not imapcted by Actor->SetUserMatrix() matrixT->MultiplyPoint(inV, inV); if(Projection) { if(ProjMode==ProjectOnYZ) { inV[0] = 0; } else if(ProjMode==ProjectOnXZ) { inV[1] = 0; } else if(ProjMode==ProjectOnXY) { inV[2] = 0; } } newVectors->SetTuple (ptId, inV); } outPD->SetVectors(newVectors); newVectors->Delete(); matrixT->Delete(); return 1; } void vtkVectorOrienter::SetVOI(const int& imin,const int& imax, const int& jmin,const int& jmax, const int& kmin,const int& kmax) { if(imin==imax) ProjMode = ProjectOnYZ; else if(jmin==jmax) ProjMode = ProjectOnXZ; else if(kmin==kmax) ProjMode = ProjectOnXY; } void vtkVectorOrienter::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); os << indent << "VOI: \n"; os << indent << " Imin,Imax: (" << this->VOI[0] << ", " << this->VOI[1] << ")\n"; os << indent << " Jmin,Jmax: (" << this->VOI[2] << ", " << this->VOI[3] << ")\n"; os << indent << " Kmin,Kmax: (" << this->VOI[4] << ", " << this->VOI[5] << ")\n"; }