VTK - 如何使用单个actor渲染多个3d文本对象

PeG*_*nOS 6 3d vector-graphics vtk

我试图使用vtk对象vtkVectorText渲染文本.它适用于单个3d位置.我需要的是在一些3d(vtkPoint)点上方放置一个3d文本.我尝试用vtkTextActor3d做这个,但是每个文本对象都需要一个单独的actor,我最终得到了10k演员,当我试图旋转场景时,这是非常糟糕和滞后的.

我还尝试应用一些appendFilter来创建一个vtkVectorText数组,从appendFilter的对象获取非结构化网格,然后将其转换为polydata,以便使用我想要的点位置渲染非结构化网格.它没有显示任何内容,因为我无法弄清楚执行此操作的最佳方法是什么.

有人可以帮我弄这个吗?

这是我上一部分的代码:

vtkSmartPointer<vtkAppendFilter> appendFilter = vtkSmartPointer<vtkAppendFilter>::New();
//for each point
for (int i = 0; i < N;i++) {
    vtkSmartPointer<vtkVectorText> vecText = vtkSmartPointer<vtkVectorText>::New();
    vecText->SetText("My text, needs to appear multiple times");
    vecText->Update();
    appendFilter->AddInputData(vecText->GetOutput());
    appendFilter->Update();
}
vtkSmartPointer<vtkUnstructuredGrid> unstructuredGrid = appendFilter->GetOutput();
unstructuredGrid->Allocate(N);
unstructuredGrid->SetPoints(points);
vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
geometryFilter->SetInputData(unstructuredGrid);
geometryFilter->Update();
vtkSmartPointer<vtkPolyDataMapper> textMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
textMapper->SetInputConnection(geometryFilter->GetOutputPort());
vtkSmartPointer<vtkActor> textActor = vtkSmartPointer<vtkActor>::New();
textActor->SetMapper(textMapper);
textActor->GetProperty()->SetColor(0, 1, 0);

renderer->AddActor(textActor);
Run Code Online (Sandbox Code Playgroud)

tom*_*omj 2

如果每个点的文本都相同,我建议将其用作字形:

vtkSmartPointer<vtkPolyData> pointsHolder = vtkSmartPointer<vtkPolyData>::New();
pointsHolder->SetPoints(points); // I assume that these are the points where you want the object to be rendered
vtkSmartPointer<vtkGlyph3DMapper> glyphMapper = vtkSmartPointer<vtkGlyph3DMapper>::New();
glyphMapper->SetSourceConnection(vecText->GetOutputPort()); // this says WHAT should be rendered
glyphMapper->SetInputData(pointsHolder); // this says WHERE
textActor->SetMapper(glyphMapper);
Run Code Online (Sandbox Code Playgroud)

这将在“points”数组中的所有点处渲染文本(我假设它是一个 vtkPoints 数组,其中包含您希望渲染文本的位置)。通过这种方式,您可以执行将其附加到一个网格中时无法执行的各种操作,例如通过提供比例数组为每个字形设置不同的大小,或通过提供掩码数组以交互方式打开/关闭它们等,请参阅http://www.vtk.org/doc/nightly/html/classvtkGlyph3DMapper.html

如果每个点的文本可能不同,您可能必须以附加的方式进行操作。我可以在您的附加代码中看到一些错误:

1) 首先是一个小的性能 - 调用appendFilter->Update(); 仅在设置所有输入后一次。

2)

unstructuredGrid->Allocate(N);
unstructuredGrid->SetPoints(points);
Run Code Online (Sandbox Code Playgroud)

通过调用 Allocate,您只是重置了appendfilter 为您所做的一切。即使没有它,第二行也会重写为文本生成的所有点的位置。附加过滤器的输出就是您应该直接分配给映射器的输出,必须删除这两行。就像 vtkGeometryFilter 一样,我没有看到任何原因(我猜你用它来获取 vtkPolyData 而不是 vtkUnstructedGrid - 只需使用 vtkAppendPolydata 而不是 vtkAppendFilter,它将直接生成多数据)。

3)但是,现在不使用“points”数组,即您的文本将不会位于正确的位置。在将每个文本实例分配给附加过滤器之前,您必须转换其多数据。最简单的方法是使用“points”数组中的点作为平移向量,因此您可以将点的坐标添加到 vecText->GetOutput() 的每个点,然后再将其发送到附加过滤器,如下所示:

vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New();
//for each point
for (int i = 0; i < N;i++) {
    vtkSmartPointer<vtkVectorText> vecText = vtkSmartPointer<vtkVectorText>::New();
    vecText->SetText("My text, needs to appear multiple times");
    vecText->Update();
    vtkPolyData *output = vecText->GetOutput();
    double *location = points->GetPoint(i);
    for (int j = 0; j < output->GetNumberOfPoints(); j++) {
        double *point = output->GetPoint(j);
        output->GetPoints()->SetPoint(j, point[0] + location[0], point[1] + location[1], points[2] + location[2]);
    }
    appendFilter->AddInputData(output);
}
appendFilter->Update();
Run Code Online (Sandbox Code Playgroud)

例如,如果您想将文本居中,则需要更聪明的方法。