vtkStrahlerMetric.cxx 4.6 KB
Newer Older
1
/*=========================================================================
2

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Program:   Visualization Toolkit
Module:    vtkStrahlerMetric.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.

=========================================================================*/

/*-------------------------------------------------------------------------
Copyright 2008 Sandia Corporation.
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/

#include "vtkStrahlerMetric.h"
Jason Shepherd's avatar
Jason Shepherd committed
23 24

#include "vtkFloatArray.h"
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#include "vtkObjectFactory.h"
#include "vtkOutEdgeIterator.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkDataSetAttributes.h"
#include "vtkSmartPointer.h"

//--------------------------------------------------------------------------

vtkStandardNewMacro(vtkStrahlerMetric);

vtkStrahlerMetric::vtkStrahlerMetric()
{
  this->MaxStrahler = 0;
  this->Normalize = 0;
Jason Shepherd's avatar
Jason Shepherd committed
40 41
  this->MetricArrayName = 0;
  this->SetMetricArrayName( "Strahler" );
42 43
}

44 45 46 47 48
vtkStrahlerMetric::~vtkStrahlerMetric()
{
  this->SetMetricArrayName(0);
}

49 50 51
//----------------------------------------------------------------------------

float vtkStrahlerMetric::CalculateStrahler(
52
  vtkIdType root,
53 54 55 56 57 58 59
  vtkFloatArray *metric,
  vtkTree *tree)
{
  float strahler, maxStrahler, *childStrahler;
  bool same;
  vtkSmartPointer<vtkOutEdgeIterator> children
    = vtkSmartPointer<vtkOutEdgeIterator>::New();
60

61
  vtkIdType nrChildren = tree->GetNumberOfChildren(root);
62

63 64 65 66 67 68 69 70 71 72 73 74 75
  // A leaf node has a Strahler value of 1.
  if (nrChildren == 0)
    {
    strahler = 1.0;
    }
  else
    {
    // Non-leaf node: find the Strahler values of the children.
    childStrahler = new float[nrChildren];
    tree->GetOutEdges(root, children);
    for (vtkIdType i = 0; i < nrChildren; i++)
      {
      childStrahler[i] = this->CalculateStrahler(
76
        children->Next().Target,
77 78 79 80 81 82
        metric,
        tree);
      }
    // Determine if the children have the same strahler values
    same = true;
    maxStrahler = childStrahler[0];
83
    for (vtkIdType j = 1; j < nrChildren; j++)
84 85
      {
      same = same && (maxStrahler == childStrahler[j]);
86
      if (maxStrahler <  childStrahler[j])
87 88 89 90 91 92 93
        {
        maxStrahler = childStrahler[j];
        }
      }
    // Calculate the strahler value for this node
    strahler = (same) ? maxStrahler + nrChildren - 1
      : maxStrahler + nrChildren - 2;
94

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    delete [] childStrahler;
    }
  // Record the strahler value within the array.
  metric->InsertValue(root, strahler);
  if (strahler > this->MaxStrahler)
    {
    this->MaxStrahler = strahler;
    }
  return strahler;
}


int vtkStrahlerMetric::RequestData(vtkInformation *vtkNotUsed(request),
                                   vtkInformationVector **inputVector,
                                   vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
114

115
  vtkDebugMacro(<<"StrahlerMetric executing." );
116

117 118 119 120 121
  // get the input and output
  vtkTree *input = vtkTree::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkTree *output = vtkTree::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));
122

123 124
  // The output model should share the data of the input.
  output->ShallowCopy(input);
125

126
  // Create a new array to hold the metric.
127
  vtkFloatArray *metric = vtkFloatArray::New();
128 129
  metric->SetName(this->MetricArrayName);
  metric->SetNumberOfValues(input->GetNumberOfVertices());
130

131
  this->MaxStrahler = 1.0;
132

133 134 135 136
  this->CalculateStrahler(
    input->GetRoot(),
    metric,
    input);
137

138 139 140 141 142 143 144
  if (this->Normalize)
    {
    for (vtkIdType i = 0; i < input->GetNumberOfVertices(); i++)
      {
      metric->SetValue(i, metric->GetValue(i)/this->MaxStrahler);
      }
    }
145

146 147
  output->GetVertexData()->AddArray(metric);
  metric->Delete();
148

149 150 151 152 153 154 155 156 157 158 159
  vtkDebugMacro(<<"StrahlerMetric done.");
  return 1;
}

void vtkStrahlerMetric::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "Normalize: " << this->Normalize << endl;
  os << indent << "MaxStrahler: " << this->MaxStrahler << endl;
  os << indent << "MetricArrayName: " << (this->MetricArrayName ? this->MetricArrayName : "(none)") << endl;
}