使用vtkTubeFilter创建一个闭合回路

3
我想要的: 指定一组点,使用 vtkCellArray 指定连接性使其成为一个封闭圆,从中创建 vtkPolyData 并应用 vtkTubeFilter 使其具有一定的体积。 我得到的: 尽管明确定义了,但连接不正确的循环没有正确地连接第一个和最后一个元素。另一个令人困惑的问题是,管道似乎变宽了,逐渐靠近连接不正确的起始/结束。

this

我的做法: 我从 VTK 维基上的 这个示例 开始创建折线。下面是代码(Python 3.4,VTK 7.0):
import vtk


def rendering(mapper):
    """Takes mapper and handles the rendering."""
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)

    # Create a renderer, render window, and interactor
    renderer = vtk.vtkRenderer()
    renderWindow = vtk.vtkRenderWindow()
    renderWindow.AddRenderer(renderer)
    renderWindowInteractor = vtk.vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)
    # Add the actors to the scene
    renderer.AddActor(actor)
    # Render and interact
    renderWindow.Render()
    renderWindowInteractor.Start()
    return

pts = vtk.vtkPoints()
pts.SetNumberOfPoints(4)
pts.SetPoint(0, 0.5, 0, 0)
pts.SetPoint(1, 1, 0.5, 0)
pts.SetPoint(2, 0.5, 1, 0)
pts.SetPoint(3, 0, 0.5, 0)

lines = vtk.vtkCellArray()
lines.InsertNextCell(5)
lines.InsertCellPoint(0)
lines.InsertCellPoint(1)
lines.InsertCellPoint(2)
lines.InsertCellPoint(3)
lines.InsertCellPoint(0)

poly = vtk.vtkPolyData()
poly.SetPoints(pts)
poly.SetLines(lines)

tubes = vtk.vtkTubeFilter()
tubes.SetInputData(poly)
tubes.CappingOn()
tubes.SidesShareVerticesOff()
tubes.SetNumberOfSides(4)
tubes.SetRadius(0.1)
tubes.Update()

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputData(tubes.GetOutput())
rendering(mapper)

我希望有人能提出如何修复此行为的建议。我认为可能是 polydatatubes 中缺少参数。

2个回答

2

管道滤波器不支持生成周期性的管道。您可以通过使接缝(管道相遇处)共线来近似实现该效果。因此,不是

pts = vtk.vtkPoints()
pts.SetNumberOfPoints(4)
pts.SetPoint(0, 0.5, 0, 0)
pts.SetPoint(1, 1, 0.5, 0)
pts.SetPoint(2, 0.5, 1, 0)
pts.SetPoint(3, 0, 0.5, 0)

lines = vtk.vtkCellArray()
lines.InsertNextCell(5)
lines.InsertCellPoint(0)
lines.InsertCellPoint(1)
lines.InsertCellPoint(2)
lines.InsertCellPoint(3)
lines.InsertCellPoint(0)

你可以这样做:
pts = vtk.vtkPoints()
pts.SetNumberOfPoints(5)
pts.SetPoint(0, 0.25, 0.25, 0)
pts.SetPoint(1, 0.5, 0, 0)
pts.SetPoint(2, 1, 0.5, 0)
pts.SetPoint(3, 0.5, 1, 0)
pts.SetPoint(4, 0, 0.5, 0)

lines = vtk.vtkCellArray()
lines.InsertNextCell(6, range(5) + [0,])

由于接缝线可能出现在一个片段的中间,因此您可能希望关闭CappingOff()。

"凸起"也会移动到接缝线上,并且似乎是VTK中的一个错误。如果尚未列出问题,请搜索VTK的错误跟踪器并提交报告。


这是迄今为止提出的最佳解决方法,但“颠簸是个问题”。VTK正在处理他们的错误跟踪系统,所以我无法提交。 - Ian
我认为这个回答已经非常好了,你最好领取它的赏金! - Ian

1

虽然这是几年前的事情,但是迟到的人可能想看一下这个PR: https://gitlab.kitware.com/vtk/vtk/-/merge_requests/2047

它没有被合并到主分支,但是使用这些更改,您可以通过循环折线来得到一个封闭的管道:

    // Reset input polydata to a single cell, looped polyline
    double lpt0[3] = { 0.0, 0.0, 0.0 };
    double lpt1[3] = { 1.0, 0.0, 0.0 };
    double lpt2[3] = { 1.0, 1.0, 0.0 };
    double lpt3[3] = { 0.0, 1.0, 0.0 };

    vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
    pts->InsertNextPoint(lpt0);
    pts->InsertNextPoint(lpt1);
    pts->InsertNextPoint(lpt2);
    pts->InsertNextPoint(lpt3);

    vtkSmartPointer<vtkPolyLine> line
      = vtkSmartPointer<vtkPolyLine>::New();
    line->GetPointIds()->InsertNextId(0);
    line->GetPointIds()->InsertNextId(1);
    line->GetPointIds()->InsertNextId(2);
    line->GetPointIds()->InsertNextId(3);
    line->GetPointIds()->InsertNextId(0);

    vtkSmartPointer<vtkCellArray> cells
      = vtkSmartPointer<vtkCellArray>::New();
    cells->InsertNextCell(line);

    inputPolyData = vtkSmartPointer<vtkPolyData>::New();
    inputPolyData->SetPoints(pts);
    inputPolyData->SetLines(cells);

    tubeFilter->SetInputData(inputPolyData);
    tubeFilter->LoopedOn();
    tubeFilter->Update();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接