1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkTubeFilter.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   vtkTubeFilter
17  * @brief   filter that generates tubes around lines
18  *
19  * vtkTubeFilter is a filter that generates a tube around each input line.
20  * The tubes are made up of triangle strips and rotate around the tube with
21  * the rotation of the line normals. (If no normals are present, they are
22  * computed automatically.) The radius of the tube can be set to vary with
23  * scalar or vector value. If the radius varies with scalar value the radius
24  * is linearly adjusted. If the radius varies with vector value, a mass
25  * flux preserving variation is used. The number of sides for the tube also
26  * can be specified. You can also specify which of the sides are visible. This
27  * is useful for generating interesting striping effects. Other options
28  * include the ability to cap the tube and generate texture coordinates.
29  * Texture coordinates can be used with an associated texture map to create
30  * interesting effects such as marking the tube with stripes corresponding
31  * to length or time.
32  *
33  * This filter is typically used to create thick or dramatic lines. Another
34  * common use is to combine this filter with vtkStreamTracer to generate
35  * streamtubes.
36  *
37  * @warning
38  * The number of tube sides must be greater than 3. If you wish to use fewer
39  * sides (i.e., a ribbon), use vtkRibbonFilter.
40  *
41  * @warning
42  * The input line must not have duplicate points, or normals at points that
43  * are parallel to the incoming/outgoing line segments. (Duplicate points
44  * can be removed with vtkCleanPolyData.) If a line does not meet this
45  * criteria, then that line is not tubed.
46  *
47  * @sa
48  * vtkRibbonFilter vtkStreamTracer
49  *
50  * @par Thanks:
51  * Michael Finch for absolute scalar radius
52 */
53 
54 #ifndef vtkTubeFilter_h
55 #define vtkTubeFilter_h
56 
57 #include "vtkFiltersCoreModule.h" // For export macro
58 #include "vtkPolyDataAlgorithm.h"
59 
60 #define VTK_VARY_RADIUS_OFF 0
61 #define VTK_VARY_RADIUS_BY_SCALAR 1
62 #define VTK_VARY_RADIUS_BY_VECTOR 2
63 #define VTK_VARY_RADIUS_BY_ABSOLUTE_SCALAR 3
64 
65 #define VTK_TCOORDS_OFF                    0
66 #define VTK_TCOORDS_FROM_NORMALIZED_LENGTH 1
67 #define VTK_TCOORDS_FROM_LENGTH            2
68 #define VTK_TCOORDS_FROM_SCALARS           3
69 
70 class vtkCellArray;
71 class vtkCellData;
72 class vtkDataArray;
73 class vtkFloatArray;
74 class vtkPointData;
75 class vtkPoints;
76 
77 class VTKFILTERSCORE_EXPORT vtkTubeFilter : public vtkPolyDataAlgorithm
78 {
79 public:
80   vtkTypeMacro(vtkTubeFilter,vtkPolyDataAlgorithm);
81   void PrintSelf(ostream& os, vtkIndent indent) override;
82 
83   /**
84    * Construct object with radius 0.5, radius variation turned off, the
85    * number of sides set to 3, and radius factor of 10.
86    */
87   static vtkTubeFilter *New();
88 
89   //@{
90   /**
91    * Set the minimum tube radius (minimum because the tube radius may vary).
92    */
93   vtkSetClampMacro(Radius,double,0.0,VTK_DOUBLE_MAX);
94   vtkGetMacro(Radius,double);
95   //@}
96 
97   //@{
98   /**
99    * Turn on/off the variation of tube radius with scalar value.
100    */
101   vtkSetClampMacro(VaryRadius,int,
102                    VTK_VARY_RADIUS_OFF,VTK_VARY_RADIUS_BY_ABSOLUTE_SCALAR);
103   vtkGetMacro(VaryRadius,int);
SetVaryRadiusToVaryRadiusOff()104   void SetVaryRadiusToVaryRadiusOff()
105     {this->SetVaryRadius(VTK_VARY_RADIUS_OFF);};
SetVaryRadiusToVaryRadiusByScalar()106   void SetVaryRadiusToVaryRadiusByScalar()
107     {this->SetVaryRadius(VTK_VARY_RADIUS_BY_SCALAR);};
SetVaryRadiusToVaryRadiusByVector()108   void SetVaryRadiusToVaryRadiusByVector()
109     {this->SetVaryRadius(VTK_VARY_RADIUS_BY_VECTOR);};
SetVaryRadiusToVaryRadiusByAbsoluteScalar()110   void SetVaryRadiusToVaryRadiusByAbsoluteScalar()
111     {this->SetVaryRadius(VTK_VARY_RADIUS_BY_ABSOLUTE_SCALAR);};
112   const char *GetVaryRadiusAsString();
113   //@}
114 
115   //@{
116   /**
117    * Set the number of sides for the tube. At a minimum, number of sides is 3.
118    */
119   vtkSetClampMacro(NumberOfSides,int,3,VTK_INT_MAX);
120   vtkGetMacro(NumberOfSides,int);
121   //@}
122 
123   //@{
124   /**
125    * Set the maximum tube radius in terms of a multiple of the minimum radius.
126    */
127   vtkSetMacro(RadiusFactor,double);
128   vtkGetMacro(RadiusFactor,double);
129   //@}
130 
131   //@{
132   /**
133    * Set the default normal to use if no normals are supplied, and the
134    * DefaultNormalOn is set.
135    */
136   vtkSetVector3Macro(DefaultNormal,double);
137   vtkGetVectorMacro(DefaultNormal,double,3);
138   //@}
139 
140   //@{
141   /**
142    * Set a boolean to control whether to use default normals.
143    * DefaultNormalOn is set.
144    */
145   vtkSetMacro(UseDefaultNormal,vtkTypeBool);
146   vtkGetMacro(UseDefaultNormal,vtkTypeBool);
147   vtkBooleanMacro(UseDefaultNormal,vtkTypeBool);
148   //@}
149 
150   //@{
151   /**
152    * Set a boolean to control whether tube sides should share vertices.
153    * This creates independent strips, with constant normals so the
154    * tube is always faceted in appearance.
155    */
156   vtkSetMacro(SidesShareVertices, vtkTypeBool);
157   vtkGetMacro(SidesShareVertices, vtkTypeBool);
158   vtkBooleanMacro(SidesShareVertices, vtkTypeBool);
159   //@}
160 
161   //@{
162   /**
163    * Turn on/off whether to cap the ends with polygons. Initial value is off.
164    */
165   vtkSetMacro(Capping,vtkTypeBool);
166   vtkGetMacro(Capping,vtkTypeBool);
167   vtkBooleanMacro(Capping,vtkTypeBool);
168   //@}
169 
170   //@{
171   /**
172    * Control the striping of the tubes. If OnRatio is greater than 1,
173    * then every nth tube side is turned on, beginning with the Offset
174    * side.
175    */
176   vtkSetClampMacro(OnRatio,int,1,VTK_INT_MAX);
177   vtkGetMacro(OnRatio,int);
178   //@}
179 
180   //@{
181   /**
182    * Control the striping of the tubes. The offset sets the
183    * first tube side that is visible. Offset is generally used with
184    * OnRatio to create nifty striping effects.
185    */
186   vtkSetClampMacro(Offset,int,0,VTK_INT_MAX);
187   vtkGetMacro(Offset,int);
188   //@}
189 
190   //@{
191   /**
192    * Control whether and how texture coordinates are produced. This is
193    * useful for striping the tube with length textures, etc. If you
194    * use scalars to create the texture, the scalars are assumed to be
195    * monotonically increasing (or decreasing).
196    */
197   vtkSetClampMacro(GenerateTCoords,int,VTK_TCOORDS_OFF,
198                    VTK_TCOORDS_FROM_SCALARS);
199   vtkGetMacro(GenerateTCoords,int);
SetGenerateTCoordsToOff()200   void SetGenerateTCoordsToOff()
201     {this->SetGenerateTCoords(VTK_TCOORDS_OFF);}
SetGenerateTCoordsToNormalizedLength()202   void SetGenerateTCoordsToNormalizedLength()
203     {this->SetGenerateTCoords(VTK_TCOORDS_FROM_NORMALIZED_LENGTH);}
SetGenerateTCoordsToUseLength()204   void SetGenerateTCoordsToUseLength()
205     {this->SetGenerateTCoords(VTK_TCOORDS_FROM_LENGTH);}
SetGenerateTCoordsToUseScalars()206   void SetGenerateTCoordsToUseScalars()
207     {this->SetGenerateTCoords(VTK_TCOORDS_FROM_SCALARS);}
208   const char *GetGenerateTCoordsAsString();
209   //@}
210 
211   //@{
212   /**
213    * Control the conversion of units during the texture coordinates
214    * calculation. The TextureLength indicates what length (whether
215    * calculated from scalars or length) is mapped to the [0,1)
216    * texture space.
217    */
218   vtkSetClampMacro(TextureLength,double,0.000001,VTK_INT_MAX);
219   vtkGetMacro(TextureLength,double);
220   //@}
221 
222   //@{
223   /**
224    * Set/get the desired precision for the output types. See the documentation
225    * for the vtkAlgorithm::DesiredOutputPrecision enum for an explanation of
226    * the available precision settings.
227    */
228   vtkSetMacro(OutputPointsPrecision,int);
229   vtkGetMacro(OutputPointsPrecision,int);
230   //@}
231 
232 protected:
233   vtkTubeFilter();
~vtkTubeFilter()234   ~vtkTubeFilter() override {}
235 
236   // Usual data generation method
237   int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
238 
239   double Radius; //minimum radius of tube
240   int VaryRadius; //controls radius variation
241   int NumberOfSides; //number of sides to create tube
242   double RadiusFactor; //maximum allowable radius
243   double DefaultNormal[3];
244   vtkTypeBool UseDefaultNormal;
245   vtkTypeBool SidesShareVertices;
246   vtkTypeBool Capping; //control whether tubes are capped
247   int OnRatio; //control the generation of the sides of the tube
248   int Offset;  //control the generation of the sides
249   int GenerateTCoords; //control texture coordinate generation
250   int OutputPointsPrecision;
251   double TextureLength; //this length is mapped to [0,1) texture space
252 
253   // Helper methods
254   int GeneratePoints(vtkIdType offset, vtkIdType npts, vtkIdType *pts,
255                      vtkPoints *inPts, vtkPoints *newPts,
256                      vtkPointData *pd, vtkPointData *outPD,
257                      vtkFloatArray *newNormals, vtkDataArray *inScalars,
258                      double range[2], vtkDataArray *inVectors, double maxNorm,
259                      vtkDataArray *inNormals);
260   void GenerateStrips(vtkIdType offset, vtkIdType npts, vtkIdType *pts,
261                       vtkIdType inCellId, vtkCellData *cd, vtkCellData *outCD,
262                       vtkCellArray *newStrips);
263   void GenerateTextureCoords(vtkIdType offset, vtkIdType npts, vtkIdType *pts,
264                              vtkPoints *inPts, vtkDataArray *inScalars,
265                             vtkFloatArray *newTCoords);
266   vtkIdType ComputeOffset(vtkIdType offset,vtkIdType npts);
267 
268   // Helper data members
269   double Theta;
270 
271 private:
272   vtkTubeFilter(const vtkTubeFilter&) = delete;
273   void operator=(const vtkTubeFilter&) = delete;
274 };
275 
276 #endif
277