diff --git a/Core/Code/Interactions/mitkDispatcher.cpp b/Core/Code/Interactions/mitkDispatcher.cpp index 49edf6d322..21cfc07785 100644 --- a/Core/Code/Interactions/mitkDispatcher.cpp +++ b/Core/Code/Interactions/mitkDispatcher.cpp @@ -1,234 +1,235 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDispatcher.h" #include "mitkInteractionEvent.h" #include "mitkInternalEvent.h" // MicroServices #include "mitkGetModuleContext.h" #include "mitkModule.h" #include "mitkModuleRegistry.h" #include "mitkInteractionEventObserver.h" mitk::Dispatcher::Dispatcher() : m_ProcessingMode(REGULAR) { m_EventObserverTracker = new mitk::ServiceTracker(GetModuleContext()); m_EventObserverTracker->Open(); } void mitk::Dispatcher::AddDataInteractor(const DataNode* dataNode) { RemoveDataInteractor(dataNode); RemoveOrphanedInteractors(); DataInteractor::Pointer dataInteractor = dataNode->GetDataInteractor(); if (dataInteractor.IsNotNull()) { m_Interactors.push_back(dataInteractor); } } /* * Note: One DataInteractor can only have one DataNode and vice versa, * BUT the m_Interactors list may contain another DataInteractor that is still connected to this DataNode, * in this case we have to remove >1 DataInteractor. (Some special case of switching DataNodes between DataInteractors and registering a * DataNode to a DataStorage after assigning it to an DataInteractor) */ void mitk::Dispatcher::RemoveDataInteractor(const DataNode* dataNode) { for (ListInteractorType::iterator it = m_Interactors.begin(); it != m_Interactors.end();) { if ((*it)->GetDataNode() == dataNode) { it = m_Interactors.erase(it); } else { ++it; } } } size_t mitk::Dispatcher::GetNumberOfInteractors() { return m_Interactors.size(); } mitk::Dispatcher::~Dispatcher() { if (m_EventObserverTracker != NULL) { + m_EventObserverTracker->Close(); delete m_EventObserverTracker; } } bool mitk::Dispatcher::ProcessEvent(InteractionEvent* event) { InteractionEvent::Pointer p = event; //MITK_INFO << event->GetEventClass(); bool eventIsHandled = false; /* Filter out and handle Internal Events separately */ InternalEvent* internalEvent = dynamic_cast(event); if (internalEvent != NULL) { eventIsHandled = HandleInternalEvent(internalEvent); // InternalEvents that are handled are not sent to the listeners if (eventIsHandled) { return true; } } switch (m_ProcessingMode) { case CONNECTEDMOUSEACTION: // finished connected mouse action if (p->GetEventClass() == "MouseReleaseEvent") { m_ProcessingMode = REGULAR; eventIsHandled = m_SelectedInteractor->HandleEvent(event, m_SelectedInteractor->GetDataNode()); } // give event to selected interactor if (eventIsHandled == false) { eventIsHandled = m_SelectedInteractor->HandleEvent(event, m_SelectedInteractor->GetDataNode()); } break; case GRABINPUT: eventIsHandled = m_SelectedInteractor->HandleEvent(event, m_SelectedInteractor->GetDataNode()); SetEventProcessingMode(m_SelectedInteractor); break; case PREFERINPUT: if (m_SelectedInteractor->HandleEvent(event, m_SelectedInteractor->GetDataNode()) == true) { SetEventProcessingMode(m_SelectedInteractor); eventIsHandled = true; } break; case REGULAR: break; } // Standard behavior. Is executed in STANDARD mode and PREFERINPUT mode, if preferred interactor rejects event. if (m_ProcessingMode == REGULAR || (m_ProcessingMode == PREFERINPUT && eventIsHandled == false)) { m_Interactors.sort(cmp()); // sorts interactors by layer (descending); for (std::list::iterator it = m_Interactors.begin(); it != m_Interactors.end(); ++it) { // explicit copy of pointer because HandleEvent function causes the m_Interactors list to be updated, // which in turn invalidates the iterator. DataInteractor::Pointer dataInteractor = *it; if (dataInteractor->HandleEvent(event, dataInteractor->GetDataNode())) { // if an event is handled several properties are checked, in order to determine the processing mode of the dispatcher SetEventProcessingMode(dataInteractor); if (p->GetEventClass() == "MousePressEvent" && m_ProcessingMode == REGULAR) { m_SelectedInteractor = dataInteractor; m_ProcessingMode = CONNECTEDMOUSEACTION; } eventIsHandled = true; break; } } } /* Notify InteractionEventObserver */ std::list listEventObserver; m_EventObserverTracker->GetServiceReferences(listEventObserver); for (std::list::iterator it = listEventObserver.begin(); it != listEventObserver.end(); ++it) { Any patternName = it->GetProperty("org.mitk.statemachinepattern"); //if (!patternName.Empty() || patternName.ToString() == "") //{ InteractionEventObserver* interactionEventObserver = m_EventObserverTracker->GetService(*it); if (interactionEventObserver != NULL) { interactionEventObserver->Notify(event, eventIsHandled); } //} } // Process event queue if (!m_QueuedEvents.empty()) { InteractionEvent::Pointer e = m_QueuedEvents.front(); m_QueuedEvents.pop_front(); ProcessEvent(e); } return eventIsHandled; } /* * Checks if DataNodes associated with DataInteractors point back to them. * If not remove the DataInteractors. (This can happen when s.o. tries to set DataNodes to multiple DataInteractors) */ void mitk::Dispatcher::RemoveOrphanedInteractors() { for (ListInteractorType::iterator it = m_Interactors.begin(); it != m_Interactors.end();) { DataNode::Pointer dn = (*it)->GetDataNode(); if (dn.IsNull()) { it = m_Interactors.erase(it); } else { DataInteractor::Pointer interactor = dn->GetDataInteractor(); if (interactor != it->GetPointer()) { it = m_Interactors.erase(it); } else { ++it; } } } } void mitk::Dispatcher::QueueEvent(InteractionEvent* event) { m_QueuedEvents.push_back(event); } void mitk::Dispatcher::SetEventProcessingMode(DataInteractor::Pointer dataInteractor) { m_ProcessingMode = dataInteractor->GetMode(); if (dataInteractor->GetMode() != REGULAR) { m_SelectedInteractor = dataInteractor; } } bool mitk::Dispatcher::HandleInternalEvent(InternalEvent* internalEvent) { if (internalEvent->GetSignalName() == IntDeactivateMe && internalEvent->GetTargetInteractor() != NULL) { internalEvent->GetTargetInteractor()->GetDataNode()->SetDataInteractor(NULL); internalEvent->GetTargetInteractor()->SetDataNode(NULL); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); return true; } return false; } diff --git a/Core/Code/Interactions/mitkEventMapper.cpp b/Core/Code/Interactions/mitkEventMapper.cpp index 23515bdbaf..82db98a890 100644 --- a/Core/Code/Interactions/mitkEventMapper.cpp +++ b/Core/Code/Interactions/mitkEventMapper.cpp @@ -1,710 +1,706 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ /** * EventMapping: * This class maps the Events, usually given by the OS or here by QT, to a MITK internal EventId. * It loads all information from the xml-file (possible, understandable Events with the mitkEventID). * If an event appears, the method MapEvent is called with the event params. * This Method looks up the event params, and tries to find an mitkEventId to it. * If yes, then sends the event and the found ID to the globalStateMachine, which handles all * further operations of that event. * */ #include "mitkEventMapper.h" #include "mitkInteractionConst.h" #include "mitkStateEvent.h" #include "mitkOperationEvent.h" #include "mitkGlobalInteraction.h" #include #include "mitkStandardFileLocations.h" //#include #include "mitkConfig.h" #include "mitkCoreObjectFactory.h" #include #include #include #include // us #include "mitkModule.h" #include "mitkModuleResource.h" #include "mitkModuleResourceStream.h" #include "mitkModuleRegistry.h" #include #include namespace mitk { vtkStandardNewMacro(EventMapper); } #ifdef MBI_INTERNAL_CONFERENCE #include #include #include #include #include #endif //MBI_INTERNAL_CONFERENCE //XML Event const std::string mitk::EventMapper::STYLE = "STYLE"; const std::string mitk::EventMapper::NAME = "NAME"; const std::string mitk::EventMapper::ID = "ID"; const std::string mitk::EventMapper::TYPE = "TYPE"; const std::string mitk::EventMapper::BUTTON = "BUTTON"; const std::string mitk::EventMapper::BUTTONSTATE = "BUTTONSTATE"; const std::string mitk::EventMapper::KEY = "KEY"; const std::string mitk::EventMapper::EVENTS = "events"; const std::string mitk::EventMapper::EVENT = "event"; mitk::EventMapper::EventDescriptionVec mitk::EventMapper::m_EventDescriptions; std::string mitk::EventMapper::m_XmlFileName; mitk::StateEvent mitk::EventMapper::m_StateEvent; std::string mitk::EventMapper::m_StyleName; struct ltstr { bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; mitk::EventMapper::EventMapper() { //map with string to key for mapping string from xml-file to int m_EventConstMap["Type_None"] = mitk::Type_None; // invalid event m_EventConstMap["Type_Timer"] = mitk::Type_Timer; // timer event m_EventConstMap["Type_MouseButtonPress"] = mitk::Type_MouseButtonPress; // mouse button pressed m_EventConstMap["Type_MouseButtonRelease"] = mitk::Type_MouseButtonRelease; // mouse button released m_EventConstMap["Type_MouseButtonDblClick"] = mitk::Type_MouseButtonDblClick; // mouse button double click m_EventConstMap["Type_MouseMove"] = mitk::Type_MouseMove; // mouse move m_EventConstMap["Type_KeyPress"] = mitk::Type_KeyPress; // key pressed m_EventConstMap["Type_KeyRelease"] = mitk::Type_KeyRelease; // key released m_EventConstMap["Type_FocusIn"] = 8; // keyboard focus received m_EventConstMap["Type_FocusOut"] = 9; // keyboard focus lost m_EventConstMap["Type_Enter"] = 10; // mouse enters widget m_EventConstMap["Type_Leave"] = 11; // mouse leaves widget m_EventConstMap["Type_Paint"] = 12; // paint widget m_EventConstMap["Type_Move"] = 13; // move widget m_EventConstMap["Type_Resize"] = 14; // resize widget m_EventConstMap["Type_Create"] = 15; // after object creation m_EventConstMap["Type_Destroy"] = 16; // during object destruction m_EventConstMap["Type_Show"] = 17; // widget is shown m_EventConstMap["Type_Hide"] = 18; // widget is hidden m_EventConstMap["Type_Close"] = 19; // request to close widget m_EventConstMap["Type_Quit"] = 20; // request to quit application m_EventConstMap["Type_Reparent"] = 21; // widget has been reparented m_EventConstMap["Type_ShowMinimized"] = 22; // widget is shown minimized m_EventConstMap["Type_ShowNormal"] = 23; // widget is shown normal m_EventConstMap["Type_WindowActivate"] = 24; // window was activated m_EventConstMap["Type_WindowDeactivate"] = 25; // window was deactivated m_EventConstMap["Type_ShowToParent"] = 26; // widget is shown to parent m_EventConstMap["Type_HideToParent"] = 27; // widget is hidden to parent m_EventConstMap["Type_ShowMaximized"] = 28; // widget is shown maximized m_EventConstMap["Type_ShowFullScreen"] = 29; // widget is shown full-screen m_EventConstMap["Type_Accel"] = 30; // accelerator event m_EventConstMap["Type_Wheel"] = 31; // wheel event m_EventConstMap["Type_AccelAvailable"] = 32; // accelerator available event m_EventConstMap["Type_CaptionChange"] = 33; // caption changed m_EventConstMap["Type_IconChange"] = 34; // icon changed m_EventConstMap["Type_ParentFontChange"] = 35; // parent font changed m_EventConstMap["Type_ApplicationFontChange"] = 36;// application font changed m_EventConstMap["Type_ParentPaletteChange"] = 37; // parent palette changed m_EventConstMap["Type_ApplicationPaletteChange"] = 38;// application palette changed m_EventConstMap["Type_PaletteChange"] = 39; // widget palette changed m_EventConstMap["Type_Clipboard"] = 40; // internal clipboard event m_EventConstMap["Type_Speech"] = 42; // reserved for speech input m_EventConstMap["Type_SockAct"] = 50; // socket activation m_EventConstMap["Type_AccelOverride"] = 51; // accelerator override event m_EventConstMap["Type_DeferredDelete"] = 52; // deferred delete event m_EventConstMap["Type_DragEnter"] = 60; // drag moves into widget m_EventConstMap["Type_DragMove"] = 61; // drag moves in widget m_EventConstMap["Type_DragLeave"] = 62; // drag leaves or is cancelled m_EventConstMap["Type_Drop"] = 63; // actual drop m_EventConstMap["Type_DragResponse"] = 64; // drag accepted/rejected m_EventConstMap["Type_ChildInserted"] = 70; // new child widget m_EventConstMap["Type_ChildRemoved"] = 71; // deleted child widget m_EventConstMap["Type_LayoutHint"] = 72; // child min/max size changed m_EventConstMap["Type_ShowWindowRequest"] = 73; // widget's window should be mapped m_EventConstMap["Type_ActivateControl"] = 80; // ActiveX activation m_EventConstMap["Type_DeactivateControl"] = 81; // ActiveX deactivation m_EventConstMap["Type_ContextMenu"] = 82; // context popup menu m_EventConstMap["Type_IMStart"] = 83; // input method composition start m_EventConstMap["Type_IMCompose"] = 84; // input method composition m_EventConstMap["Type_IMEnd"] = 85; // input method composition end m_EventConstMap["Type_Accessibility"] = 86; // accessibility information is requested m_EventConstMap["Type_TabletMove"] = 87; // Wacom tablet event m_EventConstMap["Type_LocaleChange"] = 88; // the system locale changed m_EventConstMap["Type_LanguageChange"] = 89; // the application language changed m_EventConstMap["Type_LayoutDirectionChange"] = 90; // the layout direction changed m_EventConstMap["Type_Style"] = 91; // internal style event m_EventConstMap["Type_TabletPress"] = 92; // tablet press m_EventConstMap["Type_TabletRelease"] = 93; // tablet release // apparently not necessary, since the IDs can be assigned earlier (in the AddOns after they are generated in the driver) //m_EventConstMap["Type_TDMouseInput"] = mitk::Type_TDMouseInput; // 3D mouse input occured m_EventConstMap["Type_User"] = 1000; // first user event id m_EventConstMap["Type_MaxUser"] = 65535; // last user event id //ButtonState m_EventConstMap["BS_NoButton"] = mitk::BS_NoButton;//0x0000 m_EventConstMap["BS_LeftButton"] = mitk::BS_LeftButton;//0x0001 m_EventConstMap["BS_RightButton"] = mitk::BS_RightButton;//0x0002 m_EventConstMap["BS_MidButton"] = mitk::BS_MidButton;//0x0004 m_EventConstMap["BS_MouseButtonMask"] = mitk::BS_MouseButtonMask;//0x0007 m_EventConstMap["BS_ShiftButton"] = mitk::BS_ShiftButton;//0x0008 m_EventConstMap["BS_ControlButton"] = mitk::BS_ControlButton;//0x0010 m_EventConstMap["BS_AltButton"] = mitk::BS_AltButton;//0x0020 m_EventConstMap["BS_KeyButtonMask"] = mitk::BS_KeyButtonMask;//0x0038 m_EventConstMap["BS_Keypad"] = mitk::BS_Keypad;//0x4000 //Modifier m_EventConstMap["Mod_SHIFT"] = 0x00200000; m_EventConstMap["Mod_CTRL"] = 0x00400000; m_EventConstMap["Mod_ALT"] = 0x00800000; m_EventConstMap["Mod_MODIFIER_MASK"] = 0x00e00000; m_EventConstMap["Mod_UNICODE_ACCEL"] = 0x10000000; m_EventConstMap["Mod_ASCII_ACCEL"] = 0x10000000; //Key m_EventConstMap["Key_Escape"] = 0x1000; m_EventConstMap["Key_Tab"] = 0x1001; m_EventConstMap["Key_Backtab"] = 0x1002; m_EventConstMap["Key_BackTab"] = 0x1002; m_EventConstMap["Key_Backspace"] = 0x1003; m_EventConstMap["Key_BackSpace"] = 0x1003; m_EventConstMap["Key_Return"] = 0x1004; m_EventConstMap["Key_Enter"] = 0x1005; m_EventConstMap["Key_Insert"] = 0x1006; m_EventConstMap["Key_Delete"] = 0x1007; m_EventConstMap["Key_Pause"] = 0x1008; m_EventConstMap["Key_Print"] = 0x1009; m_EventConstMap["Key_SysReq"] = 0x100a; m_EventConstMap["Key_Home"] = 0x1010; m_EventConstMap["Key_End"] = 0x1011; m_EventConstMap["Key_Left"] = 0x1012; m_EventConstMap["Key_Up"] = 0x1013; m_EventConstMap["Key_Right"] = 0x1014; m_EventConstMap["Key_Down"] = 0x1015; m_EventConstMap["Key_Prior"] = 0x1016; m_EventConstMap["Key_PageUp"] = 0x1016; m_EventConstMap["Key_Next"] = 0x1017; m_EventConstMap["Key_PageDown"] = 0x1017; m_EventConstMap["Key_Shift"] = 0x1020; m_EventConstMap["Key_Control"] = 0x1021; m_EventConstMap["Key_Meta"] = 0x1022; m_EventConstMap["Key_Alt"] = 0x1023; m_EventConstMap["Key_CapsLock"] = 0x1024; m_EventConstMap["Key_NumLock"] = 0x1025; m_EventConstMap["Key_ScrollLock"] = 0x1026; m_EventConstMap["Key_F1"] = 0x1030; m_EventConstMap["Key_F2"] = 0x1031; m_EventConstMap["Key_F3"] = 0x1032; m_EventConstMap["Key_F4"] = 0x1033; m_EventConstMap["Key_F5"] = 0x1034; m_EventConstMap["Key_F6"] = 0x1035; m_EventConstMap["Key_F7"] = 0x1036; m_EventConstMap["Key_F8"] = 0x1037; m_EventConstMap["Key_F9"] = 0x1038; m_EventConstMap["Key_F10"] = 0x1039; m_EventConstMap["Key_F11"] = 0x103a; m_EventConstMap["Key_F12"] = 0x103b; m_EventConstMap["Key_F13"] = 0x103c; m_EventConstMap["Key_F14"] = 0x103d; m_EventConstMap["Key_F15"] = 0x103e; m_EventConstMap["Key_F16"] = 0x103f; m_EventConstMap["Key_F17"] = 0x1040; m_EventConstMap["Key_F18"] = 0x1041; m_EventConstMap["Key_F19"] = 0x1042; m_EventConstMap["Key_F20"] = 0x1043; m_EventConstMap["Key_F21"] = 0x1044; m_EventConstMap["Key_F22"] = 0x1045; m_EventConstMap["Key_F23"] = 0x1046; m_EventConstMap["Key_F24"] = 0x1047; m_EventConstMap["Key_F25"] = 0x1048; m_EventConstMap["Key_F26"] = 0x1049; m_EventConstMap["Key_F27"] = 0x104a; m_EventConstMap["Key_F28"] = 0x104b; m_EventConstMap["Key_F29"] = 0x104c; m_EventConstMap["Key_F30"] = 0x104d; m_EventConstMap["Key_F31"] = 0x104e; m_EventConstMap["Key_F32"] = 0x104f; m_EventConstMap["Key_F33"] = 0x1050; m_EventConstMap["Key_F34"] = 0x1051; m_EventConstMap["Key_F35"] = 0x1052; m_EventConstMap["Key_Super_L"] = 0x1053; m_EventConstMap["Key_Super_R"] = 0x1054; m_EventConstMap["Key_Menu"] = 0x1055; m_EventConstMap["Key_Hyper_L"] = 0x1056; m_EventConstMap["Key_Hyper_R"] = 0x1057; m_EventConstMap["Key_Help"] = 0x1058; m_EventConstMap["Key_Muhenkan"] = 0x1122; m_EventConstMap["Key_Henkan"] = 0x1123; m_EventConstMap["Key_Hiragana_Katakana"] = 0x1127; m_EventConstMap["Key_Zenkaku_Hankaku"] = 0x112A; m_EventConstMap["Key_Space"] = 0x20; m_EventConstMap["Key_Any"] = 0x20; m_EventConstMap["Key_Exclam"] = 0x21; m_EventConstMap["Key_QuoteDbl"] = 0x22; m_EventConstMap["Key_NumberSign"] = 0x23; m_EventConstMap["Key_Dollar"] = 0x24; m_EventConstMap["Key_Percent"] = 0x25; m_EventConstMap["Key_Ampersand"] = 0x26; m_EventConstMap["Key_Apostrophe"] = 0x27; m_EventConstMap["Key_ParenLeft"] = 0x28; m_EventConstMap["Key_ParenRight"] = 0x29; m_EventConstMap["Key_Asterisk"] = 0x2a; m_EventConstMap["Key_Plus"] = 0x2b; m_EventConstMap["Key_Comma"] = 0x2c; m_EventConstMap["Key_Minus"] = 0x2d; m_EventConstMap["Key_Period"] = 0x2e; m_EventConstMap["Key_Slash"] = 0x2f; m_EventConstMap["Key_0"] = 0x30; m_EventConstMap["Key_1"] = 0x31; m_EventConstMap["Key_2"] = 0x32; m_EventConstMap["Key_3"] = 0x33; m_EventConstMap["Key_4"] = 0x34; m_EventConstMap["Key_5"] = 0x35; m_EventConstMap["Key_6"] = 0x36; m_EventConstMap["Key_7"] = 0x37; m_EventConstMap["Key_8"] = 0x38; m_EventConstMap["Key_9"] = 0x39; m_EventConstMap["Key_Colon"] = 0x3a; m_EventConstMap["Key_Semicolon"] = 0x3b; m_EventConstMap["Key_Less"] = 0x3c; m_EventConstMap["Key_Equal"] = 0x3d; m_EventConstMap["Key_Greater"] = 0x3e; m_EventConstMap["Key_Question"] = 0x3f; m_EventConstMap["Key_At"] = 0x40; m_EventConstMap["Key_A"] = 0x41; m_EventConstMap["Key_B"] = 0x42; m_EventConstMap["Key_C"] = 0x43; m_EventConstMap["Key_D"] = 0x44; m_EventConstMap["Key_E"] = 0x45; m_EventConstMap["Key_F"] = 0x46; m_EventConstMap["Key_G"] = 0x47; m_EventConstMap["Key_H"] = 0x48; m_EventConstMap["Key_I"] = 0x49; m_EventConstMap["Key_J"] = 0x4a; m_EventConstMap["Key_K"] = 0x4b; m_EventConstMap["Key_L"] = 0x4c; m_EventConstMap["Key_M"] = 0x4d; m_EventConstMap["Key_N"] = 0x4e; m_EventConstMap["Key_O"] = 0x4f; m_EventConstMap["Key_P"] = 0x50; m_EventConstMap["Key_Q"] = 0x51; m_EventConstMap["Key_R"] = 0x52; m_EventConstMap["Key_S"] = 0x53; m_EventConstMap["Key_T"] = 0x54; m_EventConstMap["Key_U"] = 0x55; m_EventConstMap["Key_V"] = 0x56; m_EventConstMap["Key_W"] = 0x57; m_EventConstMap["Key_X"] = 0x58; m_EventConstMap["Key_Y"] = 0x59; m_EventConstMap["Key_Z"] = 0x5a; m_EventConstMap["Key_BracketLeft"] = 0x5b; m_EventConstMap["Key_Backslash"] = 0x5c; m_EventConstMap["Key_BracketRight"] = 0x5d; m_EventConstMap["Key_AsciiCircum"] = 0x5e; m_EventConstMap["Key_Underscore"] = 0x5f; m_EventConstMap["Key_QuoteLeft"] = 0x60; m_EventConstMap["Key_BraceLeft"] = 0x7b; m_EventConstMap["Key_Bar"] = 0x7c; m_EventConstMap["Key_BraceRight"] = 0x7d; m_EventConstMap["Key_AsciiTilde"] = 0x7e; m_EventConstMap["Key_nobreakspace"] = 0x0a0; m_EventConstMap["Key_exclamdown"] = 0x0a1; m_EventConstMap["Key_cent"] = 0x0a2; m_EventConstMap["Key_sterling"] = 0x0a3; m_EventConstMap["Key_currency"] = 0x0a4; m_EventConstMap["Key_yen"] = 0x0a5; m_EventConstMap["Key_brokenbar"] = 0x0a6; m_EventConstMap["Key_section"] = 0x0a7; m_EventConstMap["Key_diaeresis"] = 0x0a8; m_EventConstMap["Key_copyright"] = 0x0a9; m_EventConstMap["Key_ordfeminine"] = 0x0aa; m_EventConstMap["Key_guillemotleft"] = 0x0ab; m_EventConstMap["Key_notsign"] = 0x0ac; m_EventConstMap["Key_hyphen"] = 0x0ad; m_EventConstMap["Key_registered"] = 0x0ae; m_EventConstMap["Key_macron"] = 0x0af; m_EventConstMap["Key_degree"] = 0x0b0; m_EventConstMap["Key_plusminus"] = 0x0b1; m_EventConstMap["Key_twosuperior"] = 0x0b2; m_EventConstMap["Key_threesuperior"] = 0x0b3; m_EventConstMap["Key_acute"] = 0x0b4; m_EventConstMap["Key_mu"] = 0x0b5; m_EventConstMap["Key_paragraph"] = 0x0b6; m_EventConstMap["Key_periodcentered"] = 0x0b7; m_EventConstMap["Key_cedilla"] = 0x0b8; m_EventConstMap["Key_onesuperior"] = 0x0b9; m_EventConstMap["Key_masculine"] = 0x0ba; m_EventConstMap["Key_guillemotright"] = 0x0bb; m_EventConstMap["Key_onequarter"] = 0x0bc; m_EventConstMap["Key_onehalf"] = 0x0bd; m_EventConstMap["Key_threequarters"] = 0x0be; m_EventConstMap["Key_questiondown"] = 0x0bf; m_EventConstMap["Key_Agrave"] = 0x0c0; m_EventConstMap["Key_Aacute"] = 0x0c1; m_EventConstMap["Key_Acircumflex"] = 0x0c2; m_EventConstMap["Key_Atilde"] = 0x0c3; m_EventConstMap["Key_Adiaeresis"] = 0x0c4; m_EventConstMap["Key_Aring"] = 0x0c5; m_EventConstMap["Key_AE"] = 0x0c6; m_EventConstMap["Key_Ccedilla"] = 0x0c7; m_EventConstMap["Key_Egrave"] = 0x0c8; m_EventConstMap["Key_Eacute"] = 0x0c9; m_EventConstMap["Key_Ecircumflex"] = 0x0ca; m_EventConstMap["Key_Ediaeresis"] = 0x0cb; m_EventConstMap["Key_Igrave"] = 0x0cc; m_EventConstMap["Key_Iacute"] = 0x0cd; m_EventConstMap["Key_Icircumflex"] = 0x0ce; m_EventConstMap["Key_Idiaeresis"] = 0x0cf; m_EventConstMap["Key_ETH"] = 0x0d0; m_EventConstMap["Key_Ntilde"] = 0x0d1; m_EventConstMap["Key_Ograve"] = 0x0d2; m_EventConstMap["Key_Oacute"] = 0x0d3; m_EventConstMap["Key_Ocircumflex"] = 0x0d4; m_EventConstMap["Key_Otilde"] = 0x0d5; m_EventConstMap["Key_Odiaeresis"] = 0x0d6; m_EventConstMap["Key_multiply"] = 0x0d7; m_EventConstMap["Key_Ooblique"] = 0x0d8; m_EventConstMap["Key_Ugrave"] = 0x0d9; m_EventConstMap["Key_Uacute"] = 0x0da; m_EventConstMap["Key_Ucircumflex"] = 0x0db; m_EventConstMap["Key_Udiaeresis"] = 0x0dc; m_EventConstMap["Key_Yacute"] = 0x0dd; m_EventConstMap["Key_THORN"] = 0x0de; m_EventConstMap["Key_ssharp"] = 0x0df; m_EventConstMap["Key_agrave"] = 0x0e0; m_EventConstMap["Key_aacute"] = 0x0e1; m_EventConstMap["Key_acircumflex"] = 0x0e2; m_EventConstMap["Key_atilde"] = 0x0e3; m_EventConstMap["Key_adiaeresis"] = 0x0e4; m_EventConstMap["Key_aring"] = 0x0e5; m_EventConstMap["Key_ae"] = 0x0e6; m_EventConstMap["Key_ccedilla"] = 0x0e7; m_EventConstMap["Key_egrave"] = 0x0e8; m_EventConstMap["Key_eacute"] = 0x0e9; m_EventConstMap["Key_ecircumflex"] = 0x0ea; m_EventConstMap["Key_ediaeresis"] = 0x0eb; m_EventConstMap["Key_igrave"] = 0x0ec; m_EventConstMap["Key_iacute"] = 0x0ed; m_EventConstMap["Key_icircumflex"] = 0x0ee; m_EventConstMap["Key_idiaeresis"] = 0x0ef; m_EventConstMap["Key_eth"] = 0x0f0; m_EventConstMap["Key_ntilde"] = 0x0f1; m_EventConstMap["Key_ograve"] = 0x0f2; m_EventConstMap["Key_oacute"] = 0x0f3; m_EventConstMap["Key_ocircumflex"] = 0x0f4; m_EventConstMap["Key_otilde"] = 0x0f5; m_EventConstMap["Key_odiaeresis"] = 0x0f6; m_EventConstMap["Key_division"] = 0x0f7; m_EventConstMap["Key_oslash"] = 0x0f8; m_EventConstMap["Key_ugrave"] = 0x0f9; m_EventConstMap["Key_uacute"] = 0x0fa; m_EventConstMap["Key_ucircumflex"] = 0x0fb; m_EventConstMap["Key_udiaeresis"] = 0x0fc; m_EventConstMap["Key_yacute"] = 0x0fd; m_EventConstMap["Key_thorn"] = 0x0fe; m_EventConstMap["Key_ydiaeresis"] = 0x0ff; m_EventConstMap["Key_unknown"] = 0xffff; m_EventConstMap["Key_none"] = 0xffff; } mitk::EventMapper::~EventMapper() { } //##Documentation //## searches for the event in m_EventDescription and adds the corresponding eventID //## bool mitk::EventMapper::MapEvent(Event* event, GlobalInteraction* globalInteraction, int mitkPostedEventID ) { int eventID = mitkPostedEventID; if( mitkPostedEventID == 0 ) { //search the event in the list of event descriptions, if found, then take the number and produce a stateevent EventDescriptionVecIter iter; for (iter = m_EventDescriptions.begin(); iter!=m_EventDescriptions.end();iter++) { if (*iter == *event) break; } if (iter == m_EventDescriptions.end())//not found return false; eventID = (*iter).GetId(); } //set the Menger_Var m_StateEvent and send to StateMachine, which does everything further! m_StateEvent.Set( eventID, event ); /* Group and Object EventId: then EventMapper has the power to decide which operations hang together; each event causes n (n e N) operations (e.g. StateChanges, data-operations...). Undo must recall all these coherent operations, so all of the same objectId. But Undo has also the power to recall more operationsets, for example a set for building up a new object, so that a newly build up object is deleted after a Undo and not only the latest set point. The StateMachines::ExecuteAction have the power to descide weather a new GroupID has to be calculated (by example after the editing of a new object) A user interaction with the mouse is started by a mousePressEvent, continues with a MouseMove and finishes with a MouseReleaseEvent */ switch (event->GetType()) { case mitk::Type_MouseButtonPress://Increase mitk::OperationEvent::IncCurrObjectEventId(); break; case mitk::Type_MouseMove://same break; case mitk::Type_MouseButtonRelease://same break; case mitk::Type_User://same break; case mitk::Type_KeyPress://Increase mitk::OperationEvent::IncCurrObjectEventId(); break; default://increase mitk::OperationEvent::IncCurrObjectEventId(); } #ifdef MBI_INTERNAL_CONFERENCE //Conference - pass local events through if ( mitkPostedEventID == 0 ) { mitk::CoreObjectFactory::GetInstance()->MapEvent(event,eventID); } #endif //MBI_INTERNAL_CONFERENCE mitk::OperationEvent::ExecuteIncrement(); if ( globalInteraction != NULL ) { return globalInteraction->HandleEvent( &m_StateEvent ); } else { return mitk::GlobalInteraction::GetInstance()->HandleEvent(&m_StateEvent); } } bool mitk::EventMapper::LoadBehavior(std::string fileName) { if ( fileName.empty() ) return false; if (m_XmlFileName.length() > 0) { if (fileName.compare(m_XmlFileName) == 0) return true; // this is nothing bad, we already loaded this file. } this->SetFileName( fileName.c_str() ); m_XmlFileName = fileName.c_str(); return ( this->Parse() ); } bool mitk::EventMapper::LoadBehaviorString(std::string xmlString) { if ( xmlString.empty() ) return false; return ( this->Parse(xmlString.c_str(), xmlString.length()) ); } bool mitk::EventMapper::LoadStandardBehavior() { - Module* module = GetModuleContext()->GetModule(); - if (module == NULL) { - mitkThrow()<< ("Module context unavailable." ); - return false; - } + Module* module = ModuleRegistry::GetModule("Mitk"); ModuleResource resource = module->GetResource("Interactions/Legacy/StateMachine.xml"); if (!resource.IsValid()) { mitkThrow()<< ("Resource not valid. State machine pattern not found:Interactions/Legacy/StateMachine.xml" ); } mitk::ModuleResourceStream stream(resource); - this->SetStream(&stream); - return this->Parse(); + std::string patternString((std::istreambuf_iterator(stream)), std::istreambuf_iterator()); + return this->LoadBehaviorString(patternString); } //##Documentation //## @brief converts the given const String declared in the xml-file //## to the defined const int inline int mitk::EventMapper::convertConstString2ConstInt(std::string input) { ConstMapIter tempIt = m_EventConstMap.find(input.c_str()); if (tempIt != m_EventConstMap.end()) { return (tempIt)->second; } //mitk::StatusBar::GetInstance()->DisplayText("Warning! from mitkEventMapper.cpp: Couldn't find matching Event Int from Event String in XML-File"); return -1;//for didn't find anything } void mitk::EventMapper::StartElement (const char *elementName, const char **atts) { if ( elementName == EVENT ) { // EventDescription(int type, int button, int buttonState,int key, std::string name, int id) EventDescription eventDescr( convertConstString2ConstInt( ReadXMLStringAttribut( TYPE, atts )), convertConstString2ConstInt( ReadXMLStringAttribut( BUTTON, atts )), ReadXMLIntegerAttribut( BUTTONSTATE, atts ), convertConstString2ConstInt( ReadXMLStringAttribut( KEY, atts )), ReadXMLStringAttribut( NAME, atts ), ReadXMLIntegerAttribut( ID, atts )); //check for a double entry unless it is an event for internal usage if (eventDescr.GetType()!= mitk::Type_User) { for (EventDescriptionVecIter iter = m_EventDescriptions.begin(); iter!=m_EventDescriptions.end(); iter++) { if (*iter == eventDescr) { MITK_DEBUG << "Event description " << eventDescr.GetName() << " already present! Skipping event description"; return; } } } m_EventDescriptions.push_back(eventDescr); } else if ( elementName == EVENTS ) m_StyleName = ReadXMLStringAttribut( STYLE, atts ); } std::string mitk::EventMapper::GetStyleName() const { return m_StyleName; } std::string mitk::EventMapper::ReadXMLStringAttribut( std::string name, const char** atts ) { if(atts) { const char** attsIter = atts; while(*attsIter) { if ( name == *attsIter ) { attsIter++; return *attsIter; } attsIter++; attsIter++; } } return std::string(); } int mitk::EventMapper::ReadXMLIntegerAttribut( std::string name, const char** atts ) { std::string s = ReadXMLStringAttribut( name, atts ); static const std::string hex = "0x"; int result; if ( s[0] == hex[0] && s[1] == hex[1] ) result = strtol( s.c_str(), NULL, 16 ); else result = atoi( s.c_str() ); return result; } void mitk::EventMapper::SetStateEvent(mitk::Event* event) { m_StateEvent.Set( m_StateEvent.GetId(), event ); } bool mitk::EventMapper::RefreshStateEvent(mitk::StateEvent* stateEvent) { //search the event within stateEvent in the list of event descriptions, if found adapt stateEvent ID EventDescriptionVecIter iter; for (iter = m_EventDescriptions.begin(); iter!=m_EventDescriptions.end(); iter++) { if (*iter == *(stateEvent->GetEvent())) break; } if (iter != m_EventDescriptions.end())//found { stateEvent->Set((*iter).GetId(), stateEvent->GetEvent()); return true; } else return false; return false; } void mitk::EventMapper::AddEventMapperAddOn(mitk::EventMapperAddOn* newAddOn) { bool addOnAlreadyAdded = false; for(AddOnVectorType::const_iterator it = this->m_AddOnVector.begin();it != m_AddOnVector.end();it++) { if(*it == newAddOn) { addOnAlreadyAdded = true; break; } } if(!addOnAlreadyAdded) { m_AddOnVector.push_back(newAddOn); MITK_INFO << "AddOn Count: " << m_AddOnVector.size(); } } void mitk::EventMapper::RemoveEventMapperAddOn(mitk::EventMapperAddOn* unusedAddOn) { for(AddOnVectorType::iterator it = this->m_AddOnVector.begin();it != m_AddOnVector.end();it++) { if(*it == unusedAddOn) { m_AddOnVector.erase(it); break; } } } diff --git a/Core/Code/Rendering/mitkBaseRenderer.cpp b/Core/Code/Rendering/mitkBaseRenderer.cpp index d6c516ed04..0e1015498e 100644 --- a/Core/Code/Rendering/mitkBaseRenderer.cpp +++ b/Core/Code/Rendering/mitkBaseRenderer.cpp @@ -1,835 +1,835 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkBaseRenderer.h" #include "mitkMapper.h" #include "mitkResliceMethodProperty.h" // Geometries #include "mitkPlaneGeometry.h" #include "mitkSlicedGeometry3D.h" // Controllers #include "mitkCameraController.h" #include "mitkSliceNavigationController.h" #include "mitkCameraRotationController.h" #include "mitkVtkInteractorCameraController.h" #ifdef MITK_USE_TD_MOUSE #include "mitkTDMouseVtkCameraController.h" #else #include "mitkCameraController.h" #endif #include "mitkVtkLayerController.h" // Events // TODO: INTERACTION_LEGACY #include "mitkEventMapper.h" #include "mitkGlobalInteraction.h" #include "mitkPositionEvent.h" #include "mitkDisplayPositionEvent.h" #include "mitkProperties.h" #include "mitkWeakPointerProperty.h" #include "mitkInteractionConst.h" // VTK #include #include #include #include #include #include #include mitk::BaseRenderer::BaseRendererMapType mitk::BaseRenderer::baseRendererMap; mitk::BaseRenderer* mitk::BaseRenderer::GetInstance(vtkRenderWindow * renWin) { for (BaseRendererMapType::iterator mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); mapit++) { if ((*mapit).first == renWin) return (*mapit).second; } return NULL; } void mitk::BaseRenderer::AddInstance(vtkRenderWindow* renWin, BaseRenderer* baseRenderer) { if (renWin == NULL || baseRenderer == NULL) return; // ensure that no BaseRenderer is managed twice mitk::BaseRenderer::RemoveInstance(renWin); baseRendererMap.insert(BaseRendererMapType::value_type(renWin, baseRenderer)); } void mitk::BaseRenderer::RemoveInstance(vtkRenderWindow* renWin) { BaseRendererMapType::iterator mapit = baseRendererMap.find(renWin); if (mapit != baseRendererMap.end()) baseRendererMap.erase(mapit); } mitk::BaseRenderer* mitk::BaseRenderer::GetByName(const std::string& name) { for (BaseRendererMapType::iterator mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); mapit++) { if ((*mapit).second->m_Name == name) return (*mapit).second; } return NULL; } vtkRenderWindow* mitk::BaseRenderer::GetRenderWindowByName(const std::string& name) { for (BaseRendererMapType::iterator mapit = baseRendererMap.begin(); mapit != baseRendererMap.end(); mapit++) { if ((*mapit).second->m_Name == name) return (*mapit).first; } return NULL; } mitk::BaseRenderer::BaseRenderer(const char* name, vtkRenderWindow * renWin, mitk::RenderingManager* rm) : m_RenderWindow(NULL), m_VtkRenderer(NULL), m_MapperID(defaultMapper), m_DataStorage(NULL), m_RenderingManager(rm), m_LastUpdateTime(0), m_CameraController( NULL), m_SliceNavigationController(NULL), m_CameraRotationController(NULL), /*m_Size(),*/ m_Focused(false), m_WorldGeometry(NULL), m_TimeSlicedWorldGeometry(NULL), m_CurrentWorldGeometry(NULL), m_CurrentWorldGeometry2D(NULL), m_DisplayGeometry( NULL), m_Slice(0), m_TimeStep(), m_CurrentWorldGeometry2DUpdateTime(), m_DisplayGeometryUpdateTime(), m_TimeStepUpdateTime(), m_WorldGeometryData( NULL), m_DisplayGeometryData(NULL), m_CurrentWorldGeometry2DData(NULL), m_WorldGeometryNode(NULL), m_DisplayGeometryNode(NULL), m_CurrentWorldGeometry2DNode( NULL), m_DisplayGeometryTransformTime(0), m_CurrentWorldGeometry2DTransformTime(0), m_Name(name), /*m_Bounds(),*/m_EmptyWorldGeometry( true), m_DepthPeelingEnabled(true), m_MaxNumberOfPeels(100), m_NumberOfVisibleLODEnabledMappers(0) { m_Bounds[0] = 0; m_Bounds[1] = 0; m_Bounds[2] = 0; m_Bounds[3] = 0; m_Bounds[4] = 0; m_Bounds[5] = 0; if (name != NULL) { m_Name = name; } else { m_Name = "unnamed renderer"; itkWarningMacro(<< "Created unnamed renderer. Bad for serialization. Please choose a name."); } if (renWin != NULL) { m_RenderWindow = renWin; m_RenderWindow->Register(NULL); } else { itkWarningMacro(<< "Created mitkBaseRenderer without vtkRenderWindow present."); } m_Size[0] = 0; m_Size[1] = 0; //instances.insert( this ); //adding this BaseRenderer to the List of all BaseRenderer // TODO: INTERACTION_LEGACY m_RenderingManager->GetGlobalInteraction()->AddFocusElement(this); m_BindDispatcherInteractor = new mitk::BindDispatcherInteractor(); WeakPointerProperty::Pointer rendererProp = WeakPointerProperty::New((itk::Object*) this); m_CurrentWorldGeometry2D = mitk::PlaneGeometry::New(); m_CurrentWorldGeometry2DData = mitk::Geometry2DData::New(); m_CurrentWorldGeometry2DData->SetGeometry2D(m_CurrentWorldGeometry2D); m_CurrentWorldGeometry2DNode = mitk::DataNode::New(); m_CurrentWorldGeometry2DNode->SetData(m_CurrentWorldGeometry2DData); m_CurrentWorldGeometry2DNode->GetPropertyList()->SetProperty("renderer", rendererProp); m_CurrentWorldGeometry2DNode->GetPropertyList()->SetProperty("layer", IntProperty::New(1000)); m_CurrentWorldGeometry2DNode->SetProperty("reslice.thickslices", mitk::ResliceMethodProperty::New()); m_CurrentWorldGeometry2DNode->SetProperty("reslice.thickslices.num", mitk::IntProperty::New(1)); m_CurrentWorldGeometry2DTransformTime = m_CurrentWorldGeometry2DNode->GetVtkTransform()->GetMTime(); m_DisplayGeometry = mitk::DisplayGeometry::New(); m_DisplayGeometry->SetWorldGeometry(m_CurrentWorldGeometry2D); m_DisplayGeometryData = mitk::Geometry2DData::New(); m_DisplayGeometryData->SetGeometry2D(m_DisplayGeometry); m_DisplayGeometryNode = mitk::DataNode::New(); m_DisplayGeometryNode->SetData(m_DisplayGeometryData); m_DisplayGeometryNode->GetPropertyList()->SetProperty("renderer", rendererProp); m_DisplayGeometryTransformTime = m_DisplayGeometryNode->GetVtkTransform()->GetMTime(); mitk::SliceNavigationController::Pointer sliceNavigationController = mitk::SliceNavigationController::New("navigation"); sliceNavigationController->SetRenderer(this); sliceNavigationController->ConnectGeometrySliceEvent(this); sliceNavigationController->ConnectGeometryUpdateEvent(this); sliceNavigationController->ConnectGeometryTimeEvent(this, false); m_SliceNavigationController = sliceNavigationController; m_CameraRotationController = mitk::CameraRotationController::New(); m_CameraRotationController->SetRenderWindow(m_RenderWindow); m_CameraRotationController->AcquireCamera(); //if TD Mouse Interaction is activated, then call TDMouseVtkCameraController instead of VtkInteractorCameraController #ifdef MITK_USE_TD_MOUSE m_CameraController = mitk::TDMouseVtkCameraController::New(); #else m_CameraController = mitk::CameraController::New(NULL); #endif m_VtkRenderer = vtkRenderer::New(); if (mitk::VtkLayerController::GetInstance(m_RenderWindow) == NULL) { mitk::VtkLayerController::AddInstance(m_RenderWindow, m_VtkRenderer); mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertSceneRenderer(m_VtkRenderer); } else mitk::VtkLayerController::GetInstance(m_RenderWindow)->InsertSceneRenderer(m_VtkRenderer); } mitk::BaseRenderer::~BaseRenderer() { if (m_VtkRenderer != NULL) { m_VtkRenderer->Delete(); m_VtkRenderer = NULL; } if (m_CameraController.IsNotNull()) m_CameraController->SetRenderer(NULL); m_RenderingManager->GetGlobalInteraction()->RemoveFocusElement(this); mitk::VtkLayerController::RemoveInstance(m_RenderWindow); RemoveAllLocalStorages(); m_DataStorage = NULL; if (m_BindDispatcherInteractor != NULL) { delete m_BindDispatcherInteractor; } if (m_RenderWindow != NULL) { m_RenderWindow->Delete(); m_RenderWindow = NULL; } } void mitk::BaseRenderer::RemoveAllLocalStorages() { this->InvokeEvent(mitk::BaseRenderer::RendererResetEvent()); std::list::iterator it; for (it = m_RegisteredLocalStorageHandlers.begin(); it != m_RegisteredLocalStorageHandlers.end(); it++) (*it)->ClearLocalStorage(this, false); m_RegisteredLocalStorageHandlers.clear(); } void mitk::BaseRenderer::RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh) { m_RegisteredLocalStorageHandlers.push_back(lsh); } -mitk::Dispatcher::Pointer mitk::BaseRenderer::GetDispatcher() const +mitk::Dispatcher::Pointer mitk::BaseRenderer::GetDispatcher() { return m_BindDispatcherInteractor->GetDispatcher(); } mitk::Point3D mitk::BaseRenderer::Map2DRendererPositionTo3DWorldPosition(Point2D* mousePosition) const { Point2D p_mm; Point3D position; if (m_MapperID == 1) { GetDisplayGeometry()->ULDisplayToDisplay(*mousePosition, *mousePosition); GetDisplayGeometry()->DisplayToWorld(*mousePosition, p_mm); GetDisplayGeometry()->Map(p_mm, position); } else if (m_MapperID == 2) { GetDisplayGeometry()->ULDisplayToDisplay(*mousePosition, *mousePosition); PickWorldPoint(*mousePosition, position); } return position; } void mitk::BaseRenderer::UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh) { m_RegisteredLocalStorageHandlers.remove(lsh); } void mitk::BaseRenderer::SetDataStorage(DataStorage* storage) { if (storage != NULL) { m_DataStorage = storage; m_BindDispatcherInteractor->SetDataStorage(m_DataStorage); this->Modified(); } } const mitk::BaseRenderer::MapperSlotId mitk::BaseRenderer::defaultMapper = 1; void mitk::BaseRenderer::Paint() { } void mitk::BaseRenderer::Initialize() { } void mitk::BaseRenderer::Resize(int w, int h) { m_Size[0] = w; m_Size[1] = h; if (m_CameraController) m_CameraController->Resize(w, h); //(formerly problematic on windows: vtkSizeBug) GetDisplayGeometry()->SetSizeInDisplayUnits(w, h); } void mitk::BaseRenderer::InitRenderer(vtkRenderWindow* renderwindow) { if (m_RenderWindow != NULL) { m_RenderWindow->Delete(); } m_RenderWindow = renderwindow; if (m_RenderWindow != NULL) { m_RenderWindow->Register(NULL); } RemoveAllLocalStorages(); if (m_CameraController.IsNotNull()) { m_CameraController->SetRenderer(this); } //BUG (#1551) added settings for depth peeling m_RenderWindow->SetAlphaBitPlanes(1); m_VtkRenderer->SetUseDepthPeeling(m_DepthPeelingEnabled); m_VtkRenderer->SetMaximumNumberOfPeels(m_MaxNumberOfPeels); m_VtkRenderer->SetOcclusionRatio(0.1); } void mitk::BaseRenderer::InitSize(int w, int h) { m_Size[0] = w; m_Size[1] = h; GetDisplayGeometry()->SetSizeInDisplayUnits(w, h, false); GetDisplayGeometry()->Fit(); } void mitk::BaseRenderer::SetSlice(unsigned int slice) { if (m_Slice != slice) { m_Slice = slice; if (m_TimeSlicedWorldGeometry.IsNotNull()) { SlicedGeometry3D* slicedWorldGeometry = dynamic_cast(m_TimeSlicedWorldGeometry->GetGeometry3D(m_TimeStep)); if (slicedWorldGeometry != NULL) { if (m_Slice >= slicedWorldGeometry->GetSlices()) m_Slice = slicedWorldGeometry->GetSlices() - 1; SetCurrentWorldGeometry2D(slicedWorldGeometry->GetGeometry2D(m_Slice)); SetCurrentWorldGeometry(slicedWorldGeometry); } } else Modified(); } } void mitk::BaseRenderer::SetTimeStep(unsigned int timeStep) { if (m_TimeStep != timeStep) { m_TimeStep = timeStep; m_TimeStepUpdateTime.Modified(); if (m_TimeSlicedWorldGeometry.IsNotNull()) { if (m_TimeStep >= m_TimeSlicedWorldGeometry->GetTimeSteps()) m_TimeStep = m_TimeSlicedWorldGeometry->GetTimeSteps() - 1; SlicedGeometry3D* slicedWorldGeometry = dynamic_cast(m_TimeSlicedWorldGeometry->GetGeometry3D(m_TimeStep)); if (slicedWorldGeometry != NULL) { SetCurrentWorldGeometry2D(slicedWorldGeometry->GetGeometry2D(m_Slice)); SetCurrentWorldGeometry(slicedWorldGeometry); } } else Modified(); } } int mitk::BaseRenderer::GetTimeStep(const mitk::BaseData* data) const { if ((data == NULL) || (data->IsInitialized() == false)) { return -1; } return data->GetTimeSlicedGeometry()->MSToTimeStep(GetTime()); } mitk::ScalarType mitk::BaseRenderer::GetTime() const { if (m_TimeSlicedWorldGeometry.IsNull()) { return 0; } else { ScalarType timeInMS = m_TimeSlicedWorldGeometry->TimeStepToMS(GetTimeStep()); if (timeInMS == ScalarTypeNumericTraits::NonpositiveMin()) return 0; else return timeInMS; } } void mitk::BaseRenderer::SetWorldGeometry(mitk::Geometry3D* geometry) { itkDebugMacro("setting WorldGeometry to " << geometry); if (m_WorldGeometry != geometry) { if (geometry->GetBoundingBox()->GetDiagonalLength2() == 0) return; m_WorldGeometry = geometry; m_TimeSlicedWorldGeometry = dynamic_cast(geometry); SlicedGeometry3D* slicedWorldGeometry; if (m_TimeSlicedWorldGeometry.IsNotNull()) { itkDebugMacro("setting TimeSlicedWorldGeometry to " << m_TimeSlicedWorldGeometry); if (m_TimeStep >= m_TimeSlicedWorldGeometry->GetTimeSteps()) m_TimeStep = m_TimeSlicedWorldGeometry->GetTimeSteps() - 1; slicedWorldGeometry = dynamic_cast(m_TimeSlicedWorldGeometry->GetGeometry3D(m_TimeStep)); } else { slicedWorldGeometry = dynamic_cast(geometry); } Geometry2D::Pointer geometry2d; if (slicedWorldGeometry != NULL) { if (m_Slice >= slicedWorldGeometry->GetSlices() && (m_Slice != 0)) m_Slice = slicedWorldGeometry->GetSlices() - 1; geometry2d = slicedWorldGeometry->GetGeometry2D(m_Slice); if (geometry2d.IsNull()) { PlaneGeometry::Pointer plane = mitk::PlaneGeometry::New(); plane->InitializeStandardPlane(slicedWorldGeometry); geometry2d = plane; } SetCurrentWorldGeometry(slicedWorldGeometry); } else { geometry2d = dynamic_cast(geometry); if (geometry2d.IsNull()) { PlaneGeometry::Pointer plane = PlaneGeometry::New(); plane->InitializeStandardPlane(geometry); geometry2d = plane; } SetCurrentWorldGeometry(geometry); } SetCurrentWorldGeometry2D(geometry2d); // calls Modified() } if (m_CurrentWorldGeometry2D.IsNull()) itkWarningMacro("m_CurrentWorldGeometry2D is NULL"); } void mitk::BaseRenderer::SetDisplayGeometry(mitk::DisplayGeometry* geometry2d) { itkDebugMacro("setting DisplayGeometry to " << geometry2d); if (m_DisplayGeometry != geometry2d) { m_DisplayGeometry = geometry2d; m_DisplayGeometryData->SetGeometry2D(m_DisplayGeometry); m_DisplayGeometryUpdateTime.Modified(); Modified(); } } void mitk::BaseRenderer::SetCurrentWorldGeometry2D(mitk::Geometry2D* geometry2d) { if (m_CurrentWorldGeometry2D != geometry2d) { m_CurrentWorldGeometry2D = geometry2d; m_CurrentWorldGeometry2DData->SetGeometry2D(m_CurrentWorldGeometry2D); m_DisplayGeometry->SetWorldGeometry(m_CurrentWorldGeometry2D); m_CurrentWorldGeometry2DUpdateTime.Modified(); Modified(); } } void mitk::BaseRenderer::SendUpdateSlice() { m_DisplayGeometryUpdateTime.Modified(); m_CurrentWorldGeometry2DUpdateTime.Modified(); } void mitk::BaseRenderer::SetCurrentWorldGeometry(mitk::Geometry3D* geometry) { m_CurrentWorldGeometry = geometry; if (geometry == NULL) { m_Bounds[0] = 0; m_Bounds[1] = 0; m_Bounds[2] = 0; m_Bounds[3] = 0; m_Bounds[4] = 0; m_Bounds[5] = 0; m_EmptyWorldGeometry = true; return; } BoundingBox::Pointer boundingBox = m_CurrentWorldGeometry->CalculateBoundingBoxRelativeToTransform(NULL); const BoundingBox::BoundsArrayType& worldBounds = boundingBox->GetBounds(); m_Bounds[0] = worldBounds[0]; m_Bounds[1] = worldBounds[1]; m_Bounds[2] = worldBounds[2]; m_Bounds[3] = worldBounds[3]; m_Bounds[4] = worldBounds[4]; m_Bounds[5] = worldBounds[5]; if (boundingBox->GetDiagonalLength2() <= mitk::eps) m_EmptyWorldGeometry = true; else m_EmptyWorldGeometry = false; } void mitk::BaseRenderer::SetGeometry(const itk::EventObject & geometrySendEvent) { const SliceNavigationController::GeometrySendEvent* sendEvent = dynamic_cast(&geometrySendEvent); assert(sendEvent!=NULL); SetWorldGeometry(sendEvent->GetTimeSlicedGeometry()); } void mitk::BaseRenderer::UpdateGeometry(const itk::EventObject & geometryUpdateEvent) { const SliceNavigationController::GeometryUpdateEvent* updateEvent = dynamic_cast(&geometryUpdateEvent); if (updateEvent == NULL) return; if (m_CurrentWorldGeometry.IsNotNull()) { SlicedGeometry3D* slicedWorldGeometry = dynamic_cast(m_CurrentWorldGeometry.GetPointer()); if (slicedWorldGeometry) { Geometry2D* geometry2D = slicedWorldGeometry->GetGeometry2D(m_Slice); SetCurrentWorldGeometry2D(geometry2D); // calls Modified() } } } void mitk::BaseRenderer::SetGeometrySlice(const itk::EventObject & geometrySliceEvent) { const SliceNavigationController::GeometrySliceEvent* sliceEvent = dynamic_cast(&geometrySliceEvent); assert(sliceEvent!=NULL); SetSlice(sliceEvent->GetPos()); } void mitk::BaseRenderer::SetGeometryTime(const itk::EventObject & geometryTimeEvent) { const SliceNavigationController::GeometryTimeEvent * timeEvent = dynamic_cast(&geometryTimeEvent); assert(timeEvent!=NULL); SetTimeStep(timeEvent->GetPos()); } const double* mitk::BaseRenderer::GetBounds() const { return m_Bounds; } void mitk::BaseRenderer::MousePressEvent(mitk::MouseEvent *me) { //set the Focus on the renderer /*bool success =*/m_RenderingManager->GetGlobalInteraction()->SetFocus(this); /* if (! success) mitk::StatusBar::GetInstance()->DisplayText("Warning! from mitkBaseRenderer.cpp: Couldn't focus this BaseRenderer!"); */ //if (m_CameraController) //{ // if(me->GetButtonState()!=512) // provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine // m_CameraController->MousePressEvent(me); //} if (m_MapperID == 1) { Point2D p(me->GetDisplayPosition()); Point2D p_mm; Point3D position; GetDisplayGeometry()->ULDisplayToDisplay(p, p); GetDisplayGeometry()->DisplayToWorld(p, p_mm); GetDisplayGeometry()->Map(p_mm, position); mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position); mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction()); } else if (m_MapperID > 1) //==2 for 3D and ==5 for stencil { Point2D p(me->GetDisplayPosition()); GetDisplayGeometry()->ULDisplayToDisplay(p, p); me->SetDisplayPosition(p); mitk::EventMapper::MapEvent(me, m_RenderingManager->GetGlobalInteraction()); } } void mitk::BaseRenderer::MouseReleaseEvent(mitk::MouseEvent *me) { //if (m_CameraController) //{ // if(me->GetButtonState()!=512) // provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine // m_CameraController->MouseReleaseEvent(me); //} if (m_MapperID == 1) { Point2D p(me->GetDisplayPosition()); Point2D p_mm; Point3D position; GetDisplayGeometry()->ULDisplayToDisplay(p, p); GetDisplayGeometry()->DisplayToWorld(p, p_mm); GetDisplayGeometry()->Map(p_mm, position); mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position); mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction()); } else if (m_MapperID == 2) { Point2D p(me->GetDisplayPosition()); GetDisplayGeometry()->ULDisplayToDisplay(p, p); me->SetDisplayPosition(p); mitk::EventMapper::MapEvent(me, m_RenderingManager->GetGlobalInteraction()); } } void mitk::BaseRenderer::MouseMoveEvent(mitk::MouseEvent *me) { //if (m_CameraController) //{ // if((me->GetButtonState()<=512) || (me->GetButtonState()>=516))// provisorisch: Ctrl nicht durchlassen. Bald wird aus m_CameraController eine StateMachine // m_CameraController->MouseMoveEvent(me); //} if (m_MapperID == 1) { Point2D p(me->GetDisplayPosition()); Point2D p_mm; Point3D position; GetDisplayGeometry()->ULDisplayToDisplay(p, p); GetDisplayGeometry()->DisplayToWorld(p, p_mm); GetDisplayGeometry()->Map(p_mm, position); mitk::PositionEvent event(this, me->GetType(), me->GetButton(), me->GetButtonState(), mitk::Key_unknown, p, position); mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction()); } else if (m_MapperID == 2) { Point2D p(me->GetDisplayPosition()); GetDisplayGeometry()->ULDisplayToDisplay(p, p); me->SetDisplayPosition(p); mitk::EventMapper::MapEvent(me, m_RenderingManager->GetGlobalInteraction()); } } void mitk::BaseRenderer::PickWorldPoint(const mitk::Point2D& displayPoint, mitk::Point3D& worldPoint) const { mitk::Point2D worldPoint2D; GetDisplayGeometry()->DisplayToWorld(displayPoint, worldPoint2D); GetDisplayGeometry()->Map(worldPoint2D, worldPoint); } void mitk::BaseRenderer::WheelEvent(mitk::WheelEvent * we) { if (m_MapperID == 1) { Point2D p(we->GetDisplayPosition()); Point2D p_mm; Point3D position; GetDisplayGeometry()->ULDisplayToDisplay(p, p); GetDisplayGeometry()->DisplayToWorld(p, p_mm); GetDisplayGeometry()->Map(p_mm, position); mitk::PositionEvent event(this, we->GetType(), we->GetButton(), we->GetButtonState(), mitk::Key_unknown, p, position); mitk::EventMapper::MapEvent(we, m_RenderingManager->GetGlobalInteraction()); mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction()); } else if (m_MapperID == 2) { Point2D p(we->GetDisplayPosition()); GetDisplayGeometry()->ULDisplayToDisplay(p, p); we->SetDisplayPosition(p); mitk::EventMapper::MapEvent(we, m_RenderingManager->GetGlobalInteraction()); } } void mitk::BaseRenderer::KeyPressEvent(mitk::KeyEvent *ke) { if (m_MapperID == 1) { Point2D p(ke->GetDisplayPosition()); Point2D p_mm; Point3D position; GetDisplayGeometry()->ULDisplayToDisplay(p, p); GetDisplayGeometry()->DisplayToWorld(p, p_mm); GetDisplayGeometry()->Map(p_mm, position); mitk::KeyEvent event(this, ke->GetType(), ke->GetButton(), ke->GetButtonState(), ke->GetKey(), ke->GetText(), p); mitk::EventMapper::MapEvent(&event, m_RenderingManager->GetGlobalInteraction()); } else if (m_MapperID == 2) { Point2D p(ke->GetDisplayPosition()); GetDisplayGeometry()->ULDisplayToDisplay(p, p); ke->SetDisplayPosition(p); mitk::EventMapper::MapEvent(ke, m_RenderingManager->GetGlobalInteraction()); } } void mitk::BaseRenderer::DrawOverlayMouse(mitk::Point2D& itkNotUsed(p2d)) { MITK_INFO<<"BaseRenderer::DrawOverlayMouse()- should be inconcret implementation OpenGLRenderer."<RequestUpdate(this->m_RenderWindow); } void mitk::BaseRenderer::ForceImmediateUpdate() { m_RenderingManager->ForceImmediateUpdate(this->m_RenderWindow); } unsigned int mitk::BaseRenderer::GetNumberOfVisibleLODEnabledMappers() const { return m_NumberOfVisibleLODEnabledMappers; } mitk::RenderingManager* mitk::BaseRenderer::GetRenderingManager() const { return m_RenderingManager.GetPointer(); } /*! Sets the new Navigation controller */ void mitk::BaseRenderer::SetSliceNavigationController(mitk::SliceNavigationController *SlicenavigationController) { if (SlicenavigationController == NULL) return; //disconnect old from globalinteraction m_RenderingManager->GetGlobalInteraction()->RemoveListener(SlicenavigationController); //copy worldgeometry SlicenavigationController->SetInputWorldGeometry(SlicenavigationController->GetCreatedWorldGeometry()); SlicenavigationController->Update(); //set new m_SliceNavigationController = SlicenavigationController; m_SliceNavigationController->SetRenderer(this); if (m_SliceNavigationController.IsNotNull()) { m_SliceNavigationController->ConnectGeometrySliceEvent(this); m_SliceNavigationController->ConnectGeometryUpdateEvent(this); m_SliceNavigationController->ConnectGeometryTimeEvent(this, false); } } /*! Sets the new camera controller and deletes the vtkRenderWindowInteractor in case of the VTKInteractorCameraController */ void mitk::BaseRenderer::SetCameraController(CameraController* cameraController) { mitk::VtkInteractorCameraController::Pointer vtkInteractorCameraController = dynamic_cast(cameraController); if (vtkInteractorCameraController.IsNotNull()) MITK_INFO<<"!!!WARNING!!!: RenderWindow interaction events are no longer handled via CameraController (See Bug #954)."<SetRenderer(NULL); m_CameraController = NULL; m_CameraController = cameraController; m_CameraController->SetRenderer(this); } void mitk::BaseRenderer::PrintSelf(std::ostream& os, itk::Indent indent) const { os << indent << " MapperID: " << m_MapperID << std::endl; os << indent << " Slice: " << m_Slice << std::endl; os << indent << " TimeStep: " << m_TimeStep << std::endl; os << indent << " WorldGeometry: "; if (m_WorldGeometry.IsNull()) os << "NULL" << std::endl; else m_WorldGeometry->Print(os, indent); os << indent << " CurrentWorldGeometry2D: "; if (m_CurrentWorldGeometry2D.IsNull()) os << "NULL" << std::endl; else m_CurrentWorldGeometry2D->Print(os, indent); os << indent << " CurrentWorldGeometry2DUpdateTime: " << m_CurrentWorldGeometry2DUpdateTime << std::endl; os << indent << " CurrentWorldGeometry2DTransformTime: " << m_CurrentWorldGeometry2DTransformTime << std::endl; os << indent << " DisplayGeometry: "; if (m_DisplayGeometry.IsNull()) os << "NULL" << std::endl; else m_DisplayGeometry->Print(os, indent); os << indent << " DisplayGeometryTransformTime: " << m_DisplayGeometryTransformTime << std::endl; Superclass::PrintSelf(os, indent); } void mitk::BaseRenderer::SetDepthPeelingEnabled(bool enabled) { m_DepthPeelingEnabled = enabled; m_VtkRenderer->SetUseDepthPeeling(enabled); } void mitk::BaseRenderer::SetMaxNumberOfPeels(int maxNumber) { m_MaxNumberOfPeels = maxNumber; m_VtkRenderer->SetMaximumNumberOfPeels(maxNumber); } diff --git a/Core/Code/Rendering/mitkBaseRenderer.h b/Core/Code/Rendering/mitkBaseRenderer.h index be2274f90e..db2f18f4ba 100644 --- a/Core/Code/Rendering/mitkBaseRenderer.h +++ b/Core/Code/Rendering/mitkBaseRenderer.h @@ -1,611 +1,611 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 #define BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 #include "mitkDataStorage.h" #include "mitkGeometry2D.h" #include "mitkTimeSlicedGeometry.h" #include "mitkDisplayGeometry.h" #include "mitkGeometry2DData.h" #include "mitkCameraController.h" #include "mitkDisplayPositionEvent.h" #include "mitkWheelEvent.h" //#include "mitkMapper.h" #include "mitkSliceNavigationController.h" #include "mitkCameraController.h" #include "mitkCameraRotationController.h" #include "mitkBindDispatcherInteractor.h" #include "mitkDispatcher.h" #include #include #include #include namespace mitk { class NavigationController; class SliceNavigationController; class CameraRotationController; class CameraController; class DataStorage; class Mapper; class BaseLocalStorageHandler; //##Documentation //## @brief Organizes the rendering process //## //## Organizes the rendering process. A Renderer contains a reference to a //## DataStorage and asks the mappers of the data objects to render //## the data into the renderwindow it is associated to. //## //## \#Render() checks if rendering is currently allowed by calling //## RenderWindow::PrepareRendering(). Initialization of a rendering context //## can also be performed in this method. //## //## The actual rendering code has been moved to \#Repaint() //## Both \#Repaint() and \#Update() are declared protected now. //## //## Note: Separation of the Repaint and Update processes (rendering vs //## creating a vtk prop tree) still needs to be worked on. The whole //## rendering process also should be reworked to use VTK based classes for //## both 2D and 3D rendering. //## @ingroup Renderer class MITK_CORE_EXPORT BaseRenderer: public itk::Object { public: typedef std::map BaseRendererMapType; static BaseRendererMapType baseRendererMap; static BaseRenderer* GetInstance(vtkRenderWindow * renWin); static void AddInstance(vtkRenderWindow* renWin, BaseRenderer* baseRenderer); static void RemoveInstance(vtkRenderWindow* renWin); static BaseRenderer* GetByName(const std::string& name); static vtkRenderWindow* GetRenderWindowByName(const std::string& name); #pragma GCC visibility push(default) itkEventMacro( RendererResetEvent, itk::AnyEvent ); #pragma GCC visibility pop /** Standard class typedefs. */ mitkClassMacro(BaseRenderer, itk::Object); BaseRenderer(const char* name = NULL, vtkRenderWindow * renWin = NULL, mitk::RenderingManager* rm = NULL); //##Documentation //## @brief MapperSlotId defines which kind of mapper (e.g., 2D or 3D) shoud be used. typedef int MapperSlotId; enum StandardMapperSlot { Standard2D = 1, Standard3D = 2 }; virtual void SetDataStorage(DataStorage* storage); ///< set the datastorage that will be used for rendering //##Documentation //## return the DataStorage that is used for rendering virtual DataStorage::Pointer GetDataStorage() const { return m_DataStorage.GetPointer(); } //##Documentation //## @brief Access the RenderWindow into which this renderer renders. vtkRenderWindow* GetRenderWindow() const { return m_RenderWindow; } vtkRenderer* GetVtkRenderer() const { return m_VtkRenderer; } //##Documentation //## @brief Returns the Dispatcher which handles Events for this BaseRenderer - Dispatcher::Pointer GetDispatcher() const; + Dispatcher::Pointer GetDispatcher(); //##Documentation //## @brief Default mapper id to use. static const MapperSlotId defaultMapper; //##Documentation //## @brief Do the rendering and flush the result. virtual void Paint(); //##Documentation //## @brief Initialize the RenderWindow. Should only be called from RenderWindow. virtual void Initialize(); //##Documentation //## @brief Called to inform the renderer that the RenderWindow has been resized. virtual void Resize(int w, int h); //##Documentation //## @brief Initialize the renderer with a RenderWindow (@a renderwindow). virtual void InitRenderer(vtkRenderWindow* renderwindow); //##Documentation //## @brief Set the initial size. Called by RenderWindow after it has become //## visible for the first time. virtual void InitSize(int w, int h); //##Documentation //## @brief Draws a point on the widget. //## Should be used during conferences to show the position of the remote mouse virtual void DrawOverlayMouse(Point2D& p2d); //##Documentation //## @brief Set/Get the WorldGeometry (m_WorldGeometry) for 3D and 2D rendering, that describing the //## (maximal) area to be rendered. //## //## Depending of the type of the passed Geometry3D more or less information can be extracted: //## \li if it is a Geometry2D (which is a sub-class of Geometry3D), m_CurrentWorldGeometry2D is //## also set to point to it. m_TimeSlicedWorldGeometry is set to NULL. //## \li if it is a TimeSlicedGeometry, m_TimeSlicedWorldGeometry is also set to point to it. //## If m_TimeSlicedWorldGeometry contains instances of SlicedGeometry3D, m_CurrentWorldGeometry2D is set to //## one of geometries stored in the SlicedGeometry3D according to the value of m_Slice; otherwise //## a PlaneGeometry describing the top of the bounding-box of the Geometry3D is set as the //## m_CurrentWorldGeometry2D. //## \li otherwise a PlaneGeometry describing the top of the bounding-box of the Geometry3D //## is set as the m_CurrentWorldGeometry2D. m_TimeSlicedWorldGeometry is set to NULL. //## @todo add calculation of PlaneGeometry describing the top of the bounding-box of the Geometry3D //## when the passed Geometry3D is not sliced. //## \sa m_WorldGeometry //## \sa m_TimeSlicedWorldGeometry //## \sa m_CurrentWorldGeometry2D virtual void SetWorldGeometry(Geometry3D* geometry); itkGetConstObjectMacro(WorldGeometry, Geometry3D) //##Documentation //## @brief Get the current 3D-worldgeometry (m_CurrentWorldGeometry) used for 3D-rendering itkGetConstObjectMacro(CurrentWorldGeometry, Geometry3D) //##Documentation //## @brief Get the current 2D-worldgeometry (m_CurrentWorldGeometry2D) used for 2D-rendering itkGetConstObjectMacro(CurrentWorldGeometry2D, Geometry2D) //##Documentation //## Calculates the bounds of the DataStorage (if it contains any valid data), //## creates a geometry from these bounds and sets it as world geometry of the renderer. //## //## Call this method to re-initialize the renderer to the current DataStorage //## (e.g. after loading an additional dataset), to ensure that the view is //## aligned correctly. //## \warn This is not implemented yet. virtual bool SetWorldGeometryToDataStorageBounds() { return false; } //##Documentation //## @brief Set/Get the DisplayGeometry (for 2D rendering) //## //## The DisplayGeometry describes which part of the Geometry2D m_CurrentWorldGeometry2D //## is displayed. virtual void SetDisplayGeometry(DisplayGeometry* geometry2d); itkGetConstObjectMacro(DisplayGeometry, DisplayGeometry) itkGetObjectMacro(DisplayGeometry, DisplayGeometry) //##Documentation //## @brief Set/Get m_Slice which defines together with m_TimeStep the 2D geometry //## stored in m_TimeSlicedWorldGeometry used as m_CurrentWorldGeometry2D //## //## \sa m_Slice virtual void SetSlice(unsigned int slice); itkGetConstMacro(Slice, unsigned int) //##Documentation //## @brief Set/Get m_TimeStep which defines together with m_Slice the 2D geometry //## stored in m_TimeSlicedWorldGeometry used as m_CurrentWorldGeometry2D //## //## \sa m_TimeStep virtual void SetTimeStep(unsigned int timeStep); itkGetConstMacro(TimeStep, unsigned int) //##Documentation //## @brief Get the time-step of a BaseData object which //## exists at the time of the currently displayed content //## //## Returns -1 or mitk::BaseData::m_TimeSteps if there //## is no data at the current time. //## \sa GetTimeStep, m_TimeStep int GetTimeStep(const BaseData* data) const; //##Documentation //## @brief Get the time in ms of the currently displayed content //## //## \sa GetTimeStep, m_TimeStep ScalarType GetTime() const; //##Documentation //## @brief SetWorldGeometry is called according to the geometrySliceEvent, //## which is supposed to be a SliceNavigationController::GeometrySendEvent virtual void SetGeometry(const itk::EventObject & geometrySliceEvent); //##Documentation //## @brief UpdateWorldGeometry is called to re-read the 2D geometry from the //## slice navigation controller virtual void UpdateGeometry(const itk::EventObject & geometrySliceEvent); //##Documentation //## @brief SetSlice is called according to the geometrySliceEvent, //## which is supposed to be a SliceNavigationController::GeometrySliceEvent virtual void SetGeometrySlice(const itk::EventObject & geometrySliceEvent); //##Documentation //## @brief SetTimeStep is called according to the geometrySliceEvent, //## which is supposed to be a SliceNavigationController::GeometryTimeEvent virtual void SetGeometryTime(const itk::EventObject & geometryTimeEvent); //##Documentation //## @brief Get a data object containing the DisplayGeometry (for 2D rendering) itkGetObjectMacro(DisplayGeometryData, Geometry2DData) //##Documentation //## @brief Get a data object containing the WorldGeometry (for 2D rendering) itkGetObjectMacro(WorldGeometryData, Geometry2DData) //##Documentation //## @brief Get a DataNode pointing to a data object containing the WorldGeometry (3D and 2D rendering) itkGetObjectMacro(WorldGeometryNode, DataNode) //##Documentation //## @brief Get a DataNode pointing to a data object containing the DisplayGeometry (for 2D rendering) itkGetObjectMacro(DisplayGeometryNode, DataNode) //##Documentation //## @brief Get a DataNode pointing to a data object containing the current 2D-worldgeometry m_CurrentWorldGeometry2D (for 2D rendering) itkGetObjectMacro(CurrentWorldGeometry2DNode, DataNode) //##Documentation //## @brief Sets timestamp of CurrentWorldGeometry2D and DisplayGeometry and forces so reslicing in that renderwindow void SendUpdateSlice(); //##Documentation //## @brief Get timestamp of last call of SetCurrentWorldGeometry2D unsigned long GetCurrentWorldGeometry2DUpdateTime() { return m_CurrentWorldGeometry2DUpdateTime; } //##Documentation //## @brief Get timestamp of last call of SetDisplayGeometry unsigned long GetDisplayGeometryUpdateTime() { return m_CurrentWorldGeometry2DUpdateTime; } //##Documentation //## @brief Get timestamp of last change of current TimeStep unsigned long GetTimeStepUpdateTime() { return m_TimeStepUpdateTime; } //##Documentation //## @brief Perform a picking: find the x,y,z world coordinate of a //## display x,y coordinate. //## @warning Has to be overwritten in subclasses for the 3D-case. //## //## Implemented here only for 2D-rendering by using //## m_DisplayGeometry virtual void PickWorldPoint(const Point2D& diplayPosition, Point3D& worldPosition) const; /** \brief Determines the object (mitk::DataNode) closest to the current * position by means of picking * * \warning Implementation currently empty for 2D rendering; intended to be * implemented for 3D renderers */ virtual DataNode* PickObject(const Point2D& /*displayPosition*/, Point3D& /*worldPosition*/) const { return NULL; } //##Documentation //## @brief Get the MapperSlotId to use. itkGetMacro(MapperID, MapperSlotId) itkGetConstMacro(MapperID, MapperSlotId) //##Documentation //## @brief Set the MapperSlotId to use. itkSetMacro(MapperID, MapperSlotId) //##Documentation //## @brief Has the renderer the focus? itkGetMacro(Focused, bool) //##Documentation //## @brief Tell the renderer that it is focused. The caller is responsible for focus management, //## not the renderer itself. itkSetMacro(Focused, bool) //##Documentation //## @brief Sets whether depth peeling is enabled or not void SetDepthPeelingEnabled(bool enabled); //##Documentation //## @brief Sets maximal number of peels void SetMaxNumberOfPeels(int maxNumber); itkGetMacro(Size, int*) void SetSliceNavigationController(SliceNavigationController* SlicenavigationController); void SetCameraController(CameraController* cameraController); itkGetObjectMacro(CameraController, CameraController) itkGetObjectMacro(SliceNavigationController, SliceNavigationController) itkGetObjectMacro(CameraRotationController, CameraRotationController) itkGetMacro(EmptyWorldGeometry, bool) //##Documentation //## @brief Mouse event dispatchers //## @note for internal use only. preliminary. virtual void MousePressEvent(MouseEvent*); //##Documentation //## @brief Mouse event dispatchers //## @note for internal use only. preliminary. virtual void MouseReleaseEvent(MouseEvent*); //##Documentation //## @brief Mouse event dispatchers //## @note for internal use only. preliminary. virtual void MouseMoveEvent(MouseEvent*); //##Documentation //## @brief Wheel event dispatcher //## @note for internal use only. preliminary. virtual void WheelEvent(mitk::WheelEvent* we); //##Documentation //## @brief Key event dispatcher //## @note for internal use only. preliminary. virtual void KeyPressEvent(KeyEvent*); //##Documentation //## @brief get the name of the Renderer //## @note const char * GetName() const { return m_Name.c_str(); } //##Documentation //## @brief get the x_size of the RendererWindow //## @note int GetSizeX() const { return m_Size[0]; } //##Documentation //## @brief get the y_size of the RendererWindow //## @note int GetSizeY() const { return m_Size[1]; } const double* GetBounds() const; void RequestUpdate(); void ForceImmediateUpdate(); /** Returns number of mappers which are visible and have level-of-detail * rendering enabled */ unsigned int GetNumberOfVisibleLODEnabledMappers() const; ///** //* \brief Setter for the RenderingManager that handles this instance of BaseRenderer //*/ //void SetRenderingManager( mitk::RenderingManager* ); /** * \brief Getter for the RenderingManager that handles this instance of BaseRenderer */ virtual mitk::RenderingManager* GetRenderingManager() const; /** * \brief Provides (1) world coordinates for a given mouse position and (2) * translates mousePosition to Display coordinates */ virtual Point3D Map2DRendererPositionTo3DWorldPosition(Point2D* mousePosition) const; protected: virtual ~BaseRenderer(); //##Documentation //## @brief Call update of all mappers. To be implemented in subclasses. virtual void Update() = 0; vtkRenderWindow* m_RenderWindow; vtkRenderer* m_VtkRenderer; //##Documentation //## @brief MapperSlotId to use. Defines which kind of mapper (e.g., 2D or 3D) shoud be used. MapperSlotId m_MapperID; //##Documentation //## @brief The DataStorage that is used for rendering. DataStorage::Pointer m_DataStorage; //##Documentation //## @brief The RenderingManager that manages this instance RenderingManager::Pointer m_RenderingManager; //##Documentation //## @brief Timestamp of last call of Update(). unsigned long m_LastUpdateTime; //##Documentation //## @brief CameraController for 3D rendering //## @note preliminary. CameraController::Pointer m_CameraController; SliceNavigationController::Pointer m_SliceNavigationController; CameraRotationController::Pointer m_CameraRotationController; //##Documentation //## @brief Size of the RenderWindow. int m_Size[2]; //##Documentation //## @brief Contains whether the renderer that it is focused. The caller of //## SetFocused is responsible for focus management, not the renderer itself. //## is doubled because of mitk::FocusManager in GlobalInteraction!!! (ingmar) bool m_Focused; //##Documentation //## @brief Sets m_CurrentWorldGeometry2D virtual void SetCurrentWorldGeometry2D(Geometry2D* geometry2d); //##Documentation //## @brief Sets m_CurrentWorldGeometry virtual void SetCurrentWorldGeometry(Geometry3D* geometry); private: //##Documentation //## Pointer to the worldgeometry, describing the maximal area to be rendered //## (3D as well as 2D). //## It is const, since we are not allowed to change it (it may be taken //## directly from the geometry of an image-slice and thus it would be //## very strange when suddenly the image-slice changes its geometry). //## \sa SetWorldGeometry Geometry3D::Pointer m_WorldGeometry; //##Documentation //## m_TimeSlicedWorldGeometry is set by SetWorldGeometry if the passed Geometry3D is a //## TimeSlicedGeometry (or a sub-class of it). If it contains instances of SlicedGeometry3D, //## m_Slice and m_TimeStep (set via SetSlice and SetTimeStep, respectively) define //## which 2D geometry stored in m_TimeSlicedWorldGeometry (if available) //## is used as m_CurrentWorldGeometry2D. //## \sa m_CurrentWorldGeometry2D TimeSlicedGeometry::Pointer m_TimeSlicedWorldGeometry; //##Documentation //## Pointer to the current 3D-worldgeometry. Geometry3D::Pointer m_CurrentWorldGeometry; //##Documentation //## Pointer to the current 2D-worldgeometry. The 2D-worldgeometry //## describes the maximal area (2D manifold) to be rendered in case we //## are doing 2D-rendering. More precisely, a subpart of this according //## to m_DisplayGeometry is displayed. //## It is const, since we are not allowed to change it (it may be taken //## directly from the geometry of an image-slice and thus it would be //## very strange when suddenly the image-slice changes its geometry). Geometry2D::Pointer m_CurrentWorldGeometry2D; //##Documentation //## Pointer to the displaygeometry. The displaygeometry describes the //## geometry of the \em visible area in the window controlled by the renderer //## in case we are doing 2D-rendering. //## It is const, since we are not allowed to change it. DisplayGeometry::Pointer m_DisplayGeometry; //##Documentation //## Defines together with m_Slice which 2D geometry stored in m_TimeSlicedWorldGeometry //## is used as m_CurrentWorldGeometry2D: m_TimeSlicedWorldGeometry->GetGeometry2D(m_Slice, m_TimeStep). //## \sa m_TimeSlicedWorldGeometry unsigned int m_Slice; //##Documentation //## Defines together with m_TimeStep which 2D geometry stored in m_TimeSlicedWorldGeometry //## is used as m_CurrentWorldGeometry2D: m_TimeSlicedWorldGeometry->GetGeometry2D(m_Slice, m_TimeStep). //## \sa m_TimeSlicedWorldGeometry unsigned int m_TimeStep; //##Documentation //## @brief timestamp of last call of SetWorldGeometry itk::TimeStamp m_CurrentWorldGeometry2DUpdateTime; //##Documentation //## @brief timestamp of last call of SetDisplayGeometry itk::TimeStamp m_DisplayGeometryUpdateTime; //##Documentation //## @brief timestamp of last change of the current time step itk::TimeStamp m_TimeStepUpdateTime; //##Documentation //## @brief Helper class which establishes connection between Interactors and Dispatcher via a common DataStorage. BindDispatcherInteractor* m_BindDispatcherInteractor; protected: virtual void PrintSelf(std::ostream& os, itk::Indent indent) const; //##Documentation //## Data object containing the m_WorldGeometry defined above. Geometry2DData::Pointer m_WorldGeometryData; //##Documentation //## Data object containing the m_DisplayGeometry defined above. Geometry2DData::Pointer m_DisplayGeometryData; //##Documentation //## Data object containing the m_CurrentWorldGeometry2D defined above. Geometry2DData::Pointer m_CurrentWorldGeometry2DData; //##Documentation //## DataNode objects containing the m_WorldGeometryData defined above. DataNode::Pointer m_WorldGeometryNode; //##Documentation //## DataNode objects containing the m_DisplayGeometryData defined above. DataNode::Pointer m_DisplayGeometryNode; //##Documentation //## DataNode objects containing the m_CurrentWorldGeometry2DData defined above. DataNode::Pointer m_CurrentWorldGeometry2DNode; //##Documentation //## @brief test only unsigned long m_DisplayGeometryTransformTime; //##Documentation //## @brief test only unsigned long m_CurrentWorldGeometry2DTransformTime; std::string m_Name; double m_Bounds[6]; bool m_EmptyWorldGeometry; bool m_DepthPeelingEnabled; int m_MaxNumberOfPeels; typedef std::set LODEnabledMappersType; /** Number of mappers which are visible and have level-of-detail * rendering enabled */ unsigned int m_NumberOfVisibleLODEnabledMappers; // Local Storage Handling for mappers protected: std::list m_RegisteredLocalStorageHandlers; public: void RemoveAllLocalStorages(); void RegisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh); void UnregisterLocalStorageHandler(mitk::BaseLocalStorageHandler *lsh); }; } // namespace mitk #endif /* BASERENDERER_H_HEADER_INCLUDED_C1CCA0F4 */ diff --git a/Core/Code/Testing/mitkDispatcherTest.cpp b/Core/Code/Testing/mitkDispatcherTest.cpp index 7e739a819e..7f9f49cc66 100644 --- a/Core/Code/Testing/mitkDispatcherTest.cpp +++ b/Core/Code/Testing/mitkDispatcherTest.cpp @@ -1,120 +1,122 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkStandaloneDataStorage.h" #include "mitkDataNode.h" #include "mitkInteractor.h" #include "mitkDataInteractor.h" #include "mitkVtkPropRenderer.h" +#include "mitkBaseRenderer.h" #include "mitkTestingMacros.h" #include "mitkGlobalInteraction.h" +#include "itkLightObject.h" #include "mitkDispatcher.h" int mitkDispatcherTest(int /*argc*/, char* /*argv*/[]) { MITK_TEST_BEGIN("Dispatcher") /* * Tests the process of creating Interactors and assigning DataNodes to them. * Test checks if these Interactors are added to the Dispatcher under different conditions, * and in different call order. */ // Global interaction must(!) be initialized if used mitk ::GlobalInteraction::GetInstance()->Initialize("global"); // Here BindDispatcherInteractor and Dispatcher should be created automatically vtkRenderWindow* renWin = vtkRenderWindow::New(); mitk::VtkPropRenderer::Pointer renderer = mitk::VtkPropRenderer::New( "ContourRenderer",renWin, mitk::RenderingManager::GetInstance() ); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); mitk::DataNode::Pointer dn = mitk::DataNode::New(); mitk::DataNode::Pointer dn2 = mitk::DataNode::New(); mitk::DataInteractor::Pointer ei = mitk::DataInteractor::New(); mitk::DataInteractor::Pointer ei2 = mitk::DataInteractor::New(); MITK_TEST_CONDITION_REQUIRED( renderer->GetDispatcher()->GetNumberOfInteractors() == 0 , "01 Check Existence of Dispatcher." ); ei->SetDataNode(dn); renderer->SetDataStorage(ds); ds->Add(dn); int num = renderer->GetDispatcher()->GetNumberOfInteractors(); MITK_TEST_CONDITION_REQUIRED( num == 1 , "02 Number of registered Interactors " << num << " , expected 1" ); // This _must not_ result in additionally registered interactors. ei->SetDataNode(dn); ei->SetDataNode(dn); num = renderer->GetDispatcher()->GetNumberOfInteractors(); MITK_TEST_CONDITION_REQUIRED( num == 1 , "03 Number of registered Interactors " << num << " , expected 1" ); // Switching the DataNode of an Interactor also must not result in extra registered Interactors in Dispatcher // since dn2 is not connected to DataStorage // ei will be dropped from dispatcher ei->SetDataNode(dn2); num = renderer->GetDispatcher()->GetNumberOfInteractors(); MITK_TEST_CONDITION_REQUIRED( num == 0 , "04 Number of registered Interactors " << num << " , expected 0" ); // DataNode Added to DataStorage, now Interactor entry in Dispatcher should be replaced, // hence we restore Interactor in the Dispatcher ds->Add(dn2); num = renderer->GetDispatcher()->GetNumberOfInteractors(); MITK_TEST_CONDITION_REQUIRED( num == 1 , "05 Number of registered Interactors " << num << " , expected 1" ); // New DataNode and new interactor, this should result in additional Interactor in the Dispatcher. ei2->SetDataNode(dn); num = renderer->GetDispatcher()->GetNumberOfInteractors(); MITK_TEST_CONDITION_REQUIRED( num == 2 , "06 Number of registered Interactors " << num << " , expected 2" ); // Here ei and ei2 point to the same dn2; dn2 now only points to ei2, so ei is abandoned, // therefore ei1 is expected to be removed ei2->SetDataNode(dn2); num = renderer->GetDispatcher()->GetNumberOfInteractors(); MITK_TEST_CONDITION_REQUIRED( num == 1 , "07 Number of registered Interactors " << num << " , expected 1" ); // Setting DataNode in Interactor to NULL, should remove Interactor from Dispatcher ei2->SetDataNode(NULL); num = renderer->GetDispatcher()->GetNumberOfInteractors(); MITK_TEST_CONDITION_REQUIRED( num == 0 , "08 Number of registered Interactors " << num << " , expected 0" ); renWin->Delete(); // always end with this! MITK_TEST_END() }