vtkCompositeTransferFunctionItem.cxx 4.57 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCompositeTransferFunctionItem.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.

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

16 17
#include "vtkCallbackCommand.h"
#include "vtkCommand.h"
18 19
#include "vtkImageData.h"
#include "vtkPiecewiseFunction.h"
20
#include "vtkColorTransferFunction.h"
21 22
#include "vtkCompositeTransferFunctionItem.h"
#include "vtkObjectFactory.h"
23
#include "vtkPen.h"
24
#include "vtkPointData.h"
25
#include "vtkPoints2D.h"
26

27 28
// STD includes
#include <algorithm>
29 30 31 32 33 34 35 36
#include <cassert>

//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkCompositeTransferFunctionItem);

//-----------------------------------------------------------------------------
vtkCompositeTransferFunctionItem::vtkCompositeTransferFunctionItem()
{
37
  this->PolyLinePen->SetLineType(vtkPen::SOLID_LINE);
38 39 40 41 42 43 44 45
  this->OpacityFunction = 0;
}

//-----------------------------------------------------------------------------
vtkCompositeTransferFunctionItem::~vtkCompositeTransferFunctionItem()
{
  if (this->OpacityFunction)
    {
46
    this->OpacityFunction->RemoveObserver(this->Callback);
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
    this->OpacityFunction->Delete();
    this->OpacityFunction = 0;
    }
}

//-----------------------------------------------------------------------------
void vtkCompositeTransferFunctionItem::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "CompositeTransferFunction: ";
  if (this->OpacityFunction)
    {
    os << endl;
    this->OpacityFunction->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)" << endl;
    }
}

//-----------------------------------------------------------------------------
69
void vtkCompositeTransferFunctionItem::ComputeBounds(double* bounds)
70
{
71
  this->Superclass::ComputeBounds(bounds);
72
  if (this->OpacityFunction)
73
    {
74 75 76
    double* opacityRange = this->OpacityFunction->GetRange();
    bounds[0] = std::min(bounds[0], opacityRange[0]);
    bounds[1] = std::max(bounds[1], opacityRange[1]);
77
    }
78 79
}

80
//-----------------------------------------------------------------------------
81
void vtkCompositeTransferFunctionItem::SetOpacityFunction(vtkPiecewiseFunction* opacity)
82
{
83 84 85 86 87 88 89 90
  if (opacity == this->OpacityFunction)
    {
    return;
    }
  if (this->OpacityFunction)
    {
    this->OpacityFunction->RemoveObserver(this->Callback);
    }
91 92
  vtkSetObjectBodyMacro(OpacityFunction, vtkPiecewiseFunction, opacity);
  if (opacity)
93
    {
94
    opacity->AddObserver(vtkCommand::ModifiedEvent, this->Callback);
95
    }
96
  this->ScalarsToColorsModified(this->OpacityFunction, vtkCommand::ModifiedEvent, 0);
97 98
}

99 100 101 102
//-----------------------------------------------------------------------------
void vtkCompositeTransferFunctionItem::ComputeTexture()
{
  this->Superclass::ComputeTexture();
103 104
  double bounds[4];
  this->GetBounds(bounds);
105 106
  if (bounds[0] == bounds[1]
      || !this->OpacityFunction)
107 108 109
    {
    return;
    }
110 111 112 113 114
  if (this->Texture == 0)
    {
    this->Texture = vtkImageData::New();
    }

115
  const int dimension = this->GetTextureWidth();
116 117
  double* values = new double[dimension];
  this->OpacityFunction->GetTable(bounds[0], bounds[1], dimension, values);
118 119
  unsigned char* ptr =
    reinterpret_cast<unsigned char*>(this->Texture->GetScalarPointer(0,0,0));
120
  // TBD: maybe the shape should be defined somewhere else...
121
  if (this->MaskAboveCurve || this->PolyLinePen->GetLineType() != vtkPen::SOLID_LINE)
122
    {
123
    this->Shape->SetNumberOfPoints(dimension);
124
    double step = (bounds[1] - bounds[0]) / dimension;
125 126 127
    for (int i = 0; i < dimension; ++i)
      {
      ptr[3] = static_cast<unsigned char>(values[i] * this->Opacity * 255);
128 129 130
      if (values[i] < 0. || values[i] > 1.)
        {
        vtkWarningMacro( << "Opacity at point " << i << " is " << values[i]
131
                         << " which is outside the valid range of [0,1]");
132
        }
133
      this->Shape->SetPoint(i, bounds[0] + step * i, values[i]);
134 135 136 137
      ptr+=4;
      }
    }
  else
138
    {
139 140 141 142 143 144
    for (int i = 0; i < dimension; ++i)
      {
      ptr[3] = static_cast<unsigned char>(values[i] * this->Opacity * 255);
      assert(values[i] <= 1. && values[i] >= 0.);
      ptr+=4;
      }
145
    }
146
  delete [] values;
147
  return;
148
}