1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkImageToPolyDataFilter.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 /** 16 * @class vtkImageToPolyDataFilter 17 * @brief generate linear primitives (vtkPolyData) from an image 18 * 19 * vtkImageToPolyDataFilter converts raster data (i.e., an image) into 20 * polygonal data (i.e., quads or n-sided polygons), with each polygon 21 * assigned a constant color. This is useful for writers that generate vector 22 * formats (i.e., CGM or PostScript). To use this filter, you specify how to 23 * quantize the color (or whether to use an image with a lookup table), and 24 * what style the output should be. The output is always polygons, but the 25 * choice is n x m quads (where n and m define the input image dimensions) 26 * "Pixelize" option; arbitrary polygons "Polygonalize" option; or variable 27 * number of quads of constant color generated along scan lines "RunLength" 28 * option. 29 * 30 * The algorithm quantizes color in order to create coherent regions that the 31 * polygons can represent with good compression. By default, the input image 32 * is quantized to 256 colors using a 3-3-2 bits for red-green-blue. However, 33 * you can also supply a single component image and a lookup table, with the 34 * single component assumed to be an index into the table. (Note: a quantized 35 * image can be generated with the filter vtkImageQuantizeRGBToIndex.) The 36 * number of colors on output is equal to the number of colors in the input 37 * lookup table (or 256 if the built in linear ramp is used). 38 * 39 * The output of the filter is polygons with a single color per polygon cell. 40 * If the output style is set to "Polygonalize", the polygons may have an 41 * large number of points (bounded by something like 2*(n+m)); and the 42 * polygon may not be convex which may cause rendering problems on some 43 * systems (use vtkTriangleFilter). Otherwise, each polygon will have four 44 * vertices. The output also contains scalar data defining RGB color in 45 * unsigned char form. 46 * 47 * @warning 48 * The input linear lookup table must 49 * be of the form of 3-component unsigned char. 50 * 51 * @warning 52 * This filter defines constant cell colors. If you have a plotting 53 * device that supports Gouraud shading (linear interpolation of color), then 54 * superior algorithms are available for generating polygons from images. 55 * 56 * @warning 57 * Note that many plotting devices/formats support only a limited number of 58 * colors. 59 * 60 * @sa 61 * vtkCGMWriter vtkImageQuantizeRGBToIndex vtkTriangleFilter 62 */ 63 64 #ifndef vtkImageToPolyDataFilter_h 65 #define vtkImageToPolyDataFilter_h 66 67 #include "vtkFiltersHybridModule.h" // For export macro 68 #include "vtkPolyDataAlgorithm.h" 69 70 #define VTK_STYLE_PIXELIZE 0 71 #define VTK_STYLE_POLYGONALIZE 1 72 #define VTK_STYLE_RUN_LENGTH 2 73 74 #define VTK_COLOR_MODE_LUT 0 75 #define VTK_COLOR_MODE_LINEAR_256 1 76 77 class vtkDataArray; 78 class vtkEdgeTable; 79 class vtkIdTypeArray; 80 class vtkIntArray; 81 class vtkScalarsToColors; 82 class vtkStructuredPoints; 83 class vtkTimeStamp; 84 class vtkUnsignedCharArray; 85 86 class VTKFILTERSHYBRID_EXPORT vtkImageToPolyDataFilter : public vtkPolyDataAlgorithm 87 { 88 public: 89 vtkTypeMacro(vtkImageToPolyDataFilter, vtkPolyDataAlgorithm); 90 void PrintSelf(ostream& os, vtkIndent indent) override; 91 92 /** 93 * Instantiate object with initial number of colors 256. 94 */ 95 static vtkImageToPolyDataFilter* New(); 96 97 ///@{ 98 /** 99 * Specify how to create the output. Pixelize means converting the image 100 * to quad polygons with a constant color per quad. Polygonalize means 101 * merging colors together into polygonal regions, and then smoothing 102 * the regions (if smoothing is turned on). RunLength means creating 103 * quad polygons that may encompass several pixels on a scan line. The 104 * default behavior is Polygonalize. 105 */ 106 vtkSetClampMacro(OutputStyle, int, VTK_STYLE_PIXELIZE, VTK_STYLE_RUN_LENGTH); 107 vtkGetMacro(OutputStyle, int); SetOutputStyleToPixelize()108 void SetOutputStyleToPixelize() { this->SetOutputStyle(VTK_STYLE_PIXELIZE); } SetOutputStyleToPolygonalize()109 void SetOutputStyleToPolygonalize() { this->SetOutputStyle(VTK_STYLE_POLYGONALIZE); } SetOutputStyleToRunLength()110 void SetOutputStyleToRunLength() { this->SetOutputStyle(VTK_STYLE_RUN_LENGTH); } 111 ///@} 112 113 ///@{ 114 /** 115 * Specify how to quantize color. 116 */ 117 vtkSetClampMacro(ColorMode, int, VTK_COLOR_MODE_LUT, VTK_COLOR_MODE_LINEAR_256); 118 vtkGetMacro(ColorMode, int); SetColorModeToLUT()119 void SetColorModeToLUT() { this->SetColorMode(VTK_COLOR_MODE_LUT); } SetColorModeToLinear256()120 void SetColorModeToLinear256() { this->SetColorMode(VTK_COLOR_MODE_LINEAR_256); } 121 ///@} 122 123 ///@{ 124 /** 125 * Set/Get the vtkLookupTable to use. The lookup table is used when the 126 * color mode is set to LUT and a single component scalar is input. 127 */ 128 virtual void SetLookupTable(vtkScalarsToColors*); 129 vtkGetObjectMacro(LookupTable, vtkScalarsToColors); 130 ///@} 131 132 ///@{ 133 /** 134 * If the output style is set to polygonalize, then you can control 135 * whether to smooth boundaries. 136 */ 137 vtkSetMacro(Smoothing, vtkTypeBool); 138 vtkGetMacro(Smoothing, vtkTypeBool); 139 vtkBooleanMacro(Smoothing, vtkTypeBool); 140 ///@} 141 142 ///@{ 143 /** 144 * Specify the number of smoothing iterations to smooth polygons. (Only 145 * in effect if output style is Polygonalize and smoothing is on.) 146 */ 147 vtkSetClampMacro(NumberOfSmoothingIterations, int, 0, VTK_INT_MAX); 148 vtkGetMacro(NumberOfSmoothingIterations, int); 149 ///@} 150 151 ///@{ 152 /** 153 * Turn on/off whether the final polygons should be decimated. 154 * whether to smooth boundaries. 155 */ 156 vtkSetMacro(Decimation, vtkTypeBool); 157 vtkGetMacro(Decimation, vtkTypeBool); 158 vtkBooleanMacro(Decimation, vtkTypeBool); 159 ///@} 160 161 ///@{ 162 /** 163 * Specify the error to use for decimation (if decimation is on). 164 * The error is an absolute number--the image spacing and 165 * dimensions are used to create points so the error should be 166 * consistent with the image size. 167 */ 168 vtkSetClampMacro(DecimationError, double, 0.0, VTK_DOUBLE_MAX); 169 vtkGetMacro(DecimationError, double); 170 ///@} 171 172 ///@{ 173 /** 174 * Specify the error value between two colors where the colors are 175 * considered the same. Only use this if the color mode uses the 176 * default 256 table. 177 */ 178 vtkSetClampMacro(Error, int, 0, VTK_INT_MAX); 179 vtkGetMacro(Error, int); 180 ///@} 181 182 ///@{ 183 /** 184 * Specify the size (n by n pixels) of the largest region to 185 * polygonalize. When the OutputStyle is set to VTK_STYLE_POLYGONALIZE, 186 * large amounts of memory are used. In order to process large images, 187 * the image is broken into pieces that are at most Size pixels in 188 * width and height. 189 */ 190 vtkSetClampMacro(SubImageSize, int, 10, VTK_INT_MAX); 191 vtkGetMacro(SubImageSize, int); 192 ///@} 193 194 protected: 195 vtkImageToPolyDataFilter(); 196 ~vtkImageToPolyDataFilter() override; 197 198 int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override; 199 int FillInputPortInformation(int port, vtkInformation* info) override; 200 201 int OutputStyle; 202 int ColorMode; 203 vtkTypeBool Smoothing; 204 int NumberOfSmoothingIterations; 205 vtkTypeBool Decimation; 206 double DecimationError; 207 int Error; 208 int SubImageSize; 209 vtkScalarsToColors* LookupTable; 210 211 virtual void PixelizeImage(vtkUnsignedCharArray* pixels, int dims[3], double origin[3], 212 double spacing[3], vtkPolyData* output); 213 virtual void PolygonalizeImage(vtkUnsignedCharArray* pixels, int dims[3], double origin[3], 214 double spacing[3], vtkPolyData* output); 215 virtual void RunLengthImage(vtkUnsignedCharArray* pixels, int dims[3], double origin[3], 216 double spacing[3], vtkPolyData* output); 217 218 private: 219 vtkUnsignedCharArray* Table; // color table used to quantize points 220 vtkTimeStamp TableMTime; 221 int* Visited; // traverse & mark connected regions 222 vtkUnsignedCharArray* PolyColors; // the colors of each region -> polygon 223 vtkEdgeTable* EdgeTable; // keep track of intersection points 224 vtkEdgeTable* EdgeUseTable; // keep track of polygons use of edges 225 vtkIntArray* EdgeUses; // the two polygons that use an edge 226 // and point id associated with edge (if any) 227 228 void BuildTable(unsigned char* inPixels); 229 vtkUnsignedCharArray* QuantizeImage( 230 vtkDataArray* inScalars, int numComp, int type, int dims[3], int ext[4]); 231 int ProcessImage(vtkUnsignedCharArray* pixels, int dims[2]); 232 int BuildEdges(vtkUnsignedCharArray* pixels, int dims[3], double origin[3], double spacing[3], 233 vtkUnsignedCharArray* pointDescr, vtkPolyData* edges); 234 void BuildPolygons(vtkUnsignedCharArray* pointDescr, vtkPolyData* edges, int numPolys, 235 vtkUnsignedCharArray* polyColors); 236 void SmoothEdges(vtkUnsignedCharArray* pointDescr, vtkPolyData* edges); 237 void DecimateEdges(vtkPolyData* edges, vtkUnsignedCharArray* pointDescr, double tol2); 238 void GeneratePolygons(vtkPolyData* edges, int numPolys, vtkPolyData* output, 239 vtkUnsignedCharArray* polyColors, vtkUnsignedCharArray* pointDescr); 240 241 int GetNeighbors( 242 unsigned char* ptr, int& i, int& j, int dims[3], unsigned char* neighbors[4], int mode); 243 244 void GetIJ(int id, int& i, int& j, int dims[2]); 245 unsigned char* GetColor(unsigned char* rgb); 246 int IsSameColor(unsigned char* p1, unsigned char* p2); 247 248 private: 249 vtkImageToPolyDataFilter(const vtkImageToPolyDataFilter&) = delete; 250 void operator=(const vtkImageToPolyDataFilter&) = delete; 251 }; 252 253 #endif 254