1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkProjectedTerrainPath.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 // .NAME vtkProjectedTerrainPath - project a polyline onto a terrain
16 // .SECTION Description
17 // vtkProjectedTerrainPath projects an input polyline onto a terrain. (The
18 // terrain is defined by a 2D height image and is the second input to the
19 // filter.) The polyline projection is controlled via several modes as
20 // follows. 1) Simple mode projects the polyline points onto the terrain,
21 // taking into account the height offset instance variable. 2) Non-occluded
22 // mode insures that no parts of the polyline are occluded by the terrain
23 // (e.g. a line passes through a mountain). This may require recursive
24 // subdivision of the polyline. 3) Hug mode insures that the polyine points
25 // remain within a constant distance from the surface. This may also require
26 // recursive subdivision of the polyline. Note that both non-occluded mode
27 // and hug mode also take into account the height offset, so it is possible
28 // to create paths that hug terrain a certain distance above it. To use this
29 // filter, define two inputs: 1) a polyline, and 2) an image whose scalar
30 // values represent a height field. Then specify the mode, and the height
31 // offset to use.
32 //
33 // An description of the algorithm is as follows. The filter begins by
34 // projecting the polyline points to the image (offset by the specified
35 // height offset).  If the mode is non-occluded or hug, then the maximum
36 // error along each line segment is computed and placed into a priority
37 // queue. Each line segment is then split at the point of maximum error, and
38 // the two new line segments are evaluated for maximum error. This process
39 // continues until the line is not occluded by the terrain (non-occluded
40 // mode) or satisfies the error on variation from the surface (hug
41 // mode). (Note this process is repeated for each polyline in the
42 // input. Also, the maximum error is computed in two parts: a maximum
43 // positive error and maximum negative error. If the polyline is above the
44 // terrain--i.e., the height offset is positive--in non-occluded or hug mode
45 // all negative errors are eliminated. If the polyline is below the
46 // terrain--i.e., the height offset is negative--in non-occluded or hug mode
47 // all positive errors are eliminated.)
48 //
49 // .SECTION Caveats
50 // This algorithm requires the entire input image to be in memory, hence it
51 // may not work for extremely large images.
52 //
53 // The input height image is assumed to be positioned in the x-y plane so the
54 // scalar value is the z-coordinate, height value.
55 //
56 // A priority queue is used so that the 1) the total number of line segments
57 // can be controlled, and 2) the algorithm can terminate when the errors in
58 // the queue are less than the specified error tolerance.
59 //
60 // .SECTION See Also
61 // vtkGreedyTerrainDecimation
62 
63 #ifndef vtkProjectedTerrainPath_h
64 #define vtkProjectedTerrainPath_h
65 
66 #include "vtkFiltersHybridModule.h" // For export macro
67 #include "vtkPolyDataAlgorithm.h"
68 
69 class vtkPriorityQueue;
70 class vtkImageData;
71 class vtkEdgeList;
72 class vtkPoints;
73 
74 class VTKFILTERSHYBRID_EXPORT vtkProjectedTerrainPath : public vtkPolyDataAlgorithm
75 {
76 public:
77   // Description:
78   // Standard methids for printing and determining type information.
79   vtkTypeMacro(vtkProjectedTerrainPath,vtkPolyDataAlgorithm);
80   void PrintSelf(ostream& os, vtkIndent indent);
81 
82   // Description:
83   // Instantiate the class.
84   static vtkProjectedTerrainPath* New();
85 
86   // Description:
87   // Specify the second input (the terrain) onto which the polyline(s) should be projected.
88   // Note: This assigns a data object as the input terrain.
89   // To establish a pipeline connection, use
90   // SetSourceConnection() method.
91   void SetSourceData(vtkImageData *source);
92   vtkImageData *GetSource();
93 
94   // Description:
95   // Specify the second input (the terrain) onto which the polyline(s) should be projected.
96   // Note: vtkImageData* is required
97   void SetSourceConnection(vtkAlgorithmOutput* algOutput);
98 
99 //BTX
100   enum {SIMPLE_PROJECTION=0,NONOCCLUDED_PROJECTION,HUG_PROJECTION};
101 //ETX
102 
103   // Description:
104   // Determine how to control the projection process. Simple projection
105   // just projects the original polyline points. Non-occluded projection
106   // insures that the polyline does not intersect the terrain surface.
107   // Hug projection is similar to non-occulded projection except that
108   // produces a path that is nearly parallel to the terrain (within the
109   // user specified height tolerance).
110   vtkSetClampMacro(ProjectionMode,int,SIMPLE_PROJECTION,HUG_PROJECTION);
111   vtkGetMacro(ProjectionMode,int);
SetProjectionModeToSimple()112   void SetProjectionModeToSimple()
113     {this->SetProjectionMode(SIMPLE_PROJECTION);}
SetProjectionModeToNonOccluded()114   void SetProjectionModeToNonOccluded()
115     {this->SetProjectionMode(NONOCCLUDED_PROJECTION);}
SetProjectionModeToHug()116   void SetProjectionModeToHug()
117     {this->SetProjectionMode(HUG_PROJECTION);}
118 
119   // Description:
120   // This is the height above (or below) the terrain that the projected
121   // path should be. Positive values indicate distances above the terrain;
122   // negative values indicate distances below the terrain.
123   vtkSetMacro(HeightOffset,double);
124   vtkGetMacro(HeightOffset,double);
125 
126   // Description:
127   // This is the allowable variation in the altitude of the path
128   // with respect to the variation in the terrain. It only comes
129   // into play if the hug projection mode is enabled.
130   vtkSetClampMacro(HeightTolerance,double,0.0,VTK_FLOAT_MAX);
131   vtkGetMacro(HeightTolerance,double);
132 
133   // Description:
134   // This instance variable can be used to limit the total number of line
135   // segments created during subdivision. Note that the number of input line
136   // segments will be the minimum number that cab be output.
137   vtkSetClampMacro(MaximumNumberOfLines,vtkIdType,1,VTK_ID_MAX);
138   vtkGetMacro(MaximumNumberOfLines,vtkIdType);
139 
140 protected:
141   vtkProjectedTerrainPath();
142   ~vtkProjectedTerrainPath();
143 
144   virtual int RequestData(vtkInformation *, vtkInformationVector **,
145                           vtkInformationVector *);
146   virtual int FillInputPortInformation(int port, vtkInformation *info);
147 
148   // Supporting methods
149   void GetImageIndex(double x[3], double loc[2], int ij[2]);
150   double GetHeight(double loc[2], int ij[2]);
151   void ComputeError(vtkIdType edgeId);
152   void RemoveOcclusions();
153   void HugTerrain();
154   void SplitEdge(vtkIdType eId, double t);
155 
156   //ivars that the API addresses
157   int       ProjectionMode;
158   double    HeightOffset;
159   double    HeightTolerance;
160   vtkIdType MaximumNumberOfLines;
161 
162   //Bookeeping arrays
163   int          Dimensions[3];
164   int          Extent[6];
165   double       Origin[3];
166   double       Spacing[3];
167   vtkDataArray *Heights;
168   vtkPoints    *Points;
169   vtkIdType    NumLines;
170 
171   //Errors above/below terrain. In both instances, negative values are
172   //inserted because the priority queue puts smallest values on top.
173   vtkPriorityQueue *PositiveLineError; //errors above terrain
174   vtkPriorityQueue *NegativeLineError; //errors below terrain
175 
176   //This is a PIMPL'd vector representing edges
177   vtkEdgeList *EdgeList;
178 
179 private:
180   vtkProjectedTerrainPath(const vtkProjectedTerrainPath&);  // Not implemented.
181   void operator=(const vtkProjectedTerrainPath&);  // Not implemented.
182 
183 };
184 
185 #endif
186