2016-11-24 63 views
5

我正在尝试使用vtk对象vtkVectorText呈现文本。它适用于单个3d位置。我需要的是在3d(vtkPoint)点以上放置一个3d文字。我试着用vtkTextActor3d来做,但每个文本对象都需要一个独立的演员,而我最终得到了10k个演员,当我尝试例如旋转场景时,这非常糟糕和迟缓。VTK - 如何使用单个演员呈现多个3d文本对象

我也尝试应用一些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); 

回答

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); 

,这会使得文本在“points”数组中的所有点上(我假设它是一个vtkPoints数组,其中包含要显示文本的位置)。通过这种方式,你可以做各种你不能将它附加到一个网格物体上的东西,比如通过提供一个缩放数组或者通过提供一个遮罩数组等等来交替地打开/关闭它们来为每个字形设置不同的大小。请参阅http://www.vtk.org/doc/nightly/html/classvtkGlyph3DMapper.html

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

1)首先一个小的性能 - 调用appendFilter-> Update();只有一次,你已经设置好所有的输入。

2)

unstructuredGrid->Allocate(N); 
unstructuredGrid->SetPoints(points); 

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

3)但是,现在没有使用“点”数组,即您的文本将不在正确的位置。在将其分配给追加过滤器之前,您必须为每个文本实例转换polydata。最简单的方法是使用“点”数组中的点作为平移矢量,因此,在将点发送到附加过滤器之前,将点的坐标添加到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(); 

如果你想要例如在那里居中文本,那么需要更聪明的东西。

相关问题