2016-11-24 16 views
5

Tôi đang cố gắng hiển thị văn bản bằng vtk đối tượng vtkVectorText. Nó hoạt động tốt cho một vị trí 3d duy nhất. Những gì tôi cần là đặt một văn bản 3d ở trên một số điểm (vtkPoint) 3d. Tôi đã thử làm nó với vtkTextActor3d nhưng mỗi đối tượng văn bản yêu cầu một diễn viên riêng biệt và tôi đã kết thúc với 10k diễn viên, đó là khá xấu và laggy khi tôi cố gắng ví dụ để xoay cảnh. Tôi cũng đã thử áp dụng một số appendFilter để tạo mảng vtkVectorText, lấy lưới không có cấu trúc từ đối tượng appendFilter và sau đó chuyển đổi nó thành polydata để hiển thị lưới không có cấu trúc với các vị trí điểm mong muốn của tôi. Nó cho thấy không có gì là tôi không thể tìm ra cách tốt nhất để làm điều này là gì.VTK - Cách hiển thị nhiều đối tượng văn bản 3D với một diễn viên

Ai đó có thể giúp tôi với điều này không?

Đây là mã của tôi từ phần cuối cùng:

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

Trả lời

1

Nếu văn bản là như nhau cho mỗi điểm, tôi sẽ đề nghị sử dụng nó như một hình tượng:

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

Điều này sẽ làm cho văn bản ở tất cả các điểm trong mảng "điểm" (mà tôi giả định là một mảng vtkPoints với các vị trí mà bạn muốn văn bản được hiển thị). Bằng cách này bạn có thể làm mọi thứ mà bạn không thể khi bạn gắn nó vào một lưới, như thiết lập kích thước khác nhau cho mỗi glyph bằng cách cung cấp một mảng tỷ lệ hoặc bật/tắt tương tác bằng cách cung cấp mảng mặt nạ, v.v. xem http://www.vtk.org/doc/nightly/html/classvtkGlyph3DMapper.html

Nếu văn bản có thể khác nhau cho mỗi điểm, bạn có thể sẽ phải làm điều đó theo cách bổ sung. Tôi có thể thấy một vài lỗi trong mã phụ của bạn:

1) Đầu tiên là một hiệu suất nhỏ - gọi hàm appendFilter-> Update(); chỉ một lần, sau khi bạn đã đặt tất cả các yếu tố đầu vào.

2)

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

Bằng cách gọi Phân bổ, bạn chỉ cần tự đặt lại tất cả những gì appendfilter đã thực hiện cho bạn. Ngay cả khi không có nó, dòng thứ hai sẽ viết lại vị trí cho tất cả các điểm được tạo cho văn bản. Đầu ra của bộ lọc chắp thêm chỉ đơn giản là những gì bạn nên gán trực tiếp cho người lập bản đồ của bạn, hai dòng này phải được xóa. Cũng giống như vtkGeometryFilter, tôi không thấy bất kỳ lý do nào cho nó (tôi đoán bạn đã sử dụng nó để lấy vtkPolyData thay vì vtkUnstructuredGrid - chỉ cần sử dụng vtkAppendPolydata thay vì vtkAppendFilter, nó sẽ tạo ra polydata trực tiếp).

3) Tuy nhiên, hiện tại mảng "điểm" không được sử dụng, tức là văn bản của bạn sẽ không ở đúng vị trí. Bạn sẽ phải chuyển đổi polydata cho mỗi cá thể văn bản trước khi gán nó cho bộ lọc chắp thêm. Cách đơn giản nhất là sử dụng các điểm từ mảng "điểm" của bạn làm vectơ dịch, vì vậy bạn sẽ thêm tọa độ của điểm vào mỗi điểm của vecText-> GetOutput() trước khi gửi nó vào bộ lọc nối thêm, vì vậy, như sau:

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

Điều gì đó thông minh hơn sẽ là cần thiết nếu bạn muốn ví dụ như văn bản ở giữa.

Các vấn đề liên quan