Vtk Qt сцена с & gt; 50 (движущимися) актерами

Я пытаюсь реализовать (довольно) простую сцену, где у меня есть ~ 50 кубов, которые движутся в определенных направлениях. Положение кубов меняется 20 раз в секунду.

Моей первой съемкой было добавление и удаление актеров со сцены. Этот подход просто не масштабируется. Вся сцена запаздывает, и пользователь не может двигать камеру.

void draw(vtkRenderer *renderer)
{
renderer->RemoveAllViewProps();
for(const Cube& cube : cubes_)
{
vtkSmartPointer<vtkCubeSource> cube_source = vtkSmartPointer<vtkCubeSource>::New();
cube_source->Update();
cube_source->SetXLength(cube.lengt());
cube_source->SetYLength(cube.width());
cube_source->SetZLength(cube.height());

vtkSmartPointer<vtkPolyDataMapper> poly_mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
poly_mapper->SetInputConnection(cube_source->GetOutputPort());

vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(poly_mapper);
actor->SetPosition(cube.x(), cube.y(), cube.z());

renderer->AddActor(actor);
}
}

Второй выстрел немного лучше. Я создал «пул актеров», в котором я повторно использую актеров и скрываю ненужных.
Тем не менее, движущаяся камера отстает, а остальная часть моего пользовательского интерфейса (у меня есть некоторые дополнительные виджеты внутри виджета Vtk), кажется, отстает.

Я не мог найти соответствующий источник для Vtk, где сцена «динамична». Все примеры предварительно загружают все элементы сцены и в дальнейшем работают с ними. Может кто-нибудь сказать мне, что я здесь делаю не так?

0

Решение

это мой пример визуализации VTK

.....
vtkSmartPointer<vtkRenderer> m_vtkRenderer;
vtkSmartPointer<MouseInteractor> m_mouseInteractor;
QVector<vtkActor* > m_parcellationActors;
QVector<vtkActor* > m_electrodesActors;
QVector<vtkFollower* > m_textActors;
QVector<vtkActor*> m_vectorFieldsActors;
QVector<vtkActor*> m_streamlinesActors;
......
void VisualizationWidget::create3DViewArea()
{

m_3DViewArea = new QStackedWidget(this);
m_vtkWidget = new QVTKWidget(m_3DViewArea);
m_vtkRenderer = vtkSmartPointer<vtkRenderer>::New();
m_vtkRenderer->SetBackground(0.4, 0.4, 0.4);
this->m_vtkWidget->GetRenderWindow()->AddRenderer(m_vtkRenderer);
m_mouseInteractor = vtkSmartPointer<MouseInteractor>::New();
m_mouseInteractor ->SetDefaultRenderer(m_vtkRenderer);
this->m_vtkWidget->GetRenderWindow()->GetInteractor()->SetInteractorStyle( m_mouseInteractor);
connect(m_mouseInteractor, &MouseInteractor::onActorSelected, this, &VisualizationWidget::onActorSelectedSlot);
m_vtkLoadingWidget = new LoadingWidget(m_3DViewArea);
m_vtkLoadingWidget->setIconPath(Icon::s_getTDCSLoadingGif);
m_3DViewArea->addWidget(m_vtkLoadingWidget);
m_3DViewArea->addWidget(m_vtkWidget);
}void VisualizationWidget::setParcellationActors(QVector<vtkActor*> actors)
{
m_parcellationActors = actors;
for (int i = 0; i < m_parcellationActors.size(); ++i) {
m_vtkRenderer->AddActor(m_parcellationActors.at(i));
}

m_vtkWidget->update();
}
void VisualizationWidget::setElectrodesActors(QVector<vtkActor*> actors)
{
m_electrodesActors = actors;

for (int i = 0; i < m_electrodesActors.size(); ++i) {
m_vtkRenderer->AddActor(m_electrodesActors.at(i));
}
m_vtkWidget->update();
}

void VisualizationWidget::setElectrodesLabelsActors(QVector<vtkFollower*> actors)
{
m_textActors = actors;

for (int i = 0; i < m_textActors.size(); ++i) {
m_textActors.at(i)->SetCamera(m_vtkRenderer->GetActiveCamera());
m_vtkRenderer->AddActor(m_textActors.at(i));
}
m_vtkRenderer->ResetCamera();
m_vtkWidget->update();
}

void VisualizationWidget::setVectorFieldsActors(QVector<vtkActor*> actors)
{
for (int i = 0; i < m_vectorFieldsActors.size(); ++i) {
m_vtkRenderer->RemoveActor(m_vectorFieldsActors.at(i));
}
m_vectorFieldsActors = actors;

for (int i = 0; i <  m_vectorFieldsActors.size(); ++i) {
changeActorOpacity(m_vectorFieldsActors[i], double(m_postProcResOpacSliders.at(i)->value()) / m_postProcResOpacSliders.at(i)->maximum());
m_vtkRenderer->AddActor(m_vectorFieldsActors.at(i));
}

m_vtkRenderer->ResetCamera();
m_vtkWidget->update();
}

void VisualizationWidget::setStreamlinesActors(QVector<vtkActor*> actors)
{
for (int i = 0; i < m_streamlinesActors.size(); ++i) {
m_vtkRenderer->RemoveActor(m_streamlinesActors.at(i));
}
m_streamlinesActors = actors;

for (int i = 0; i < m_streamlinesActors.size(); ++i) {
changeActorOpacity(m_streamlinesActors[i], double(m_streamLinesSlider->value()) / m_streamLinesSlider->maximum());
m_vtkRenderer->AddActor(m_streamlinesActors.at(i));
}

m_vtkRenderer->ResetCamera();
m_vtkWidget->update();
}

void VisualizationWidget::changeActorOpacity(vtkActor* actor, double opac)
{
actor->SetVisibility(opac > 0.05);
actor->GetMapper()->Modified();
actor->GetProperty()->SetOpacity(opac);
}
1

Другие решения

После нескольких дней исследования мне удалось взломать рабочее решение:

vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
// as many points as you like
points->InsertNextPoint(-25, 0, 0);
points->InsertNextPoint(-35, 0, 0);vtkSmartPointer<vtkFloatArray> scales = vtkSmartPointer<vtkFloatArray>::New();
scales->SetNumberOfComponents(3);
// same as number of points
scales->InsertNextTuple3(1, 1., 8.);
scales->InsertNextTuple3(1., 1., 10.);vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->GetPointData()->SetVectors(scales);

vtkSmartPointer<vtkCubeSource> cubeSource = vtkSmartPointer<vtkCubeSource>::New();

vtkSmartPointer<vtkGlyph3D> glyph3D = vtkSmartPointer<vtkGlyph3D>::New();
glyph3D->OrientOff(); // disable orientation
glyph3D->SetScaleModeToScaleByVectorComponents(); // sacle along each axis
glyph3D->SetSourceConnection(cubeSource->GetOutputPort());
glyph3D->SetInputData(polydata);
glyph3D->Update();

vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(glyph3D->GetOutputPort());
mapper->ScalarVisibilityOff(); // use color from actor

vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->GetProperty()->SetColor(0, 1, 0); // this will change color for whole glyph
actor->SetMapper(mapper);

mapper->Update();

vtk_renderer->AddActor(actor);

Код сверху добавит столько кубов, и вы захотите использовать одного актера! (в моем случае это был потрясающий прирост производительности)

Далее, если вы хотите обновить позиции кубов, вам просто нужно сделать следующее:

points->Reset();
points->InsertNextPoint(-25, 0, 0);
points->InsertNextPoint(-35, 0, 0);

scales->Reset();
scales->InsertNextTuple3(1, 1., 8.);
scales->InsertNextTuple3(1., 1., 10.);

polydata_->Modified();
// call render

(обратите внимание, что я не удаляю / не добавляю актеров на сцену, что является еще одним стимулом)

1

По вопросам рекламы [email protected]