You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
718 lines
19 KiB
C++
718 lines
19 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkAMRBox.cxx
|
|
|
|
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 "vtkAMRBox.h"
|
|
|
|
#include "vtkUnsignedCharArray.h"
|
|
#include "vtkCellData.h"
|
|
#include "vtkType.h"
|
|
#include "vtkStructuredData.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkMath.h"
|
|
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
#include <cassert>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkAMRBox::vtkAMRBox()
|
|
{
|
|
this->Initialize();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkAMRBox::vtkAMRBox(const double* origin, const int* dimensions, const double* spacing, const double* globalOrigin,int gridDescription)
|
|
{
|
|
int ndim[3];
|
|
for( int d=0; d<3; ++d )
|
|
{
|
|
ndim[d] = dimensions[d]-1;
|
|
}
|
|
int lo[3], hi[3];
|
|
for( int d=0; d<3; ++d )
|
|
{
|
|
lo[d] = spacing[d]>0? vtkMath::Round( (origin[d] - globalOrigin[d])/spacing[d] ): 0;
|
|
hi[d] = lo[d] + ndim[d]-1;
|
|
}
|
|
|
|
this->SetDimensions( lo, hi, gridDescription);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkAMRBox::vtkAMRBox(
|
|
int ilo,int jlo,int klo,
|
|
int ihi,int jhi,int khi)
|
|
{
|
|
this->BuildAMRBox( ilo, jlo, klo, ihi,jhi,khi);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkAMRBox::vtkAMRBox(const int *lo, const int *hi)
|
|
{
|
|
this->BuildAMRBox( lo[0],lo[1],lo[2],hi[0],hi[1],hi[2] );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkAMRBox::vtkAMRBox(const int *dims)
|
|
{
|
|
this->BuildAMRBox(dims[0],dims[2],dims[4],dims[1],dims[3],dims[5] );
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::BuildAMRBox(
|
|
const int ilo, const int jlo, const int klo,
|
|
const int ihi, const int jhi, const int khi )
|
|
{
|
|
this->Initialize();
|
|
this->SetDimensions(ilo,jlo,klo,ihi,jhi,khi);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkAMRBox::vtkAMRBox(const vtkAMRBox &other)
|
|
{
|
|
*this = other;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkAMRBox &vtkAMRBox::operator=(const vtkAMRBox &other)
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !other.IsInvalid() );
|
|
|
|
if (this==&other) return *this;
|
|
for(int i=0; i<3; i++)
|
|
{
|
|
this->LoCorner[i] = other.LoCorner[i];
|
|
this->HiCorner[i] = other.HiCorner[i];
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::Initialize( )
|
|
{
|
|
for( int i=0; i < 3; ++i )
|
|
{
|
|
this->LoCorner[ i ] = 0;
|
|
this->HiCorner[ i ] = 0;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::SetDimensions(
|
|
int ilo,int jlo,int klo,
|
|
int ihi,int jhi,int khi, int desc)
|
|
{
|
|
assert (ihi-ilo>=-1 && jhi-jlo>=-1 && khi-klo>=-1);
|
|
this->LoCorner[0]= ilo;
|
|
this->LoCorner[1]= jlo;
|
|
this->LoCorner[2]= klo;
|
|
this->HiCorner[0]= ihi;
|
|
this->HiCorner[1]= jhi;
|
|
this->HiCorner[2]= khi;
|
|
|
|
switch( desc )
|
|
{
|
|
case VTK_XY_PLANE:
|
|
this->HiCorner[2] = this->LoCorner[2]-1;
|
|
break;
|
|
case VTK_XZ_PLANE:
|
|
this->HiCorner[1] = this->LoCorner[1]-1;
|
|
break;
|
|
case VTK_YZ_PLANE:
|
|
this->HiCorner[0] = this->LoCorner[0]-1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::SetDimensions(const int *lo, const int *hi, int desc)
|
|
{
|
|
this->SetDimensions(
|
|
lo[0],lo[1],lo[2],
|
|
hi[0],hi[1],hi[2], desc);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::SetDimensions(const int *dims, int desc)
|
|
{
|
|
this->SetDimensions(
|
|
dims[0],dims[2],dims[4],
|
|
dims[1],dims[3],dims[5], desc);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::GetDimensions(int *lo, int *hi) const
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
for (int q=0; q < 3; ++q)
|
|
{
|
|
lo[q]=this->LoCorner[q];
|
|
hi[q]=this->HiCorner[q];
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::GetDimensions(int dims[6]) const
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
dims[0]=this->LoCorner[0];
|
|
dims[1]=this->HiCorner[0];
|
|
dims[2]=this->LoCorner[1];
|
|
dims[3]=this->HiCorner[1];
|
|
dims[4]=this->LoCorner[2];
|
|
dims[5]=this->HiCorner[2];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::GetValidHiCorner(int *hi) const
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
for (int q=0; q < 3; ++q)
|
|
{
|
|
hi[q] = this->EmptyDimension(q)? this->LoCorner[q]: this->HiCorner[q];
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::GetBoxOrigin(const vtkAMRBox& extent, const double X0[3], const double spacing[3],double x0[3])
|
|
{
|
|
assert( "pre: input array is NULL" && (x0 != NULL) );
|
|
x0[0] = x0[1] = x0[2] = 0.0;
|
|
|
|
for( int i=0; i < 3; ++i )
|
|
{
|
|
x0[i] = X0[i]+ extent.GetLoCorner()[i]*spacing[i];
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::GetBounds(const vtkAMRBox& extent, const double origin[3], const double spacing[3], double bounds[6])
|
|
{
|
|
int i, j;
|
|
for( i=0, j=0; i < 3; ++i )
|
|
{
|
|
bounds[ j++ ] = origin[i]+extent.LoCorner[i]*spacing[i];
|
|
bounds[ j++ ] = origin[i]+(extent.HiCorner[i]+1)*spacing[i];
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAMRBox::HasPoint(const vtkAMRBox& box, const double origin[3], const double spacing[3], double x, double y, double z )
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !box.IsInvalid() );
|
|
|
|
double bb[6];
|
|
vtkAMRBox::GetBounds(box,origin, spacing,bb);
|
|
double min[3]={bb[0],bb[2],bb[4]};
|
|
double max[3]={bb[1],bb[3],bb[5]};
|
|
|
|
if( x >= min[0] && x <= max[0] &&
|
|
y >= min[1] && y <= max[1] &&
|
|
z >= min[2] && z <= max[2] )
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAMRBox::operator==(const vtkAMRBox &other) const
|
|
{
|
|
if ((this->Empty() && other.Empty())
|
|
||(this->LoCorner[0]==other.LoCorner[0]
|
|
&& this->LoCorner[1]==other.LoCorner[1]
|
|
&& this->LoCorner[2]==other.LoCorner[2]
|
|
&& this->HiCorner[0]==other.HiCorner[0]
|
|
&& this->HiCorner[1]==other.HiCorner[1]
|
|
&& this->HiCorner[2]==other.HiCorner[2]))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
ostream &vtkAMRBox::Print(ostream &os) const
|
|
{
|
|
os << "-D AMR box => "
|
|
<< "Low: (" << this->LoCorner[0]
|
|
<< "," << this->LoCorner[1]
|
|
<< "," << this->LoCorner[2]
|
|
<< ") High: (" << this->HiCorner[0]
|
|
<< "," << this->HiCorner[1]
|
|
<< "," << this->HiCorner[2]
|
|
<< ")";
|
|
return os;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::Serialize( unsigned char*& buffer, vtkIdType& bytesize)
|
|
{
|
|
assert( "pre: input buffer is expected to be NULL" && (buffer==NULL) );
|
|
|
|
bytesize = vtkAMRBox::GetBytesize();
|
|
buffer = new unsigned char[ bytesize ];
|
|
assert( buffer != NULL );
|
|
|
|
// STEP 0: set pointer to traverse the buffer
|
|
unsigned char* ptr = buffer;
|
|
|
|
// STEP 7: serialize the low corner
|
|
std::memcpy(ptr, &(this->LoCorner), 3*sizeof(int) );
|
|
ptr += 3*sizeof( int );
|
|
|
|
// STEP 8: serialize the high corner
|
|
std::memcpy(ptr, &(this->HiCorner), 3*sizeof(int) );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::Serialize( int* buffer) const
|
|
{
|
|
memcpy(buffer, this->LoCorner, 3*sizeof(int));
|
|
memcpy(buffer+3, this->HiCorner, 3*sizeof(int));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::Deserialize(
|
|
unsigned char* buffer, const vtkIdType& vtkNotUsed(bytesize) )
|
|
{
|
|
assert( "pre: input buffer is NULL" && (buffer != NULL) );
|
|
|
|
// STEP 0: set pointer to traverse the buffer
|
|
unsigned char *ptr = buffer;
|
|
|
|
|
|
// STEP 7: de-serialize the low corner
|
|
std::memcpy( &(this->LoCorner), ptr, 3*sizeof(int) );
|
|
ptr += 3*sizeof( int );
|
|
|
|
// STEP 8: de-serialize the high corner
|
|
std::memcpy(&(this->HiCorner), ptr, 3*sizeof(int) );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAMRBox::IntersectBoxAlongDimension(const vtkAMRBox &other, const int q)
|
|
{
|
|
assert( "pre: dimension is out-of-bounds!" && (q >= 0) && (q <= 2) );
|
|
if(this->EmptyDimension(q) || other.EmptyDimension(q))
|
|
{
|
|
return false;
|
|
}
|
|
if( this->LoCorner[q] <= other.LoCorner[q] )
|
|
{
|
|
this->LoCorner[q] = other.LoCorner[q];
|
|
}
|
|
if (this->HiCorner[q] >= other.HiCorner[q])
|
|
{
|
|
this->HiCorner[q] = other.HiCorner[q];
|
|
}
|
|
if (this->LoCorner[q] >= this->HiCorner[q])
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool vtkAMRBox::Intersect(const vtkAMRBox &other)
|
|
{
|
|
if( !this->IntersectBoxAlongDimension(other,0) ||
|
|
!this->IntersectBoxAlongDimension(other,1) ||
|
|
!this->IntersectBoxAlongDimension(other,2) )
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
int vtkAMRBox::GetCellLinearIndex(const vtkAMRBox& box, const int i, const int j, const int k, int dim[3])
|
|
{
|
|
// Convert to local numbering
|
|
int I[3]={ i-box.GetLoCorner()[0],
|
|
j-box.GetLoCorner()[1],
|
|
k-box.GetLoCorner()[2]};
|
|
|
|
// Get Cell sizes
|
|
int N[3] = {dim[0]-1, dim[1]-1,dim[2]-1};
|
|
|
|
// Reduce the sizes and indices to those
|
|
// that correspond to the non-null dimensions
|
|
int nd(0);
|
|
for(int d=0; d<3; d++)
|
|
{
|
|
if(!box.EmptyDimension(d))
|
|
{
|
|
N[nd] = N[d];
|
|
I[nd] = I[d];
|
|
assert(I[nd]>=0 && I[nd]<N[nd]);
|
|
nd++;
|
|
}
|
|
}
|
|
|
|
int idx=0;
|
|
for(int d=nd-1; d>=0; d--)
|
|
{
|
|
idx= idx*N[d]+I[d];
|
|
}
|
|
return idx;
|
|
}
|
|
|
|
|
|
|
|
void vtkAMRBox::Coarsen(int r)
|
|
{
|
|
assert( "pre: Input refinement ratio must be >= 2" && (r >= 2) );
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
|
|
if( this->Empty() )
|
|
{
|
|
std::cerr << "WARNING: tried refining an empty AMR box!\n";
|
|
std::cerr << "FILE:" << __FILE__ << std::endl;
|
|
std::cerr << "LINE:" << __LINE__ << std::endl;
|
|
std::cerr.flush();
|
|
return;
|
|
}
|
|
for(int q=0; q < 3; ++q )
|
|
{
|
|
if(this->EmptyDimension(q))
|
|
{
|
|
continue;
|
|
}
|
|
this->LoCorner[q]=( (this->LoCorner[q] < 0)?
|
|
-abs(this->LoCorner[q]+1)/r-1 : this->LoCorner[q]/r);
|
|
this->HiCorner[q]=( this->HiCorner[q]<0 ?
|
|
-abs(this->HiCorner[q]+1)/r-1 : this->HiCorner[q]/r);
|
|
}
|
|
assert( "post: Coarsened AMR box should not be empty!" && !this->Empty() );
|
|
assert( "post: Coarsened AMR Box instance is invalid" && !this->IsInvalid() );
|
|
}
|
|
|
|
void vtkAMRBox::Refine(int r)
|
|
{
|
|
assert( "pre: Input refinement ratio must be >= 1" && (r >= 1) );
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
|
|
if( this->Empty() )
|
|
{
|
|
std::cerr << "WARNING: tried refining an empty AMR box!\n";
|
|
std::cerr << "FILE:" << __FILE__ << std::endl;
|
|
std::cerr << "LINE:" << __LINE__ << std::endl;
|
|
std::cerr.flush();
|
|
return;
|
|
}
|
|
for(int q=0; q < 3; ++q )
|
|
{
|
|
if(!this->EmptyDimension(q))
|
|
{
|
|
this->LoCorner[q]=this->LoCorner[q]*r;
|
|
this->HiCorner[q]=(this->HiCorner[q]+1)*r-1;
|
|
}
|
|
}
|
|
assert( "post: Refined AMR box should not be empty!" && !this->Empty() );
|
|
assert( "post: Refined AMR Box instance is invalid" && !this->IsInvalid() );
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAMRBox::DoesBoxIntersectAlongDimension(
|
|
const vtkAMRBox &other, const int q) const
|
|
{
|
|
if(this->EmptyDimension(q) && other.EmptyDimension(q))
|
|
{
|
|
return true;
|
|
}
|
|
int minVal = 0;
|
|
int maxVal = 0;
|
|
minVal = (this->LoCorner[q] < other.LoCorner[q]) ?
|
|
other.LoCorner[q] : this->LoCorner[q];
|
|
maxVal = (this->HiCorner[q] > other.HiCorner[q]) ?
|
|
other.HiCorner[q] : this->HiCorner[q];
|
|
|
|
if (minVal >= maxVal)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
bool vtkAMRBox::DoesIntersect(const vtkAMRBox &other) const
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
if (this->Empty())
|
|
{
|
|
return false;
|
|
}
|
|
if (other.Empty())
|
|
{
|
|
return false;
|
|
}
|
|
if( !this->DoesBoxIntersectAlongDimension(other,0) ||
|
|
!this->DoesBoxIntersectAlongDimension(other,1) ||
|
|
!this->DoesBoxIntersectAlongDimension(other,2) )
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int vtkAMRBox::ComputeStructuredCoordinates(const vtkAMRBox& box, const double dataOrigin[3],
|
|
const double h[3], const double x[3], int ijk[3], double pcoords[3])
|
|
{
|
|
double origin[3];
|
|
vtkAMRBox::GetBoxOrigin(box,dataOrigin,h,origin);
|
|
|
|
int num[3];
|
|
box.GetNumberOfNodes(num);
|
|
int extent[6] = {0,num[0]-1,0,num[1]-1,0,num[2]-1};
|
|
|
|
double bounds[6];
|
|
vtkAMRBox::GetBounds(box,dataOrigin,h,bounds);
|
|
|
|
return vtkImageData::ComputeStructuredCoordinates(x,ijk,pcoords,extent, h, origin,bounds);
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
void vtkAMRBox::GetGhostVector(int r, int nghost[6]) const
|
|
{
|
|
// STEP 0: initialize nghost
|
|
for( int i=0; i < 3; ++i )
|
|
{
|
|
nghost[i*2] = nghost[i*2+1] = 0;
|
|
}
|
|
|
|
// STEP 1: compute number of ghost layers along each dimension's min and max.
|
|
// Detecting partially overlapping boxes is based on the following:
|
|
// Cell location k at level L-1 holds the range [k*r,k*r+(r-1)] of
|
|
// level L, where r is the refinement ratio. Consequently, if the
|
|
// min extent of the box is greater than k*r or if the max extent
|
|
// of the box is less than k*r+(r-1), then the grid partially overlaps.
|
|
|
|
vtkAMRBox coarsenedBox = *this;
|
|
coarsenedBox.Coarsen(r);
|
|
for( int i=0; i < 3; ++i )
|
|
{
|
|
if(!this->EmptyDimension(i))
|
|
{
|
|
int minRange[2];
|
|
minRange[0] = coarsenedBox.LoCorner[i]*r;
|
|
minRange[1] = coarsenedBox.LoCorner[i]*r + (r-1);
|
|
if( this->LoCorner[i] > minRange[0] )
|
|
{
|
|
nghost[i*2]=(minRange[1]+1)- this->LoCorner[i];
|
|
}
|
|
|
|
int maxRange[2];
|
|
maxRange[0] = coarsenedBox.HiCorner[i]*r;
|
|
maxRange[1] = coarsenedBox.HiCorner[i]*r + (r-1);
|
|
if( this->HiCorner[i] < maxRange[1] )
|
|
{
|
|
nghost[i*2+1] = this->HiCorner[i]-(maxRange[0]-1);
|
|
}
|
|
}
|
|
} // END for all dimensions
|
|
}
|
|
|
|
void vtkAMRBox::RemoveGhosts(int r)
|
|
{
|
|
// Detecting partially overlapping boxes is based on the following:
|
|
// Cell location k at level L-1 holds the range [k*r,k*r+(r-1)] of
|
|
// level L, where r is the refinement ratio. Consequently, if the
|
|
// min extent of the box is greater than k*r or if the max extent
|
|
// of the box is less than k*r+(r-1), then the grid partially overlaps.
|
|
vtkAMRBox coarsenedBox = *this;
|
|
coarsenedBox.Coarsen(r);
|
|
for( int i=0; i < 3; ++i )
|
|
{
|
|
if(!this->EmptyDimension(i))
|
|
{
|
|
int minRange[2];
|
|
minRange[0] = coarsenedBox.LoCorner[i]*r;
|
|
minRange[1] = coarsenedBox.LoCorner[i]*r + (r-1);
|
|
if( this->LoCorner[i] > minRange[0] )
|
|
{
|
|
this->LoCorner[i]=(minRange[1]+1);
|
|
}
|
|
|
|
int maxRange[2];
|
|
maxRange[0] = coarsenedBox.HiCorner[i]*r;
|
|
maxRange[1] = coarsenedBox.HiCorner[i]*r + (r-1);
|
|
if( this->HiCorner[i] < maxRange[1] )
|
|
{
|
|
this->HiCorner[i] = (maxRange[0]-1);
|
|
}
|
|
}
|
|
} // END for all dimensions
|
|
}
|
|
|
|
|
|
int vtkAMRBox::ComputeDimension() const
|
|
{
|
|
int dim(3);
|
|
for(int i=0;i<3; i++)
|
|
{
|
|
if(this->EmptyDimension(i))
|
|
{
|
|
dim--;
|
|
}
|
|
}
|
|
return( dim );
|
|
}
|
|
|
|
void vtkAMRBox::GetNumberOfCells(int ext[3]) const
|
|
{
|
|
ext[0] = this->HiCorner[0]-this->LoCorner[0]+1;
|
|
ext[1] = this->HiCorner[1]-this->LoCorner[1]+1;
|
|
ext[2] = this->HiCorner[2]-this->LoCorner[2]+1;
|
|
}
|
|
|
|
vtkIdType vtkAMRBox::GetNumberOfCells() const
|
|
{
|
|
int cellExtent[3];
|
|
this->GetNumberOfCells(cellExtent);
|
|
int numCells = 0;
|
|
for( int i=0; i < 3; ++i )
|
|
{
|
|
if( numCells == 0 )
|
|
{
|
|
numCells = cellExtent[i];
|
|
}
|
|
else if( cellExtent[i] != 0 )
|
|
{
|
|
numCells *= cellExtent[i];
|
|
}
|
|
}
|
|
return( numCells );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAMRBox::Contains(int i,int j,int k) const
|
|
{
|
|
int ijk[3] = {i,j,k};
|
|
return this->Contains(ijk);
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAMRBox::Contains(const int *I) const
|
|
{
|
|
bool res(true);
|
|
for(int i=0; i<3; i++)
|
|
{
|
|
if (!this->EmptyDimension(i) && (this->LoCorner[i]>I[i] || this->HiCorner[i]<I[i]))
|
|
{
|
|
res = false;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool vtkAMRBox::Contains(const vtkAMRBox &other) const
|
|
{
|
|
const int *lo=other.LoCorner;
|
|
const int *hi=other.HiCorner;
|
|
return this->Contains(lo) && this->Contains(hi);
|
|
}
|
|
|
|
void vtkAMRBox::GetNumberOfNodes(int *ext) const
|
|
{
|
|
ext[0] = this->HiCorner[0]-this->LoCorner[0]+2;
|
|
ext[1] = this->HiCorner[1]-this->LoCorner[1]+2;
|
|
ext[2] = this->HiCorner[2]-this->LoCorner[2]+2;
|
|
assert(ext[0]>=1 && ext[1]>=1 && ext[2]>=1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkIdType vtkAMRBox::GetNumberOfNodes() const
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
int ext[3];
|
|
this->GetNumberOfNodes( ext );
|
|
int numNodes = 0;
|
|
for( int i=0; i < 3; ++i )
|
|
{
|
|
if( numNodes == 0 )
|
|
{
|
|
numNodes = ext[i];
|
|
}
|
|
else if( ext[i] != 0 )
|
|
{
|
|
numNodes *= ext[i];
|
|
}
|
|
}
|
|
return( numNodes );
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::Shift(int i, int j, int k)
|
|
{
|
|
int ijk[3] = {i,j,k};
|
|
this->Shift(ijk);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::Shift(const int *ijk)
|
|
{
|
|
for(int q=0; q < 3; ++q )
|
|
{
|
|
this->LoCorner[q] = this->LoCorner[q]+ijk[q];
|
|
this->HiCorner[q] = this->HiCorner[q]+ijk[q];
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::Grow(int byN)
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
// TODO: One question here is, should we allow negative indices?
|
|
// Or should we otherwise, ensure that the box is grown with
|
|
// bounds.
|
|
for(int q=0; q < 3; ++q )
|
|
{
|
|
if(!this->EmptyDimension(q))
|
|
{
|
|
this->LoCorner[q]-=byN;
|
|
this->HiCorner[q]+=byN;
|
|
}
|
|
}
|
|
assert( "post: Grown AMR Box instance is invalid" && !this->IsInvalid() );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkAMRBox::Shrink(int byN)
|
|
{
|
|
assert( "pre: AMR Box instance is invalid" && !this->IsInvalid() );
|
|
// TODO: One question here is, should we allow negative indices?
|
|
// Or should we otherwise, ensure that the box is grown with
|
|
// bounds.
|
|
for(int q=0; q < 3; ++q )
|
|
{
|
|
if(!this->EmptyDimension(q))
|
|
{
|
|
this->LoCorner[q]+=byN;
|
|
this->HiCorner[q]-=byN;
|
|
}
|
|
}
|
|
assert( "post: Grown AMR Box instance is invalid" && !this->IsInvalid() );
|
|
}
|