1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageSliceCollection.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 "vtkImageSliceCollection.h"
#include "vtkObjectFactory.h"
#include "vtkImageSlice.h"
#include "vtkImageProperty.h"
vtkStandardNewMacro(vtkImageSliceCollection);
//----------------------------------------------------------------------------
// protected function to delete an element. Internal use only.
void vtkImageSliceCollection::DeleteElement(vtkCollectionElement *e)
{
vtkCollection::DeleteElement(e);
}
//----------------------------------------------------------------------------
// Desctructor for the vtkImageSliceCollection class. This removes all
// objects from the collection.
vtkImageSliceCollection::~vtkImageSliceCollection()
{
this->RemoveAllItems();
}
//----------------------------------------------------------------------------
// Add an image to the list. The new image is inserted in the
// list according to it's layer number.
void vtkImageSliceCollection::AddItem(vtkImageSlice *a)
{
vtkCollectionElement* elem = new vtkCollectionElement;
// Check if the top item is NULL
if (this->Top == NULL)
{
this->Top = elem;
elem->Item = a;
elem->Next = NULL;
this->Bottom = elem;
this->NumberOfItems++;
a->Register(this);
return;
}
// Insert according to the layer number
int layerNumber = a->GetProperty()->GetLayerNumber();
for (vtkCollectionElement *indexElem = this->Top;
indexElem != 0;
indexElem = indexElem->Next)
{
vtkImageSlice* tempImage = static_cast<vtkImageSlice*>(indexElem->Item);
if (layerNumber < tempImage->GetProperty()->GetLayerNumber())
{
// The indexElem item's layer number is larger, so swap
// the new item and the indexElem item.
elem->Item = indexElem->Item;
elem->Next = indexElem->Next;
indexElem->Item = a;
indexElem->Next = elem;
this->NumberOfItems++;
a->Register(this);
return;
}
}
//End of list found before a larger layer number
elem->Item = a;
elem->Next = NULL;
this->Bottom->Next = elem;
this->Bottom = elem;
this->NumberOfItems++;
a->Register(this);
}
//----------------------------------------------------------------------------
// small helper struct
class vtkImageSliceLayerPair
{
public:
vtkImageSlice *image;
int layer;
};
//----------------------------------------------------------------------------
// Sorts the vtkImageSliceCollection by layer number. Smaller layer
// numbers are first. Layer numbers can be any integer value.
void vtkImageSliceCollection::Sort()
{
// Create a temporary array of pointers to images
int numElems = this->GetNumberOfItems();
vtkImageSliceLayerPair defaultLayerArray[8];
vtkImageSliceLayerPair *layerArray = defaultLayerArray;
if (numElems > 8)
{
layerArray = new vtkImageSliceLayerPair [numElems];
}
// Start at the beginning of the collection
vtkCollectionSimpleIterator ait;
this->InitTraversal(ait);
// Fill the image array with the items in the collection
for (int ii = 0; ii < numElems; ii++)
{
vtkImageSlice *image = this->GetNextImage(ait);
layerArray[ii].image = image;
layerArray[ii].layer = image->GetProperty()->GetLayerNumber();
}
// The collection will be small (often with n=2) so do a brute-force
// selection sort, which also keeps items with the same layer number
// in the same order as before the sort.
for (int i = 0; i < numElems - 1; i++)
{
int imin = i;
int lmin = layerArray[imin].layer;
int j = i + 1;
do
{
int l = layerArray[j].layer;
if (l < lmin)
{
imin = j;
lmin = l;
}
}
while (++j < numElems);
vtkImageSliceLayerPair t = layerArray[imin];
layerArray[imin] = layerArray[i];
layerArray[i] = t;
}
// Now move the items around in the linked list -
// keep the links the same, but swap around the items
vtkCollectionElement* elem = this->Top;
for (int jj = 0; jj < numElems; jj++)
{
elem->Item = layerArray[jj].image;
elem = elem->Next;
}
if (layerArray != defaultLayerArray)
{
delete [] layerArray;
}
}
|