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