Библиотека сайта rus-linux.net
Система VTK
Глава 24 из 1 тома книги "Архитектура приложений с открытым исходным кодом".
Оригинал: VTK, глава из книги "The Architecture of Open Source Applications" том 1.
Автор: Berk Geveci и Will Schroeder
Перевод: Н.Ромоданов
24.2.5. События и взаимодействие
Взаимодействие с данными является неотъемлемой частью визуализации. В системе VTK это происходит в различных формах. На самом простейшем уровне, пользователи могут наблюдать события и реагировать на них соответствующим образом с помощью команд (шаблон проектирования «команда/наблюдатель»). Во всех подклассах класса vtkObject
поддерживаются списки наблюдателей, которые самостоятельно регистрируются в объекте. Во время регистрации, наблюдатели указывают, какое именно событие (или события) их интересует, и добавляют соответствующую команду, которая будет вызвана, если и когда происходит это событие. Чтобы увидеть, как это работает, рассмотрим следующий пример, в котором фильтр (здесь полигональный прореживающий фильтра) имеет наблюдателя, следящим за тремя событиями StartEven
t (начало события), ProgressEvent
(продожение события) и EndEvent
(завершение события). Эти события вызываются, когда фильтр начинает выполнение, периодически во время выполнения, а затем по окончанию выполнения. Затем в классе vtkCommand
есть метод Execute
, который выводит соответствующую информацию, касающуюся того, сколько потребовалось времени для выполнения алгоритма:
class vtkProgressCommand : public vtkCommand { public: static vtkProgressCommand *New() { return new vtkProgressCommand; } virtual void Execute(vtkObject *caller, unsigned long, void *callData) { double progress = *(static_cast<double*>(callData)); std::cout < "Progress at " < progress< std::endl; } }; vtkCommand* pobserver = vtkProgressCommand::New(); vtkDecimatePro *deci = vtkDecimatePro::New(); deci->SetInputConnection( byu->GetOutputPort() ); deci->SetTargetReduction( 0.75 ); deci->AddObserver( vtkCommand::ProgressEvent, pobserver );
Хотя это примитивная форма взаимодействия, она является основополагающей для многих приложений, в которых используется система VTK. Например, простой код, показанный выше, может быть легко преобразован для отображения и управления линейным индикатором процесса, который есть в графическом интерфейсе. Такая подсистема «команда/наблюдатель» также будет центральной в трехмерных виджетах в системе VTK, которые являются сложными интерактивным объектами, используемыми для выполнения запросов, обработки и редактирования данных, и которые описываются ниже.
Как показано в примере, приведенном выше, важно отметить, что события в системе VTK являются предопределенными, но есть скрытая лазейка для событий, которые может определять пользователь. В классе vtkComman
d определяется набор перечисляемых событий (например, vtkCommand::ProgressEvent
в приведенном выше примере), а также событие, определяемое пользователем. Событие UserEvent
, которое является просто интегрированным значением, обычно используемым в качестве смещения от начального значения в наборе событий, определяемых в приложении пользователем. Так, например, vtkCommand::UserEvent+100
может относиться к конкретному событию, которое не входит в набор событий, определенных в системе VTK.
С точки зрения пользователя, виджет VTK выступает на сцене в качестве актера, за исключением того, что пользователь может взаимодействовать с ним, манипулируя рукоятками или другими геометрическими элементами (манипуляции рукоятками и геометрическими элементами базируются использовании функций выбора pick, которые были описаны ранее). Взаимодействие с таким виджетом в известной степени интуитивно понятно: пользователь берется за сферические рукоятки и перемещает их, или захватывает линию и перемещает ее. Но за кулисами происходит возникновение событий (например, InteractionEvent
) и приложение, запрограммированное должным образом, может отслеживать эти события, а затем принимать соответствующие меры. Например, при возникновении события vtkCommand::InteractionEvent
часто происходит следующее:
vtkLW2Callback *myCallback = vtkLW2Callback::New(); myCallback->PolyData = seeds; // streamlines создают точки, обновляемые при взаимодействии myCallback->Actor = streamline; // актер streamline становится видимым при взаимодействии vtkLineWidget2 *lineWidget = vtkLineWidget2::New(); lineWidget->SetInteractor(iren); lineWidget->SetRepresentation(rep); lineWidget->AddObserver(vtkCommand::InteractionEvent,myCallback);
Виджеты VTK фактически построены с использованием двух объектов: подкласса класса vtkInteractorObserver
и подкласса класса vtkProp
. Наблюдатель vtkInteractorObserver
просто наблюдает в окне рендеринга за взаимодействием с пользователем (т.е. за событиями мыши и клавиатуры) и обрабатывает их. Манипулирование подклассами класса vtkProp
(то есть, актеры) просто происходит с помощью vtkInteractorObserver
. Обычно такая манипуляция включает изменение геометрии vtkProp
, к которой относятся управление освещенностью, изменение вида курсора и/или преобразование данных. Конечно, конкретные особенности виджетов требуют, чтобы были написаны подклассы, позволяющие управлять нюансами его поведения, и в настоящее время в системе есть более 50 различных виджетов.
Продолжение статьи: Краткое описание библиотек