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.
 
 
 
 
 
 

361 lines
10 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkExtentTranslator.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 "vtkExtentTranslator.h"
#include "vtkObjectFactory.h"
#include "vtkLargeInteger.h"
vtkCxxRevisionMacro(vtkExtentTranslator, "$Revision: 1.21 $");
vtkStandardNewMacro(vtkExtentTranslator);
//----------------------------------------------------------------------------
vtkExtentTranslator::vtkExtentTranslator()
{
this->Piece = 0;
this->NumberOfPieces = 0;
this->GhostLevel = 0;
this->Extent[0] = this->Extent[2] = this->Extent[4] = 0;
this->Extent[1] = this->Extent[3] = this->Extent[5] = -1;
this->WholeExtent[0] = this->WholeExtent[2] = this->WholeExtent[4] = 0;
this->WholeExtent[1] = this->WholeExtent[3] = this->WholeExtent[5] = -1;
// Set a default split mode to be slabs
this->SplitMode = vtkExtentTranslator::BLOCK_MODE;
}
//----------------------------------------------------------------------------
vtkExtentTranslator::~vtkExtentTranslator()
{
}
//----------------------------------------------------------------------------
int vtkExtentTranslator::PieceToExtent()
{
return
this->PieceToExtentThreadSafe(this->Piece, this->NumberOfPieces,
this->GhostLevel, this->WholeExtent,
this->Extent, this->SplitMode, 0);
}
//----------------------------------------------------------------------------
int vtkExtentTranslator::PieceToExtentByPoints()
{
return
this->PieceToExtentThreadSafe(this->Piece, this->NumberOfPieces,
this->GhostLevel, this->WholeExtent,
this->Extent, this->SplitMode, 1);
}
int vtkExtentTranslator::PieceToExtentThreadSafe(int piece, int numPieces,
int ghostLevel,
int *wholeExtent,
int *resultExtent,
int splitMode,
int byPoints)
{
memcpy(resultExtent, wholeExtent, sizeof(int)*6);
int ret;
if (byPoints)
{
ret = this->SplitExtentByPoints(piece, numPieces, resultExtent, splitMode);
}
else
{
ret = this->SplitExtent(piece, numPieces, resultExtent, splitMode);
}
if (ret == 0)
{
// Nothing in this piece.
resultExtent[0] = resultExtent[2] = resultExtent[4] = 0;
resultExtent[1] = resultExtent[3] = resultExtent[5] = -1;
return 0;
}
if (ghostLevel > 0)
{
resultExtent[0] -= ghostLevel;
resultExtent[1] += ghostLevel;
resultExtent[2] -= ghostLevel;
resultExtent[3] += ghostLevel;
resultExtent[4] -= ghostLevel;
resultExtent[5] += ghostLevel;
if (resultExtent[0] < wholeExtent[0])
{
resultExtent[0] = wholeExtent[0];
}
if (resultExtent[1] > wholeExtent[1])
{
resultExtent[1] = wholeExtent[1];
}
if (resultExtent[2] < wholeExtent[2])
{
resultExtent[2] = wholeExtent[2];
}
if (resultExtent[3] > wholeExtent[3])
{
resultExtent[3] = wholeExtent[3];
}
if (resultExtent[4] < wholeExtent[4])
{
resultExtent[4] = wholeExtent[4];
}
if (resultExtent[5] > wholeExtent[5])
{
resultExtent[5] = wholeExtent[5];
}
}
return 1;
}
//----------------------------------------------------------------------------
int vtkExtentTranslator::SplitExtent(int piece, int numPieces, int *ext,
int splitMode)
{
int numPiecesInFirstHalf;
unsigned long size[3];
int splitAxis;
vtkLargeInteger mid;
if (piece >= numPieces || piece < 0)
{
return 0;
}
// keep splitting until we have only one piece.
// piece and numPieces will always be relative to the current ext.
while (numPieces > 1)
{
// Get the dimensions for each axis.
size[0] = ext[1]-ext[0];
size[1] = ext[3]-ext[2];
size[2] = ext[5]-ext[4];
// choose what axis to split on based on the SplitMode
// if the user has requested x, y, or z slabs then try to
// honor that request. If that axis is already split as
// far as it can go, then drop to block mode.
if (splitMode < 3 && size[splitMode] > 1)
{
splitAxis = splitMode;
}
// otherwise use block mode
else
{
// choose the biggest axis
if (size[2] >= size[1] && size[2] >= size[0] && size[2]/2 >= 1)
{
splitAxis = 2;
}
else if (size[1] >= size[0] && size[1]/2 >= 1)
{
splitAxis = 1;
}
else if (size[0]/2 >= 1)
{
splitAxis = 0;
}
else
{
// signal no more splits possible
splitAxis = -1;
}
}
if (splitAxis == -1)
{
// can not split any more.
if (piece == 0)
{
// just return the remaining piece
numPieces = 1;
}
else
{
// the rest must be empty
return 0;
}
}
else
{
// split the chosen axis into two pieces.
numPiecesInFirstHalf = (numPieces / 2);
mid = size[splitAxis];
mid = (mid * numPiecesInFirstHalf) / numPieces + ext[splitAxis*2];
if (piece < numPiecesInFirstHalf)
{
// piece is in the first half
// set extent to the first half of the previous value.
ext[splitAxis*2+1] = mid.CastToInt();
// piece must adjust.
numPieces = numPiecesInFirstHalf;
}
else
{
// piece is in the second half.
// set the extent to be the second half. (two halves share points)
ext[splitAxis*2] = mid.CastToInt();
// piece must adjust
numPieces = numPieces - numPiecesInFirstHalf;
piece -= numPiecesInFirstHalf;
}
}
} // end of while
return 1;
}
//----------------------------------------------------------------------------
int vtkExtentTranslator::SplitExtentByPoints(int piece, int numPieces,
int *ext, int splitMode)
{
int numPiecesInFirstHalf;
int size[3], splitAxis;
vtkLargeInteger mid;
// keep splitting until we have only one piece.
// piece and numPieces will always be relative to the current ext.
while (numPieces > 1)
{
// Get the dimensions for each axis.
size[0] = ext[1]-ext[0] + 1;
size[1] = ext[3]-ext[2] + 1;
size[2] = ext[5]-ext[4] + 1;
// choose what axis to split on based on the SplitMode
// if the user has requested x, y, or z slabs then try to
// honor that request. If that axis is already split as
// far as it can go, then drop to block mode.
if (splitMode < 3 && size[splitMode] > 1)
{
splitAxis = splitMode;
}
// otherwise use block mode
else
{
if (size[2] >= size[1] && size[2] >= size[0] && size[2]/2 >= 1)
{
splitAxis = 2;
}
else if (size[1] >= size[0] && size[1]/2 >= 1)
{
splitAxis = 1;
}
else if (size[0]/2 >= 1)
{
splitAxis = 0;
}
else
{
// signal no more splits possible
splitAxis = -1;
}
}
if (splitAxis == -1)
{
// can not split any more.
if (piece == 0)
{
// just return the remaining piece
numPieces = 1;
}
else
{
// the rest must be empty
return 0;
}
}
else
{
// split the chosen axis into two pieces.
numPiecesInFirstHalf = (numPieces / 2);
mid = size[splitAxis];
mid = (mid * numPiecesInFirstHalf) / numPieces + ext[splitAxis*2];
if (piece < numPiecesInFirstHalf)
{
// piece is in the first half
// set extent to the first half of the previous value.
ext[splitAxis*2+1] = mid.CastToInt() - 1;
// piece must adjust.
numPieces = numPiecesInFirstHalf;
}
else
{
// piece is in the second half.
// set the extent to be the second half.
ext[splitAxis*2] = mid.CastToInt();
// piece must adjust
numPieces = numPieces - numPiecesInFirstHalf;
piece -= numPiecesInFirstHalf;
}
}
} // end of while
return 1;
}
//----------------------------------------------------------------------------
void vtkExtentTranslator::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Piece: " << this->Piece << endl;
os << indent << "NumberOfPieces: " << this->NumberOfPieces << endl;
os << indent << "GhostLevel: " << this->GhostLevel << endl;
os << indent << "Extent: " << this->Extent[0] << ", "
<< this->Extent[1] << ", " << this->Extent[2] << ", "
<< this->Extent[3] << ", " << this->Extent[4] << ", "
<< this->Extent[5] << endl;
os << indent << "WholeExtent: " << this->WholeExtent[0] << ", "
<< this->WholeExtent[1] << ", " << this->WholeExtent[2] << ", "
<< this->WholeExtent[3] << ", " << this->WholeExtent[4] << ", "
<< this->WholeExtent[5] << endl;
os << indent << "SplitMode: ";
if (this->SplitMode == vtkExtentTranslator::BLOCK_MODE)
{
os << "Block\n";
}
else if (this->SplitMode == vtkExtentTranslator::X_SLAB_MODE)
{
os << "X Slab\n";
}
else if (this->SplitMode == vtkExtentTranslator::Y_SLAB_MODE)
{
os << "Y Slab\n";
}
else if (this->SplitMode == vtkExtentTranslator::Z_SLAB_MODE)
{
os << "Z Slab\n";
}
else
{
os << "Unknown\n";
}
}