vtkImageConnector.cxx 4.94 KB
Newer Older
Charles Law's avatar
Charles Law committed
1 2 3 4 5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkImageConnector.cxx

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 8
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
Will Schroeder's avatar
Will Schroeder committed
9

10 11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
     PURPOSE.  See the above copyright notice for more information.
Charles Law's avatar
Charles Law committed
13 14 15

=========================================================================*/
#include "vtkImageConnector.h"
16 17

#include "vtkImageData.h"
18 19
#include "vtkObjectFactory.h"

Brad King's avatar
Brad King committed
20
vtkStandardNewMacro(vtkImageConnector);
Charles Law's avatar
Charles Law committed
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

//----------------------------------------------------------------------------
vtkImageConnector::vtkImageConnector()
{
  this->Seeds = NULL;
  this->LastSeed = NULL;
  this->ConnectedValue = 255;
  this->UnconnectedValue = 128;
}

//----------------------------------------------------------------------------
vtkImageConnector::~vtkImageConnector()
{
  this->RemoveAllSeeds();
}

//----------------------------------------------------------------------------
void vtkImageConnector::RemoveAllSeeds()
{
  vtkImageConnectorSeed *temp;

  while (this->Seeds)
    {
    temp = this->Seeds;
    this->Seeds = temp->Next;
    delete temp;
    }
  this->LastSeed = NULL;
}


//----------------------------------------------------------------------------
vtkImageConnectorSeed *vtkImageConnector::NewSeed(int index[3], void *ptr)
{
55
  vtkImageConnectorSeed *seed = vtkImageConnectorSeed::New();
Charles Law's avatar
Charles Law committed
56 57 58 59 60 61 62
  int idx;

  for (idx = 0; idx < 3; ++idx)
    {
    seed->Index[idx] = index[idx];
    }
  seed->Pointer = ptr;
Charles Law's avatar
Charles Law committed
63
  seed->Next = NULL;
Charles Law's avatar
Charles Law committed
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

  return seed;
}

//----------------------------------------------------------------------------
// Add a new seed to the end of the seed list.
void vtkImageConnector::AddSeedToEnd(vtkImageConnectorSeed *seed)
{
  // Add the seed to the end of the list
  if (this->LastSeed == NULL)
    { // no seeds yet
    this->LastSeed = this->Seeds = seed;
    }
  else
    {
    this->LastSeed->Next = seed;
    this->LastSeed = seed;
    }
}

//----------------------------------------------------------------------------
// Add a new seed to the start of the seed list.
void vtkImageConnector::AddSeed(vtkImageConnectorSeed *seed)
{
  seed->Next = this->Seeds;
  this->Seeds = seed;
  if ( ! this->LastSeed)
    {
    this->LastSeed = seed;
    }
}

//----------------------------------------------------------------------------
// Removes a seed from the start of the seed list, and returns the seed.
vtkImageConnectorSeed *vtkImageConnector::PopSeed()
{
  vtkImageConnectorSeed *seed;

  seed = this->Seeds;
  this->Seeds = seed->Next;
  if (this->Seeds == NULL)
    {
    this->LastSeed = NULL;
    }
  return seed;
}

//----------------------------------------------------------------------------
112
// Input a data of 0's and "UnconnectedValue"s. Seeds of this object are
Charles Law's avatar
Charles Law committed
113
// used to find connected pixels.
114
// All pixels connected to seeds are set to ConnectedValue.
Ken Martin's avatar
Ken Martin committed
115 116
// The data has to be unsigned char.
void vtkImageConnector::MarkData(vtkImageData *data, int numberOfAxes, int extent[6])
Charles Law's avatar
Charles Law committed
117
{
118 119
  vtkIdType *incs, *pIncs;
  int *pExtent;
Charles Law's avatar
Charles Law committed
120 121 122
  vtkImageConnectorSeed *seed;
  unsigned char *ptr;
  int newIndex[3], *pIndex, idx;
Charles Law's avatar
Charles Law committed
123
  long count = 0;
Charles Law's avatar
Charles Law committed
124

Ken Martin's avatar
Ken Martin committed
125
  incs = data->GetIncrements();
Charles Law's avatar
Charles Law committed
126 127
  while (this->Seeds)
    {
Charles Law's avatar
Charles Law committed
128
    ++count;
Charles Law's avatar
Charles Law committed
129
    seed = this->PopSeed();
Charles Law's avatar
Charles Law committed
130
    // just in case the seed has not been marked visited.
131
    *(static_cast<unsigned char *>(seed->Pointer)) = this->ConnectedValue;
132
    // Add neighbors
Charles Law's avatar
Charles Law committed
133 134 135 136 137 138 139 140 141 142 143
    newIndex[0] = seed->Index[0];
    newIndex[1] = seed->Index[1];
    newIndex[2] = seed->Index[2];
    pExtent = extent;
    pIncs = incs;
    pIndex = newIndex;
    for (idx = 0; idx < numberOfAxes; ++idx)
      {
      // check pixel below
      if (*pExtent < *pIndex)
        {
144
        ptr = static_cast<unsigned char *>(seed->Pointer) - *pIncs;
Charles Law's avatar
Charles Law committed
145 146
        if (*ptr == this->UnconnectedValue)
          { // add a new seed
Charles Law's avatar
Charles Law committed
147
          --(*pIndex);
148
          *ptr = this->ConnectedValue;
Charles Law's avatar
Charles Law committed
149
          this->AddSeedToEnd(this->NewSeed(newIndex, ptr));
Charles Law's avatar
Charles Law committed
150
          ++(*pIndex);
Charles Law's avatar
Charles Law committed
151 152 153 154 155 156
          }
        }
      ++pExtent;
      // check above pixel
      if (*pExtent > *pIndex)
        {
157
        ptr = static_cast<unsigned char *>(seed->Pointer) + *pIncs;
Charles Law's avatar
Charles Law committed
158 159
        if (*ptr == this->UnconnectedValue)
          { // add a new seed
Charles Law's avatar
Charles Law committed
160
          ++(*pIndex);
161
          *ptr = this->ConnectedValue;
Charles Law's avatar
Charles Law committed
162
          this->AddSeedToEnd(this->NewSeed(newIndex, ptr));
Charles Law's avatar
Charles Law committed
163
          --(*pIndex);
Charles Law's avatar
Charles Law committed
164 165
          }
        }
Charles Law's avatar
Charles Law committed
166 167 168 169
      ++pExtent;
      // move to next axis
      ++pIncs;
      ++pIndex;
Charles Law's avatar
Charles Law committed
170
      }
171

Charles Law's avatar
Charles Law committed
172 173
    // Delete seed
    delete seed;
Charles Law's avatar
Charles Law committed
174
    }
Charles Law's avatar
Charles Law committed
175
  vtkDebugMacro("Marked " << count << " pixels");
Charles Law's avatar
Charles Law committed
176 177
}

178
void vtkImageConnector::PrintSelf(ostream& os, vtkIndent indent)
179
{
Brad King's avatar
Brad King committed
180
  this->Superclass::PrintSelf(os,indent);
181

182 183 184
  os << indent << "ConnectedValue: " << this->ConnectedValue << "\n";
  os << indent << "UnconnectedValue: " << this->UnconnectedValue << "\n";

185
}
186