我正在尝试使用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);
答案 0 :(得分:1)
如果每个点的文本相同,我建议将其用作字形:
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);
这将在&#34;点&#34;中的所有点处呈现文本。数组(我假设是一个vtkPoints数组,其中包含您希望呈现文本的位置)。通过这种方式,您可以在将其附加到一个网格中时执行各种操作,例如通过提供缩放数组为每个字形设置不同的大小,或者通过提供掩模数组等以交互方式打开/关闭它们。,见http://www.vtk.org/doc/nightly/html/classvtkGlyph3DMapper.html
如果每个点的文本可能不同,您可能必须以附加的方式进行。我可以在你的附加代码中看到一些错误:
1)首先是一个小的性能 - 调用appendFilter-&gt; Update();在设置完所有输入后,只有一次。
2)
unstructuredGrid->Allocate(N);
unstructuredGrid->SetPoints(points);
通过调用Allocate,您只需重置appendfilter为您完成的所有操作。即使没有它,第二行也会重写为文本生成的所有点的位置。附加过滤器的输出就是您应该直接分配给映射器的输出,这两行必须删除。和vtkGeometryFilter一样,我没有看到它的任何原因(我猜你用它来获取vtkPolyData而不是vtkUnstructuredGrid - 只需使用vtkAppendPolydata而不是vtkAppendFilter,它将直接产生polydata)。
3)然而,现在&#34;点&#34;未使用数组,即您的文本将不在正确的位置。在将其分配给追加过滤器之前,您必须为每个文本实例转换polydata。最简单的方法是使用你的&#34;点&#34;数组作为转换向量,所以你要将点的坐标添加到vecText-&gt; 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();
如果您想要将文本置于中心位置,则需要更聪明的东西。