/*=auto=========================================================================

  Portions (c) Copyright 2005 Brigham and Women's Hospital (BWH) All Rights Reserved.

  See Doc/copyright/copyright.txt
  or http://www.slicer.org/copyright/copyright.txt for details.

  Program:   3D Slicer
  Module:    $RCSfile: vtkHyperStreamlineDTMRI.h,v $
  Date:      $Date: 2007/02/23 19:06:47 $
  Version:   $Revision: 1.13 $

=========================================================================auto=*/
///  vtkHyperStreamlineDTMRI - generate hyperstreamline in arbitrary dataset
/// 
/// vtkHyperStreamlineDTMRI is a filter that integrates through a tensor field to 
/// generate a hyperstreamline. The integration is along the maximum eigenvector
/// and the cross section of the hyperstreamline is defined by the two other
/// eigenvectors. Thus the shape of the hyperstreamline is "tube-like", with 
/// the cross section being elliptical. Hyperstreamlines are used to visualize
/// tensor fields.
//
/// The starting point of a hyperstreamline can be defined in one of two ways. 
/// First, you may specify an initial position. This is a x-y-z global 
/// coordinate. The second option is to specify a starting location. This is 
/// cellId, subId, and  cell parametric coordinates.
//
/// The integration of the hyperstreamline occurs through the major eigenvector 
/// field. IntegrationStepLength controls the step length within each cell 
/// (this is in mm). The length of the 
/// hyperstreamline is controlled by MaximumPropagationDistance. This parameter
/// is the length of the hyperstreamline in units of distance. 
/// .SECTION See Also
/// vtkTensorGlyph vtkStreamer

#ifndef __vtkHyperStreamlineDTMRI_h
#define __vtkHyperStreamlineDTMRI_h

#include "vtkTeemConfigure.h"
#include "vtkHyperStreamline.h"
#include "vtkDiffusionTensorMathematics.h" /// for VTK_TENS_FRACTIONAL_ANISOTROPY
#include "vtkTractographyPointAndArray.h"

class VTK_Teem_EXPORT vtkHyperStreamlineDTMRI : public vtkHyperStreamline
{
public:
  vtkTypeRevisionMacro(vtkHyperStreamlineDTMRI,vtkHyperStreamline);
  void PrintSelf(ostream& os, vtkIndent indent);

  /// 
  /// Construct object with initial starting position (0,0,0); integration
  /// step length 0.5; both directions of integration; terminal
  /// eigenvalue 0.0
  static vtkHyperStreamlineDTMRI *New();

  /// 
  /// If radius of curvature becomes smaller than this number, tracking stops.
  /// This is how tight of a turn is allowed.
  /// The units are degrees per mm. (Actually per units of measurement
  /// in your data).
  vtkGetMacro(RadiusOfCurvature,vtkFloatingPointType);
  vtkSetMacro(RadiusOfCurvature,vtkFloatingPointType);

  /// 
  /// This is in mm, unlike superclass value which is a fraction of a cell.
  vtkSetMacro(IntegrationStepLength,double);

  /// 
  /// Type of anisotropy used to stop tractography.
  vtkGetMacro(StoppingMode,int);
  vtkSetMacro(StoppingMode,int);
  void SetStoppingModeToFractionalAnisotropy()
    {this->SetStoppingMode(vtkDiffusionTensorMathematics::VTK_TENS_FRACTIONAL_ANISOTROPY);};
  void SetStoppingModeToLinearMeasure()
    {this->SetStoppingMode(vtkDiffusionTensorMathematics::VTK_TENS_LINEAR_MEASURE);};
  void SetStoppingModeToPlanarMeasure()
    {this->SetStoppingMode(vtkDiffusionTensorMathematics::VTK_TENS_PLANAR_MEASURE);};
  void SetStoppingModeToSphericalMeasure()
    {this->SetStoppingMode(vtkDiffusionTensorMathematics::VTK_TENS_SPHERICAL_MEASURE);};


  /// If StoppingMode criterion becomes smaller than this number,
  /// tracking stops.
  vtkGetMacro(StoppingThreshold,vtkFloatingPointType);
  vtkSetMacro(StoppingThreshold,vtkFloatingPointType);

  /// 
  /// Whether to output the interpolated tensor at each point
  /// of the output streamline
  vtkGetMacro(OutputTensors, int);
  vtkSetMacro(OutputTensors, int);
  vtkBooleanMacro(OutputTensors, int);

  /// 
  /// Whether to produce one polyline per integration direction
  /// (so two per seed point), or one polyline per seed point.
  /// Superclass behavior would be two per seed point.
  vtkGetMacro(OneTrajectoryPerSeedPoint, int);
  vtkSetMacro(OneTrajectoryPerSeedPoint, int);
  vtkBooleanMacro(OneTrajectoryPerSeedPoint, int);

protected:
  vtkHyperStreamlineDTMRI();
  ~vtkHyperStreamlineDTMRI();

  /// Integrate data
  virtual int RequestData(vtkInformation *,vtkInformationVector**, vtkInformationVector *);
  void BuildLines(vtkDataSet *input, vtkPolyData *output);
  void BuildLinesForSingleTrajectory(vtkDataSet *input, vtkPolyData *output);
  void BuildLinesForTwoTrajectories(vtkDataSet *input, vtkPolyData *output);

  vtkFloatingPointType RadiusOfCurvature;
  int StoppingMode;
  vtkFloatingPointType StoppingThreshold;

  int OutputTensors;

  int OneTrajectoryPerSeedPoint;

  vtkTractographyArray *Streamers;

private:
  vtkHyperStreamlineDTMRI(const vtkHyperStreamlineDTMRI&);  /// Not implemented.
  void operator=(const vtkHyperStreamlineDTMRI&);  /// Not implemented.
};

#endif


