Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

403 lines
11 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkPointSet.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 "vtkPointSet.h"
#include "vtkCell.h"
#include "vtkGarbageCollector.h"
#include "vtkGenericCell.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkPointLocator.h"
#include "vtkSource.h"
vtkCxxRevisionMacro(vtkPointSet, "$Revision: 1.3.12.1 $");
vtkCxxSetObjectMacro(vtkPointSet,Points,vtkPoints);
vtkPointSet::vtkPointSet ()
{
this->Points = NULL;
this->Locator = NULL;
}
//----------------------------------------------------------------------------
vtkPointSet::~vtkPointSet ()
{
this->Initialize();
if ( this->Locator )
{
this->Locator->UnRegister(this);
this->Locator = NULL;
}
}
//----------------------------------------------------------------------------
// Copy the geometric structure of an input point set object.
void vtkPointSet::CopyStructure(vtkDataSet *ds)
{
vtkPointSet *ps=(vtkPointSet *)ds;
if ( this->Points != ps->Points )
{
if ( this->Locator )
{
this->Locator->Initialize();
}
this->SetPoints(ps->Points);
}
}
//----------------------------------------------------------------------------
void vtkPointSet::Initialize()
{
vtkDataSet::Initialize();
if ( this->Points )
{
this->Points->UnRegister(this);
this->Points = NULL;
}
if ( this->Locator )
{
this->Locator->Initialize();
}
}
//----------------------------------------------------------------------------
void vtkPointSet::ComputeBounds()
{
double *bounds;
if ( this->Points )
{
bounds = this->Points->GetBounds();
for (int i=0; i<6; i++)
{
this->Bounds[i] = bounds[i];
}
this->ComputeTime.Modified();
}
}
//----------------------------------------------------------------------------
unsigned long int vtkPointSet::GetMTime()
{
unsigned long int dsTime = vtkDataSet::GetMTime();
if ( this->Points )
{
if ( this->Points->GetMTime() > dsTime )
{
dsTime = this->Points->GetMTime();
}
}
// don't get locator's mtime because its an internal object that cannot be
// modified directly from outside. Causes problems due to FindCell()
// SetPoints() method.
return dsTime;
}
//----------------------------------------------------------------------------
vtkIdType vtkPointSet::FindPoint(double x[3])
{
if ( !this->Points )
{
return -1;
}
if ( !this->Locator )
{
this->Locator = vtkPointLocator::New();
this->Locator->Register(this);
this->Locator->Delete();
this->Locator->SetDataSet(this);
}
if ( this->Points->GetMTime() > this->Locator->GetMTime() )
{
this->Locator->SetDataSet(this);
}
return this->Locator->FindClosestPoint(x);
}
//the furthest the walk can be - prevents aimless wandering
#define VTK_MAX_WALK 12
//----------------------------------------------------------------------------
vtkIdType vtkPointSet::FindCell(double x[3], vtkCell *cell,
vtkGenericCell *gencell, vtkIdType cellId,
double tol2, int& subId, double pcoords[3],
double *weights)
{
vtkIdType ptId;
int walk;
double closestPoint[3];
double dist2;
vtkIdList *cellIds, *ptIds;
int initialCellProvided = 1;
// make sure everything is up to snuff
if ( !this->Points )
{
return -1;
}
cellIds = vtkIdList::New();
cellIds->Allocate(8,100);
ptIds = vtkIdList::New();
ptIds->Allocate(8,100);
if ( !this->Locator )
{
this->Locator = vtkPointLocator::New();
this->Locator->Register(this);
this->Locator->Delete();
this->Locator->SetDataSet(this);
}
if ( this->Points->GetMTime() > this->Locator->GetMTime() )
{
this->Locator->SetDataSet(this);
}
// If we don't have a starting cell, we'll have to find one. Find
// the closest point to the input position, then get the cells that use
// the point. Then use one of the cells to begin the walking process.
if ( !cell )
{
initialCellProvided = 0;
ptId = this->Locator->FindClosestPoint(x);
if ( ptId < 0 )
{
cellIds->Delete();
ptIds->Delete();
return (-1); //if point completely outside of data
}
this->GetPointCells(ptId, cellIds);
if ( cellIds->GetNumberOfIds() > 0 )
{
cellId = cellIds->GetId(0); //arbitrarily use first cell in list
if ( gencell )
{
this->GetCell(cellId, gencell);
}
else
{
cell = this->GetCell(cellId);
}
// See whether this randomly choosen cell contains the point
double dx[3];
dx[0] = x[0];
dx[1] = x[1];
dx[2] = x[2];
if ( ( gencell &&
gencell->EvaluatePosition(dx,closestPoint,subId,
pcoords, dist2,weights) == 1
&& dist2 <= tol2 ) ||
( !gencell &&
cell->EvaluatePosition(dx,closestPoint,subId,
pcoords, dist2,weights) == 1
&& dist2 <= tol2 ) )
{
cellIds->Delete();
ptIds->Delete();
return cellId;
}
}
}
else //EvaluatePosition insures that pcoords is defined
{
cell->EvaluatePosition(x,NULL,subId,pcoords,dist2,weights);
}
// If a cell is supplied, or we didn't find a starting cell (in the
// previous chunk of code), then we use this to start our search. A
// walking scheme is used, where we walk towards the point and eventually
// locate the cell that contains the point.
if ( cell || cellIds->GetNumberOfIds() > 0 ) //we have a starting cell
{
for ( walk=0; walk < VTK_MAX_WALK; walk++ )
{
if ( cell )
{
cell->CellBoundary(subId, pcoords, ptIds);
}
else
{
gencell->CellBoundary(subId, pcoords, ptIds);
}
this->GetCellNeighbors(cellId, ptIds, cellIds);
if ( cellIds->GetNumberOfIds() > 0 )
{
cellId = cellIds->GetId(0);
if ( gencell )
{
cell = NULL;
this->GetCell(cellId, gencell);
}
else
{
cell = this->GetCell(cellId);
}
}
else
{
break; //outside of data
}
if ( ( (!cell &&
gencell->EvaluatePosition(x,closestPoint,subId,pcoords,
dist2,weights) == 1 ) ||
(cell && cell->EvaluatePosition(x,closestPoint,
subId,pcoords,
dist2,weights) == 1 ) )
&& dist2 <= tol2 )
{
cellIds->Delete();
ptIds->Delete();
return cellId;
}
}//for a walk
}//if we have a starting cell
cellIds->Delete();
ptIds->Delete();
//sometimes the initial cell is a really bad guess so we'll
//just ignore it and start from scratch as a last resort
if ( initialCellProvided )
{
return this->FindCell(x, NULL, gencell, cellId, tol2,
subId, pcoords, weights);
}
else
{
return -1;
}
}
//----------------------------------------------------------------------------
vtkIdType vtkPointSet::FindCell(double x[3], vtkCell *cell, vtkIdType cellId,
double tol2, int& subId,double pcoords[3],
double *weights)
{
return
this->FindCell( x, cell, NULL, cellId, tol2, subId, pcoords, weights );
}
#undef VTK_MAX_WALK
//----------------------------------------------------------------------------
void vtkPointSet::Squeeze()
{
if ( this->Points )
{
this->Points->Squeeze();
}
vtkDataSet::Squeeze();
}
//----------------------------------------------------------------------------
void vtkPointSet::ReportReferences(vtkGarbageCollector* collector)
{
this->Superclass::ReportReferences(collector);
vtkGarbageCollectorReport(collector, this->Locator, "Locator");
}
//----------------------------------------------------------------------------
unsigned long vtkPointSet::GetActualMemorySize()
{
unsigned long size=this->vtkDataSet::GetActualMemorySize();
if ( this->Points )
{
size += this->Points->GetActualMemorySize();
}
return size;
}
//----------------------------------------------------------------------------
void vtkPointSet::ShallowCopy(vtkDataObject *dataObject)
{
vtkPointSet *pointSet = vtkPointSet::SafeDownCast(dataObject);
if ( pointSet != NULL )
{
this->SetPoints(pointSet->GetPoints());
}
// Do superclass
this->vtkDataSet::ShallowCopy(dataObject);
}
//----------------------------------------------------------------------------
void vtkPointSet::DeepCopy(vtkDataObject *dataObject)
{
vtkPointSet *pointSet = vtkPointSet::SafeDownCast(dataObject);
if ( pointSet != NULL )
{
if (this->Points == NULL)
{
if ( pointSet->GetPoints() != NULL )
{
this->Points = pointSet->GetPoints()->NewInstance();
this->Points->SetDataType(pointSet->GetPoints()->GetDataType());
this->Points->Register(this);
this->Points->Delete();
}
else
{
this->Points = vtkPoints::New();
this->Points->Register(this);
this->Points->Delete();
}
}
this->Points->DeepCopy(pointSet->GetPoints());
}
// Do superclass
this->vtkDataSet::DeepCopy(dataObject);
}
//----------------------------------------------------------------------------
vtkPointSet* vtkPointSet::GetData(vtkInformation* info)
{
return info? vtkPointSet::SafeDownCast(info->Get(DATA_OBJECT())) : 0;
}
//----------------------------------------------------------------------------
vtkPointSet* vtkPointSet::GetData(vtkInformationVector* v, int i)
{
return vtkPointSet::GetData(v->GetInformationObject(i));
}
//----------------------------------------------------------------------------
void vtkPointSet::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Number Of Points: " << this->GetNumberOfPoints() << "\n";
os << indent << "Point Coordinates: " << this->Points << "\n";
os << indent << "Locator: " << this->Locator << "\n";
}