diff --git a/Core/Code/Interactions/mitkDisplayInteractor.cpp b/Core/Code/Interactions/mitkDisplayInteractor.cpp index 110296f94b..9fc865c38e 100644 --- a/Core/Code/Interactions/mitkDisplayInteractor.cpp +++ b/Core/Code/Interactions/mitkDisplayInteractor.cpp @@ -1,340 +1,345 @@ /*=================================================================== 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 "mitkDisplayInteractor.h" #include "mitkBaseRenderer.h" #include "mitkInteractionPositionEvent.h" #include "mitkPropertyList.h" #include // level window #include "mitkStandaloneDataStorage.h" #include "mitkNodePredicateDataType.h" #include "mitkLevelWindowProperty.h" #include "mitkLevelWindow.h" void mitk::DisplayInteractor::Notify(InteractionEvent* interactionEvent, bool isHandled) { // to use the state machine pattern, // the event is passed to the state machine interface to be handled if (!isHandled || m_AlwaysReact) { this->HandleEvent(interactionEvent, NULL); } } void mitk::DisplayInteractor::ConnectActionsAndFunctions() { CONNECT_CONDITION( "check_position_event", CheckPositionEvent ); CONNECT_FUNCTION("init", Init); CONNECT_FUNCTION("move", Move); CONNECT_FUNCTION("zoom", Zoom); CONNECT_FUNCTION("scroll", Scroll); CONNECT_FUNCTION("ScrollOneDown", ScrollOneDown); CONNECT_FUNCTION("ScrollOneUp", ScrollOneUp); CONNECT_FUNCTION("levelWindow", AdjustLevelWindow); } mitk::DisplayInteractor::DisplayInteractor() : m_IndexToSliceModifier(4) , m_AutoRepeat(false) , m_AlwaysReact(false) , m_ZoomFactor(2) { m_StartDisplayCoordinate.Fill(0); m_LastDisplayCoordinate.Fill(0); m_CurrentDisplayCoordinate.Fill(0); } mitk::DisplayInteractor::~DisplayInteractor() { } bool mitk::DisplayInteractor::CheckPositionEvent( const InteractionEvent* interactionEvent ) { const InteractionPositionEvent* positionEvent = dynamic_cast(interactionEvent); if (positionEvent == NULL) { return false; } return true; } bool mitk::DisplayInteractor::Init(StateMachineAction*, InteractionEvent* interactionEvent) { BaseRenderer* sender = interactionEvent->GetSender(); InteractionPositionEvent* positionEvent = static_cast(interactionEvent); Vector2D origin = sender->GetDisplayGeometry()->GetOriginInMM(); double scaleFactorMMPerDisplayUnit = sender->GetDisplayGeometry()->GetScaleFactorMMPerDisplayUnit(); m_StartDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); m_LastDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); m_CurrentDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); m_StartCoordinateInMM = mitk::Point2D( (origin + m_StartDisplayCoordinate.GetVectorFromOrigin() * scaleFactorMMPerDisplayUnit).GetDataPointer()); return true; } bool mitk::DisplayInteractor::Move(StateMachineAction*, InteractionEvent* interactionEvent) { BaseRenderer* sender = interactionEvent->GetSender(); InteractionPositionEvent* positionEvent = static_cast(interactionEvent); // perform translation - sender->GetDisplayGeometry()->MoveBy((positionEvent->GetPointerPositionOnScreen() - m_LastDisplayCoordinate) * (-1.0)); + Vector2D offset; + offset[0] = positionEvent->GetPointerPositionOnScreen()[0] - m_LastDisplayCoordinate[0]; + offset[1] = positionEvent->GetPointerPositionOnScreen()[1] - m_LastDisplayCoordinate[1]; + // Invert x-axis since renderwindow has inverted y axis + offset[0]*=-1.0; + sender->GetDisplayGeometry()->MoveBy(offset); sender->GetRenderingManager()->RequestUpdate(sender->GetRenderWindow()); m_LastDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); return true; } bool mitk::DisplayInteractor::Zoom(StateMachineAction*, InteractionEvent* interactionEvent) { const BaseRenderer::Pointer sender = interactionEvent->GetSender(); InteractionPositionEvent* positionEvent = static_cast(interactionEvent); float factor = 1.0; float distance = 0; if (m_ZoomDirection == "updown") { distance = m_CurrentDisplayCoordinate[1] - m_LastDisplayCoordinate[1]; } else { distance = m_CurrentDisplayCoordinate[0] - m_LastDisplayCoordinate[0]; } // set zooming speed - if (distance < 0.0) + if (distance > 0.0) { factor = 1.0 / m_ZoomFactor; } - else if (distance > 0.0) + else if (distance < 0.0) { factor = 1.0 * m_ZoomFactor; } sender->GetDisplayGeometry()->ZoomWithFixedWorldCoordinates(factor, m_StartDisplayCoordinate, m_StartCoordinateInMM); sender->GetRenderingManager()->RequestUpdate(sender->GetRenderWindow()); m_LastDisplayCoordinate = m_CurrentDisplayCoordinate; m_CurrentDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); return true; } bool mitk::DisplayInteractor::Scroll(StateMachineAction*, InteractionEvent* interactionEvent) { InteractionPositionEvent* positionEvent = static_cast(interactionEvent); mitk::SliceNavigationController::Pointer sliceNaviController = interactionEvent->GetSender()->GetSliceNavigationController(); if (sliceNaviController) { int delta = 0; // Scrolling direction if (m_ScrollDirection == "updown") { delta = static_cast(m_LastDisplayCoordinate[1] - positionEvent->GetPointerPositionOnScreen()[1]); } else { delta = static_cast(m_LastDisplayCoordinate[0] - positionEvent->GetPointerPositionOnScreen()[0]); } // Set how many pixels the mouse has to be moved to scroll one slice // if we moved less than 'm_IndexToSliceModifier' pixels slice ONE slice only if (delta > 0 && delta < m_IndexToSliceModifier) { delta = m_IndexToSliceModifier; } else if (delta < 0 && delta > -m_IndexToSliceModifier) { delta = -m_IndexToSliceModifier; } delta /= m_IndexToSliceModifier; int newPos = sliceNaviController->GetSlice()->GetPos() + delta; // if auto repeat is on, start at first slice if you reach the last slice and vice versa int maxSlices = sliceNaviController->GetSlice()->GetSteps(); if (m_AutoRepeat) { while (newPos < 0) { newPos += maxSlices; } while (newPos >= maxSlices) { newPos -= maxSlices; } } else { // if the new slice is below 0 we still show slice 0 // due to the stepper using unsigned int we have to do this ourselves if (newPos < 1) { newPos = 0; } } // set the new position sliceNaviController->GetSlice()->SetPos(newPos); m_LastDisplayCoordinate = m_CurrentDisplayCoordinate; m_CurrentDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); } return true; } bool mitk::DisplayInteractor::ScrollOneDown(StateMachineAction*, InteractionEvent* interactionEvent) { mitk::SliceNavigationController::Pointer sliceNaviController = interactionEvent->GetSender()->GetSliceNavigationController(); if (!sliceNaviController->GetSliceLocked()) { mitk::Stepper* stepper = sliceNaviController->GetSlice(); if (stepper->GetSteps() <= 1) { stepper = sliceNaviController->GetTime(); } stepper->Next(); } return true; } bool mitk::DisplayInteractor::ScrollOneUp(StateMachineAction*, InteractionEvent* interactionEvent) { mitk::SliceNavigationController::Pointer sliceNaviController = interactionEvent->GetSender()->GetSliceNavigationController(); if (!sliceNaviController->GetSliceLocked()) { mitk::Stepper* stepper = sliceNaviController->GetSlice(); if (stepper->GetSteps() <= 1) { stepper = sliceNaviController->GetTime(); } stepper->Previous(); return true; } return false; } bool mitk::DisplayInteractor::AdjustLevelWindow(StateMachineAction*, InteractionEvent* interactionEvent) { BaseRenderer::Pointer sender = interactionEvent->GetSender(); InteractionPositionEvent* positionEvent = static_cast(interactionEvent); m_LastDisplayCoordinate = m_CurrentDisplayCoordinate; m_CurrentDisplayCoordinate = positionEvent->GetPointerPositionOnScreen(); // search for active image mitk::DataStorage::Pointer storage = sender->GetDataStorage(); mitk::DataNode::Pointer node = NULL; mitk::DataStorage::SetOfObjects::ConstPointer allImageNodes = storage->GetSubset(mitk::NodePredicateDataType::New("Image")); for (unsigned int i = 0; i < allImageNodes->size(); i++) { bool isActiveImage = false; bool propFound = allImageNodes->at(i)->GetBoolProperty("imageForLevelWindow", isActiveImage); if (propFound && isActiveImage) { node = allImageNodes->at(i); continue; } } if (node.IsNull()) { node = storage->GetNode(mitk::NodePredicateDataType::New("Image")); } if (node.IsNull()) { return false; } mitk::LevelWindow lv = mitk::LevelWindow(); node->GetLevelWindow(lv); ScalarType level = lv.GetLevel(); ScalarType window = lv.GetWindow(); // calculate adjustments from mouse movements level += (m_CurrentDisplayCoordinate[0] - m_LastDisplayCoordinate[0]) * static_cast(2); window += (m_CurrentDisplayCoordinate[1] - m_LastDisplayCoordinate[1]) * static_cast(2); lv.SetLevelWindow(level, window); dynamic_cast(node->GetProperty("levelwindow"))->SetLevelWindow(lv); sender->GetRenderingManager()->RequestUpdateAll(); return true; } void mitk::DisplayInteractor::ConfigurationChanged() { mitk::PropertyList::Pointer properties = GetAttributes(); // auto repeat std::string strAutoRepeat = ""; if (properties->GetStringProperty("autoRepeat", strAutoRepeat)) { if (strAutoRepeat == "true") { m_AutoRepeat = true; } else { m_AutoRepeat = false; } } // pixel movement for scrolling one slice std::string strPixelPerSlice = ""; if (properties->GetStringProperty("pixelPerSlice", strPixelPerSlice)) { m_IndexToSliceModifier = atoi(strPixelPerSlice.c_str()); } else { m_IndexToSliceModifier = 4; } // scroll direction if (!properties->GetStringProperty("zoomDirection", m_ScrollDirection)) { m_ScrollDirection = "updown"; } // zoom direction if (!properties->GetStringProperty("zoomDirection", m_ZoomDirection)) { m_ZoomDirection = "updown"; } // zoom factor std::string strZoomFactor = ""; properties->GetStringProperty("zoomFactor", strZoomFactor); m_ZoomFactor = .05; if (atoi(strZoomFactor.c_str()) > 0) { m_ZoomFactor = 1.0 + (atoi(strZoomFactor.c_str()) / 100.0); } // allwaysReact std::string strAlwaysReact = ""; if (properties->GetStringProperty("alwaysReact", strAlwaysReact)) { if (strAlwaysReact == "true") { m_AlwaysReact = true; } else { m_AlwaysReact = false; } } else { m_AlwaysReact = false; } } bool mitk::DisplayInteractor::FilterEvents(InteractionEvent* /*interactionEvent*/, DataNode* /*dataNode*/) { return true; } diff --git a/Core/Code/Interactions/mitkEventFactory.cpp b/Core/Code/Interactions/mitkEventFactory.cpp index 59c098cdc2..1c9db30a4b 100755 --- a/Core/Code/Interactions/mitkEventFactory.cpp +++ b/Core/Code/Interactions/mitkEventFactory.cpp @@ -1,507 +1,511 @@ /*=================================================================== 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 "mitkEventFactory.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace { std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } return elems; } std::vector split(const std::string &s, char delim) { std::vector < std::string > elems; return split(s, delim, elems); } } mitk::InteractionEvent::Pointer mitk::EventFactory::CreateEvent(PropertyList::Pointer list) { // std::string eventClass, eventVariant; list->GetStringProperty(InteractionEventConst::xmlParameterEventClass().c_str(), eventClass); list->GetStringProperty(InteractionEventConst::xmlParameterEventVariant().c_str(), eventVariant); // Query all possible attributes, if they are not present, set their default values. // Position Events & Key Events std::string strModifiers; InteractionEvent::ModifierKeys modifiers = InteractionEvent::NoKey; std::string strEventButton; InteractionEvent::MouseButtons eventButton = InteractionEvent::NoButton; std::string strButtonState; InteractionEvent::MouseButtons buttonState = InteractionEvent::NoButton; std::string strKey; std::string key; std::string strWheelDelta; int wheelDelta; std::string strSignalName = ""; Point2D pos; pos.Fill(0); std::string strPos; // Position on screen if( list->GetStringProperty(InteractionEventConst::xmlEventPropertyPositionOnScreen().c_str(), strPos)) { //split comma separated string int commaPos; commaPos = strPos.find_first_of(','); pos[0] = static_cast(std::atof(strPos.substr(0, commaPos).c_str())); pos[1] = static_cast(std::atof(strPos.substr(commaPos+1, strPos.length()).c_str())); } // Parse modifier information if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyModifier().c_str(), strModifiers)) { std::vector mods = split(strModifiers, ','); for (std::vector::iterator it = mods.begin(); it != mods.end(); ++it) { std::transform((*it).begin(), (*it).end(), (*it).begin(), ::toupper); if (*it == "CTRL") { modifiers = modifiers | InteractionEvent::ControlKey; } else if (*it == "ALT") { modifiers = modifiers | InteractionEvent::AltKey; } else if (*it == "SHIFT") { modifiers = modifiers | InteractionEvent::ShiftKey; } else { MITK_WARN<< "mitkEventFactory: Invalid event modifier in config file :" << (*it); } } } // Set EventButton if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyEventButton().c_str(), strEventButton)) { std::transform(strEventButton.begin(), strEventButton.end(), strEventButton.begin(), ::toupper); if (strEventButton == "MIDDLEMOUSEBUTTON") { eventButton = InteractionEvent::MiddleMouseButton; } else if (strEventButton == "LEFTMOUSEBUTTON") { eventButton = InteractionEvent::LeftMouseButton; } else if (strEventButton == "RIGHTMOUSEBUTTON") { eventButton = InteractionEvent::RightMouseButton; } else { MITK_WARN<< "mitkEventFactory: Invalid event button in config file: " << strEventButton; } } // Parse ButtonStates if (list->GetStringProperty(InteractionEventConst::xmlEventPropertyButtonState().c_str(), strButtonState)) { std::vector mods = split(strButtonState, ','); for (std::vector::iterator it = mods.begin(); it != mods.end(); ++it) { std::transform((*it).begin(), (*it).end(), (*it).begin(), ::toupper); if (*it == "MIDDLEMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::MiddleMouseButton; } else if (*it == "LEFTMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::LeftMouseButton; } else if (*it == "RIGHTMOUSEBUTTON") { buttonState = buttonState | InteractionEvent::RightMouseButton; } else { MITK_WARN<< "mitkEventFactory: Invalid event buttonstate in config file:" << (*it); } } } // Key if (!list->GetStringProperty(InteractionEventConst::xmlEventPropertyKey().c_str(), strKey)) { key = ""; } else { key = strKey; } // WheelDelta if (!list->GetStringProperty(InteractionEventConst::xmlEventPropertyScrollDirection().c_str(), strWheelDelta)) { wheelDelta = 0; } else { std::transform(strWheelDelta.begin(), strWheelDelta.end(), strWheelDelta.begin(), ::toupper); if (strWheelDelta == "DOWN") { wheelDelta = -1; } else { wheelDelta = 1; } } // Internal Signals Name list->GetStringProperty(InteractionEventConst::xmlEventPropertySignalName().c_str(), strSignalName); // Get BaseRenderer by name mitk::BaseRenderer* renderer = NULL; std::string strRenderer; if(list->GetStringProperty(mitk::InteractionEventConst::xmlEventPropertyRendererName().c_str(), strRenderer)) { //look up for renderer registered with the name in xml file renderer = mitk::BaseRenderer::GetByName(strRenderer); } /* * Here the objects are created */ mitk::InteractionEvent::Pointer event; std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); if (eventClass == "MOUSEPRESSEVENT") { // buttonstates incorporate the event button (as in Qt) buttonState = buttonState | eventButton; event = MousePressEvent::New(renderer, pos, buttonState, modifiers, eventButton); } else if (eventClass == "MOUSEDOUBLECLICKEVENT") { buttonState = buttonState | eventButton; event = MouseDoubleClickEvent::New(renderer, pos, buttonState, modifiers, eventButton); } else if (eventClass == "MOUSEMOVEEVENT") { event = MouseMoveEvent::New(renderer, pos, buttonState, modifiers); } else if (eventClass == "MOUSERELEASEEVENT") { event = MouseReleaseEvent::New(renderer, pos, buttonState, modifiers, eventButton); } else if (eventClass == "INTERACTIONKEYEVENT") { event = InteractionKeyEvent::New(renderer, key, modifiers); } else if (eventClass == "MOUSEWHEELEVENT") { event = MouseWheelEvent::New(renderer, pos, buttonState, modifiers, wheelDelta); } else if (eventClass == "INTERACTIONPOSITIONEVENT") { event = InteractionPositionEvent::New(renderer, pos); } else if (eventClass == "INTERNALEVENT") { event = InternalEvent::New(renderer, NULL, strSignalName); } else if (eventClass == "INTERACTIONEVENT") { event = InteractionEvent::New(renderer); } if (event.IsNull()) { MITK_WARN<< "Event couldn't be constructed. Please check your StateMachine patterns and config files\n for the following event class, which is not valid: " << eventClass; return NULL; } return event; } std::string mitk::EventFactory::EventToXML(mitk::InteractionEvent *event) { + InternalEvent* ie = dynamic_cast (event); + if (ie != NULL) + return ""; + std::string eventClass = event->GetNameOfClass(); std::string eventXML = "<" + InteractionEventConst::xmlTagEventVariant() + " " + InteractionEventConst::xmlParameterEventClass() + "=\""; std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); eventXML += eventClass + "\" >\n"; // here follow event specific attributes if (eventClass == "MOUSEPRESSEVENT" || eventClass == "MOUSERELEASEEVENT" || eventClass == "MOUSEDOUBLECLICKEVENT" || eventClass == "MOUSEMOVEEVENT" || eventClass == "MOUSEWHEELEVENT") { if (!(eventClass == "MOUSEMOVEEVENT") && !(eventClass == "MOUSEWHEELEVENT")) { // EventButton eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyEventButton() + "\" "; eventXML += InteractionEventConst::xmlParameterValue() + "=\""; eventXML += GetEventButton(event); eventXML += "\"/>\n"; } // ButtonState if (GetButtonState(event) != "") { eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyButtonState() + "\" "; eventXML += InteractionEventConst::xmlParameterValue() + "=\""; eventXML += GetButtonState(event); eventXML += "\"/>\n"; } // Modifiers if (GetModifierState(event) != "") { eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyModifier() + "\" "; eventXML += InteractionEventConst::xmlParameterValue() + "=\""; eventXML += GetModifierState(event); eventXML += "\"/>\n"; } // Position on Screen eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyPositionOnScreen() + "\" "; eventXML += InteractionEventConst::xmlParameterValue() + "=\""; eventXML += GetPositionOnScreen(event); eventXML += "\"/>\n"; // Position in World eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyPositionInWorld() + "\" "; eventXML += InteractionEventConst::xmlParameterValue() + "=\""; eventXML += GetPositionInWorld(event); eventXML += "\"/>\n"; } // TODO Implement Key Events!! // else if (eventClass == "INTERACTIONKEYEVENT") // { // event = InteractionKeyEvent::New(NULL, key, modifiers); // } else { MITK_WARN << "Event not recognized, discarding event of type " << event->GetNameOfClass(); } if (eventClass == "MOUSEWHEELEVENT") { MouseWheelEvent* we = dynamic_cast (event); int delta = we->GetWheelDelta(); std::stringstream ss; ss << delta; eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyWheelDelta() + "\" "; eventXML += InteractionEventConst::xmlParameterValue() + "=\""; eventXML += ss.str(); eventXML += "\"/>\n"; } // Renderer name eventXML += " <" + InteractionEventConst::xmlTagAttribute() +" " + InteractionEventConst::xmlParameterName() + "=\"" + InteractionEventConst::xmlEventPropertyRendererName() + "\" "; eventXML += InteractionEventConst::xmlParameterValue() + "=\""; eventXML += event->GetSender()->GetName(); eventXML += "\"/>\n"; // closing tag: eventXML += ""; return eventXML; } std::string mitk::EventFactory::GetButtonState(mitk::InteractionEvent *event) { InteractionEvent::MouseButtons buttonState = InteractionEvent::NoButton; std::string eventClass = event->GetNameOfClass(); std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); std::string strButtonState = ""; if (eventClass == "MOUSEPRESSEVENT") { MousePressEvent* mme = dynamic_cast (event); buttonState = mme->GetButtonStates(); } if (eventClass == "MOUSERELEASEEVENT") { MouseReleaseEvent* mme = dynamic_cast (event); buttonState = mme->GetButtonStates(); } if (eventClass == "MOUSEDOUBLECLICKEVENT") { MouseDoubleClickEvent* mme = dynamic_cast (event); buttonState = mme->GetButtonStates(); } if (eventClass == "MOUSEMOVEEVENT") { MouseMoveEvent* mme = dynamic_cast (event); buttonState = mme->GetButtonStates(); } if (eventClass == "MOUSEWHEELEVENT") { MouseWheelEvent* mme = dynamic_cast (event); buttonState = mme->GetButtonStates(); } if (buttonState & InteractionEvent::LeftMouseButton ) { strButtonState = "LeftMouseButton"; } if (buttonState & InteractionEvent::RightMouseButton ) { if (strButtonState != "") strButtonState += ","; strButtonState += "RightMouseButton"; } if (buttonState & InteractionEvent::MiddleMouseButton ) { if (strButtonState != "") strButtonState += ","; strButtonState += "MiddleMouseButton"; } return strButtonState; } std::string mitk::EventFactory::GetModifierState(mitk::InteractionEvent *event) { InteractionEvent::ModifierKeys modifierKeys = InteractionEvent::NoKey; std::string eventClass = event->GetNameOfClass(); std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); std::string strModKeys = ""; // TODO Add InteractionKey if (eventClass == "MOUSEPRESSEVENT") { MousePressEvent* mme = dynamic_cast (event); modifierKeys = mme->GetModifiers(); } if (eventClass == "MOUSERELEASEEVENT") { MouseReleaseEvent* mme = dynamic_cast (event); modifierKeys = mme->GetModifiers(); } if (eventClass == "MOUSEDOUBLECLICKEVENT") { MouseDoubleClickEvent* mme = dynamic_cast (event); modifierKeys = mme->GetModifiers(); } if (eventClass == "MOUSEMOVEEVENT") { MouseMoveEvent* mme = dynamic_cast (event); modifierKeys = mme->GetModifiers(); } if (eventClass == "MOUSEWHEELEVENT") { MouseWheelEvent* mme = dynamic_cast (event); modifierKeys = mme->GetModifiers(); } if (modifierKeys & InteractionEvent::ShiftKey ) { strModKeys = "SHIFT"; } if (modifierKeys & InteractionEvent::ControlKey ) { if (strModKeys != "") strModKeys += ","; strModKeys += "CTRL"; } if (modifierKeys & InteractionEvent::AltKey ) { if (strModKeys != "") strModKeys += ","; strModKeys += "ALT"; } return strModKeys; } std::string mitk::EventFactory::GetEventButton(mitk::InteractionEvent *event) { InteractionEvent::MouseButtons button = InteractionEvent::NoButton; std::string eventClass = event->GetNameOfClass(); std::transform(eventClass.begin(), eventClass.end(), eventClass.begin(), ::toupper); std::string stdButton = ""; // TODO Add InteractionKey if (eventClass == "MOUSEPRESSEVENT") { MousePressEvent* mme = dynamic_cast (event); button = mme->GetEventButton(); } if (eventClass == "MOUSERELEASEEVENT") { MouseReleaseEvent* mme = dynamic_cast (event); button = mme->GetEventButton(); } if (eventClass == "MOUSEDOUBLECLICKEVENT") { MouseDoubleClickEvent* mme = dynamic_cast (event); button = mme->GetEventButton(); } if (button & InteractionEvent::LeftMouseButton ) { stdButton = "LeftMouseButton"; } if (button & InteractionEvent::RightMouseButton ) { stdButton = "RightMouseButton"; } if (button & InteractionEvent::MiddleMouseButton ) { stdButton = "MiddleMouseButton"; } return stdButton; } std::string mitk::EventFactory::GetPositionInWorld(mitk::InteractionEvent *event) { std::stringstream ss; InteractionPositionEvent* pe = dynamic_cast (event); if (pe != NULL) { Point3D p = pe->GetPositionInWorld(); ss << p[0] << "," << p[1] << "," << p[2]; } return ss.str(); } std::string mitk::EventFactory::GetPositionOnScreen(mitk::InteractionEvent *event) { std::stringstream ss; InteractionPositionEvent* pe = dynamic_cast (event); if (pe != NULL) { Point2D p = pe->GetPointerPositionOnScreen(); ss << p[0] << "," << p[1]; } return ss.str(); } diff --git a/Core/Code/Interactions/mitkInteractionPositionEvent.cpp b/Core/Code/Interactions/mitkInteractionPositionEvent.cpp index 74f963600e..17aec1c975 100644 --- a/Core/Code/Interactions/mitkInteractionPositionEvent.cpp +++ b/Core/Code/Interactions/mitkInteractionPositionEvent.cpp @@ -1,57 +1,57 @@ /*=================================================================== 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 "mitkInteractionPositionEvent.h" #include mitk::InteractionPositionEvent::InteractionPositionEvent(mitk::BaseRenderer* baseRenderer, const mitk::Point2D& mousePosition) : InteractionEvent(baseRenderer) , m_PointerPosition(mousePosition) { if (GetSender() != NULL) { - m_WorldPosition = GetSender()->Map2DRendererPositionTo3DWorldPosition(&m_PointerPosition); + m_WorldPosition = GetSender()->Map2DRendererPositionTo3DWorldPosition(m_PointerPosition); } else { m_WorldPosition.Fill(0); } } -const mitk::Point2D mitk::InteractionPositionEvent::GetPointerPositionOnScreen() const +mitk::Point2D mitk::InteractionPositionEvent::GetPointerPositionOnScreen() const { return m_PointerPosition; } -const mitk::Point3D mitk::InteractionPositionEvent::GetPositionInWorld() const +mitk::Point3D mitk::InteractionPositionEvent::GetPositionInWorld() const { return m_WorldPosition; } bool mitk::InteractionPositionEvent::IsEqual(const InteractionEvent& other) const { return Superclass::IsEqual(other); } mitk::InteractionPositionEvent::~InteractionPositionEvent() { } bool mitk::InteractionPositionEvent::IsSuperClassOf(const InteractionEvent::Pointer& baseClass) const { return (dynamic_cast(baseClass.GetPointer()) != NULL) ; } diff --git a/Core/Code/Interactions/mitkInteractionPositionEvent.h b/Core/Code/Interactions/mitkInteractionPositionEvent.h index 74ad60a5f1..8a59ba3602 100644 --- a/Core/Code/Interactions/mitkInteractionPositionEvent.h +++ b/Core/Code/Interactions/mitkInteractionPositionEvent.h @@ -1,65 +1,65 @@ /*=================================================================== 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 MITKINTERACTIONPOSITIONEVENT_H_ #define MITKINTERACTIONPOSITIONEVENT_H_ #include "itkObject.h" #include "itkObjectFactory.h" #include "mitkCommon.h" #include "mitkInteractionEvent.h" #include "mitkInteractionEventConst.h" #include #include namespace mitk { /** * \class InteractionPositionEvent * * \brief Super class for all position events. * * This class is instantiated with a BaseRenderer and the 2D pointer position relative to the renderer, * the object then queries the Renderer for 3D world coordinates and supplies them to deriving classes. * */ class MITK_CORE_EXPORT InteractionPositionEvent : public InteractionEvent { public: mitkClassMacro(InteractionPositionEvent,InteractionEvent); mitkNewMacro2Param(Self, BaseRenderer*, const Point2D&); - const Point2D GetPointerPositionOnScreen() const; - const Point3D GetPositionInWorld() const; + Point2D GetPointerPositionOnScreen() const; + Point3D GetPositionInWorld() const; virtual bool IsSuperClassOf(const InteractionEvent::Pointer& baseClass) const; protected: InteractionPositionEvent(BaseRenderer* baseRenderer, const Point2D& mousePosition); virtual ~InteractionPositionEvent(); virtual bool IsEqual(const InteractionEvent&) const; private: - Point2D m_PointerPosition; + const Point2D m_PointerPosition; Point3D m_WorldPosition; }; } /* namespace mitk */ #endif /* MITKINTERACTIONPOSITIONEVENT_H_ */ diff --git a/Core/Code/Rendering/mitkBaseRenderer.cpp b/Core/Code/Rendering/mitkBaseRenderer.cpp index 30ceb8082c..b3a6c44a2f 100644 --- a/Core/Code/Rendering/mitkBaseRenderer.cpp +++ b/Core/Code/Rendering/mitkBaseRenderer.cpp @@ -1,889 +1,891 @@ /*=================================================================== 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" #include "mitkKeyEvent.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" #include "mitkOverlayManager.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_WorldTimeGeometry(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( GetName() ); 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_OverlayManager.IsNotNull()) { m_OverlayManager->RemoveBaseRenderer(this); } 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 { return m_BindDispatcherInteractor->GetDispatcher(); } -mitk::Point3D mitk::BaseRenderer::Map2DRendererPositionTo3DWorldPosition(Point2D* mousePosition) const +mitk::Point3D mitk::BaseRenderer::Map2DRendererPositionTo3DWorldPosition(const Point2D mousePosition) const { Point2D p_mm; + Point2D displayPoint; Point3D position; + if (m_MapperID == 1) { - GetDisplayGeometry()->ULDisplayToDisplay(*mousePosition, *mousePosition); - GetDisplayGeometry()->DisplayToWorld(*mousePosition, p_mm); + GetDisplayGeometry()->ULDisplayToDisplay(mousePosition, displayPoint); + GetDisplayGeometry()->DisplayToWorld(displayPoint, p_mm); GetDisplayGeometry()->Map(p_mm, position); } else if (m_MapperID == 2) { - GetDisplayGeometry()->ULDisplayToDisplay(*mousePosition, *mousePosition); - PickWorldPoint(*mousePosition, position); + GetDisplayGeometry()->ULDisplayToDisplay(mousePosition, displayPoint); + PickWorldPoint(displayPoint, 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_WorldTimeGeometry.IsNotNull()) { SlicedGeometry3D* slicedWorldGeometry = dynamic_cast(m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep).GetPointer()); 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::SetOverlayManager(itk::SmartPointer overlayManager) { if(overlayManager.IsNull()) return; if(this->m_OverlayManager.IsNotNull()) { if(this->m_OverlayManager.GetPointer() == overlayManager.GetPointer()) { return; } else { this->m_OverlayManager->RemoveBaseRenderer(this); } } this->m_OverlayManager = overlayManager; this->m_OverlayManager->AddBaseRenderer(this); //TODO } itk::SmartPointer mitk::BaseRenderer::GetOverlayManager() { if(this->m_OverlayManager.IsNull()) { m_OverlayManager = mitk::OverlayManager::New(); m_OverlayManager->AddBaseRenderer(this); } return this->m_OverlayManager; } void mitk::BaseRenderer::SetTimeStep(unsigned int timeStep) { if (m_TimeStep != timeStep) { m_TimeStep = timeStep; m_TimeStepUpdateTime.Modified(); if (m_WorldTimeGeometry.IsNotNull()) { if (m_TimeStep >= m_WorldTimeGeometry->CountTimeSteps()) m_TimeStep = m_WorldTimeGeometry->CountTimeSteps() - 1; SlicedGeometry3D* slicedWorldGeometry = dynamic_cast(m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep).GetPointer()); 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->GetTimeGeometry()->TimePointToTimeStep(GetTime()); } mitk::ScalarType mitk::BaseRenderer::GetTime() const { if (m_WorldTimeGeometry.IsNull()) { return 0; } else { ScalarType timeInMS = m_WorldTimeGeometry->TimeStepToTimePoint(GetTimeStep()); if (timeInMS == ScalarTypeNumericTraits::NonpositiveMin()) return 0; else return timeInMS; } } void mitk::BaseRenderer::SetWorldTimeGeometry(mitk::TimeGeometry* geometry) { assert(geometry != NULL); itkDebugMacro("setting WorldTimeGeometry to " << geometry); if (m_WorldTimeGeometry != geometry) { if (geometry->GetBoundingBoxInWorld()->GetDiagonalLength2() == 0) return; m_WorldTimeGeometry = geometry; itkDebugMacro("setting WorldTimeGeometry to " << m_WorldTimeGeometry); if (m_TimeStep >= m_WorldTimeGeometry->CountTimeSteps()) m_TimeStep = m_WorldTimeGeometry->CountTimeSteps() - 1; Geometry3D* geometry3d; geometry3d = m_WorldTimeGeometry->GetGeometryForTimeStep(m_TimeStep); SetWorldGeometry3D(geometry3d); } } void mitk::BaseRenderer::SetWorldGeometry3D(mitk::Geometry3D* geometry) { itkDebugMacro("setting WorldGeometry3D to " << geometry); if (m_WorldGeometry != geometry) { if (geometry->GetBoundingBox()->GetDiagonalLength2() == 0) return; m_WorldGeometry = geometry; SlicedGeometry3D* slicedWorldGeometry; 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::UpdateOverlays() { if(m_OverlayManager.IsNotNull()) { m_OverlayManager->UpdateOverlays(this); } } void mitk::BaseRenderer::SetGeometry(const itk::EventObject & geometrySendEvent) { const SliceNavigationController::GeometrySendEvent* sendEvent = dynamic_cast(&geometrySendEvent); assert(sendEvent!=NULL); SetWorldTimeGeometry(sendEvent->GetTimeGeometry()); } 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->SetInputWorldTimeGeometry(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 27049d754b..9b04ed28a7 100644 --- a/Core/Code/Rendering/mitkBaseRenderer.h +++ b/Core/Code/Rendering/mitkBaseRenderer.h @@ -1,644 +1,644 @@ /*=================================================================== 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 "mitkTimeGeometry.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 // DEPRECATED #include namespace mitk { class NavigationController; class SliceNavigationController; class CameraRotationController; class CameraController; class DataStorage; class Mapper; class BaseLocalStorageHandler; class OverlayManager; //##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; //##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_WorldTimeGeometry is set to NULL. //## \li if it is a TimeGeometry, m_WorldTimeGeometry is also set to point to it. //## If m_WorldTimeGeometry 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_WorldTimeGeometry 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_WorldTimeGeometry //## \sa m_CurrentWorldGeometry2D virtual void SetWorldGeometry3D(Geometry3D* geometry); virtual void SetWorldTimeGeometry(mitk::TimeGeometry* geometry); /** * \deprecatedSince{2013_09} Please use TimeGeometry instead of TimeSlicedGeometry. For more information see http://www.mitk.org/Development/Refactoring%20of%20the%20Geometry%20Classes%20-%20Part%201 */ DEPRECATED(void SetWorldGeometry3D(TimeSlicedGeometry* geometry)); itkGetConstObjectMacro(WorldGeometry, Geometry3D) itkGetObjectMacro(WorldGeometry, Geometry3D) itkGetConstObjectMacro(WorldTimeGeometry, TimeGeometry) itkGetObjectMacro(WorldTimeGeometry, TimeGeometry) //##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_WorldTimeGeometry used as m_CurrentWorldGeometry2D //## //## \sa m_Slice virtual void SetSlice(unsigned int slice); //##Documentation //## @brief Sets an OverlayManager which is used to add various Overlays to this //## renderer. If an OverlayManager was already set it will be overwritten. void SetOverlayManager(itk::SmartPointer overlayManager); //##Documentation //## @brief Get the OverlayManager registered with this renderer //## if none was set, it will be created at this point. itk::SmartPointer GetOverlayManager(); itkGetConstMacro(Slice, unsigned int) //##Documentation //## @brief Set/Get m_TimeStep which defines together with m_Slice the 2D geometry //## stored in m_WorldTimeGeometry 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; + virtual Point3D Map2DRendererPositionTo3DWorldPosition(const 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); //##Documentation //## @brief This method is called during the rendering process to update or render the Overlays //## which are stored in the OverlayManager void UpdateOverlays(); 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; itk::SmartPointer m_OverlayManager; //##Documentation //## m_WorldTimeGeometry is set by SetWorldGeometry if the passed Geometry3D is a //## TimeGeometry (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_WorldTimeGeometry (if available) //## is used as m_CurrentWorldGeometry2D. //## \sa m_CurrentWorldGeometry2D TimeGeometry::Pointer m_WorldTimeGeometry; //##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_WorldTimeGeometry //## is used as m_CurrentWorldGeometry2D: m_WorldTimeGeometry->GetGeometry2D(m_Slice, m_TimeStep). //## \sa m_WorldTimeGeometry unsigned int m_Slice; //##Documentation //## Defines together with m_TimeStep which 2D geometry stored in m_WorldTimeGeometry //## is used as m_CurrentWorldGeometry2D: m_WorldTimeGeometry->GetGeometry2D(m_Slice, m_TimeStep). //## \sa m_WorldTimeGeometry 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 */