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 161 162
|
/*=========================================================================
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 "vtkImageProperty.h"
#include "vtkImageSlice.h"
#include "vtkObjectFactory.h"
VTK_ABI_NAMESPACE_BEGIN
vtkStandardNewMacro(vtkImageSliceCollection);
//------------------------------------------------------------------------------
void vtkImageSliceCollection::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
//------------------------------------------------------------------------------
// protected function to delete an element. Internal use only.
void vtkImageSliceCollection::DeleteElement(vtkCollectionElement* e)
{
vtkCollection::DeleteElement(e);
}
//------------------------------------------------------------------------------
// Destructor 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;
elem->Item = a;
// Find insertion location according to the layer number
vtkCollectionElement* prevElem = nullptr;
int layerNumber = a->GetProperty()->GetLayerNumber();
for (vtkCollectionElement* indexElem = this->Top; indexElem != nullptr;
indexElem = indexElem->Next)
{
vtkImageSlice* tempImage = static_cast<vtkImageSlice*>(indexElem->Item);
if (layerNumber < tempImage->GetProperty()->GetLayerNumber())
{
break;
}
prevElem = indexElem;
}
// Insert the new element into the linked list
if (prevElem == nullptr)
{
elem->Next = this->Top;
this->Top = elem;
}
else
{
elem->Next = prevElem->Next;
prevElem->Next = elem;
}
// Check if this is the new bottom
if (elem->Next == nullptr)
{
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;
}
}
VTK_ABI_NAMESPACE_END
|