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