/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkInterpolatedVelocityField.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 "vtkInterpolatedVelocityField.h" #include "vtkDataArray.h" #include "vtkDataSet.h" #include "vtkGenericCell.h" #include "vtkObjectFactory.h" #include "vtkPointData.h" #include vtkCxxRevisionMacro(vtkInterpolatedVelocityField, "$Revision: 1.2 $"); vtkStandardNewMacro(vtkInterpolatedVelocityField); typedef vtkstd::vector< vtkDataSet* > DataSetsTypeBase; class vtkInterpolatedVelocityFieldDataSetsType: public DataSetsTypeBase {}; vtkInterpolatedVelocityField::vtkInterpolatedVelocityField() { this->NumFuncs = 3; // u, v, w this->NumIndepVars = 4; // x, y, z, t this->Weights = 0; this->WeightsSize = 0; this->GenCell = vtkGenericCell::New(); this->LastCellId = -1; this->CacheHit = 0; this->CacheMiss = 0; this->Caching = 1; // Caching on by default this->Cell = vtkGenericCell::New(); this->VectorsSelection = 0; this->DataSets = new vtkInterpolatedVelocityFieldDataSetsType; this->LastDataSet = 0; } vtkInterpolatedVelocityField::~vtkInterpolatedVelocityField() { this->NumFuncs = 0; this->NumIndepVars = 0; this->GenCell->Delete(); delete[] this->Weights; this->Weights = 0; this->Cell->Delete(); this->SetVectorsSelection(0); delete this->DataSets; } static int tmp_count=0; // Evaluate u,v,w at x,y,z,t int vtkInterpolatedVelocityField::FunctionValues(double* x, double* f) { vtkDataSet* ds; if(!this->LastDataSet && !this->DataSets->empty()) { ds = (*this->DataSets)[0]; this->LastDataSet = ds; } else { ds = this->LastDataSet; } int retVal = this->FunctionValues(ds, x, f); if (!retVal) { tmp_count = 0; for(DataSetsTypeBase::iterator i = this->DataSets->begin(); i != this->DataSets->end(); ++i) { ds = *i; if(ds && ds != this->LastDataSet) { this->ClearLastCellId(); retVal = this->FunctionValues(ds, x, f); if (retVal) { this->LastDataSet = ds; return retVal; } } } this->ClearLastCellId(); return 0; } tmp_count++; return retVal; } const double vtkInterpolatedVelocityField::TOLERANCE_SCALE = 1.0E-8; // Evaluate u,v,w at x,y,z,t int vtkInterpolatedVelocityField::FunctionValues(vtkDataSet* dataset, double* x, double* f) { int i, j, subId , numPts, id; vtkDataArray* vectors; double vec[3]; double dist2; int ret; for(i=0; i<3; i++) { f[i] = 0; } // See if a dataset has been specified and if there are input vectors if (!dataset || !(vectors = dataset->GetPointData()->GetVectors(this->VectorsSelection))) { vtkErrorMacro(<<"Can't evaluate dataset!"); return 0; } double tol2 = dataset->GetLength() * vtkInterpolatedVelocityField::TOLERANCE_SCALE; int found = 0; if (this->Caching) { // See if the point is in the cached cell if (this->LastCellId == -1 || !(ret=this->GenCell->EvaluatePosition(x, 0, subId, this->LastPCoords, dist2, this->Weights)) || ret == -1) { // if not, find and get it if (this->LastCellId != - 1 ) { this->CacheMiss++; dataset->GetCell(this->LastCellId, this->Cell); this->LastCellId = dataset->FindCell(x, this->Cell, this->GenCell, -1, tol2, subId, this->LastPCoords, this->Weights); if (this->LastCellId != - 1) { dataset->GetCell(this->LastCellId, this->GenCell); found = 1; } } } else { this->CacheHit++; found = 1; } } if (!found) { // if the cell is not found, do a global search (ignore initial // cell if there is one) this->LastCellId = dataset->FindCell(x, 0, this->GenCell, -1, tol2, subId, this->LastPCoords, this->Weights); if (this->LastCellId != - 1) { dataset->GetCell(this->LastCellId, this->GenCell); } else { return 0; } } // if the cell is valid if (this->LastCellId >= 0) { numPts = this->GenCell->GetNumberOfPoints(); // interpolate the vectors for (j=0; j < numPts; j++) { id = this->GenCell->PointIds->GetId(j); vectors->GetTuple(id, vec); for (i=0; i < 3; i++) { f[i] += vec[i] * this->Weights[j]; } } } // if not, return false else { return 0; } return 1; } void vtkInterpolatedVelocityField::AddDataSet(vtkDataSet* dataset) { if (!dataset) { return; } this->DataSets->push_back(dataset); int size = dataset->GetMaxCellSize(); if (size > this->WeightsSize) { this->WeightsSize = size; delete[] this->Weights; this->Weights = new double[size]; } } int vtkInterpolatedVelocityField::GetLastWeights(double* w) { int j, numPts; // If last cell is valid, fill w with the interpolation weights // and return true if (this->LastCellId >= 0) { numPts = this->GenCell->GetNumberOfPoints(); for (j=0; j < numPts; j++) { w[j] = this->Weights[j]; } return 1; } // otherwise, return false else { return 0; } } int vtkInterpolatedVelocityField::GetLastLocalCoordinates(double pcoords[3]) { int j; // If last cell is valid, fill p with the local coordinates // and return true if (this->LastCellId >= 0) { for (j=0; j < 3; j++) { pcoords[j] = this->LastPCoords[j]; } return 1; } // otherwise, return false else { return 0; } } void vtkInterpolatedVelocityField::CopyParameters( vtkInterpolatedVelocityField* from) { this->Caching = from->Caching; } void vtkInterpolatedVelocityField::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); if ( this->VectorsSelection ) { os << indent << "VectorsSelection: " << this->VectorsSelection << endl; } else { os << indent << "VectorsSelection: (none)" << endl; } if ( this->GenCell ) { os << indent << "Last cell: " << this->GenCell << endl; } else { os << indent << "Last cell: (none)" << endl; } os << indent << "Weights: " << this->Weights << endl; os << indent << "Last cell Id: " << this->LastCellId << endl; os << indent << "Cache hit: " << this->CacheHit << endl; os << indent << "Cache miss: " << this->CacheMiss << endl; os << indent << "Caching: "; if ( this->Caching ) { os << "on." << endl; } else { os << "off." << endl; } os << indent << "VectorsSelection: " << (this->VectorsSelection?this->VectorsSelection:"(none)") << endl; os << indent << "LastDataSet : " << this->LastDataSet << endl; }