VTK: vtkTubeFilter生成管道

                 vtkTubeFilter可以用來生成包圍一條折線的管道。下面是一個vtkTubeFilter的使用例子。圍繞一條線創建一個圓柱形管道。

         

#include <vtkSmartPointer.h>
#include <vtkLine.h>
#include <vtkCellArray.h>
#include <vtkTubeFilter.h>
#include <vtkLineSource.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
 
 
 
int main(int, char *[])
{
  // Create a line
  vtkSmartPointer<vtkLineSource> lineSource = 
    vtkSmartPointer<vtkLineSource>::New();
  lineSource->SetPoint1(1.0, 0.0, 0.0);
  lineSource->SetPoint2(0.0, 1.0, 0.0);
 
  // Create a mapper and actor
  vtkSmartPointer<vtkPolyDataMapper> lineMapper = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
  lineMapper->SetInputConnection(lineSource->GetOutputPort());
  vtkSmartPointer<vtkActor> lineActor = 
    vtkSmartPointer<vtkActor>::New();
  lineActor->GetProperty()->SetColor(0.0,0.0,0.1); // Give some color to the line
  lineActor->SetMapper(lineMapper);
 
  // Create a tube (cylinder) around the line
  vtkSmartPointer<vtkTubeFilter> tubeFilter = 
    vtkSmartPointer<vtkTubeFilter>::New();
  tubeFilter->SetInputConnection(lineSource->GetOutputPort());
  tubeFilter->SetRadius(.025); //default is .5
  tubeFilter->SetNumberOfSides(50);
  tubeFilter->Update();
 
  // Create a mapper and actor
  vtkSmartPointer<vtkPolyDataMapper> tubeMapper = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
  tubeMapper->SetInputConnection(tubeFilter->GetOutputPort());
  vtkSmartPointer<vtkActor> tubeActor = 
    vtkSmartPointer<vtkActor>::New();
  tubeActor->GetProperty()->SetOpacity(0.5); //Make the tube have some transparency.
  tubeActor->SetMapper(tubeMapper);
 
  // Create a renderer, render window, and interactor
  vtkSmartPointer<vtkRenderer> renderer = 
    vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow = 
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);
 
  // Add the actor to the scene
  renderer->AddActor(tubeActor);
  renderer->AddActor(lineActor);
  renderer->SetBackground(0,1,0);
 
  // Render and interact
  renderWindow->Render();
  renderWindowInteractor->Start();
 
  return EXIT_SUCCESS;
}

效果如下圖:



   通過給折線上各點指定一個半徑標量值,可以實現一個直徑不斷變化的管道。例子如下:

int main(int argc, char *argv[])
{
    vtkSmartPointer<vtkPoints> points =
            vtkSmartPointer<vtkPoints>::New();
    points->InsertPoint(0,1,0,0);
    points->InsertPoint(1,2,0,0);
    points->InsertPoint(2,3,1,0);
    points->InsertPoint(3,4,1,0);
    points->InsertPoint(4,5,0,0);
    points->InsertPoint(5,6,0,0);

    // Fit a spline to the points
    vtkSmartPointer<vtkParametricSpline> spline =
            vtkSmartPointer<vtkParametricSpline>::New();
    spline->SetPoints(points);
    vtkSmartPointer<vtkParametricFunctionSource> functionSource =
            vtkSmartPointer<vtkParametricFunctionSource>::New();
    functionSource->SetParametricFunction(spline);
    functionSource->SetUResolution(10 * points->GetNumberOfPoints());
    functionSource->Update();

    // Interpolate the scalars
    double rad;
    vtkSmartPointer<vtkTupleInterpolator> interpolatedRadius =
            vtkSmartPointer<vtkTupleInterpolator> ::New();
    interpolatedRadius->SetInterpolationTypeToLinear();
    interpolatedRadius->SetNumberOfComponents(1);
    rad = .2; interpolatedRadius->AddTuple(0,&rad);
    rad = .2; interpolatedRadius->AddTuple(1,&rad);
    rad = .15; interpolatedRadius->AddTuple(2,&rad);
    rad = .15; interpolatedRadius->AddTuple(3,&rad);
    rad = .1; interpolatedRadius->AddTuple(4,&rad);
    rad = .1; interpolatedRadius->AddTuple(5,&rad);

    // Generate the radius scalars
    vtkSmartPointer<vtkDoubleArray> tubeRadius =
            vtkSmartPointer<vtkDoubleArray>::New();
    unsigned int n = functionSource->GetOutput()->GetNumberOfPoints();
    tubeRadius->SetNumberOfTuples(n);
    tubeRadius->SetName("TubeRadius");
    double tMin = interpolatedRadius->GetMinimumT(); std::cout << "tMin:" <<tMin;
    double tMax = interpolatedRadius->GetMaximumT(); std::cout << "tMax:" <<tMax;
    double r;
    for (unsigned int i = 0; i < n; ++i)
    {
        double t = (tMax - tMin) / (n - 1) * i + tMin;
        interpolatedRadius->InterpolateTuple(t, &r);
        tubeRadius->SetTuple1(i, r);
    }

    // Add the scalars to the polydata
    vtkSmartPointer<vtkPolyData> tubePolyData =
            vtkSmartPointer<vtkPolyData>::New();
    tubePolyData = functionSource->GetOutput();
    tubePolyData->GetPointData()->AddArray(tubeRadius);
    tubePolyData->GetPointData()->SetActiveScalars("TubeRadius");

    // Create the tubes
    vtkSmartPointer<vtkTubeFilter> tuber =
            vtkSmartPointer<vtkTubeFilter>::New();
#if VTK_MAJOR_VERSION <= 5
    tuber->SetInput(tubePolyData);
#else
    tuber->SetInputData(tubePolyData);
#endif
    tuber->SetNumberOfSides(50);
    tuber->SetVaryRadiusToVaryRadiusByAbsoluteScalar();

    //--------------
    // Setup actors and mappers
    vtkSmartPointer<vtkPolyDataMapper> lineMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
#if VTK_MAJOR_VERSION <= 5
    lineMapper->SetInput(tubePolyData);
#else
    lineMapper->SetInputData(tubePolyData);
#endif
    lineMapper->SetScalarRange(tubePolyData->GetScalarRange());

    vtkSmartPointer<vtkPolyDataMapper> tubeMapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    tubeMapper->SetInputConnection(tuber->GetOutputPort());
    tubeMapper->SetScalarRange(tubePolyData->GetScalarRange());

    vtkSmartPointer<vtkActor> lineActor = vtkSmartPointer<vtkActor>::New();
    lineActor->SetMapper(lineMapper);
    vtkSmartPointer<vtkActor> tubeActor = vtkSmartPointer<vtkActor>::New();
    tubeActor->SetMapper(tubeMapper);
    tubeActor->GetProperty()->SetOpacity(0.3);

    // Setup render window, renderer, and interactor
    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow =
            vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);
    renderer->AddActor(lineActor);
    renderer->AddActor(tubeActor);
    renderer->SetBackground(.2, .3, .4);
    renderWindow->Render();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章