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.
 
 
 
 
 
 

491 lines
13 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkImageStencilData.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 "vtkImageStencilData.h"
#include "vtkImageStencilSource.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include <math.h>
vtkCxxRevisionMacro(vtkImageStencilData, "$Revision: 1.15.6.1 $");
vtkStandardNewMacro(vtkImageStencilData);
//----------------------------------------------------------------------------
vtkImageStencilData::vtkImageStencilData()
{
this->Spacing[0] = this->OldSpacing[0] = 1;
this->Spacing[1] = this->OldSpacing[1] = 1;
this->Spacing[2] = this->OldSpacing[2] = 1;
this->Origin[0] = this->OldOrigin[0] = 0;
this->Origin[1] = this->OldOrigin[1] = 0;
this->Origin[2] = this->OldOrigin[2] = 0;
this->NumberOfExtentEntries = 0;
this->ExtentLists = NULL;
this->ExtentListLengths = NULL;
int extent[6] = {0, -1, 0, -1, 0, -1};
memcpy(this->Extent, extent, 6*sizeof(int));
this->Information->Set(vtkDataObject::DATA_EXTENT_TYPE(), VTK_3D_EXTENT);
this->Information->Set(vtkDataObject::DATA_EXTENT(), this->Extent, 6);
}
//----------------------------------------------------------------------------
vtkImageStencilData::~vtkImageStencilData()
{
this->Initialize();
}
//----------------------------------------------------------------------------
void vtkImageStencilData::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
int extent[6];
this->GetExtent(extent);
os << indent << "Extent: ("
<< extent[0] << ", "
<< extent[1] << ", "
<< extent[2] << ", "
<< extent[3] << ", "
<< extent[4] << ", "
<< extent[5] << ")\n";
os << indent << "Spacing: ("
<< this->Spacing[0] << ", "
<< this->Spacing[1] << ", "
<< this->Spacing[2] << ")\n";
os << indent << "Origin: ("
<< this->Origin[0] << ", "
<< this->Origin[1] << ", "
<< this->Origin[2] << ")\n";
os << indent << "OldSpacing: ("
<< this->OldSpacing[0] << ", "
<< this->OldSpacing[1] << ", "
<< this->OldSpacing[2] << ")\n";
os << indent << "OldOrigin: ("
<< this->OldOrigin[0] << ", "
<< this->OldOrigin[1] << ", "
<< this->OldOrigin[2] << ")\n";
}
//----------------------------------------------------------------------------
void vtkImageStencilData::Initialize()
{
if (this->ExtentLists)
{
int n = this->NumberOfExtentEntries;
for (int i = 0; i < n; i++)
{
delete [] this->ExtentLists[i];
}
delete [] this->ExtentLists;
}
this->ExtentLists = NULL;
this->NumberOfExtentEntries = 0;
if (this->ExtentListLengths)
{
delete [] this->ExtentListLengths;
}
this->ExtentListLengths = NULL;
if(this->Information)
{
int extent[6] = {0, -1, 0, -1, 0, -1};
memcpy(this->Extent, extent, 6*sizeof(int));
}
}
//----------------------------------------------------------------------------
void vtkImageStencilData::SetExtent(int* extent)
{
memcpy(this->Extent, extent, 6*sizeof(int));
}
//----------------------------------------------------------------------------
void vtkImageStencilData::SetExtent(int x1, int x2, int y1, int y2, int z1, int z2)
{
int ext[6];
ext[0] = x1;
ext[1] = x2;
ext[2] = y1;
ext[3] = y2;
ext[4] = z1;
ext[5] = z2;
this->SetExtent(ext);
}
//----------------------------------------------------------------------------
void vtkImageStencilData::ShallowCopy(vtkDataObject *o)
{
vtkImageStencilData *s = vtkImageStencilData::SafeDownCast(o);
if (s)
{
this->InternalImageStencilDataCopy(s);
}
vtkDataObject::ShallowCopy(o);
}
//----------------------------------------------------------------------------
void vtkImageStencilData::DeepCopy(vtkDataObject *o)
{
vtkImageStencilData *s = vtkImageStencilData::SafeDownCast(o);
if (s)
{
this->InternalImageStencilDataCopy(s);
}
vtkDataObject::DeepCopy(o);
}
//----------------------------------------------------------------------------
void vtkImageStencilData::InternalImageStencilDataCopy(vtkImageStencilData *s)
{
// copy information that accompanies the data
this->SetSpacing(s->Spacing);
this->SetOrigin(s->Origin);
// delete old data
if (this->ExtentLists)
{
int n = this->NumberOfExtentEntries;
for (int i = 0; i < n; i++)
{
delete [] this->ExtentLists[i];
}
delete [] this->ExtentLists;
}
this->ExtentLists = NULL;
this->NumberOfExtentEntries = 0;
if (this->ExtentListLengths)
{
delete [] this->ExtentListLengths;
}
this->ExtentListLengths = NULL;
// copy new data
if (s->NumberOfExtentEntries != 0)
{
this->NumberOfExtentEntries = s->NumberOfExtentEntries;
int n = this->NumberOfExtentEntries;
this->ExtentListLengths = new int[n];
this->ExtentLists = new int *[n];
for (int i = 0; i < n; i++)
{
this->ExtentListLengths[i] = s->ExtentListLengths[i];
int m = this->ExtentListLengths[i];
this->ExtentLists[i] = new int[m];
for (int j = 0; j < m; j++)
{
this->ExtentLists[i][j] = s->ExtentLists[i][j];
}
}
}
memcpy(this->Extent, s->GetExtent(), 6*sizeof(int));
}
//----------------------------------------------------------------------------
// Override from vtkDataObject because we have to handle the Spacing
// and Origin as well as the UpdateExtent.
void vtkImageStencilData::PropagateUpdateExtent()
{
#if 0
// If we need to update due to PipelineMTime, or the fact that our
// data was released, then propagate the update extent to the source
// if there is one.
if ( this->UpdateTime < this->PipelineMTime || this->DataReleased ||
this->UpdateExtentIsOutsideOfTheExtent() ||
this->SpacingOrOriginHasChanged() ||
this->LastUpdateExtentWasOutsideOfTheExtent)
{
if (this->Source)
{
this->Source->PropagateUpdateExtent(this);
}
}
// update the value of this ivar
this->LastUpdateExtentWasOutsideOfTheExtent =
this->UpdateExtentIsOutsideOfTheExtent();
#else
this->Superclass::PropagateUpdateExtent();
#endif
}
//----------------------------------------------------------------------------
// Override from vtkDataObject because we have to handle the Spacing
// and Origin as well as the UpdateExtent.
void vtkImageStencilData::TriggerAsynchronousUpdate()
{
#if 0
// If we need to update due to PipelineMTime, or the fact that our
// data was released, then propagate the trigger to the source
// if there is one.
if ( this->UpdateTime < this->PipelineMTime || this->DataReleased ||
this->UpdateExtentIsOutsideOfTheExtent() ||
this->SpacingOrOriginHasChanged())
{
if (this->Source)
{
this->Source->TriggerAsynchronousUpdate();
}
}
#else
this->Superclass::TriggerAsynchronousUpdate();
#endif
}
//----------------------------------------------------------------------------
void vtkImageStencilData::UpdateData()
{
#if 0
// If we need to update due to PipelineMTime, or the fact that our
// data was released, then propagate the UpdateData to the source
// if there is one.
if (this->UpdateTime < this->PipelineMTime || this->DataReleased ||
this->UpdateExtentIsOutsideOfTheExtent() ||
this->SpacingOrOriginHasChanged())
{
if (this->Source)
{
this->Source->UpdateData(this);
}
}
#else
this->Superclass::UpdateData();
#endif
}
//----------------------------------------------------------------------------
int vtkImageStencilData::SpacingOrOriginHasChanged()
{
double *spacing = this->Spacing;
double *origin = this->Origin;
double *ospacing = this->OldSpacing;
double *oorigin = this->OldOrigin;
return (spacing[0] != ospacing[0] || origin[0] != oorigin[0] ||
spacing[1] != ospacing[1] || origin[1] != oorigin[1] ||
spacing[2] != ospacing[2] || origin[2] != oorigin[2]);
}
//----------------------------------------------------------------------------
void vtkImageStencilData::AllocateExtents()
{
int extent[6];
this->GetExtent(extent);
int numEntries = (extent[3] - extent[2] + 1)*(extent[5] - extent[4] + 1);
if (numEntries != this->NumberOfExtentEntries)
{
if (this->NumberOfExtentEntries != 0)
{
int n = this->NumberOfExtentEntries;
for (int i = 0; i < n; i++)
{
delete [] this->ExtentLists[i];
}
delete [] this->ExtentLists;
delete [] this->ExtentListLengths;
}
this->NumberOfExtentEntries = numEntries;
this->ExtentLists = NULL;
this->ExtentListLengths = NULL;
if (numEntries)
{
this->ExtentLists = new int *[numEntries];
this->ExtentListLengths = new int[numEntries];
for (int i = 0; i < numEntries; i++)
{
this->ExtentListLengths[i] = 0;
this->ExtentLists[i] = NULL;
}
}
}
else
{
for (int i = 0; i < numEntries; i++)
{
if (this->ExtentListLengths[i] != 0)
{
this->ExtentListLengths[i] = 0;
delete this->ExtentLists[i];
this->ExtentLists[i] = NULL;
}
}
}
}
//----------------------------------------------------------------------------
// Given the output x extent [rmin,rmax] and the current y, z indices,
// return the sub extents [r1,r2] for which transformation/interpolation
// are to be done. The variable 'iter' should be initialized to zero
// before the first call. The return value is zero if there are no
// extents remaining.
int vtkImageStencilData::GetNextExtent(int &r1, int &r2,
int rmin, int rmax,
int yIdx, int zIdx, int &iter)
{
int extent[6];
this->GetExtent(extent);
int yExt = extent[3] - extent[2] + 1;
int zExt = extent[5] - extent[4] + 1;
yIdx -= extent[2];
zIdx -= extent[4];
// initialize r1, r2 to defaults
r1 = rmax + 1;
r2 = rmax;
if (yIdx < 0 || yIdx >= yExt || zIdx < 0 || zIdx >= zExt)
{ // out-of-bounds in y or z, use null extent
return 0;
}
// get the ExtentList and ExtentListLength for this yIdx,zIdx
int incr = zIdx*yExt + yIdx;
int *clist = this->ExtentLists[incr];
int clistlen = this->ExtentListLengths[incr];
if (iter <= 0)
{
int state = 1; // start outside
if (iter < 0) // unless iter is negative at start
{
iter = 0;
state = -1;
}
r1 = VTK_INT_MIN;
for ( ; iter < clistlen; iter++)
{
if (clist[iter] >= rmin)
{
if (state > 0)
{
r1 = clist[iter++];
}
break;
}
state = -state;
}
if (r1 == VTK_INT_MIN)
{
r1 = rmin;
if (state > 0)
{
r1 = rmax + 1;
}
}
}
else
{
if (iter >= clistlen)
{
return 0;
}
r1 = clist[iter++];
}
if (r1 > rmax)
{
r1 = rmax + 1;
return 0;
}
if (iter >= clistlen)
{
return 1;
}
r2 = clist[iter++] - 1;
if (r2 > rmax)
{
r2 = rmax;
}
return 1;
}
//----------------------------------------------------------------------------
// Insert a sub extent [r1,r2] on to the list for the x row at (yIdx,zIdx).
void vtkImageStencilData::InsertNextExtent(int r1, int r2, int yIdx, int zIdx)
{
// calculate the index into the extent array
int extent[6];
this->GetExtent(extent);
int yExt = extent[3] - extent[2] + 1;
int incr = (zIdx - extent[4])*yExt + (yIdx - extent[2]);
int &clistlen = this->ExtentListLengths[incr];
int *&clist = this->ExtentLists[incr];
if (clistlen == 0)
{ // no space has been allocated yet
clist = new int[2];
}
else
{ // check whether more space is needed
// the allocated space is always the smallest power of two
// that is not less than the number of stored items, therefore
// we need to allocate space when clistlen is a power of two
int clistmaxlen = 2;
while (clistlen > clistmaxlen)
{
clistmaxlen *= 2;
}
if (clistmaxlen == clistlen)
{ // need to allocate more space
clistmaxlen *= 2;
int *newclist = new int[clistmaxlen];
for (int k = 0; k < clistlen; k++)
{
newclist[k] = clist[k];
}
delete [] clist;
clist = newclist;
}
}
clist[clistlen++] = r1;
clist[clistlen++] = r2 + 1;
}
//----------------------------------------------------------------------------
vtkImageStencilData* vtkImageStencilData::GetData(vtkInformation* info)
{
return info? vtkImageStencilData::SafeDownCast(info->Get(DATA_OBJECT())) : 0;
}
//----------------------------------------------------------------------------
vtkImageStencilData* vtkImageStencilData::GetData(vtkInformationVector* v,
int i)
{
return vtkImageStencilData::GetData(v->GetInformationObject(i));
}