Refactor dicomimageview. Change SyncScrollBar by use SetValueSilently function.

This commit is contained in:
Krad
2022-07-01 14:15:50 +08:00
parent 5e94261f17
commit 2c088c3bee
2 changed files with 442 additions and 434 deletions

View File

@@ -28,8 +28,8 @@ DicomImageView::DicomImageView(QWidget* parent)
QGridLayout *view_layout = new QGridLayout(this);
//add container and title bar
_titleBar = createMyTitleBar();
view_layout->addWidget(_titleBar, 0, 0);
mTitleBar = createMyTitleBar();
view_layout->addWidget(mTitleBar, 0, 0);
view_layout->addWidget(wrapper, 1, 0);
view_layout->setContentsMargins(0, 0, 0, 0);
view_layout->setSpacing(0);
@@ -37,20 +37,21 @@ DicomImageView::DicomImageView(QWidget* parent)
// create layout for main container
QGridLayout* controlLayout = new QGridLayout(wrapper);
_glWidt = new QVTKOpenGLNativeWidget(wrapper);
mGLWidget = new QVTKOpenGLNativeWidget(wrapper);
//add QVTKOpenGLNativeWidget to container
m_glrenWin = vtkSmartPointer <vtkGenericOpenGLRenderWindow>::New();
_glWidt->SetRenderWindow(m_glrenWin);//set up interacte
controlLayout->addWidget(_glWidt, 0, 0);
mGLRenWin = vtkSmartPointer <vtkGenericOpenGLRenderWindow>::New();
mGLWidget->SetRenderWindow(mGLRenWin);//set up interacte
controlLayout->addWidget(mGLWidget, 0, 0);
//add scrollbar to container
_scrollBar = new ClickableScrollBar(Qt::Orientation::Vertical, this);
_scrollBar->setFocusPolicy(Qt::StrongFocus);
_scrollBar->setVisible(false);
_scrollBar->setObjectName("scrollbar");
controlLayout->addWidget(_scrollBar, 0, 1);
connect(_scrollBar, &ClickableScrollBar::clicked,this,&DicomImageView::viewerClicked);
mScrollBar = new ClickableScrollBar(Qt::Orientation::Vertical, this);
mScrollBar->setSingleStep(1);
mScrollBar->setFocusPolicy(Qt::StrongFocus);
mScrollBar->setVisible(false);
mScrollBar->setObjectName("scrollbar");
controlLayout->addWidget(mScrollBar, 0, 1);
connect(mScrollBar, &ClickableScrollBar::clicked, this, &DicomImageView::viewerClicked);
//config container UI
controlLayout->setContentsMargins(0, 0, 0, 0);
@@ -66,14 +67,14 @@ DicomImageView::DicomImageView(QWidget* parent)
//-----------------------------------------------------------------------------
DicomImageView::~DicomImageView()
{
if (_ImageViewer){
_ImageViewer->Delete();
_ImageViewer = nullptr;
if (mImageViewer){
mImageViewer->Delete();
mImageViewer = nullptr;
}
_thread.quit();//event loop
_thread.wait(); //wait until return,block mode
if (_vcr_toolbar){
_vcr_toolbar->deleteLater();
mVcrControlThread.quit();//event loop
mVcrControlThread.wait(); //wait until return,block mode
if (mVcrToolbar){
mVcrToolbar->deleteLater();
}
}
@@ -87,50 +88,23 @@ MyTitleBar * DicomImageView::createMyTitleBar()
void DicomImageView::initScrollbar()
{
//_MinSlice = _ImageViewer->GetSliceMin();
//_MaxSlice = _ImageViewer->GetSliceMax();
_scrollBar->setValue(_ImageViewer->GetSliceMin());
_scrollBar->setMaximum(_ImageViewer->GetSliceMax());
_scrollBar->setSingleStep(1);
_scrollBar->setVisible(true);
//_MinSlice = mImageViewer->GetSliceMin();
//_MaxSlice = mImageViewer->GetSliceMax();
mScrollBar->setValue(mImageViewer->GetSliceMin());
mScrollBar->setMaximum(mImageViewer->GetSliceMax());
mScrollBar->setSingleStep(1);
mScrollBar->setVisible(true);
}
//NOTE: not working
void DicomImageView::setHighlight(bool yes) {
_titleBar->SetHighlight(yes);
mTitleBar->SetHighlight(yes);
}
//SLOTS------------------------------------------------------------------------
void DicomImageView::Slot_scrollValueChanged(int slice)
{
//if the scroll bar is activated by user, emit
//if the scroll bar is activated by program, no emit
switch (_ScrollTriggerType)
{
case(scrollScope::TriggerType::USER_TRIGGER):
{
_ImageViewer->SetSlice(slice); //for interactor style use, reduce duplicate
// no break;
}
case(scrollScope::TriggerType::STYLE_TRIGGER):
{
qDebug()<<"======>>";
_ImageViewer->updateCornerInfo(TOP_LEFT);
//invoke event
double focusPoint[3] = {.0, .0, .0};
_ImageViewer->GetSlicePoint(focusPoint);
this->Signal_SyncEvent(this, VTKIS_IMAGE_SLICING, focusPoint);
break;
}
case(scrollScope::TriggerType::SYNC_ONLY):
{
_PrevSlice = slice;
break;
}
default:
break;
}
mImageViewer->SetSlice(slice);
}
void DicomImageView::Slot_ViewEmpty()
@@ -146,37 +120,37 @@ void DicomImageView::Slot_viewDoubleclicked()
void DicomImageView::Slot_WindowLevelEventForFusion(double level, double width)
{
if (IsFusion()) {
_ImageViewer->SetFusionColorLeveL(level);
_ImageViewer->SetFusionColorWindow(width);
_ImageViewer->Render();
mImageViewer->SetFusionColorLeveL(level);
mImageViewer->SetFusionColorWindow(width);
mImageViewer->Render();
}
}
void DicomImageView::Slot_Transformation()
{
_ImageViewer->updateOrienInfo();
_ImageViewer->Render();
mImageViewer->updateOrienInfo();
mImageViewer->Render();
}
//Widget event----------------------------------------------------------------
void DicomImageView::wheelEvent(QWheelEvent *event)
{
if (HasSeries()) {
int _Slice = _ImageViewer->GetSlice();
int _MinSlice = _ImageViewer->GetSliceMin();
int _MaxSlice = _ImageViewer->GetSliceMax();
int _Slice = mImageViewer->GetSlice();
int _MinSlice = mImageViewer->GetSliceMin();
int _MaxSlice = mImageViewer->GetSliceMax();
if (event->delta() > 0)
{
if (_Slice > _MinSlice)
{
_Slice -= 1;
_scrollBar->setValue(_Slice);
mImageViewer->SetSlice(_Slice);
}
else
{
_Slice = _MinSlice;
_scrollBar->setValue(_Slice);
mImageViewer->SetSlice(_Slice);
}
}
else
@@ -184,12 +158,12 @@ void DicomImageView::wheelEvent(QWheelEvent *event)
if (_Slice < _MaxSlice)
{
_Slice += 1;
_scrollBar->setValue(_Slice);
mImageViewer->SetSlice(_Slice);
}
else
{
_Slice = _MaxSlice;
_scrollBar->setValue(_Slice);
mImageViewer->SetSlice(_Slice);
}
}
}
@@ -201,33 +175,19 @@ void DicomImageView::mousePressEvent(QMouseEvent* event)
emit Signal_ViewClicked(this);
}
/**
* @brief DicomImageView::dragEnterEvent
* 拖拽进入
* @param e
*/
// DND support-----------------------------------------------------------------
void DicomImageView::dragEnterEvent(QDragEnterEvent *e) {
if (e->mimeData()->hasFormat("text/plain")) {
e->acceptProposedAction();
}
}
/**
* @brief DicomImageView::dragMoveEvent
* 拖拽移动
* @param e
*/
void DicomImageView::dragMoveEvent(QDragMoveEvent *e) {
if (e->mimeData()->hasFormat("text/plain")) {
e->acceptProposedAction();
}
}
/**
* @brief DicomImageView::dropEvent
* 拖拽松开
* @param e
*/
void DicomImageView::dropEvent(QDropEvent *e) {
if (e->mimeData()->hasFormat("text/plain")) {
e->acceptProposedAction();
@@ -239,29 +199,25 @@ void DicomImageView::dropEvent(QDropEvent *e) {
}
}
/**
* @brief DicomImageView::dragLeaveEvent
* 离开事件
* @param e
*/
void DicomImageView::dragLeaveEvent(QDragLeaveEvent *) {
return;
}
// layout resize---------------------------------------------------------------
void DicomImageView::resizeEvent(QResizeEvent *event)
{
//auto size conner info
if (!_ImageViewer) return;
if (_ImageViewer->GetvtkCornerAnnotation()) {
_ImageViewer->GetvtkCornerAnnotation()->SetMaximumFontSize(FontSizeHelper::getSize(frameGeometry().size()));
_ImageViewer->Render();
if (!mImageViewer) return;
if (mImageViewer->GetvtkCornerAnnotation()) {
mImageViewer->GetvtkCornerAnnotation()->SetMaximumFontSize(FontSizeHelper::getSize(frameGeometry().size()));
mImageViewer->Render();
}
if (isCine) {
if (mIsCine) {
int ax = (this->geometry().bottomLeft().x() + this->geometry().bottomRight().x()) / 2 +
VCRHelper::getVCRXOffset();
int ay = (this->geometry().bottomLeft().y() + this->geometry().bottomRight().y()) / 2 +
VCRHelper::getVCRYOffset();
_vcr_toolbar->move(ax, ay);
mVcrToolbar->move(ax, ay);
}
}
@@ -269,28 +225,28 @@ void DicomImageView::resizeEvent(QResizeEvent *event)
//Fusion about -------------------------------------------------------------
bool DicomImageView::IsFusion()
{
return _ImageViewer->GetFusion();
return mImageViewer->GetFusion();
}
void DicomImageView::SetFusionInput(DicomImageView *overlay)
{
_overlay = overlay;
mOverlayView = overlay;
vtkImageData *overlay_data = _overlay->getSeriesInstance()->GetData();
vtkImageData *overlay_data = mOverlayView->getSeriesInstance()->GetData();
double window;
double level;
_overlay->GetWindowLevel(level, window);
mOverlayView->GetWindowLevel(level, window);
_ImageViewer->FusionOn();
_overlay->OverlayOn();
_overlay->SetBaseView(this);
mImageViewer->FusionOn();
mOverlayView->OverlayOn();
mOverlayView->SetBaseView(this);
_ImageViewer->SetFusionInputData(overlay_data);
_ImageViewer->SetFusionColorLeveL(level);
_ImageViewer->SetFusionColorWindow(window);
_ImageViewer->SetFusionOpacity(_ImageViewer->GetFusionOpacity());
mImageViewer->SetFusionInputData(overlay_data);
mImageViewer->SetFusionColorLeveL(level);
mImageViewer->SetFusionColorWindow(window);
mImageViewer->SetFusionOpacity(mImageViewer->GetFusionOpacity());
// Example for vtkDiscretizableColorTransferFunction
vtkNew< vtkDiscretizableColorTransferFunction> table;
@@ -299,14 +255,14 @@ void DicomImageView::SetFusionInput(DicomImageView *overlay)
table->AddRGBPoint(0.33, 1.0, 0.0, 0.0);
table->AddRGBPoint(0.66, 1.0, 1.0, 0.0);
table->AddRGBPoint(1.0, 1.0, 1.0, 1.0);
_ImageViewer->SetFusionColorTable(table);
mImageViewer->SetFusionColorTable(table);
}
void DicomImageView::SetFusionOpacity(double percent) {
if (IsFusion()) {
_ImageViewer->IncreFusionOpacity(percent);
_ImageViewer->Render();
mImageViewer->IncreFusionOpacity(percent);
mImageViewer->Render();
}
}
@@ -318,21 +274,21 @@ void DicomImageView::removeViewWithFusion()
if (HasSeries())
{
if (IsFusion()) {
disconnect(_overlay, &DicomImageView::Signal_WindowLevelEventForFusion,
this, &DicomImageView::Slot_WindowLevelEventForFusion);
disconnect(mOverlayView, &DicomImageView::Signal_WindowLevelEventForFusion,
this, &DicomImageView::Slot_WindowLevelEventForFusion);
this->removeFusion();
_overlay->SetBaseView(nullptr);
_overlay = nullptr;
mOverlayView->SetBaseView(nullptr);
mOverlayView = nullptr;
}
if (IsOverlay()) {
disconnect(this, &DicomImageView::Signal_WindowLevelEventForFusion,
_base, &DicomImageView::Slot_WindowLevelEventForFusion);
mBaseView, &DicomImageView::Slot_WindowLevelEventForFusion);
_base->removeFusion();
_base->SetOverlayView(nullptr);
_base = nullptr;
mBaseView->removeFusion();
mBaseView->SetOverlayView(nullptr);
mBaseView = nullptr;
}
}
@@ -340,50 +296,50 @@ void DicomImageView::removeViewWithFusion()
void DicomImageView::removeFusion()
{
_ImageViewer->RemoveFusionData();
_ImageViewer->FusionOff();
_ImageViewer->Render();
_overlay->OverlayOff();
mImageViewer->RemoveFusionData();
mImageViewer->FusionOff();
mImageViewer->Render();
mOverlayView->OverlayOff();
}
void DicomImageView::setDicomImageView(SeriesImageSet *series)
{
if (!_ImageViewer){
if (!mImageViewer){
_ImageViewer = infinitiViewer::New();
_ImageViewer->SetRenderWindow(m_glrenWin);
_ImageViewer->SetupInteractor(m_glrenWin->GetInteractor());
mImageViewer = infinitiViewer::New();
mImageViewer->SetRenderWindow(mGLRenWin);
mImageViewer->SetupInteractor(mGLRenWin->GetInteractor());
}
//series->setVTKOpenGLNativeWidget(this->_glView);
LoadSeries(series);
//whenver change instance,set scroll value to zero
initScrollbar();
if (!slotInited){
connect(_scrollBar, &QScrollBar::valueChanged, this, &DicomImageView::Slot_scrollValueChanged);
if (!mIsSlotInited){
connect(mScrollBar, &QScrollBar::valueChanged, this, &DicomImageView::Slot_scrollValueChanged);
connect(this, &DicomImageView::Signal_Transformation, this, &DicomImageView::Slot_Transformation);
slotInited = true;
mIsSlotInited = true;
}
}
bool DicomImageView::HasSeries()
{
return _Series ;
return mSeries ;
}
void DicomImageView::LoadSeries(SeriesImageSet *series)
{
_Series = series;
_ImageViewer->SetInputData(_Series->GetData());
_ImageViewer->initCornerInfo(series->GetProperty());
_ImageViewer->setUpImageViewer();
_ImageViewer->updateOrienInfo();
mSeries = series;
mImageViewer->SetInputData(mSeries->GetData());
mImageViewer->initCornerInfo(series->GetProperty());
mImageViewer->setUpImageViewer();
mImageViewer->updateOrienInfo();
//以下是一些转接函数
//使用connect 替代 AddObserver,避免出现多种事件机制架构
connect(_ImageViewer->GetSignalRaiser(),&vtkSignalRaiser::raiseEvent, this, &DicomImageView::syncEventFunc);
connect(mImageViewer->GetSignalRaiser(),&vtkSignalRaiser::raiseEvent, this, &DicomImageView::syncEventFunc);
//目前 替换了一部分包括SlicedEventEndDollyEventEndWindowLevelEventEndPanEvent主要关联到sync
ActorDraggableInteractorStyle *style = _ImageViewer->GetInteractorStyle();
ActorDraggableInteractorStyle *style = mImageViewer->GetInteractorStyle();
style->AddObserver(ActorDraggableInteractorStyle::AfterViewerClicked, this, &DicomImageView::viewerClicked);
style->AddObserver(vtkCommand::EventIds::WindowLevelEvent, this, &DicomImageView::updateWindowLevelCb);
style->AddObserver(ActorDraggableInteractorStyle::DoubleClickEvent, this, &DicomImageView::doubleclickedEventCb);
@@ -394,8 +350,8 @@ void DicomImageView::LoadSeries(SeriesImageSet *series)
//Callbacks------------------------------------------------------------------------------------
void DicomImageView::updateWindowLevelCb(vtkObject* caller, unsigned long eid, void *calldata)
{
_ImageViewer->updateCornerInfo(BOTTOM_RIGHT);
emit Signal_WindowLevelEventForFusion(_ImageViewer->GetColorLevel(), _ImageViewer->GetColorWindow());
mImageViewer->updateCornerInfo(BOTTOM_RIGHT);
emit Signal_WindowLevelEventForFusion(mImageViewer->GetColorLevel(), mImageViewer->GetColorWindow());
}
void DicomImageView::scalarEventCb(vtkObject* sender, unsigned long eventId, void* calldata)
@@ -405,7 +361,7 @@ void DicomImageView::scalarEventCb(vtkObject* sender, unsigned long eventId, voi
{
case(ActorDraggableInteractorStyle::ScalarShiftEvent):
qDebug() << "ScalarShiftEvent";
_ImageViewer->SwitchToNextPreset();
mImageViewer->SwitchToNextPreset();
break;
case(ActorDraggableInteractorStyle::ScalarOpacityEvent):
@@ -439,9 +395,14 @@ void DicomImageView::syncEventFunc(vtkObject* caller, unsigned long eid, void *c
case(ActorDraggableInteractorStyle::DraggableStyleEvents::EndDollyEvent):
this->Signal_SyncEvent(this, VTKIS_IMAGE_ZOOM, calldata);
break;
case(ActorDraggableInteractorStyle::DraggableStyleEvents::SlicedEvent):
_scrollBar->setValue(r[0]);
break;
case(ActorDraggableInteractorStyle::DraggableStyleEvents::SlicedEvent):{
mScrollBar->SetValueSilently(r[0]);
//invoke event
double focusPoint[3] = {.0, .0, .0};
mImageViewer->GetSlicePoint(focusPoint);
this->Signal_SyncEvent(this, VTKIS_IMAGE_SLICING, focusPoint);
break;
}
default:
break;
}
@@ -453,21 +414,17 @@ void DicomImageView::ResetView()
{
removeViewWithFusion();
removeViewWithMeasure();
_ImageViewer->GetRenderer()->RemoveAllViewProps();
mImageViewer->GetRenderer()->RemoveAllViewProps();
this->Render();
_ImageViewer->Delete();
_ImageViewer = nullptr;
mImageViewer->Delete();
mImageViewer = nullptr;
//don't delete series It's belong to data cache
_Series = nullptr;
_ScrollTriggerType = scrollScope::TriggerType::USER_TRIGGER;
_PrevSlice = 0;
_SliceStep = 0;
mSeries = nullptr;
}
_scrollBar->setVisible(false);
if (isCine)
_vcr_toolbar->setVisible(false);
mScrollBar->setVisible(false);
if (mIsCine)
mVcrToolbar->setVisible(false);
}
@@ -475,7 +432,7 @@ int DicomImageView::getSeriesNumber()
{
if (HasSeries())
{
return _Series->GetSeriesNumber();
return mSeries->GetSeriesNumber();
}
return -1;
}
@@ -483,7 +440,7 @@ int DicomImageView::getSeriesNumber()
void DicomImageView::ShowMetaData()
{
QString fileName = QString::fromLatin1(this->_Series->getCurImageName());
QString fileName = QString::fromLatin1(this->mSeries->getCurImageName());
if (!fileName.isEmpty()) {
DcmFileFormat dcmFile;
if (!dcmFile.loadFile(fileName.toStdString()).good())
@@ -510,40 +467,36 @@ void DicomImageView::Render()
{
if (HasSeries())
{
if (_ImageViewer->GetvtkCornerAnnotation()) {
_ImageViewer->GetvtkCornerAnnotation()->SetMaximumFontSize(FontSizeHelper::getSize(frameGeometry().size()));
if (mImageViewer->GetvtkCornerAnnotation()) {
mImageViewer->GetvtkCornerAnnotation()->SetMaximumFontSize(FontSizeHelper::getSize(frameGeometry().size()));
}
_ImageViewer->Render();
mImageViewer->Render();
}
}
void DicomImageView::SetSlice(int slice)
{
if (_ImageViewer == nullptr)
if (mImageViewer == nullptr)
{
return;
}
if (HasSeries())
{
_ImageViewer->SetSlice(slice);
//_ImageViewer->updateCornerInfo(TOP_LEFT);
_scrollBar->setValue(slice);
mImageViewer->SetSlice(slice);
}
}
void DicomImageView::AddSlice(int step)
{
if (_ImageViewer == nullptr)
if (mImageViewer == nullptr)
{
return;
}
if (HasSeries())
{
int curSlice = _ImageViewer->GetSlice() + step;
_ImageViewer->SetSlice(curSlice);
_scrollBar->setValue(curSlice);
int curSlice = mImageViewer->GetSlice() + step;
mImageViewer->SetSlice(curSlice);
}
}
@@ -551,8 +504,8 @@ void DicomImageView::SetZoomScale(double scale)
{
if (HasSeries())
{
_ImageViewer->SetZoomScale(scale);
_ImageViewer->Render();
mImageViewer->SetZoomScale(scale);
mImageViewer->Render();
}
}
@@ -561,8 +514,8 @@ void DicomImageView::SetPanOffset(double * pan)
if (HasSeries())
{
_ImageViewer->SetPanOffset(pan);
_ImageViewer->Render();
mImageViewer->SetPanOffset(pan);
mImageViewer->Render();
}
}
@@ -571,7 +524,7 @@ void DicomImageView::ResetPanZoom()
{
if (HasSeries())
{
_ImageViewer->ResetZoomScaleToFitWindowSize();
mImageViewer->ResetZoomScaleToFitWindowSize();
}
}
@@ -581,11 +534,11 @@ void DicomImageView::SetWindowLevel(double level, double width)
if (HasSeries())
{
_ImageViewer->SetColorLevel(level);
_ImageViewer->SetColorWindow(width);
mImageViewer->SetColorLevel(level);
mImageViewer->SetColorWindow(width);
//You have to call updateConerInfo manually
//only mouse event can rely on callback
_ImageViewer->updateCornerInfo(BOTTOM_RIGHT);
mImageViewer->updateCornerInfo(BOTTOM_RIGHT);
emit Signal_WindowLevelEventForFusion(level, width);
}
@@ -594,8 +547,8 @@ void DicomImageView::SetWindowLevel(double level, double width)
void DicomImageView::GetWindowLevel(double &level, double &width) {
if (HasSeries())
{
level = _ImageViewer->GetColorLevel();
width = _ImageViewer->GetColorWindow();
level = mImageViewer->GetColorLevel();
width = mImageViewer->GetColorWindow();
}
}
@@ -603,15 +556,15 @@ void DicomImageView::ToggleNegativeMode()
{
if (HasSeries())
{
if (isNegative)
if (mIsNegative)
{
_ImageViewer->SetNegativeMode(false);
isNegative = false;
mImageViewer->SetNegativeMode(false);
mIsNegative = false;
}
else
{
_ImageViewer->SetNegativeMode(true);
isNegative = true;
mImageViewer->SetNegativeMode(true);
mIsNegative = true;
}
}
@@ -620,17 +573,17 @@ void DicomImageView::ToggleNegativeMode()
void DicomImageView::HFlip()
{
if (HasSeries()) {
int slice = _ImageViewer->GetSlice();
int slice = mImageViewer->GetSlice();
//HFlip
//_ImageViewer->GetRenderer()->GetActiveCamera()->SetViewUp(0, 1, 0);
_ImageViewer->GetRenderer()->GetActiveCamera()->Azimuth(180);
//mImageViewer->GetRenderer()->GetActiveCamera()->SetViewUp(0, 1, 0);
mImageViewer->GetRenderer()->GetActiveCamera()->Azimuth(180);
FlipExportHelper::toggleFlip();
//to avoid black out problem during slicing
//slicing is related with rotation, you have to recalculate to get it right
_ImageViewer->GetRenderer()->ResetCameraClippingRange();
_ImageViewer->SetSlice(slice);
mImageViewer->GetRenderer()->ResetCameraClippingRange();
mImageViewer->SetSlice(slice);
_ImageViewer->GetRenderWindow()->Render();
mImageViewer->GetRenderWindow()->Render();
emit Signal_Transformation(H_FLIP);
}
}
@@ -638,20 +591,20 @@ void DicomImageView::HFlip()
void DicomImageView::VFlip()
{
if (HasSeries()) {
//double scale = _ImageViewer->GetRenderer()->GetActiveCamera()->GetParallelScale();
//double scale = mImageViewer->GetRenderer()->GetActiveCamera()->GetParallelScale();
int slice = _ImageViewer->GetSlice();
int slice = mImageViewer->GetSlice();
//Method 2: Order matters
_ImageViewer->GetRenderer()->GetActiveCamera()->Elevation(-180);
_ImageViewer->GetRenderer()->GetActiveCamera()->Roll(180);
//_ImageViewer->GetRenderer()->GetActiveCamera()->SetViewUp(0,-1,0);
mImageViewer->GetRenderer()->GetActiveCamera()->Elevation(-180);
mImageViewer->GetRenderer()->GetActiveCamera()->Roll(180);
//mImageViewer->GetRenderer()->GetActiveCamera()->SetViewUp(0,-1,0);
FlipExportHelper::toggleFlip();
//to avoid black out problem during slicing
//slicing is related with rotation, you have to recalculate to get it right
_ImageViewer->GetRenderer()->ResetCameraClippingRange();
_ImageViewer->SetSlice(slice);
_ImageViewer->GetRenderWindow()->Render();
mImageViewer->GetRenderer()->ResetCameraClippingRange();
mImageViewer->SetSlice(slice);
mImageViewer->GetRenderWindow()->Render();
emit Signal_Transformation(V_FLIP);
}
@@ -660,13 +613,13 @@ void DicomImageView::VFlip()
void DicomImageView::Rotate(double angle, TransFormType operation)
{
if (HasSeries()) {
int slice = _ImageViewer->GetSlice();
_ImageViewer->GetRenderer()->GetActiveCamera()->Roll(angle);
int slice = mImageViewer->GetSlice();
mImageViewer->GetRenderer()->GetActiveCamera()->Roll(angle);
//to avoid black out problem during slicing
//slcing is related with rotation, you have to recalculate to get it right
_ImageViewer->GetRenderer()->ResetCameraClippingRange();
_ImageViewer->SetSlice(slice);
// _ImageViewer->GetRenderWindow()->Render();
mImageViewer->GetRenderer()->ResetCameraClippingRange();
mImageViewer->SetSlice(slice);
// mImageViewer->GetRenderWindow()->Render();
emit Signal_Transformation(operation);
}
@@ -676,21 +629,21 @@ void DicomImageView::ClearTransformations()
{
if (HasSeries())
{
int slice = _ImageViewer->GetSlice();
int slice = mImageViewer->GetSlice();
ResetPanZoom();
double cameraPosition[3];
double vup[3];
_Series->getCameraCfg(vup, cameraPosition);
mSeries->getCameraCfg(vup, cameraPosition);
//necessary to reset flip and rotate
_ImageViewer->GetRenderer()->GetActiveCamera()->SetPosition(cameraPosition);
_ImageViewer->GetRenderer()->GetActiveCamera()->SetViewUp(vup);
mImageViewer->GetRenderer()->GetActiveCamera()->SetPosition(cameraPosition);
mImageViewer->GetRenderer()->GetActiveCamera()->SetViewUp(vup);
//avoid black out problem
_ImageViewer->GetRenderer()->ResetCameraClippingRange();
_ImageViewer->SetSlice(slice);
mImageViewer->GetRenderer()->ResetCameraClippingRange();
mImageViewer->SetSlice(slice);
//Render
_ImageViewer->GetRenderWindow()->Render();
mImageViewer->GetRenderWindow()->Render();
emit Signal_Transformation(CLEAR);
}
}
@@ -699,7 +652,7 @@ void DicomImageView::updateCornerInfoAll()
{
if (HasSeries())
{
_ImageViewer->updateCornerInfoAll();
mImageViewer->updateCornerInfoAll();
}
}
@@ -707,141 +660,141 @@ void DicomImageView::updateCornerInfoPrivacy()
{
if (HasSeries())
{
_ImageViewer->updateCornerInfo(TOP_RIGHT);
mImageViewer->updateCornerInfo(TOP_RIGHT);
}
}
//--VCR about------------------------------------------------------------------
bool DicomImageView::isVCRVisible()
{
if (!_vcr_toolbar) return false;
return _vcr_toolbar->isVisible();
if (!mVcrToolbar) return false;
return mVcrToolbar->isVisible();
}
void DicomImageView::setVCRVisible(bool visible)
{
if (!_vcr_toolbar) return ;
_vcr_toolbar->setVisible(visible);
if (!mVcrToolbar) return ;
mVcrToolbar->setVisible(visible);
}
void DicomImageView::cineModeOn()
{
if (!_vcr_toolbar) return;
if (!mVcrToolbar) return;
//updateVCRToolbarPos();
int ax = (this->geometry().bottomLeft().x() + this->geometry().bottomRight().x()) / 2 + VCRHelper::getVCRXOffset();
int ay = (this->geometry().bottomLeft().y() + this->geometry().bottomRight().y()) / 2 + VCRHelper::getVCRYOffset();
_vcr_toolbar->move(ax, ay);
mVcrToolbar->move(ax, ay);
_vcr_toolbar->show();
mVcrToolbar->show();
this->initCineModeThread();
_vcr_toolbar->reConnectController(_vcr_ctrl);
mVcrToolbar->reConnectController(mVcrController);
}
void DicomImageView::initCineModeThread()
{
_vcr_ctrl = new pqVCRController(nullptr, this);
_vcr_ctrl->moveToThread(&_thread);
connect(&_thread, &QThread::finished, _vcr_ctrl, &QObject::deleteLater);
_thread.start();
isCine = true;
mVcrController = new pqVCRController(nullptr, this);
mVcrController->moveToThread(&mVcrControlThread);
connect(&mVcrControlThread, &QThread::finished, mVcrController, &QObject::deleteLater);
mVcrControlThread.start();
mIsCine = true;
}
void DicomImageView::onFirstFrame()
{
if (HasSeries()) {
_scrollBar->setValue(_ImageViewer->GetSliceMin());
mScrollBar->setValue(mImageViewer->GetSliceMin());
}
}
void DicomImageView::onPreviousFrame()
{
if (HasSeries()) {
int slice = _ImageViewer->GetSlice();
int slice = mImageViewer->GetSlice();
slice = --slice;
int min_slice = _ImageViewer->GetSliceMin();
int min_slice = mImageViewer->GetSliceMin();
if (slice < min_slice)
{
slice = _ImageViewer->GetSliceMax();
slice = mImageViewer->GetSliceMax();
}
_scrollBar->setValue(slice);
mScrollBar->setValue(slice);
}
}
void DicomImageView::onNextFrame()
{
if (HasSeries()) {
int slice = _ImageViewer->GetSlice();
int slice = mImageViewer->GetSlice();
slice = ++slice;
int max_slice = _ImageViewer->GetSliceMax();
int max_slice = mImageViewer->GetSliceMax();
if (slice > max_slice)
{
slice = _ImageViewer->GetSliceMin();
slice = mImageViewer->GetSliceMin();
}
_scrollBar->setValue(slice);
mScrollBar->setValue(slice);
}
}
void DicomImageView::onLastFrame()
{
if (HasSeries()) {
_scrollBar->setValue(_ImageViewer->GetSliceMax());
mScrollBar->setValue(mImageViewer->GetSliceMax());
}
}
//-- Measure about--------------------------------------------------------------------------------------
void DicomImageView::ActiveMeasure(Measure *m)
{
if (nullptr != _Series)
if (nullptr != mSeries)
{
_ImageViewer->ActiveMeasure(m);
mImageViewer->ActiveMeasure(m);
}
}
void DicomImageView::DeleteSelectedMeasure()
{
if (nullptr != _Series)
if (nullptr != mSeries)
{
_ImageViewer->DeleteSelectedMeasure();
mImageViewer->DeleteSelectedMeasure();
}
}
void DicomImageView::DeleteCurrentSliceMeasure()
{
if (nullptr != _Series)
if (nullptr != mSeries)
{
_ImageViewer->DeleteCurrentSliceMeasure();
mImageViewer->DeleteCurrentSliceMeasure();
}
}
void DicomImageView::DeleteCurrentSeriesMeasure()
{
if (nullptr != _Series)
if (nullptr != mSeries)
{
_ImageViewer->DeleteCurrentSeriesMeasure();
mImageViewer->DeleteCurrentSeriesMeasure();
}
}
void DicomImageView::removeViewWithMeasure()
{
_ImageViewer->UnActiveMeasure();
_ImageViewer->DeleteCurrentSeriesMeasure();
mImageViewer->UnActiveMeasure();
mImageViewer->DeleteCurrentSeriesMeasure();
}
void DicomImageView::SetSliceOrientation(int orientation) {
slice_orientation = orientation;
_ImageViewer->SetSliceOrientation(orientation);
mSliceOrientation = orientation;
mImageViewer->SetSliceOrientation(orientation);
int max = 0;
int min = 0;
_ImageViewer->GetSliceRange(min, max);
_scrollBar->setValue(min);
_scrollBar->setMaximum(max);
_scrollBar->setValue(0);
mImageViewer->GetSliceRange(min, max);
mScrollBar->setValue(min);
mScrollBar->setMaximum(max);
mScrollBar->setValue(0);
}
int DicomImageView::GetSliceOrientation() {
return slice_orientation;
return mSliceOrientation;
}
void DicomImageView::viewerClicked() {
@@ -849,8 +802,8 @@ void DicomImageView::viewerClicked() {
}
void DicomImageView::SyncScrollBar() {
setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY);
_scrollBar->setValue(_ImageViewer->GetSlice());
_ImageViewer->updateCornerInfo(TOP_LEFT);
setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER);
// setScrollChangedType(scrollScope::TriggerType::SYNC_ONLY);
mScrollBar->SetValueSilently(mImageViewer->GetSlice());
mImageViewer->updateCornerInfo(TOP_LEFT);
// setScrollChangedType(scrollScope::TriggerType::USER_TRIGGER);
}

View File

@@ -1,163 +1,192 @@
#pragma once
#ifndef OMEGAV_DICOM_IMAGE_VIEW_H
#define OMEGAV_DICOM_IMAGE_VIEW_H
#include <QFrame>
#include <QOpenGLWidget>
#include "UI/Widget/ClickableScrollBar.h"
#include <QGridLayout>
#include "Common/SeriesImageSet.h"
#include <QThread>
#include "Common/SeriesImageSet.h"
#include "UI/Widget/ClickableScrollBar.h"
#include "Rendering/infinitiViewer.h"
class vtkCornerAnnotation;
class vtkGenericOpenGLRenderWindow;
class MyTitleBar;
class pqVCRController;
class pqVCRToolbar;
class QVTKOpenGLNativeWidget;
class Measure;
namespace scrollScope {
enum TriggerType
{
USER_TRIGGER, //a,b,c
STYLE_TRIGGER,//b,c
SYNC_ONLY,//do nothing
};
}
class DicomImageView : public QFrame
{
Q_OBJECT
class DicomImageView : public QFrame {
Q_OBJECT
public:
//a:real effect
//b:corner info update
//c:scroll value sync
explicit DicomImageView(QWidget* parent = Q_NULLPTR);
~DicomImageView() override;
void ShowMetaData();
QVTKOpenGLNativeWidget* getGLWidget()
{
return _glWidt;
}
infinitiViewer* getImageViewer()
{
return _ImageViewer;
}
explicit DicomImageView(QWidget *parent = Q_NULLPTR);
void setScrollChangedType(int type)
{
_ScrollTriggerType = type;
}
void setHighlight(bool yes);
void Render();
~DicomImageView() override;
//Series
void setDicomImageView(SeriesImageSet *series);
bool HasSeries();
int getSeriesNumber();
SeriesImageSet* getSeriesInstance()
{
return _Series;
}
void ShowMetaData();
//Reset
void ResetView();
QVTKOpenGLNativeWidget *getGLWidget() {
return mGLWidget;
}
infinitiViewer *getImageViewer() {
return mImageViewer;
}
void setHighlight(bool yes);
void Render();
//Series
void setDicomImageView(SeriesImageSet *series);
bool HasSeries();
int getSeriesNumber();
SeriesImageSet *getSeriesInstance() {
return mSeries;
}
//Reset
void ResetView();
//Corner Info
void updateCornerInfoAll();
void updateCornerInfoPrivacy();
//Corner Info
void updateCornerInfoAll();
//Window level
void GetWindowLevel(double &level, double &width);
void SetWindowLevel(double level, double width);
void updateCornerInfoPrivacy();
//Transformation
void ClearTransformations();
void HFlip();
void VFlip();
void Rotate(double angle, TransFormType operation);
//Window level
void GetWindowLevel(double &level, double &width);
void SetWindowLevel(double level, double width);
//Transformation
void ClearTransformations();
void HFlip();
void VFlip();
void Rotate(double angle, TransFormType operation);
//Fusion
bool IsFusion();
void SetFusionOpacity(double percent);
void SetFusionInput(DicomImageView *overlap);
void removeViewWithFusion();
//Fusion
bool IsFusion();
void SetFusionOpacity(double percent);
void SetFusionInput(DicomImageView *overlap);
void removeViewWithFusion();
//Measure
void ActiveMeasure(Measure *m);
void DeleteSelectedMeasure();
void DeleteCurrentSliceMeasure();
void DeleteCurrentSeriesMeasure();
void removeViewWithMeasure();
//Measure
void ActiveMeasure(Measure *m);
void DeleteSelectedMeasure();
void DeleteCurrentSliceMeasure();
void DeleteCurrentSeriesMeasure();
void removeViewWithMeasure();
//Sync slice
void AddSlice(int step);
void SetSlice(int slice);
void SetZoomScale(double scale);
void SetPanOffset(double * p);
void SyncScrollBar();
//Sync slice
void AddSlice(int step);
//CineMode
void onFirstFrame();
void onPreviousFrame();
void onNextFrame();
void onLastFrame();
bool IsCine() { return isCine; }
void cineModeOn();
bool isVCRVisible();
void setVCRVisible(bool);
void setVCRToolbar(pqVCRToolbar* toolbar)
{
_vcr_toolbar = toolbar;
}
pqVCRToolbar* getVCRToolbar()
{
return _vcr_toolbar;
}
pqVCRController* getVCRController()
{
return _vcr_ctrl;
}
void SetSlice(int slice);
//Negative
void ToggleNegativeMode();
void SetZoomScale(double scale);
void SetPanOffset(double *p);
void SyncScrollBar();
//CineMode
void onFirstFrame();
void onPreviousFrame();
void onNextFrame();
void onLastFrame();
bool IsCine() { return mIsCine; }
void cineModeOn();
bool isVCRVisible();
void setVCRVisible(bool);
void setVCRToolbar(pqVCRToolbar *toolbar) {
mVcrToolbar = toolbar;
}
pqVCRToolbar *getVCRToolbar() {
return mVcrToolbar;
}
pqVCRController *getVCRController() {
return mVcrController;
}
//Negative
void ToggleNegativeMode();
void SetSliceOrientation(int orientation);
void SetSliceOrientation(int orientation);
int GetSliceOrientation();
bool CompareWorldSliceOrientation(DicomImageView* view){
return this->_ImageViewer->GetWorldSliceOrientation() == view->_ImageViewer->GetWorldSliceOrientation();
bool CompareWorldSliceOrientation(DicomImageView *view) {
return this->mImageViewer->GetWorldSliceOrientation() == view->mImageViewer->GetWorldSliceOrientation();
}
void SyncSlicePoint(double* point){
_ImageViewer->SyncSlicePoint(point);
_ImageViewer->Render();
void SyncSlicePoint(double *point) {
mImageViewer->SyncSlicePoint(point);
mImageViewer->Render();
}
signals:
/**
* This signal will be emitted whenever a mouse event occurs within the QVTK window.
*/
void scroll_ValueChanged(int);
void Signal_ViewEmpty(DicomImageView *view);
void Signal_ViewClicked(DicomImageView *view);
void Signal_viewDoubleclicked(DicomImageView *view);
void Signal_scrollValueChanged(DicomImageView *view, int slice);
void Signal_DragDropEvent(DicomImageView *view,thumbnailImage* tb);
void Signal_SyncEvent(DicomImageView *view, int interactionMode,void* calldata);
void Signal_WindowLevelEventForFusion(double level,double width);
void Signal_Transformation(TransFormType);
void Signal_ViewEmpty(DicomImageView *view);
void Signal_ViewClicked(DicomImageView *view);
void Signal_viewDoubleclicked(DicomImageView *view);
void Signal_DragDropEvent(DicomImageView *view, thumbnailImage *tb);
void Signal_SyncEvent(DicomImageView *view, int interactionMode, void *calldata);
void Signal_WindowLevelEventForFusion(double level, double width);
void Signal_Transformation(TransFormType);
public slots:
//for title bar use
void Slot_viewDoubleclicked();
void Slot_ViewEmpty();
void Slot_scrollValueChanged(int);
void Slot_WindowLevelEventForFusion(double level, double width);
void Slot_Transformation();
//for title bar use
void Slot_viewDoubleclicked();
void Slot_ViewEmpty();
void Slot_scrollValueChanged(int);
void Slot_WindowLevelEventForFusion(double level, double width);
void Slot_Transformation();
void viewerClicked();
protected:
@@ -166,82 +195,108 @@ protected:
* @attention 只能捕获到titlebar区域的点击
* @param event
*/
void mousePressEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void dragEnterEvent(QDragEnterEvent *e);
void dragMoveEvent(QDragMoveEvent *e);
void dropEvent(QDropEvent *e);
void dragLeaveEvent(QDragLeaveEvent *e);
void resizeEvent(QResizeEvent *event);
void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
/**
* @brief DicomImageView::dragEnterEvent
* 拖拽进入
* @param e
*/
void dragEnterEvent(QDragEnterEvent *e) Q_DECL_OVERRIDE;
/**
* @brief DicomImageView::dragMoveEvent
* 拖拽移动
* @param e
*/
void dragMoveEvent(QDragMoveEvent *e) Q_DECL_OVERRIDE;
/**
* @brief DicomImageView::dropEvent
* 拖拽松开
* @param e
*/
void dropEvent(QDropEvent *e) Q_DECL_OVERRIDE;
/**
* @brief DicomImageView::dragLeaveEvent
* 离开事件
* @param e
*/
void dragLeaveEvent(QDragLeaveEvent *e) Q_DECL_OVERRIDE;
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
private:
void removeFusion();
void removeFusion();
void OverlayOn()
{
isOverlay = true;
}
void OverlayOff()
{
isOverlay = false;
}
bool IsOverlay()
{
return isOverlay;
}
void SetBaseView(DicomImageView *v)
{
_base = v;
}
void SetOverlayView(DicomImageView *v)
{
_overlay = v;
}
void OverlayOn() {
mIsOverlay = true;
}
void OverlayOff() {
mIsOverlay = false;
}
bool IsOverlay() {
return mIsOverlay;
}
void SetBaseView(DicomImageView *v) {
mBaseView = v;
}
void SetOverlayView(DicomImageView *v) {
mOverlayView = v;
}
//Callback
void doubleclickedEventCb(vtkObject* sender, unsigned long eventId, void* calldata = nullptr);
void scalarEventCb(vtkObject* sender, unsigned long eventId, void* calldata = nullptr);
void updateWindowLevelCb(vtkObject*caller, unsigned long eid, void *calldata);
void syncEventFunc(vtkObject*caller, unsigned long eid, void *calldata);
//Callback
void doubleclickedEventCb(vtkObject *sender, unsigned long eventId, void *calldata = nullptr);
void scalarEventCb(vtkObject *sender, unsigned long eventId, void *calldata = nullptr);
void updateWindowLevelCb(vtkObject *caller, unsigned long eid, void *calldata);
void syncEventFunc(vtkObject *caller, unsigned long eid, void *calldata);
void initCineModeThread();
void initCineModeThread();
/**
* create a TitleBar for this widget
* @return
*/
MyTitleBar* createMyTitleBar();
/**
* create a TitleBar for this widget
* @return
*/
MyTitleBar *createMyTitleBar();
void ResetPanZoom();
void initScrollbar();
void LoadSeries(SeriesImageSet *series);
vtkSmartPointer <vtkGenericOpenGLRenderWindow> m_glrenWin;
void initScrollbar();
infinitiViewer* _ImageViewer = nullptr;
SeriesImageSet* _Series = nullptr;
ClickableScrollBar* _scrollBar =nullptr;
MyTitleBar *_titleBar =nullptr;
QVTKOpenGLNativeWidget* _glWidt = nullptr;
pqVCRToolbar* _vcr_toolbar = nullptr;
pqVCRController *_vcr_ctrl = nullptr;
QThread _thread;
DicomImageView *_overlay = nullptr;
DicomImageView *_base = nullptr;
void LoadSeries(SeriesImageSet *series);
int _SliceStep =0;
int _PrevSlice =0;
int _ScrollTriggerType = scrollScope::TriggerType::USER_TRIGGER;
int slice_orientation = 2;
vtkSmartPointer<vtkGenericOpenGLRenderWindow> mGLRenWin;
bool isCine = false;
bool isNegative = false;
bool isOverlay = false;
bool slotInited = false;
infinitiViewer *mImageViewer = nullptr;
SeriesImageSet *mSeries = nullptr;
ClickableScrollBar *mScrollBar = nullptr;
MyTitleBar *mTitleBar = nullptr;
QVTKOpenGLNativeWidget *mGLWidget = nullptr;
pqVCRToolbar *mVcrToolbar = nullptr;
pqVCRController *mVcrController = nullptr;
QThread mVcrControlThread;
DicomImageView *mOverlayView = nullptr;
DicomImageView *mBaseView = nullptr;
int mSliceOrientation = 2;
bool mIsCine = false;
bool mIsNegative = false;
bool mIsOverlay = false;
bool mIsSlotInited = false;
};
#endif