/*========================================================================= Program: ParaView Module: vtkCompleteArrays.cxx Copyright (c) Kitware, Inc. All rights reserved. See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "vtkCompleteArrays.h" #include "vtkCellData.h" #include "vtkCharArray.h" #include "vtkClientServerStream.h" #include "vtkDataArray.h" #include "vtkDataSet.h" #include "vtkDoubleArray.h" #include "vtkFloatArray.h" #include "vtkIdTypeArray.h" #include "vtkInformation.h" #include "vtkInformationVector.h" #include "vtkIntArray.h" #include "vtkLongArray.h" #include "vtkMultiProcessController.h" #include "vtkObjectFactory.h" #include "vtkPVArrayInformation.h" #include "vtkPVDataInformation.h" #include "vtkPVDataSetAttributesInformation.h" #include "vtkPointData.h" #include "vtkPointSet.h" #include "vtkShortArray.h" #include "vtkUnsignedCharArray.h" #include "vtkUnsignedIntArray.h" #include "vtkUnsignedLongArray.h" #include "vtkUnsignedShortArray.h" vtkStandardNewMacro(vtkCompleteArrays); vtkCxxSetObjectMacro(vtkCompleteArrays,Controller,vtkMultiProcessController); //----------------------------------------------------------------------------- vtkCompleteArrays::vtkCompleteArrays() { this->Controller = vtkMultiProcessController::GetGlobalController(); if (this->Controller) { this->Controller->Register(this); } } //----------------------------------------------------------------------------- vtkCompleteArrays::~vtkCompleteArrays() { if (this->Controller) { this->Controller->UnRegister(this); this->Controller = NULL; } } //----------------------------------------------------------------------------- int vtkCompleteArrays::RequestData( vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector* outputVector) { vtkInformation* info = outputVector->GetInformationObject(0); vtkDataSet *output = vtkDataSet::SafeDownCast( info->Get(vtkDataObject::DATA_OBJECT())); vtkInformation* inInfo = inputVector[0]->GetInformationObject(0); vtkDataSet *input = vtkDataSet::SafeDownCast( inInfo->Get(vtkDataObject::DATA_OBJECT())); int noNeed = 0; int myProcId; int numProcs; int idx; vtkClientServerStream css; // Initialize // vtkDebugMacro(<<"Completing array"); output->CopyStructure( input ); output->GetPointData()->PassData(input->GetPointData()); output->GetCellData()->PassData(input->GetCellData()); myProcId = this->Controller->GetLocalProcessId(); numProcs = this->Controller->GetNumberOfProcesses(); if (numProcs <= 1) { return 1; } if (myProcId == 0) { if (input->GetNumberOfPoints() > 0 && input->GetNumberOfCells() > 0) { noNeed = 1; } this->Controller->Broadcast(&noNeed, 1, 0); if (noNeed) { return 1; } // Receive and collected information from the remote processes. vtkPVDataInformation* dataInfo = vtkPVDataInformation::New(); vtkPVDataInformation* tmpInfo = vtkPVDataInformation::New(); for (idx = 1; idx < numProcs; ++idx) { int length = 0; this->Controller->Receive(&length, 1, idx, 3389002); unsigned char* data = new unsigned char[length]; this->Controller->Receive(data, length, idx, 3389003); css.SetData(data, length); tmpInfo->CopyFromStream(&css); delete [] data; dataInfo->AddInformation(tmpInfo); } this->FillArrays( output->GetPointData(), dataInfo->GetPointDataInformation()); this->FillArrays( output->GetCellData(), dataInfo->GetCellDataInformation()); vtkPointSet* ps = vtkPointSet::SafeDownCast(output); if (ps) { vtkDataArray* pointArray = this->CreateArray( dataInfo->GetPointArrayInformation()); if (!pointArray) { vtkErrorMacro("Could not create point array. " "The output will not contain points"); } else { vtkPoints* pts = vtkPoints::New(); pts->SetData(pointArray); pointArray->Delete(); ps->SetPoints(pts); pts->Delete(); } } dataInfo->Delete(); tmpInfo->Delete(); } else { // remote processes this->Controller->Broadcast(&noNeed, 1, 0); if (noNeed) { return 1; } vtkPVDataInformation* dataInfo = vtkPVDataInformation::New(); dataInfo->CopyFromObject(output); dataInfo->CopyToStream(&css); size_t length; const unsigned char* data; css.GetData(&data, &length); int len = static_cast(length); this->Controller->Send(&len, 1, 0, 3389002); this->Controller->Send(const_cast(data), len, 0, 3389003); dataInfo->Delete(); } return 1; } //----------------------------------------------------------------------------- vtkDataArray* vtkCompleteArrays::CreateArray(vtkPVArrayInformation* aInfo) { vtkDataArray* array = 0; switch (aInfo->GetDataType()) { case VTK_FLOAT: array = vtkFloatArray::New(); break; case VTK_DOUBLE: array = vtkDoubleArray::New(); break; case VTK_INT: array = vtkIntArray::New(); break; case VTK_CHAR: array = vtkCharArray::New(); break; case VTK_ID_TYPE: array = vtkIdTypeArray::New(); break; case VTK_LONG: array = vtkLongArray::New(); break; case VTK_SHORT: array = vtkShortArray::New(); break; case VTK_UNSIGNED_CHAR: array = vtkUnsignedCharArray::New(); break; case VTK_UNSIGNED_INT: array = vtkUnsignedIntArray::New(); break; case VTK_UNSIGNED_LONG: array = vtkUnsignedLongArray::New(); break; case VTK_UNSIGNED_SHORT: array = vtkUnsignedShortArray::New(); break; default: array = NULL; } if (array) { array->SetNumberOfComponents(aInfo->GetNumberOfComponents()); array->SetName(aInfo->GetName()); } return array; } //----------------------------------------------------------------------------- void vtkCompleteArrays::FillArrays(vtkDataSetAttributes* da, vtkPVDataSetAttributesInformation* attrInfo) { int num, idx; vtkPVArrayInformation* arrayInfo; vtkDataArray* array; da->Initialize(); num = attrInfo->GetNumberOfArrays(); for (idx = 0; idx < num; ++idx) { arrayInfo = attrInfo->GetArrayInformation(idx); array = this->CreateArray(arrayInfo); if (array) { switch (attrInfo->IsArrayAnAttribute(idx)) { case vtkDataSetAttributes::SCALARS: da->SetScalars(array); break; case vtkDataSetAttributes::VECTORS: da->SetVectors(array); break; case vtkDataSetAttributes::NORMALS: da->SetNormals(array); break; case vtkDataSetAttributes::TENSORS: da->SetTensors(array); break; case vtkDataSetAttributes::TCOORDS: da->SetTCoords(array); break; default: da->AddArray(array); } array->Delete(); array = NULL; } } } //----------------------------------------------------------------------------- void vtkCompleteArrays::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); if (this->Controller) { os << indent << "Controller: " << this->Controller << endl; } else { os << indent << "Controller: (none)\n"; } }