Add ReferenceLine.(need fix resize logic)
This commit is contained in:
@@ -27,9 +27,11 @@ ReferenceLineLegendActor::ReferenceLineLegendActor() {
|
|||||||
shadow2D->SetMapper(mapper2);
|
shadow2D->SetMapper(mapper2);
|
||||||
actor2D->GetProperty()->SetLineWidth(1.0);
|
actor2D->GetProperty()->SetLineWidth(1.0);
|
||||||
//马尔斯绿
|
//马尔斯绿
|
||||||
actor2D->GetProperty()->SetColor(0.004, 0.515, 0.5);
|
actor2D->GetProperty()->SetColor(0.98, 0.82, 0.414);
|
||||||
shadow2D->GetProperty()->SetColor(0.0, 0.0, 0.0);
|
shadow2D->GetProperty()->SetColor(0.68, 0.52, 0.114);
|
||||||
|
// shadow2D->GetProperty()->SetColor(0.0, 0.0, 0.0);
|
||||||
shadow2D->GetProperty()->SetLineWidth(3.0);
|
shadow2D->GetProperty()->SetLineWidth(3.0);
|
||||||
|
shadow2D->GetProperty()->SetOpacity(0.75);
|
||||||
linePoints->SetNumberOfPoints(4);
|
linePoints->SetNumberOfPoints(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,15 +53,19 @@ int ReferenceLineLegendActor::RenderOverlay(vtkViewport *viewport) {
|
|||||||
auto renderer = vtkRenderer::SafeDownCast(viewport);
|
auto renderer = vtkRenderer::SafeDownCast(viewport);
|
||||||
if (!renderer) return 0;
|
if (!renderer) return 0;
|
||||||
BuildShape(renderer);
|
BuildShape(renderer);
|
||||||
|
if (Visibility){
|
||||||
shadow2D->RenderOverlay(viewport);
|
shadow2D->RenderOverlay(viewport);
|
||||||
return actor2D->RenderOverlay(viewport);
|
return actor2D->RenderOverlay(viewport);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReferenceLineLegendActor::BuildShape(vtkRenderer *renderer) {
|
void ReferenceLineLegendActor::BuildShape(vtkRenderer *renderer) {
|
||||||
if(mModifyTime == MTime)return;
|
if (mModifyTime == MTime)return;
|
||||||
|
if (Visibility) {
|
||||||
|
|
||||||
vtkNew<vtkPoints> pts;
|
vtkNew<vtkPoints> pts;
|
||||||
for(vtkIdType i = 0; i<linePoints->GetNumberOfPoints(); ++i)
|
for (vtkIdType i = 0; i < linePoints->GetNumberOfPoints(); ++i) {
|
||||||
{
|
|
||||||
double p[3] = {.0, .0, .0};
|
double p[3] = {.0, .0, .0};
|
||||||
renderer->SetWorldPoint(linePoints->GetPoint(i));
|
renderer->SetWorldPoint(linePoints->GetPoint(i));
|
||||||
renderer->WorldToDisplay();
|
renderer->WorldToDisplay();
|
||||||
@@ -69,23 +75,22 @@ void ReferenceLineLegendActor::BuildShape(vtkRenderer *renderer) {
|
|||||||
double p1[3] = {.0, .0, .0};
|
double p1[3] = {.0, .0, .0};
|
||||||
double p2[3] = {.0, .0, .0};
|
double p2[3] = {.0, .0, .0};
|
||||||
pts->GetPoint(0, p1);
|
pts->GetPoint(0, p1);
|
||||||
pts->GetPoint(1, p1);
|
|
||||||
double dis2 = vtkMath::Distance2BetweenPoints(p1,p2);
|
|
||||||
pts->GetPoint(2, p1);
|
pts->GetPoint(2, p1);
|
||||||
|
double dis2 = vtkMath::Distance2BetweenPoints(p1, p2);
|
||||||
|
pts->GetPoint(1, p1);
|
||||||
pts->GetPoint(3, p1);
|
pts->GetPoint(3, p1);
|
||||||
double dis2_2 = vtkMath::Distance2BetweenPoints(p1,p2);
|
double dis2_2 = vtkMath::Distance2BetweenPoints(p1, p2);
|
||||||
vtkNew<vtkPoints> displayPts;
|
vtkNew<vtkPoints> displayPts;
|
||||||
if (dis2>dis2_2){
|
if (dis2 > dis2_2) {
|
||||||
pts->GetPoint(0,p1);
|
pts->GetPoint(0, p1);
|
||||||
pts->GetPoint(1, p2);
|
pts->GetPoint(2, p2);
|
||||||
displayPts->InsertNextPoint(round(p1[0])+0.5,round(p1[1])+0.5, round(p1[2])+0.5 );
|
displayPts->InsertNextPoint(round(p1[0]) + 0.5, round(p1[1]) + 0.5, round(p1[2]) + 0.5);
|
||||||
displayPts->InsertNextPoint( round(p2[0])+0.5,round(p2[1])+0.5, round(p2[2])+0.5);
|
displayPts->InsertNextPoint(round(p2[0]) + 0.5, round(p2[1]) + 0.5, round(p2[2]) + 0.5);
|
||||||
}
|
} else {
|
||||||
else{
|
pts->GetPoint(1, p1);
|
||||||
pts->GetPoint(2,p1);
|
|
||||||
pts->GetPoint(3, p2);
|
pts->GetPoint(3, p2);
|
||||||
displayPts->InsertNextPoint( round(p1[0])+0.5,round(p1[1])+0.5, round(p1[2])+0.5);
|
displayPts->InsertNextPoint(round(p1[0]) ,round(p1[1]) , round(p1[2]) );
|
||||||
displayPts->InsertNextPoint( round(p2[0])+0.5,round(p2[1])+0.5, round(p2[2])+0.5);
|
displayPts->InsertNextPoint(round(p2[0]) , round(p2[1]) , round(p2[2]) );
|
||||||
}
|
}
|
||||||
vtkNew<vtkPolyLineSource> source;
|
vtkNew<vtkPolyLineSource> source;
|
||||||
source->SetPoints(displayPts);
|
source->SetPoints(displayPts);
|
||||||
@@ -93,5 +98,6 @@ void ReferenceLineLegendActor::BuildShape(vtkRenderer *renderer) {
|
|||||||
renderData->DeepCopy(source->GetOutput());
|
renderData->DeepCopy(source->GetOutput());
|
||||||
shadow2D->GetMapper()->SetInputDataObject(renderData);
|
shadow2D->GetMapper()->SetInputDataObject(renderData);
|
||||||
actor2D->GetMapper()->SetInputDataObject(renderData);
|
actor2D->GetMapper()->SetInputDataObject(renderData);
|
||||||
|
}
|
||||||
mModifyTime = MTime;
|
mModifyTime = MTime;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ infinitiViewer::infinitiViewer()
|
|||||||
SliceOrientation(infinitiViewer::SLICE_ORIENTATION_XY), FirstRender(1), Slice(0), loadedMeasureSlice(0),
|
SliceOrientation(infinitiViewer::SLICE_ORIENTATION_XY), FirstRender(1), Slice(0), loadedMeasureSlice(0),
|
||||||
currentPresetIndex(1), Fusion(false), firstFusion(true), FusionOpacity(0.5), list(nullptr),
|
currentPresetIndex(1), Fusion(false), firstFusion(true), FusionOpacity(0.5), list(nullptr),
|
||||||
measureStore(MeasureStore::Instance()),
|
measureStore(MeasureStore::Instance()),
|
||||||
rulerActive(false) {
|
rulerActive(false){
|
||||||
this->ImageMapper->SliceAtFocalPointOn();
|
this->ImageMapper->SliceAtFocalPointOn();
|
||||||
this->ImageMapper->SliceFacesCameraOn();
|
this->ImageMapper->SliceFacesCameraOn();
|
||||||
this->ImageActor->SetPickable(true);
|
this->ImageActor->SetPickable(true);
|
||||||
@@ -185,7 +185,8 @@ void infinitiViewer::SetRenderWindow(vtkRenderWindow *arg) {
|
|||||||
if (this->RenderWindow) {
|
if (this->RenderWindow) {
|
||||||
this->RenderWindow->Register(this);
|
this->RenderWindow->Register(this);
|
||||||
}
|
}
|
||||||
this->RenderWindow->AddObserver(vtkCommand::EventIds::RenderEvent, this, &infinitiViewer::RenderRuler);
|
//add legend to render
|
||||||
|
this->RenderWindow->AddObserver(vtkCommand::EventIds::RenderEvent, this, &infinitiViewer::RenderLegend);
|
||||||
this->InstallPipeline();
|
this->InstallPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,6 +221,7 @@ void infinitiViewer::SetInputData(vtkImageData *in) {
|
|||||||
this->ImageActor->GetMapper()->SetInputData(in);
|
this->ImageActor->GetMapper()->SetInputData(in);
|
||||||
this->RemoveFusionData();
|
this->RemoveFusionData();
|
||||||
this->ActiveRuler();
|
this->ActiveRuler();
|
||||||
|
this-> ActiveReferenceLine();
|
||||||
double zVec = in->GetSpacing()[2];
|
double zVec = in->GetSpacing()[2];
|
||||||
defaultProjection[2][2] = zVec>0.0?1.0:-1.0;
|
defaultProjection[2][2] = zVec>0.0?1.0:-1.0;
|
||||||
}
|
}
|
||||||
@@ -503,13 +505,14 @@ void infinitiViewer::applySliceOffset(double offset, double direction){
|
|||||||
UpdateTopLeftCornerInfo();
|
UpdateTopLeftCornerInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkSmartPointer<vtkPoints> infinitiViewer::GetSliceBoundPoints() {
|
vtkPoints* infinitiViewer::GetSliceBoundPoints() {
|
||||||
double bounds[6] = {.0, .0, .0, .0, .0, .0};
|
double bounds[6] = {.0, .0, .0, .0, .0, .0};
|
||||||
ImageMapper->GetBounds(bounds);
|
ImageMapper->GetBounds(bounds);
|
||||||
vtkCamera *camera = this->Renderer->GetActiveCamera();
|
vtkCamera *camera = this->Renderer->GetActiveCamera();
|
||||||
double fpt[3] = {.0, .0, .0};
|
double fpt[3] = {.0, .0, .0};
|
||||||
camera->GetFocalPoint(fpt);
|
camera->GetFocalPoint(fpt);
|
||||||
bounds[SliceOrientation * 2] = fpt[SliceOrientation];
|
bounds[SliceOrientation * 2] = fpt[SliceOrientation];
|
||||||
|
bounds[SliceOrientation * 2+1] = fpt[SliceOrientation];
|
||||||
vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
|
vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
|
||||||
//只取4个点
|
//只取4个点
|
||||||
pts->InsertNextPoint(bounds[0], bounds[2], bounds[4]);
|
pts->InsertNextPoint(bounds[0], bounds[2], bounds[4]);
|
||||||
@@ -530,7 +533,34 @@ vtkSmartPointer<vtkPoints> infinitiViewer::GetSliceBoundPoints() {
|
|||||||
pts->InsertNextPoint(bounds[0], bounds[2], bounds[5]);
|
pts->InsertNextPoint(bounds[0], bounds[2], bounds[5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pts;
|
vtkPoints* worldPts = vtkPoints::New();
|
||||||
|
//model to world
|
||||||
|
for (vtkIdType i = 0; i < pts->GetNumberOfPoints(); ++i) {
|
||||||
|
double temp[4] = {.0, .0, .0, 1.};
|
||||||
|
pts->GetPoint(i, temp);
|
||||||
|
matrix->MultiplyPoint(temp, temp);
|
||||||
|
temp[0] = temp[0] + imageDataOrigin[0];
|
||||||
|
temp[1] = temp[1] + imageDataOrigin[1];
|
||||||
|
temp[2] = temp[2] + imageDataOrigin[2];
|
||||||
|
worldPts->InsertNextPoint(temp);
|
||||||
|
}
|
||||||
|
return worldPts;
|
||||||
|
}
|
||||||
|
|
||||||
|
void infinitiViewer::updateReferenceLine(vtkPoints* worldPts){
|
||||||
|
//model to world
|
||||||
|
matrix->Invert();
|
||||||
|
for (vtkIdType i = 0; i < worldPts->GetNumberOfPoints(); ++i) {
|
||||||
|
double temp[4] = {.0, .0, .0, 1.};
|
||||||
|
worldPts->GetPoint(i, temp);
|
||||||
|
temp[0] = temp[0] - imageDataOrigin[0];
|
||||||
|
temp[1] = temp[1] - imageDataOrigin[1];
|
||||||
|
temp[2] = temp[2] - imageDataOrigin[2];
|
||||||
|
matrix->MultiplyPoint(temp, temp);
|
||||||
|
referenceLine->setPoint(i,temp);
|
||||||
|
}
|
||||||
|
matrix->Invert();
|
||||||
|
Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void infinitiViewer::SyncSlicePoint(double *point) {
|
void infinitiViewer::SyncSlicePoint(double *point) {
|
||||||
@@ -1216,6 +1246,7 @@ void infinitiViewer::SetSliceOrientation(int orientation) {
|
|||||||
SetSlice(0);
|
SetSlice(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO:暂时只有正交数据!!!否则强制转型会有一些问题
|
||||||
int infinitiViewer::GetWorldSliceOrientation() {
|
int infinitiViewer::GetWorldSliceOrientation() {
|
||||||
double orientations[4] = {.0, .0, .0, 1.0};
|
double orientations[4] = {.0, .0, .0, 1.0};
|
||||||
orientations[SliceOrientation] = 1.0;
|
orientations[SliceOrientation] = 1.0;
|
||||||
@@ -1310,10 +1341,19 @@ void infinitiViewer::UnActiveRuler() {
|
|||||||
rulerActive = false;
|
rulerActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void infinitiViewer::RenderRuler() {
|
void infinitiViewer::ActiveReferenceLine() {
|
||||||
|
referenceLine->SetVisibility(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infinitiViewer::UnActiveReferenceLine() {
|
||||||
|
referenceLine->SetVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void infinitiViewer::RenderLegend() {
|
||||||
if (AnnoHelper::IsAnno()) {
|
if (AnnoHelper::IsAnno()) {
|
||||||
if (Renderer) {
|
if (Renderer) {
|
||||||
ruler->RenderOverlay(Renderer);
|
if (rulerActive)ruler->RenderOverlay(Renderer);
|
||||||
|
referenceLine->RenderOverlay(Renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
//for convert vtkEvent to Qt signal
|
//for convert vtkEvent to Qt signal
|
||||||
#include "Events/vtkSignalRaiser.h"
|
#include "Events/vtkSignalRaiser.h"
|
||||||
#include "Rendering/Legend/RulerLegendActor.h"
|
#include "Rendering/Legend/RulerLegendActor.h"
|
||||||
|
#include "Rendering/Legend/ReferenceLineLegendActor.h"
|
||||||
#include "Common/QGlobals.h"
|
#include "Common/QGlobals.h"
|
||||||
|
|
||||||
class vtkAlgorithm;
|
class vtkAlgorithm;
|
||||||
@@ -159,7 +160,9 @@ vtkTypeMacro(infinitiViewer, vtkObject);
|
|||||||
|
|
||||||
void ChangeSlice(vtkObject *, unsigned long eventid, void *calldata);
|
void ChangeSlice(vtkObject *, unsigned long eventid, void *calldata);
|
||||||
|
|
||||||
vtkSmartPointer<vtkPoints> GetSliceBoundPoints();
|
vtkPoints* GetSliceBoundPoints();
|
||||||
|
|
||||||
|
void updateReferenceLine(vtkPoints* pts);
|
||||||
|
|
||||||
//@{
|
//@{
|
||||||
/**
|
/**
|
||||||
@@ -369,6 +372,10 @@ vtkTypeMacro(infinitiViewer, vtkObject);
|
|||||||
|
|
||||||
void UnActiveRuler();
|
void UnActiveRuler();
|
||||||
|
|
||||||
|
void ActiveReferenceLine();
|
||||||
|
|
||||||
|
void UnActiveReferenceLine();
|
||||||
|
|
||||||
//for convert vtkEvent to Qt signal
|
//for convert vtkEvent to Qt signal
|
||||||
vtkSignalRaiser *GetSignalRaiser() {
|
vtkSignalRaiser *GetSignalRaiser() {
|
||||||
return &raiser;
|
return &raiser;
|
||||||
@@ -429,7 +436,7 @@ private:
|
|||||||
|
|
||||||
void UpdateTopLeftCornerInfo();
|
void UpdateTopLeftCornerInfo();
|
||||||
|
|
||||||
void RenderRuler();
|
void RenderLegend();
|
||||||
|
|
||||||
vtkRenderWindow *RenderWindow;
|
vtkRenderWindow *RenderWindow;
|
||||||
vtkRenderer *Renderer;
|
vtkRenderer *Renderer;
|
||||||
@@ -445,6 +452,7 @@ private:
|
|||||||
vtkScalarBarActor *bar;
|
vtkScalarBarActor *bar;
|
||||||
|
|
||||||
vtkNew<RulerLegendActor> ruler;
|
vtkNew<RulerLegendActor> ruler;
|
||||||
|
vtkNew<ReferenceLineLegendActor> referenceLine;
|
||||||
vtkNew<vtkMatrix4x4> matrix;
|
vtkNew<vtkMatrix4x4> matrix;
|
||||||
DicomCornerInfo m_cornerInfo;
|
DicomCornerInfo m_cornerInfo;
|
||||||
|
|
||||||
|
|||||||
@@ -105,31 +105,51 @@ void ImageViewManager::setCurrentView(DicomImageView *view) {
|
|||||||
if (currentView != view) {
|
if (currentView != view) {
|
||||||
if (currentView) currentView->setHighlight(false);
|
if (currentView) currentView->setHighlight(false);
|
||||||
currentView = view;
|
currentView = view;
|
||||||
|
|
||||||
currentView->setHighlight(true);
|
currentView->setHighlight(true);
|
||||||
emit currentViewReload(view);
|
reloadCurrentView(view);
|
||||||
// emit currentViewChanged(currentView->getSeriesInstance()->getUniqueID());
|
// emit currentViewChanged(currentView->getSeriesInstance()->getUniqueID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageViewManager::smartDo(SmartDoCallback cb, DicomImageView *sourceView, void *callData, DoScope scope) {
|
void ImageViewManager::smartDo(SmartDoCallback cb, DicomImageView *sourceView, void *callData, DoScope scope) {
|
||||||
|
smartDo(cb, nullptr, sourceView, callData, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageViewManager::smartDo(SmartDoCallback cb,SmartDoCallback otherCb, DicomImageView *sourceView, void *callData, DoScope scope) {
|
||||||
switch (scope) {
|
switch (scope) {
|
||||||
case DoScope::Current: {
|
case DoScope::Current: {
|
||||||
if (currentView)
|
if (currentView)
|
||||||
cb(currentView, callData);
|
cb(currentView, callData);
|
||||||
|
else{
|
||||||
|
if (otherCb){
|
||||||
|
std::for_each(vList.begin(), vList.end(), [=](auto v) {
|
||||||
|
//check series
|
||||||
|
if (v == sourceView) return;
|
||||||
|
if (!v->hasSeries()) return;
|
||||||
|
otherCb(v, callData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DoScope::SameSeries: {
|
case DoScope::SameSeries: {
|
||||||
std::for_each(vList.begin(), vList.end(), [=](auto v) {
|
std::for_each(vList.begin(), vList.end(), [=](auto v) {
|
||||||
|
if (v == sourceView) return;
|
||||||
|
if (!v->hasSeries()) return;
|
||||||
//check series
|
//check series
|
||||||
auto series = sourceView->getSeriesInstance();
|
auto series = sourceView->getSeriesInstance();
|
||||||
if (v->getSeriesInstance() == series && v->getSliceOrientation() == sourceView->getSliceOrientation()) {
|
if (v->getSeriesInstance() == series && v->getSliceOrientation() == sourceView->getSliceOrientation()) {
|
||||||
cb(v, callData);
|
cb(v, callData);
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
if (otherCb) otherCb(v, callData);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DoScope::SameStudySeries: {
|
case DoScope::SameStudySameOrientation: {
|
||||||
std::for_each(vList.begin(), vList.end(), [=](auto v) {
|
std::for_each(vList.begin(), vList.end(), [=](auto v) {
|
||||||
if (v == sourceView) return;
|
if (v == sourceView) return;
|
||||||
if (!v->hasSeries()) return;
|
if (!v->hasSeries()) return;
|
||||||
@@ -141,6 +161,7 @@ void ImageViewManager::smartDo(SmartDoCallback cb, DicomImageView *sourceView, v
|
|||||||
//equal slice orientation
|
//equal slice orientation
|
||||||
&& v->getSliceOrientation() == sourceView->getSliceOrientation()) {
|
&& v->getSliceOrientation() == sourceView->getSliceOrientation()) {
|
||||||
cb(v, callData);
|
cb(v, callData);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
//equal study
|
//equal study
|
||||||
else if (strcmp(currentSeries->getStudyUID(), series->getStudyUID()) == 0
|
else if (strcmp(currentSeries->getStudyUID(), series->getStudyUID()) == 0
|
||||||
@@ -149,7 +170,9 @@ void ImageViewManager::smartDo(SmartDoCallback cb, DicomImageView *sourceView, v
|
|||||||
//Intersect bounds
|
//Intersect bounds
|
||||||
&& currentSeries->IntersectWorldBounds(series)) {
|
&& currentSeries->IntersectWorldBounds(series)) {
|
||||||
cb(v, callData);
|
cb(v, callData);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (otherCb) otherCb(v, callData);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -161,6 +184,35 @@ void ImageViewManager::smartDo(SmartDoCallback cb, DicomImageView *sourceView, v
|
|||||||
if (v->CompareWorldSliceOrientation(sourceView)) {
|
if (v->CompareWorldSliceOrientation(sourceView)) {
|
||||||
cb(v, callData);
|
cb(v, callData);
|
||||||
}
|
}
|
||||||
|
else if (otherCb) otherCb(v, callData);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DoScope::SameStudyOrthogonalSeries: {
|
||||||
|
std::for_each(vList.begin(), vList.end(), [=](auto v) {
|
||||||
|
if (v == sourceView) return;
|
||||||
|
if (!v->hasSeries()) return;
|
||||||
|
//check series
|
||||||
|
auto series = sourceView->getSeriesInstance();
|
||||||
|
if (!series) return;
|
||||||
|
auto currentSeries = v->getSeriesInstance();
|
||||||
|
//same series
|
||||||
|
if (series == currentSeries
|
||||||
|
//equal slice orientation
|
||||||
|
&& v->getSliceOrientation() != sourceView->getSliceOrientation()) {
|
||||||
|
cb(v, callData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//equal study
|
||||||
|
else if (strcmp(currentSeries->getStudyUID(), series->getStudyUID()) == 0
|
||||||
|
//no equal world slice orientation
|
||||||
|
&& !v->CompareWorldSliceOrientation(sourceView)
|
||||||
|
//Intersect bounds
|
||||||
|
&& currentSeries->IntersectWorldBounds(series)) {
|
||||||
|
cb(v, callData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (otherCb) otherCb(v, callData);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -179,6 +231,7 @@ void ImageViewManager::smartDo(SmartDoCallback cb, DicomImageView *sourceView, v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Slots and actions------------------------------------------------------------
|
//Slots and actions------------------------------------------------------------
|
||||||
void ImageViewManager::viewClicked(DicomImageView *view) {
|
void ImageViewManager::viewClicked(DicomImageView *view) {
|
||||||
if (!view) return;
|
if (!view) return;
|
||||||
@@ -203,7 +256,7 @@ void ImageViewManager::viewDoubleClicked(DicomImageView *view) {
|
|||||||
|
|
||||||
void ImageViewManager::viewSliced(DicomImageView *src, void *sliceData) {
|
void ImageViewManager::viewSliced(DicomImageView *src, void *sliceData) {
|
||||||
//Sync slice
|
//Sync slice
|
||||||
if (SyncHelper::getSyncItem(SLICE_POS)) {
|
if (sliceData && SyncHelper::getSyncItem(SLICE_POS)) {
|
||||||
if (SyncHelper::getSyncState() == AUTO_SYNC) {
|
if (SyncHelper::getSyncState() == AUTO_SYNC) {
|
||||||
this->smartDo([](auto v, auto callData) {
|
this->smartDo([](auto v, auto callData) {
|
||||||
if (v->hasSeries()) {
|
if (v->hasSeries()) {
|
||||||
@@ -211,7 +264,7 @@ void ImageViewManager::viewSliced(DicomImageView *src, void *sliceData) {
|
|||||||
v->syncSlicePoint(r);
|
v->syncSlicePoint(r);
|
||||||
v->SyncScrollBar();
|
v->SyncScrollBar();
|
||||||
}
|
}
|
||||||
}, src, sliceData, ImageViewManager::SameStudySeries);
|
}, src, sliceData, ImageViewManager::SameStudySameOrientation);
|
||||||
}
|
}
|
||||||
else if (SyncHelper::getSyncState() == MANUAL_SYNC) {
|
else if (SyncHelper::getSyncState() == MANUAL_SYNC) {
|
||||||
this->smartDo([](auto v, auto callData) {
|
this->smartDo([](auto v, auto callData) {
|
||||||
@@ -224,7 +277,28 @@ void ImageViewManager::viewSliced(DicomImageView *src, void *sliceData) {
|
|||||||
}, src, sliceData, ImageViewManager::SameOrientationSeries);
|
}, src, sliceData, ImageViewManager::SameOrientationSeries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO: reference line
|
//reference line
|
||||||
|
if (!currentView->hasSeries()) {
|
||||||
|
smartDo([](auto v, auto callData) {
|
||||||
|
v->updateReferenceLine(nullptr);
|
||||||
|
},nullptr, nullptr, ImageViewManager::All);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
renderReferenceLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageViewManager::renderReferenceLine() {
|
||||||
|
vtkPoints* pts = currentView->hasSeries() ? currentView->getSliceBoundPoints() : nullptr;
|
||||||
|
smartDo([](auto v, auto callData) {
|
||||||
|
if (v->hasSeries()) {
|
||||||
|
//disable global trigger slot
|
||||||
|
vtkPoints *p = (vtkPoints *) callData;
|
||||||
|
v->updateReferenceLine(p);
|
||||||
|
}
|
||||||
|
}, [](auto v, auto callData){
|
||||||
|
v->updateReferenceLine(nullptr);
|
||||||
|
},currentView, pts, SameStudyOrthogonalSeries);
|
||||||
|
currentView->updateReferenceLine(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageViewManager::viewPaned(DicomImageView *src, void* offsetVector) {
|
void ImageViewManager::viewPaned(DicomImageView *src, void* offsetVector) {
|
||||||
@@ -244,7 +318,7 @@ void ImageViewManager::viewPaned(DicomImageView *src, void* offsetVector) {
|
|||||||
double vector[3] = {d[3], d[4] , d[5]};
|
double vector[3] = {d[3], d[4] , d[5]};
|
||||||
v->shiftCamera(vector);
|
v->shiftCamera(vector);
|
||||||
}
|
}
|
||||||
}, src, offsetVector, ImageViewManager::SameStudySeries);
|
}, src, offsetVector, ImageViewManager::SameStudySameOrientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,7 +339,7 @@ void ImageViewManager::viewZoomed(DicomImageView *src, double* scaleFactor) {
|
|||||||
double d = ((double *) callData)[1];
|
double d = ((double *) callData)[1];
|
||||||
v->setZoomScale(d);
|
v->setZoomScale(d);
|
||||||
}
|
}
|
||||||
}, src, scaleFactor, ImageViewManager::SameStudySeries);
|
}, src, scaleFactor, ImageViewManager::SameStudySameOrientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,7 +352,7 @@ void ImageViewManager::viewEndWindowLevel(DicomImageView *src, double level, dou
|
|||||||
double *d = (double *) callData;
|
double *d = (double *) callData;
|
||||||
v->setWindowLevel(d[0], d[1]);
|
v->setWindowLevel(d[0], d[1]);
|
||||||
}
|
}
|
||||||
}, src, data, ImageViewManager::SameStudySeries);
|
}, src, data, ImageViewManager::SameStudySameOrientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,11 +362,17 @@ void ImageViewManager::viewReload(const std::string &unique_info) {
|
|||||||
DicomLoader *helper = DicomLoader::GetInstance();
|
DicomLoader *helper = DicomLoader::GetInstance();
|
||||||
currentView->loadSeries(helper->getSeriesImageSet(unique_info));
|
currentView->loadSeries(helper->getSeriesImageSet(unique_info));
|
||||||
currentView->render();
|
currentView->render();
|
||||||
emit currentViewReload(currentView);
|
reloadCurrentView(currentView);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageViewManager::viewCleared(DicomImageView* view) {
|
void ImageViewManager::viewCleared(DicomImageView* view) {
|
||||||
emit currentViewReload(view);
|
smartDo([](auto v, auto callData) {
|
||||||
|
auto src = (DicomImageView*)callData;
|
||||||
|
if (v->isFusion() && v->getFusionInput() == src){
|
||||||
|
v->unloadFusion();
|
||||||
|
}
|
||||||
|
}, view, view, AllExceptSelf);
|
||||||
|
reloadCurrentView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageViewManager::setInteractionMode(int InteractionMode) {
|
void ImageViewManager::setInteractionMode(int InteractionMode) {
|
||||||
@@ -347,7 +427,7 @@ void ImageViewManager::deleteMeasure(EventObject* deleteType){
|
|||||||
|
|
||||||
void ImageViewManager::switchSliceOrientation() {
|
void ImageViewManager::switchSliceOrientation() {
|
||||||
currentView->setSliceOrientation((currentView->getSliceOrientation() + 1) % 3);
|
currentView->setSliceOrientation((currentView->getSliceOrientation() + 1) % 3);
|
||||||
emit currentViewReload(currentView);
|
reloadCurrentView(currentView);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Corner about-----------------------------------------------------------------
|
//Corner about-----------------------------------------------------------------
|
||||||
@@ -411,7 +491,7 @@ int ImageViewManager::checkSyncAbility(DicomImageView* view) {
|
|||||||
if (v->hasSeries()) {
|
if (v->hasSeries()) {
|
||||||
d[0] = true;
|
d[0] = true;
|
||||||
}
|
}
|
||||||
}, view, &flag, ImageViewManager::SameStudySeries);
|
}, view, &flag, ImageViewManager::SameStudySameOrientation);
|
||||||
if (flag) return AUTO_SYNC;
|
if (flag) return AUTO_SYNC;
|
||||||
this->smartDo([](auto v, auto callData) {
|
this->smartDo([](auto v, auto callData) {
|
||||||
bool *d = (bool *) callData;
|
bool *d = (bool *) callData;
|
||||||
@@ -429,3 +509,8 @@ void ImageViewManager::clearCurrentView() {
|
|||||||
currentView->viewCleared();
|
currentView->viewCleared();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageViewManager::reloadCurrentView(DicomImageView * view){
|
||||||
|
renderReferenceLine();
|
||||||
|
emit currentViewReloaded(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,8 +104,9 @@ public:
|
|||||||
Current,
|
Current,
|
||||||
SameSeries,
|
SameSeries,
|
||||||
//Equal Study, Equal World Bounds series
|
//Equal Study, Equal World Bounds series
|
||||||
SameStudySeries,
|
SameStudySameOrientation,
|
||||||
SameOrientationSeries,
|
SameOrientationSeries,
|
||||||
|
SameStudyOrthogonalSeries,
|
||||||
AllExceptSelf,
|
AllExceptSelf,
|
||||||
All
|
All
|
||||||
};
|
};
|
||||||
@@ -114,11 +115,11 @@ public:
|
|||||||
|
|
||||||
void smartDo(SmartDoCallback cb, DicomImageView *sourceView = nullptr, void *callData = nullptr,
|
void smartDo(SmartDoCallback cb, DicomImageView *sourceView = nullptr, void *callData = nullptr,
|
||||||
DoScope scope = Current);
|
DoScope scope = Current);
|
||||||
|
void smartDo(SmartDoCallback cb, SmartDoCallback otherCb, DicomImageView *sourceView = nullptr, void *callData = nullptr,
|
||||||
|
DoScope scope = Current);
|
||||||
|
void reloadCurrentView(DicomImageView * view);
|
||||||
signals:
|
signals:
|
||||||
// void currentViewChanged(const std::string& seriesID);
|
void currentViewReloaded( DicomImageView * view);
|
||||||
void currentViewReload( DicomImageView * view);
|
|
||||||
void fusionCheckStateChanged(bool able);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<DicomImageView *> vList;
|
QList<DicomImageView *> vList;
|
||||||
@@ -127,6 +128,7 @@ private:
|
|||||||
bool mMaxed;
|
bool mMaxed;
|
||||||
|
|
||||||
|
|
||||||
|
void renderReferenceLine();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#ifndef OMEGAV_DICOM_IMAGE_VIEW_H
|
#ifndef OMEGAV_DICOM_IMAGE_VIEW_H
|
||||||
#define OMEGAV_DICOM_IMAGE_VIEW_H
|
#define OMEGAV_DICOM_IMAGE_VIEW_H
|
||||||
|
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
@@ -172,6 +172,21 @@ public:
|
|||||||
mImageViewer->applySliceOffset(offset, direction);
|
mImageViewer->applySliceOffset(offset, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vtkPoints* getSliceBoundPoints(){
|
||||||
|
return mImageViewer->GetSliceBoundPoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateReferenceLine(vtkPoints* pts){
|
||||||
|
if (!mImageViewer) return;
|
||||||
|
if (!pts){
|
||||||
|
mImageViewer->UnActiveReferenceLine();
|
||||||
|
mImageViewer->Render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mImageViewer->ActiveReferenceLine();
|
||||||
|
mImageViewer->updateReferenceLine(pts);
|
||||||
|
}
|
||||||
|
|
||||||
bool checkMPRAble(){
|
bool checkMPRAble(){
|
||||||
return DicomImageView::checkMPRAble(this);
|
return DicomImageView::checkMPRAble(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ void QDicomViewer::SetupConnections() {
|
|||||||
initCine();
|
initCine();
|
||||||
initScreenControl();
|
initScreenControl();
|
||||||
|
|
||||||
connect(ui->viewContainer->getViewManager(),&ImageViewManager::currentViewReload,
|
connect(ui->viewContainer->getViewManager(), &ImageViewManager::currentViewReloaded,
|
||||||
ui->toolBar, &DefaultToolBar::resetNeedCheckFunctionButtons);
|
ui->toolBar, &DefaultToolBar::resetNeedCheckFunctionButtons);
|
||||||
|
|
||||||
worker.setManager(ui->viewContainer->getViewManager());
|
worker.setManager(ui->viewContainer->getViewManager());
|
||||||
connect(ui->viewContainer->getViewManager(),
|
connect(ui->viewContainer->getViewManager(),
|
||||||
&ImageViewManager::currentViewReload,
|
&ImageViewManager::currentViewReloaded,
|
||||||
&worker,&ImageViewStateCheckWorker::checkImageViewState, Qt::QueuedConnection);
|
&worker,&ImageViewStateCheckWorker::checkImageViewState, Qt::QueuedConnection);
|
||||||
connect(&worker,&ImageViewStateCheckWorker::imageViewStateChanged,
|
connect(&worker,&ImageViewStateCheckWorker::imageViewStateChanged,
|
||||||
ui->toolBar,&DefaultToolBar::updateNeedCheckFunctionButtons, Qt::QueuedConnection);
|
ui->toolBar,&DefaultToolBar::updateNeedCheckFunctionButtons, Qt::QueuedConnection);
|
||||||
|
|||||||
Reference in New Issue
Block a user