Dynamic orientation from calculate.
This commit is contained in:
@@ -18,13 +18,14 @@
|
|||||||
#include "vtkPiecewiseFunction.h"
|
#include "vtkPiecewiseFunction.h"
|
||||||
#include "vector"
|
#include "vector"
|
||||||
#include "vtkCornerAnnotation.h"
|
#include "vtkCornerAnnotation.h"
|
||||||
#include "measure/Measure.h"
|
|
||||||
#include "measure/MeasureStore.h"
|
#include "measure/MeasureStore.h"
|
||||||
#include "vtkTextActor.h"
|
#include "vtkTextActor.h"
|
||||||
#include "vtkTextProperty.h"
|
#include "vtkTextProperty.h"
|
||||||
#include "ExtendMedicalImageProperties.h"
|
#include "ExtendMedicalImageProperties.h"
|
||||||
#include "measure/RulerLegendActor.h"
|
|
||||||
#include "util/ColorMapReader.h"
|
#include "util/ColorMapReader.h"
|
||||||
|
#include "vtkMath.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "DicomLoader.h"
|
#include "DicomLoader.h"
|
||||||
@@ -652,6 +653,7 @@ void infinitiViewer::SetSliceOrientation(int orientation)
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->UpdateOrientation();
|
this->UpdateOrientation();
|
||||||
|
updateOrienInfo();
|
||||||
// this->UpdateDisplayExtent();
|
// this->UpdateDisplayExtent();
|
||||||
|
|
||||||
if (this->Renderer && this->GetInput())
|
if (this->Renderer && this->GetInput())
|
||||||
@@ -685,13 +687,13 @@ void infinitiViewer::UpdateOrientation()
|
|||||||
case infinitiViewer::SLICE_ORIENTATION_XZ:
|
case infinitiViewer::SLICE_ORIENTATION_XZ:
|
||||||
cam->SetFocalPoint(0, 0, 0);
|
cam->SetFocalPoint(0, 0, 0);
|
||||||
cam->SetPosition(0, 1, 0); // 1 if medical ?
|
cam->SetPosition(0, 1, 0); // 1 if medical ?
|
||||||
cam->SetViewUp(0, 0, 1);
|
cam->SetViewUp(0, 0, -1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case infinitiViewer::SLICE_ORIENTATION_YZ:
|
case infinitiViewer::SLICE_ORIENTATION_YZ:
|
||||||
cam->SetFocalPoint(0, 0, 0);
|
cam->SetFocalPoint(0, 0, 0);
|
||||||
cam->SetPosition(1, 0, 0); // -1 if medical ?
|
cam->SetPosition( 1, 0, 0); // -1 if medical ?
|
||||||
cam->SetViewUp(0, 0, 1);
|
cam->SetViewUp(0, 0, -1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -985,7 +987,6 @@ void infinitiViewer::Render()
|
|||||||
int currentIndex = ImageMapper->GetSliceNumber();
|
int currentIndex = ImageMapper->GetSliceNumber();
|
||||||
if (currentIndex != lastIndex) this->SetSlice(lastIndex);
|
if (currentIndex != lastIndex) this->SetSlice(lastIndex);
|
||||||
this->Renderer->GetActiveCamera()->SetParallelScale(xs < 150 ? 75 : (xs - 1) / 2.0);
|
this->Renderer->GetActiveCamera()->SetParallelScale(xs < 150 ? 75 : (xs - 1) / 2.0);
|
||||||
|
|
||||||
//calibration of image by VFlip
|
//calibration of image by VFlip
|
||||||
//this->Renderer->GetActiveCamera()->Elevation(-180);
|
//this->Renderer->GetActiveCamera()->Elevation(-180);
|
||||||
//this->Renderer->GetActiveCamera()->Roll(180);
|
//this->Renderer->GetActiveCamera()->Roll(180);
|
||||||
@@ -1257,77 +1258,67 @@ void infinitiViewer::initCornerInfo(ExtendMedicalImageProperties* pSeries)
|
|||||||
m_cornerInfo.ConstAnno[TOP_RIGHT_PRIVACY].append("****");
|
m_cornerInfo.ConstAnno[TOP_RIGHT_PRIVACY].append("****");
|
||||||
m_cornerInfo.ConstAnno[TOP_RIGHT_PRIVACY].append("\n");
|
m_cornerInfo.ConstAnno[TOP_RIGHT_PRIVACY].append("\n");
|
||||||
|
|
||||||
std::vector<std::string>* orien_list = orientationHelper::getOrientationStrList("");
|
double* d = pSeries->GetDirectionCosine();
|
||||||
//currently only adapt to USCT Format
|
double xVector[3] = {d[0], d[1], d[2]};
|
||||||
if (orien_list)
|
double yVector[3] = {d[3], d[4], d[5]};
|
||||||
{
|
double zVector[3] = {0, 0, 0};
|
||||||
m_cornerInfo.ConstAnno[BOTTOM_MIDDLE].append(orien_list->at(BOTTOM_MIDDLE - 4));
|
vtkMath::Cross(xVector, yVector, zVector);
|
||||||
m_cornerInfo.ConstAnno[BOTTOM_MIDDLE].append("\n");
|
|
||||||
|
|
||||||
m_cornerInfo.ConstAnno[RIGHT_MIDDLE].append(orien_list->at(RIGHT_MIDDLE - 4));
|
|
||||||
m_cornerInfo.ConstAnno[RIGHT_MIDDLE].append("\n");
|
|
||||||
|
|
||||||
|
|
||||||
m_cornerInfo.ConstAnno[LEFT_MIDDLE].append(orien_list->at(LEFT_MIDDLE - 4));
|
matrix->Zero();
|
||||||
m_cornerInfo.ConstAnno[LEFT_MIDDLE].append("\n");
|
matrix->SetElement(0, 0, xVector[0]);
|
||||||
|
matrix->SetElement(0, 1, xVector[1]);
|
||||||
m_cornerInfo.ConstAnno[TOP_MIDDLE].append(orien_list->at(TOP_MIDDLE - 4));
|
matrix->SetElement(0, 2, xVector[2]);
|
||||||
m_cornerInfo.ConstAnno[TOP_MIDDLE].append("\n");
|
matrix->SetElement(1, 0, yVector[0]);
|
||||||
}
|
matrix->SetElement(1, 1, yVector[1]);
|
||||||
|
matrix->SetElement(1, 2, yVector[2]);
|
||||||
|
matrix->SetElement(2, 0, zVector[0]);
|
||||||
|
matrix->SetElement(2, 1, zVector[1]);
|
||||||
|
matrix->SetElement(2, 2, zVector[2]);
|
||||||
|
matrix->SetElement(3, 3, 1);
|
||||||
|
matrix->Invert();
|
||||||
}
|
}
|
||||||
|
|
||||||
void infinitiViewer::updateOrienInfo(TransFormType type)
|
int getOrientationIndex(double* v){
|
||||||
|
int max_index = 0;
|
||||||
|
if (fabs(v[0])>fabs(v[1])){
|
||||||
|
if (fabs(v[0])<=fabs(v[2])) max_index = 2;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(fabs(v[1])>=fabs(v[2])) max_index=1;
|
||||||
|
else max_index = 2;
|
||||||
|
}
|
||||||
|
return v[max_index]>0?max_index*2:2*max_index+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getOppositeOrientation(int f){
|
||||||
|
int inner_idx = f % 2;
|
||||||
|
return f + 1 - inner_idx * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infinitiViewer::updateOrienInfo()
|
||||||
{
|
{
|
||||||
|
static const char* dds[6] ={"R","L","P","A","F","H"};
|
||||||
|
double proj[4] ={0,0,0,1};
|
||||||
|
Renderer->GetActiveCamera()->GetDirectionOfProjection(proj);
|
||||||
|
double viewUp[4]= {0,0,0,1};
|
||||||
|
this->Renderer->GetActiveCamera()->GetViewUp(viewUp);
|
||||||
|
double viewRight[4] = {0, 0, 0, 1};
|
||||||
|
vtkMath::Cross(viewUp,proj, viewRight);
|
||||||
|
|
||||||
char top_middle[20];
|
double viewUpVector[4]= {0,0,0,1};
|
||||||
char left_middle[20];
|
double viewRightVector[4]= {0,0,0,1};
|
||||||
|
|
||||||
|
matrix->MultiplyPoint(viewUp, viewUpVector);
|
||||||
|
int flag = getOrientationIndex(viewUpVector);
|
||||||
|
|
||||||
switch (type)
|
cornerAnnotation->SetText(TOP_MIDDLE, dds[flag]);
|
||||||
{
|
cornerAnnotation->SetText(BOTTOM_MIDDLE, dds[getOppositeOrientation(flag)]);
|
||||||
case ROTATE_90_CCW:
|
matrix->MultiplyPoint(viewRight, viewRightVector);
|
||||||
strcpy_s(top_middle, cornerAnnotation->GetText(TOP_MIDDLE));
|
flag = getOrientationIndex(viewRightVector);
|
||||||
cornerAnnotation->SetText(TOP_MIDDLE, cornerAnnotation->GetText(RIGHT_MIDDLE));
|
cornerAnnotation->SetText(RIGHT_MIDDLE, dds[flag]);
|
||||||
cornerAnnotation->SetText(RIGHT_MIDDLE, cornerAnnotation->GetText(BOTTOM_MIDDLE));
|
cornerAnnotation->SetText(LEFT_MIDDLE, dds[getOppositeOrientation(flag)]);
|
||||||
cornerAnnotation->SetText(BOTTOM_MIDDLE, cornerAnnotation->GetText(LEFT_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(LEFT_MIDDLE, top_middle);
|
|
||||||
break;
|
|
||||||
case ROTATE_90_CW:
|
|
||||||
strcpy_s(top_middle, cornerAnnotation->GetText(TOP_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(TOP_MIDDLE, cornerAnnotation->GetText(LEFT_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(LEFT_MIDDLE, cornerAnnotation->GetText(BOTTOM_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(BOTTOM_MIDDLE, cornerAnnotation->GetText(RIGHT_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(RIGHT_MIDDLE, top_middle);
|
|
||||||
break;
|
|
||||||
case ROTATE_180:
|
|
||||||
strcpy_s(top_middle, cornerAnnotation->GetText(TOP_MIDDLE));
|
|
||||||
strcpy_s(left_middle, cornerAnnotation->GetText(LEFT_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(TOP_MIDDLE, cornerAnnotation->GetText(BOTTOM_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(LEFT_MIDDLE, cornerAnnotation->GetText(RIGHT_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(BOTTOM_MIDDLE, top_middle);
|
|
||||||
cornerAnnotation->SetText(RIGHT_MIDDLE, left_middle);
|
|
||||||
break;
|
|
||||||
case H_FLIP:
|
|
||||||
strcpy_s(left_middle, cornerAnnotation->GetText(LEFT_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(LEFT_MIDDLE, cornerAnnotation->GetText(RIGHT_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(RIGHT_MIDDLE, left_middle);
|
|
||||||
break;
|
|
||||||
case V_FLIP:
|
|
||||||
strcpy_s(top_middle, cornerAnnotation->GetText(TOP_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(TOP_MIDDLE, cornerAnnotation->GetText(BOTTOM_MIDDLE));
|
|
||||||
cornerAnnotation->SetText(BOTTOM_MIDDLE, top_middle);
|
|
||||||
break;
|
|
||||||
case CLEAR:
|
|
||||||
cornerAnnotation->SetText(TOP_MIDDLE, m_cornerInfo.ConstAnno[TOP_MIDDLE].c_str());
|
|
||||||
cornerAnnotation->SetText(BOTTOM_MIDDLE, m_cornerInfo.ConstAnno[BOTTOM_MIDDLE].c_str());
|
|
||||||
cornerAnnotation->SetText(LEFT_MIDDLE, m_cornerInfo.ConstAnno[LEFT_MIDDLE].c_str());
|
|
||||||
cornerAnnotation->SetText(RIGHT_MIDDLE, m_cornerInfo.ConstAnno[RIGHT_MIDDLE].c_str());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cornerAnnotation->Modified();
|
cornerAnnotation->Modified();
|
||||||
this->Render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "vector"
|
#include "vector"
|
||||||
#include "QList"
|
#include "QList"
|
||||||
#include "measure\DraggableActor.h"
|
#include "measure\DraggableActor.h"
|
||||||
|
#include "vtkMatrix4x4.h"
|
||||||
|
|
||||||
//for convert vtkEvent to Qt signal
|
//for convert vtkEvent to Qt signal
|
||||||
#include "measure\vtkSignalRaiser.h"
|
#include "measure\vtkSignalRaiser.h"
|
||||||
@@ -58,7 +59,7 @@ public:
|
|||||||
void updateCornerInfo(int index);
|
void updateCornerInfo(int index);
|
||||||
void updateCornerInfoAll();
|
void updateCornerInfoAll();
|
||||||
void initCornerInfo(ExtendMedicalImageProperties *pSeriesTags);
|
void initCornerInfo(ExtendMedicalImageProperties *pSeriesTags);
|
||||||
void updateOrienInfo(TransFormType type);
|
void updateOrienInfo();
|
||||||
void setUpImageViewer();
|
void setUpImageViewer();
|
||||||
|
|
||||||
//For Export
|
//For Export
|
||||||
@@ -389,6 +390,7 @@ private:
|
|||||||
|
|
||||||
DicomCornerInfo m_cornerInfo;
|
DicomCornerInfo m_cornerInfo;
|
||||||
char SOP_UID[20];
|
char SOP_UID[20];
|
||||||
|
vtkNew<vtkMatrix4x4> matrix;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -153,9 +153,10 @@ void DicomImageView::Slot_WindowLevelEventForFusion(double level, double width)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DicomImageView::Slot_UpdateOrienInfo(TransFormType operation)
|
void DicomImageView::Slot_Transformation()
|
||||||
{
|
{
|
||||||
_ImageViewer->updateOrienInfo(operation);
|
_ImageViewer->updateOrienInfo();
|
||||||
|
_ImageViewer->Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Widget event----------------------------------------------------------------
|
//Widget event----------------------------------------------------------------
|
||||||
@@ -360,7 +361,7 @@ void DicomImageView::setDicomImageView(SeriesImageSet *series)
|
|||||||
initScrollbar();
|
initScrollbar();
|
||||||
|
|
||||||
connect(_scrollBar, &QScrollBar::valueChanged, this, &DicomImageView::Slot_scrollValueChanged);
|
connect(_scrollBar, &QScrollBar::valueChanged, this, &DicomImageView::Slot_scrollValueChanged);
|
||||||
connect(this, &DicomImageView::Signal_Transformation, this, &DicomImageView::Slot_UpdateOrienInfo);
|
connect(this, &DicomImageView::Signal_Transformation, this, &DicomImageView::Slot_Transformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DicomImageView::HasSeries()
|
bool DicomImageView::HasSeries()
|
||||||
@@ -374,8 +375,9 @@ void DicomImageView::LoadSeries(SeriesImageSet *series)
|
|||||||
_ImageViewer->SetInputData(_Series->GetData());
|
_ImageViewer->SetInputData(_Series->GetData());
|
||||||
_ImageViewer->initCornerInfo(series->GetProperty());
|
_ImageViewer->initCornerInfo(series->GetProperty());
|
||||||
_ImageViewer->setUpImageViewer();
|
_ImageViewer->setUpImageViewer();
|
||||||
|
_ImageViewer->updateOrienInfo();
|
||||||
//以下是一些转接函数
|
//以下是一些转接函数
|
||||||
//TODO: 考虑使用connect 替代 AddObserver,避免出现多种事件机制架构
|
//使用connect 替代 AddObserver,避免出现多种事件机制架构
|
||||||
connect(_ImageViewer->GetSignalRaiser(),&vtkSignalRaiser::raiseEvent, this, &DicomImageView::syncEventFunc);
|
connect(_ImageViewer->GetSignalRaiser(),&vtkSignalRaiser::raiseEvent, this, &DicomImageView::syncEventFunc);
|
||||||
//目前 替换了一部分包括SlicedEvent,EndDollyEvent,EndWindowLevelEvent,EndPanEvent,主要关联到sync
|
//目前 替换了一部分包括SlicedEvent,EndDollyEvent,EndWindowLevelEvent,EndPanEvent,主要关联到sync
|
||||||
|
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ public slots:
|
|||||||
void Slot_ViewEmpty();
|
void Slot_ViewEmpty();
|
||||||
void Slot_scrollValueChanged(int);
|
void Slot_scrollValueChanged(int);
|
||||||
void Slot_WindowLevelEventForFusion(double level, double width);
|
void Slot_WindowLevelEventForFusion(double level, double width);
|
||||||
void Slot_UpdateOrienInfo(TransFormType);
|
void Slot_Transformation();
|
||||||
void viewerClicked();
|
void viewerClicked();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
Reference in New Issue
Block a user