Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Система VTK

Глава 24 из 1 тома книги "Архитектура приложений с открытым исходным кодом".

Оригинал: VTK, глава из книги "The Architecture of Open Source Applications" том 1.
Автор: Berk Geveci и Will Schroeder
Перевод: Н.Ромоданов

24.2.5. События и взаимодействие

Взаимодействие с данными является неотъемлемой частью визуализации. В системе VTK это происходит в различных формах. На самом простейшем уровне, пользователи могут наблюдать события и реагировать на них соответствующим образом с помощью команд (шаблон проектирования «команда/наблюдатель»). Во всех подклассах класса vtkObject поддерживаются списки наблюдателей, которые самостоятельно регистрируются в объекте. Во время регистрации, наблюдатели указывают, какое именно событие (или события) их интересует, и добавляют соответствующую команду, которая будет вызвана, если и когда происходит это событие. Чтобы увидеть, как это работает, рассмотрим следующий пример, в котором фильтр (здесь полигональный прореживающий фильтра) имеет наблюдателя, следящим за тремя событиями StartEvent (начало события), 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 являются предопределенными, но есть скрытая лазейка для событий, которые может определять пользователь. В классе vtkCommand определяется набор перечисляемых событий (например, 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 различных виджетов.


Продолжение статьи: Краткое описание библиотек