2016-11-24 7 views
5

vtk 객체 vtkVectorText를 사용하여 텍스트를 렌더링하려고합니다. 단일 3D 위치에서 잘 작동합니다. 내가 필요한 것은 3d (vtkPoint) 포인트 위에 3d 텍스트를 배치하는 것입니다. vtkTextActor3d를 사용하여 작업을 시도했지만 각각의 텍스트 객체에는 별도의 액터가 필요하며 10k 액터로 끝났습니다. 예를 들어 장면을 회전 시키려고하면 꽤 나 빠지고 느려집니다.VTK - 단일 액터로 여러 3D 텍스트 객체를 렌더링하는 방법

또한 appendFilter를 적용하여 vtkVectorText 배열을 만들고 appendFilter의 객체에서 구조화되지 않은 격자를 가져온 다음이를 polydata로 변환하여 원하는 점 위치로 구조화되지 않은 격자를 렌더링합니다. 이 작업을 수행하는 가장 좋은 방법은 무엇인지 알 수 없으므로 아무 것도 보여주지 않습니다.

누군가가 도와 줄 수 있습니까?

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

이것은 렌더링됩니다 텍스트가 각 지점에 대해 동일

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

경우, 내가 그리로 사용 제안 할 것 : 여기

는 마지막 부분에서 내 코드입니다 "points"배열에있는 모든 점의 텍스트 (텍스트를 렌더링 할 위치가있는 vtkPoints 배열이라고 가정합니다). 이런 식으로 스케일 배열을 제공하거나 마스크 배열 등을 제공하여 대화 형으로 켜기/끄기로 글리프마다 다른 크기를 설정하는 것과 같이 하나의 메쉬에 추가 할 때 할 수없는 모든 종류의 작업을 수행 할 수 있습니다. http://www.vtk.org/doc/nightly/html/classvtkGlyph3DMapper.html

텍스트가 각 포인트마다 다를 수있는 경우 추가하는 방법이 필요할 수 있습니다. 추가 코드에서 몇 가지 버그를 볼 수 있습니다 :

1) 작은 성능 우선 - appendFilter-> Update(); 모든 입력을 설정 한 후에 한 번만

2)

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

할당 호출하여, 당신은 단지 appendfilter 당신을 위해 행하신 모든 resetted. 그것이 없어도 두 번째 줄은 텍스트에 대해 생성 된 모든 점의 위치를 ​​다시 작성합니다. 추가 필터의 출력은 매퍼에 직접 할당해야하는 것이므로이 두 행을 삭제해야합니다. 그냥 vtkGeometryFilter뿐만 아니라, 나는 그것에 대한 이유를 볼 수 없다 (나는 당신이 vtkUnstructuredGrid 대신 vtkPolyData를 얻는 데 사용했다고 생각한다. 단지 vtkAppendFilter 대신 vtkAppendPolydata를 사용하면 직접 polydata를 생성 할 것이다).

3) 그러나 이제 "points"배열이 사용되지 않습니다. 즉, 텍스트가 올바른 위치에 있지 않습니다. 추가 필터에 할당하기 전에 각 텍스트 인스턴스에 대한 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(); 

예를 들어 텍스트를 가운데에 배치하려면 더 영리한 것이 필요합니다.