filter that generates tubes around lines
vtkTubeFilter is a filter that generates a tube around each input line. The tubes are made up of triangle strips and rotate around the tube with the rotation of the line normals. (If no normals are present, they are computed automatically.) The radius of the tube can be set to vary with scalar or vector value. If the radius varies with scalar value the radius is linearly adjusted. If the radius varies with vector value, a mass flux preserving variation is used. The number of sides for the tube also can be specified. You can also specify which of the sides are visible. This is useful for generating interesting striping effects. Other options include the ability to cap the tube and generate texture coordinates. Texture coordinates can be used with an associated texture map to create interesting effects such as marking the tube with stripes corresponding to length or time.
This filter is typically used to create thick or dramatic lines. Another common use is to combine this filter with vtkStreamLine to generate streamtubes.
- Warning:
- The number of tube sides must be greater than 3. If you wish to use fewer sides (i.e., a ribbon), use vtkRibbonFilter.
- The input line must not have duplicate points, or normals at points that are parallel to the incoming/outgoing line segments. (Duplicate points can be removed with vtkCleanPolyData.) If a line does not meet this criteria, then that line is not tubed.
- See also:
- vtkRibbonFilter vtkStreamLine
在本例中,先创建一个螺旋线,然后用vtkTubeFilter使线的半径随着螺旋放生变化。
1 #ifndef INITIAL_OPENGL 2 #define INITIAL_OPENGL 3 #include <vtkAutoInit.h> 4 VTK_MODULE_INIT(vtkRenderingOpenGL) 5 VTK_MODULE_INIT(vtkInteractionStyle) 6 #endif 7 #include <iostream> 8 using namespace std; 9 // VTK: Spiral with vtkTubeFilter 10 // Varying tube radius and independent RGB colors with an unsignedCharArray 11 // Contributed by Marcus Thamson 12 13 #include <vtkPolyData.h> 14 #include <vtkPoints.h> 15 #include <vtkCellArray.h> 16 #include <vtkDoubleArray.h> 17 #include <vtkPolyData.h> 18 #include <vtkPointData.h> 19 20 #include <vtkCell.h> 21 #include <vtkCellData.h> 22 #include <vtkDataSet.h> 23 #include <vtkDataSetAttributes.h> 24 #include <vtkProperty.h> 25 #include <vtkSmartPointer.h> 26 #include <vtkTubeFilter.h> 27 28 #include <vtkDataSetMapper.h> 29 #include <vtkPolyDataMapper.h> 30 #include <vtkActor.h> 31 #include <vtkRenderer.h> 32 #include <vtkRenderWindow.h> 33 #include <vtkRenderWindowInteractor.h> 34 #include <vtkCamera.h> 35 #include <vtkInteractorStyleTrackballCamera.h> 36 #include <vtkMath.h> 37 38 int main() 39 { 40 //螺旋管道; 41 double vx,vy,vz; 42 unsigned int nv=256;//vertices的个数 43 unsigned int nCyc=5;//螺旋的旋转周数 44 double rT1=0.1,rT2=0.5;//管道的起点和终点半径 45 double rs=2; //螺旋半径 46 double h=10; //高度 47 unsigned int nTv=8;//管道上的每个vertex,曲面数量 48 unsigned int i; 49 50 //创建用于螺旋管的points和cells 51 vtkSmartPointer<vtkPoints>points=vtkSmartPointer<vtkPoints>::New(); 52 double pi=vtkMath::Pi(); 53 for(i=0;i<nv;i++) 54 { 55 //螺旋坐标 56 vx=rs*cos(2*pi*nCyc*i/(nv-1)); 57 vy=rs*sin(2*pi*nCyc*i/(nv-1)); 58 vz=h*i/nv; 59 points->InsertPoint(i,vx,vy,vz); 60 } 61 vtkSmartPointer<vtkCellArray> lines=vtkSmartPointer<vtkCellArray>::New(); 62 lines->InsertNextCell(nv); 63 for(i=0;i<nv;i++) 64 { 65 lines->InsertCellPoint(i); 66 } 67 vtkSmartPointer<vtkPolyData>polyData=vtkSmartPointer<vtkPolyData>::New(); 68 polyData->SetPoints(points); 69 polyData->SetLines(lines); 70 71 //半径随着正弦函数曲线变化 72 vtkSmartPointer<vtkDoubleArray> tubeRadius=vtkSmartPointer<vtkDoubleArray>::New(); 73 tubeRadius->SetName("TubeRadius");// 74 tubeRadius->SetNumberOfTuples(nv); 75 for(i=0;i<nv;i++) 76 { 77 tubeRadius->SetTuple1(i, 78 rT1+(rT2-rT1)*sin(pi*i/(nv-1))); 79 } 80 polyData->GetPointData()->AddArray(tubeRadius); 81 polyData->GetPointData()->SetActiveScalars("TubeRadius"); 82 //RBG 数组(也许也可以添加Alpha通道) 83 //颜色从蓝-->到红 84 vtkSmartPointer<vtkUnsignedCharArray>colors=vtkSmartPointer<vtkUnsignedCharArray>::New(); 85 colors->SetName("Colors");//为该数组起名为"Colors" 86 colors->SetNumberOfComponents(3); 87 colors->SetNumberOfTuples(nv); 88 for(i=0;i<nv;i++) 89 { 90 colors->InsertTuple3(i, 91 int(255*i/(nv-1)), 92 0, 93 int(255*(nv-1-i)/(nv-1))); 94 } 95 polyData->GetPointData()->AddArray(colors);//添加颜色属性标量scalar 96 //创建未经vtkTubeFilter处理的螺旋线Actor 97 98 vtkSmartPointer<vtkPolyDataMapper>mapperSpiral=vtkSmartPointer<vtkPolyDataMapper>::New(); 99 mapperSpiral->SetInputData(polyData); 100 mapperSpiral->ScalarVisibilityOn(); 101 mapperSpiral->SetScalarModeToUsePointFieldData();//使用FieldData为对象上色 102 mapperSpiral->SelectColorArray("Colors"); 103 vtkSmartPointer<vtkActor> actorSpiral=vtkSmartPointer<vtkActor>::New(); 104 actorSpiral->SetMapper(mapperSpiral); 105 106 //管道筛选器 107 vtkSmartPointer<vtkTubeFilter> tube=vtkSmartPointer<vtkTubeFilter>::New(); 108 tube->SetInputData(polyData); 109 tube->SetNumberOfSides(nTv); 110 tube->SetVaryRadiusToVaryRadiusByAbsoluteScalar(); 111 112 vtkSmartPointer<vtkPolyDataMapper>mapper=vtkSmartPointer<vtkPolyDataMapper>::New(); 113 114 mapper->SetInputConnection(tube->GetOutputPort()); 115 116 mapper->ScalarVisibilityOn(); 117 mapper->SetScalarModeToUsePointFieldData();//使用FieldData为对象上色 118 mapper->SelectColorArray("Colors"); 119 120 vtkSmartPointer<vtkActor> actor=vtkSmartPointer<vtkActor>::New(); 121 actor->SetMapper(mapper); 122 vtkSmartPointer<vtkRenderer>renderer=vtkSmartPointer<vtkRenderer>::New(); 123 renderer->AddActor(actor); 124 // actorSpiral->SetPosition(5,0,0); 125 actorSpiral->AddPosition(5,0,0); 126 renderer->AddActor(actorSpiral);//添加未经vtkTubeFilter处理的螺旋线Actor 127 128 renderer->SetBackground(0.2,0.3,0.4); 129 //设定一个倾斜的视角 130 renderer->GetActiveCamera()->Azimuth(30); 131 renderer->GetActiveCamera()->Elevation(30); 132 renderer->ResetCamera(); 133 134 vtkSmartPointer<vtkRenderWindow>renWin=vtkSmartPointer<vtkRenderWindow>::New(); 135 vtkSmartPointer<vtkRenderWindowInteractor>iren=vtkSmartPointer<vtkRenderWindowInteractor>::New(); 136 vtkSmartPointer<vtkInteractorStyleTrackballCamera>style=vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New(); 137 138 renWin->AddRenderer(renderer); 139 renWin->SetSize(500,500); 140 renWin->Render(); 141 iren->SetRenderWindow(renWin); 142 iren->SetInteractorStyle(style); 143 iren->Start(); 144 return 0; 145 }