Библиотека сайта 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 различных виджетов.
Продолжение статьи: Краткое описание библиотек
