diff --git a/src/src/Rendering/Viewer/ResliceImageViewer.cpp b/src/src/Rendering/Viewer/ResliceImageViewer.cpp index 5a7cd4f..1243b22 100644 --- a/src/src/Rendering/Viewer/ResliceImageViewer.cpp +++ b/src/src/Rendering/Viewer/ResliceImageViewer.cpp @@ -15,11 +15,36 @@ #include #include #include +#include +#include #include "Rendering/Legend/ResliceCursorLegendActor.h" #include "Rendering/Legend/ResliceSquareLegendActor.h" #include "Interaction/ResliceImageInteractorStyle.h" +namespace { + void GetDirectionString(const double *directionVector, std::string &str) { + str.clear(); + char dV [3] = {' ', ' ', ' '}; + if (fabs(directionVector[0]) > 0.6){ + dV[0] = directionVector[0] > 0 ? 'L' : 'R'; + } + if (fabs(directionVector[1]) > 0.6){ + dV[1] = directionVector[1]> 0 ? 'P' : 'A'; + } + if (fabs(directionVector[2]) > 0.6){ + dV[2] = directionVector[2] > 0 ? 'H' : 'F'; + } + if (fabs(directionVector[2]) > fabs(directionVector[1])) std::swap(dV[1], dV[2]); + if (fabs(directionVector[1]) > fabs(directionVector[0])) std::swap(dV[0], dV[1]); + for (int i = 0; i < 3; ++i) { + if(dV[i]!=' '){ + str.append(1, dV[i]); + } + } + } +} + vtkStandardNewMacro(ResliceImageViewer); ResliceImageViewer::ResliceImageViewer() @@ -34,6 +59,7 @@ ResliceImageViewer::ResliceImageViewer() , cursor2(ResliceCursorLegendActor::New()) , Square(ResliceSquareLegendActor::New()) , Actor(vtkImageSlice::New()) + , annotation(vtkCornerAnnotation::New()) , OrientationMatrix(vtkMatrix4x4::New()) , DefaultOrientation(0) , FirstRender(true) @@ -47,6 +73,16 @@ ResliceImageViewer::ResliceImageViewer() cursor1->SetReferenceCursor(cursor2); cursor2->SetReferenceCursor(cursor1); OrientationMatrix->Identity(); + + vtkNew prop; + prop->SetFontFamilyToArial(); + this->annotation->SetTextProperty(prop); + this->annotation->GetTextProperty()->SetColor(.0,1.,1.); + // Annotate the image with window/level and mouse over pixel information + this->annotation->SetLinearFontScaleFactor(2); + this->annotation->SetNonlinearFontScaleFactor(1); + this->annotation->SetMaximumFontSize(20); + this->annotation->SetMinimumFontSize(8); } ResliceImageViewer::~ResliceImageViewer() { @@ -154,6 +190,7 @@ void ResliceImageViewer::Render() { MeasureRenderer->SetLayer(1); MeasureRenderer->AddActor2D(cursor1); MeasureRenderer->AddActor2D(cursor2); + MeasureRenderer->AddActor(annotation); cursor1->SetSlicePoint(MeasureRenderer->GetActiveCamera()->GetFocalPoint()); cursor2->SetSlicePoint(MeasureRenderer->GetActiveCamera()->GetFocalPoint()); cursor1->SetProjectDirectionVector(MeasureRenderer->GetActiveCamera()->GetDirectionOfProjection()); @@ -200,8 +237,8 @@ void ResliceImageViewer::Render() { cursor2->AddObserver(ResliceCursorLegendActor::ROLL,this, &ResliceImageViewer::handleRoll); cursor2->AddObserver(ResliceCursorLegendActor::MOVE,this, &ResliceImageViewer::handleMove); MeasureRenderer->AddActor2D(Square); + UpdateDirectionAnnotation(); Render(); - return; } Interactor->Render(); @@ -287,6 +324,7 @@ void ResliceImageViewer::ChangeSliceNormal(double *normal) { camera->SetPosition(focalPt[0]+step*normal[0],focalPt[1]+step*normal[1],focalPt[2]+step*normal[2]); camera->OrthogonalizeViewUp(); Renderer->ResetCameraClippingRange(); + UpdateDirectionAnnotation(); } void ResliceImageViewer::ChangeSlicePoint(double *point) { @@ -317,5 +355,30 @@ void ResliceImageViewer::AdjustOrthogonalScale() { int index = abs(((int)viewUp[0]) * 0 + ((int)viewUp[1]) * 1 + ((int)viewUp[2]) * 2); double pixelScale = data->GetDimensions()[index]*data->GetSpacing()[index]; - camera->SetParallelScale(pixelScale/2-3); + camera->SetParallelScale(pixelScale/2-3); +} + +void ResliceImageViewer::UpdateDirectionAnnotation() { + auto camera = Renderer->GetActiveCamera(); + double dop[4] = {.0, .0, .0, 1.}; + camera->GetDirectionOfProjection(dop); + double viewUp[4] = {.0, .0, .0, 1.}; + camera->GetViewUp(viewUp); + double viewRight[4] = {.0, .0, .0, 1.}; + vtkMath::Cross(dop,viewUp,viewRight); + OrientationMatrix->Invert(); + OrientationMatrix->MultiplyPoint(viewUp,viewUp); + OrientationMatrix->MultiplyPoint(viewRight,viewRight); + OrientationMatrix->Invert(); + double viewDown[4] = {-viewUp[0], -viewUp[1], -viewUp[2], 1.}; + double viewLeft[4] = {-viewRight[0], -viewRight[1], -viewRight[2], 1.}; + std::string str; + GetDirectionString(viewUp, str); + annotation->SetText(7,str.c_str() ); + GetDirectionString(viewRight, str); + annotation->SetText(5,str.c_str() ); + GetDirectionString(viewDown, str); + annotation->SetText(4,str.c_str() ); + GetDirectionString(viewLeft, str); + annotation->SetText(6,str.c_str() ); } diff --git a/src/src/Rendering/Viewer/ResliceImageViewer.h b/src/src/Rendering/Viewer/ResliceImageViewer.h index b477141..4cd7432 100644 --- a/src/src/Rendering/Viewer/ResliceImageViewer.h +++ b/src/src/Rendering/Viewer/ResliceImageViewer.h @@ -27,6 +27,8 @@ class ResliceCursorLegendActor; class ResliceSquareLegendActor; +class vtkCornerAnnotation; + class ResliceImageViewer :public vtkObject { public: static ResliceImageViewer *New(); @@ -71,6 +73,8 @@ private: void handleMove(); void handleResize(); + void UpdateDirectionAnnotation(); + vtkRenderWindow *RenderWindow; vtkRenderer *Renderer; vtkRenderer *MeasureRenderer; @@ -81,6 +85,7 @@ private: ResliceCursorLegendActor* cursor2; ResliceSquareLegendActor* Square; vtkImageSlice* Actor; + vtkCornerAnnotation* annotation; vtkMatrix4x4* OrientationMatrix; int DefaultOrientation; bool FirstRender;