Reslice hair cross temp1.

This commit is contained in:
Krad
2022-12-27 14:31:56 +08:00
parent fe07a9214c
commit 2120dd2432
12 changed files with 489 additions and 63 deletions

View File

@@ -11,11 +11,16 @@
#include <vtkRenderWindowInteractor.h>
#include <vtkCamera.h>
#include <vtkPropCollection.h>
#include <vtkPropPicker.h>
#include "Rendering/Legend/ResliceCursorLegendActor.h"
vtkStandardNewMacro(ResliceImageInteractorStyle)
ResliceImageInteractorStyle::ResliceImageInteractorStyle():vtkInteractorStyleImage() {
picker = vtkPropPicker::New();
picker->Register(this);
picker->Delete();
}
ResliceImageInteractorStyle::~ResliceImageInteractorStyle() {
@@ -23,23 +28,65 @@ ResliceImageInteractorStyle::~ResliceImageInteractorStyle() {
}
void ResliceImageInteractorStyle::OnMouseMove() {
switch (this->State) {
case VTKIS_NONE:
if (triggerEvent)
{
this->InvokeEvent(vtkCommand::UserEvent+20,Interactor->GetEventPosition());
this->Interactor->Render();
}
NoneStatePick();
break;
case VTKIS_POSITION_PROP: {
this->Interactor->Render();
auto cursor = ResliceCursorLegendActor::SafeDownCast(this->CurrentProp);
cursor->InvokeDragEvent();
}
default:
vtkInteractorStyleImage::OnMouseMove();
if (triggerEvent)
{
this->InvokeEvent(vtkCommand::UserEvent+20,Interactor->GetEventPosition());
this->Interactor->Render();
}
else{
vtkInteractorStyleImage::OnMouseMove();
}
}
}
void ResliceImageInteractorStyle::OnLeftButtonDown() {
triggerEvent = false;
vtkInteractorStyleImage::OnLeftButtonDown();
if (this->CurrentProp){
StartCursorInteractive();
auto cursor = ResliceCursorLegendActor::SafeDownCast(this->CurrentProp);
cursor->SetDragStartPosition(Interactor->GetEventPosition());
cursor->StartDrag();
}
else{
vtkInteractorStyleImage::OnLeftButtonDown();
}
}
void ResliceImageInteractorStyle::OnLeftButtonUp() {
vtkInteractorStyleImage::OnLeftButtonUp();
if (this->CurrentProp){
StopCursorInteractive();
ResliceCursorLegendActor::SafeDownCast(this->CurrentProp)->StopDrag();
this->InvokeEvent(ResliceCursorLegendActor::END_DRAG);
}
else {
vtkInteractorStyleImage::OnLeftButtonUp();
}
triggerEvent = true;
}
void ResliceImageInteractorStyle::NoneStatePick() {
int *pos = this->Interactor->GetEventPosition();
this->FindPokedRenderer(pos[0], pos[1]);
int ret = picker->PickProp(pos[0],pos[1],this->CurrentRenderer);
if (ret){
auto prop = picker->GetViewProp();
auto cursor = ResliceCursorLegendActor::SafeDownCast(prop);
if (cursor){
this->CurrentProp = cursor;
}
}
else {
this->CurrentProp = nullptr;
}
return;
}

View File

@@ -10,6 +10,8 @@
#include <vector>
#include <vtkRenderer.h>
class vtkPropPicker;
class ResliceImageInteractorStyle:public vtkInteractorStyleImage {
public:
static ResliceImageInteractorStyle *New();
@@ -21,18 +23,29 @@ public:
void OnLeftButtonUp() override;
void OnMouseMove() override;
virtual void StartCursorInteractive(){
this->State = VTKIS_POSITION_PROP;
}
virtual void StopCursorInteractive(){
this->State = VTKIS_NONE;
}
protected:
ResliceImageInteractorStyle();
~ResliceImageInteractorStyle() override;
void NoneStatePick();
private:
ResliceImageInteractorStyle(const ResliceImageInteractorStyle &) = delete;
void operator=(const ResliceImageInteractorStyle &) = delete;
bool triggerEvent = true;
vtkPropPicker * picker;
};

View File

@@ -36,14 +36,25 @@ void ControlPointRActor::BuildShape() {
}
void ControlPointRActor::Highlight(int highlightOn) {
if (highlightOn > 0) {
actor2D->GetProperty()->SetColor(1.0, 1.0, 0);
actor2D->GetProperty()->SetOpacity(1.0);
shadow2D->GetProperty()->SetOpacity(1.0);
} else {
actor2D->GetProperty()->SetOpacity(0.0);
shadow2D->GetProperty()->SetOpacity(0.0);
actor2D->GetProperty()->SetColor(1.0, 0.0, 0);
if (AutoHover){
if (highlightOn > 0) {
actor2D->GetProperty()->SetColor(1.0, 1.0, 0);
} else {
actor2D->GetProperty()->SetColor(1.0, 0.0, 0);
}
}
if (this->Renderer)this->Renderer->GetRenderWindow()->Render();
else{
if (highlightOn > 0) {
actor2D->GetProperty()->SetColor(1.0, 1.0, 0);
actor2D->GetProperty()->SetOpacity(1.0);
shadow2D->GetProperty()->SetOpacity(1.0);
} else {
actor2D->GetProperty()->SetOpacity(0.0);
shadow2D->GetProperty()->SetOpacity(0.0);
actor2D->GetProperty()->SetColor(1.0, 0.0, 0);
}
if (this->Renderer)this->Renderer->GetRenderWindow()->Render();
}
}

View File

@@ -18,19 +18,32 @@ public:
vtkTypeMacro(ControlPointRActor, ControlPointActor);
//@}
vtkSetMacro(AutoHover, bool);
vtkBooleanMacro(AutoHover, bool);
vtkGetMacro(AutoHover, bool);
void BuildShape() override;
void Highlight(int highlightOn) override;
void MouseEntered() override {
this->InvokeEvent(vtkCommand::EnterEvent, nullptr);
if (AutoHover){
Highlight(1);
}
}
void MouseLeave() override {
this->InvokeEvent(vtkCommand::LeaveEvent, nullptr);
if (AutoHover){
Highlight(0);
}
}
vtkIdType Index;
private:
bool AutoHover = false;
};

View File

@@ -17,8 +17,9 @@
#include <vtkPolyLineSource.h>
#include <vtkProperty2D.h>
#include <vtkDiskSource.h>
#include <vtkPlane.h>
#include "Rendering/Core/ControlPointRActor.h"
namespace {
class Vector2 {
@@ -79,9 +80,8 @@ vtkStandardNewMacro(ResliceCursorLegendActor)
ResliceCursorLegendActor::ResliceCursorLegendActor()
: vtkProp()
, LineActor(vtkActor2D::New())
, ControlPoint(ControlPointRActor::New())
, LineShadow(vtkActor2D::New())
, senseArea(vtkActor2D::New())
, ControlPoint(vtkActor2D::New())
, ControlPointSenseArea(vtkActor2D::New())
, linePolyData(vtkPolyData::New()){
vtkNew<vtkPoints> pts;
pts->SetNumberOfPoints(2);
@@ -94,12 +94,24 @@ ResliceCursorLegendActor::ResliceCursorLegendActor()
vtkNew<vtkPolyDataMapper2D> mapper1 ;
vtkNew<vtkPolyDataMapper2D> mapper2 ;
mapper->SetInputData(linePolyData);
mapper1->SetInputData(linePolyData);
mapper2->SetInputData(linePolyData);
vtkNew<vtkDiskSource> disk;
disk->SetInnerRadius(0);
disk->SetOuterRadius(5);
disk->SetCircumferentialResolution(36);
disk->SetRadialResolution(36);
vtkNew<vtkDiskSource> diskSense;
diskSense->SetInnerRadius(0);
diskSense->SetOuterRadius(10);
diskSense->SetCircumferentialResolution(36);
diskSense->SetRadialResolution(36);
mapper1->SetInputConnection(disk->GetOutputPort());
mapper2->SetInputConnection(diskSense->GetOutputPort());
LineActor->SetMapper(mapper);
LineShadow->SetMapper(mapper1);
senseArea->SetMapper(mapper2);
ControlPoint->SetWorldPosition(0,0,0);
LineActor->GetProperty()->SetLineWidth(2);
ControlPoint->SetMapper(mapper1);
ControlPoint->SetProperty(LineActor->GetProperty());
ControlPointSenseArea->SetMapper(mapper2);
ControlPointSenseArea->GetProperty()->SetOpacity(0);
}
ResliceCursorLegendActor::~ResliceCursorLegendActor() {
@@ -114,21 +126,26 @@ void AlignDoubleVector3(double* in, double *out){
}
void ResliceCursorLegendActor::BuildShape(vtkRenderer *renderer) {
if(dragging){
Drag(renderer);
}
if (LoadTime.GetMTime()>MTime.GetMTime()) return;
//handle disk
if (HandleUpdated){
renderer->SetDisplayPoint(Handle2DPoint[0],Handle2DPoint[1], 0);
if (HandleUpdated) {
renderer->SetDisplayPoint(Handle2DPoint[0], Handle2DPoint[1], 0);
renderer->DisplayToWorld();
renderer->GetWorldPoint(HandlePoint);
HandleUpdated = false;
}
ControlPoint->SetWorldPosition(HandlePoint);
ControlPoint->SetPosition(Handle2DPoint[0] - 0.5, Handle2DPoint[1] - .5);
ControlPointSenseArea->SetPosition(Handle2DPoint[0], Handle2DPoint[1] - .5);
//cross hair
double vector[3] = {.0, .0, .0};
vtkMath::Cross(GetSliceDirectionVector(), GetProjectDirectionVector(), vector);
vtkMath::Normalize(vector);
double point1[4] = {SlicePoint[0] ,
SlicePoint[1] ,
double point1[4] = {SlicePoint[0],
SlicePoint[1],
SlicePoint[2],
1.0};
@@ -136,47 +153,49 @@ void ResliceCursorLegendActor::BuildShape(vtkRenderer *renderer) {
SlicePoint[1] + vector[1],
SlicePoint[2] + vector[2],
1.0};
double out1[4] = {.0, .0, .0,.0};
double out2[4] = {.0, .0, .0, .0};
linePolyData->GetPoints()->SetNumberOfPoints(2);
renderer->SetWorldPoint(point1);
renderer->WorldToDisplay();
renderer->GetDisplayPoint(out1);
renderer->GetDisplayPoint(SliceDisplayPoint);
renderer->SetWorldPoint(point2);
renderer->WorldToDisplay();
renderer->GetDisplayPoint(out2);
double vector2D[2] = {out2[0] - out1[0], out2[1] - out1[1]};
double vector2D[2] = {out2[0] - SliceDisplayPoint[0], out2[1] - SliceDisplayPoint[1]};
vtkMath::Normalize2D(vector2D);
Vector2 v1 = {vector2D[0], vector2D[1]};
Vector2 screenVectors[2] ={{0, 1}, {1, 0}};
Vector2 p0 = {out1[0],out1[1]};
Vector2 screenVectors[2] = {{0, 1},
{1, 0}};
Vector2 p0 = {SliceDisplayPoint[0], SliceDisplayPoint[1]};
int *size = renderer->GetSize();
Vector2 pts[2] = {{-0.5,-0.5} ,{size[0] + 0.5,size[1] + 0.5}};
Vector2 pts[2] = {{-0.5, -0.5},
{size[0] + 0.5, size[1] + 0.5}};
Vector2 intersectPoint(.0, .0);
// calc the point, which line cross the screen border
int pointIdx = 0;
// line vector loop
for (int i = 0; i < 2; ++i) {
// line point loop
for (const auto & pt : pts) {
for (const auto &pt : pts) {
if (pointIdx >= 2)return;
if (IntersectLine2D(p0, v1, pt, screenVectors[i], intersectPoint)) {
int pcV = (int) intersectPoint.getValue(i);
if (pcV >= -1 && pcV <= size[i] + 1) {
linePolyData->GetPoints()->SetPoint(pointIdx++, (int)intersectPoint.X + 0.5, (int)intersectPoint.Y + 0.5, 0);
linePolyData->GetPoints()->SetPoint(pointIdx++, (int) intersectPoint.X + 0.05,
(int) intersectPoint.Y + 0.05, 0);
}
}
}
}
LoadTime.Modified();
}
void ResliceCursorLegendActor::ReleaseGraphicsResources(vtkWindow * window) {
senseArea->ReleaseGraphicsResources(window);
ControlPointSenseArea->ReleaseGraphicsResources(window);
LineActor->ReleaseGraphicsResources(window);
LineShadow->ReleaseGraphicsResources(window);
ControlPoint->ReleaseGraphicsResources(window);
vtkProp::ReleaseGraphicsResources(window);
}
@@ -184,15 +203,12 @@ void ResliceCursorLegendActor::ReleaseGraphicsResources(vtkWindow * window) {
int ResliceCursorLegendActor::RenderOverlay(vtkViewport *viewport) {
auto renderer = vtkRenderer::SafeDownCast(viewport);
if (!renderer) return 0;
if (firstRender){
ControlPoint->SetRenderer(renderer);
firstRender = false;
}
BuildShape(renderer);
if (senseArea->GetVisibility())senseArea->RenderOverlay(viewport);
if (LineShadow->GetVisibility())LineShadow->RenderOverlay(viewport);
if (LineActor->GetVisibility())LineActor->RenderOverlay(viewport);
if (ControlPoint->GetVisibility())ControlPoint->RenderOverlay(viewport);
if (ControlPointActive){
if (ControlPointSenseArea->GetVisibility())ControlPointSenseArea->RenderOverlay(viewport);
if (ControlPoint->GetVisibility())ControlPoint->RenderOverlay(viewport);
}
return 1;
}
@@ -201,6 +217,7 @@ vtkProperty2D *ResliceCursorLegendActor::GetProperty() {
}
void ResliceCursorLegendActor::UpdateMousePosition(int* pos) {
ControlPointActive = true;
double point0[3] = {.0,.0,.0};
double point1[3] = {.0,.0,.0};
linePolyData->GetPoints()->GetPoint(0,point0);
@@ -231,3 +248,127 @@ void ResliceCursorLegendActor::UpdateMousePosition(int* pos) {
void ResliceCursorLegendActor::Pick() {
vtkProp::Pick();
}
void ResliceCursorLegendActor::GetActors(vtkPropCollection * collection) {
collection->AddItem(ControlPointSenseArea);
}
void ResliceCursorLegendActor::Drag(vtkRenderer* renderer) {
int *pos = renderer->GetRenderWindow()->GetInteractor()->GetEventPosition();
int distance2 =pow((DragStartPosition[0] - (int)(SliceDisplayPoint[0])),2) + pow((DragStartPosition[1] - (int)(SliceDisplayPoint[1])),2);
if (distance2<=225 || Moving){
ApplyMove(renderer);
Moving = true;
}
else{
ApplyRoll(renderer);
Rolling = true;
}
}
void ResliceCursorLegendActor::ApplyRoll(vtkRenderer * renderer) {
int *pos = renderer->GetRenderWindow()->GetInteractor()->GetEventPosition();
double slicePt[4] = {SlicePoint[0] ,
SlicePoint[1] ,
SlicePoint[2],
1.0};;
SliceDisplayPoint[2] = 0.0;
SliceDisplayPoint[3] = 1.0;
renderer->SetDisplayPoint(SliceDisplayPoint);
renderer->DisplayToWorld();
renderer->GetWorldPoint(slicePt);
double position [4] ={ pos[0]+0.05, pos[1]+0.05,0,1};
double vector2D[2] = {position[0] - SliceDisplayPoint[0], position[1] - SliceDisplayPoint[1]};
vtkMath::Normalize2D(vector2D);
renderer->SetDisplayPoint(position);
renderer->DisplayToWorld();
renderer->GetWorldPoint(position);
double newVector[3]={position[0] - slicePt[0], position[1] - slicePt[1], position[2] - slicePt[2]};
vtkMath::Normalize(newVector);
if (ReferenceCursor){
ReferenceCursor->SetSliceDirectionVector(newVector);
}
vtkMath::Cross(newVector, GetProjectDirectionVector(), newVector);
SetSliceDirectionVector(newVector);
}
void ResliceCursorLegendActor::ApplyMove(vtkRenderer * renderer) {
int *pos = renderer->GetRenderWindow()->GetInteractor()->GetEventPosition();
if (!Moving){
LastSliceDisplayPoint[0]=SliceDisplayPoint[0];
LastSliceDisplayPoint[1]=SliceDisplayPoint[1];
}
double pt1[4] = {LastSliceDisplayPoint[0]+(pos[0]-DragStartPosition[0]) + 0.5 ,
LastSliceDisplayPoint[1]+(pos[1]-DragStartPosition[1]) + 0.5 ,
0,
1.0};
renderer->SetDisplayPoint(pt1);
renderer->DisplayToWorld();
renderer->GetWorldPoint(pt1);
double pt2[4] = {pt1[0] + 10000.0 * ProjectDirectionVector[0],
pt1[1] + 10000.0 * ProjectDirectionVector[1],
pt1[2] + 10000.0 * ProjectDirectionVector[2],
1.0};
double x ;
double intersectPoint[4]={.0,.0,.0,1.};
if (vtkPlane::IntersectWithLine(pt1, pt2, ProjectDirectionVector, SlicePoint,x,intersectPoint))
{
SetSlicePoint(intersectPoint);
if (ReferenceCursor){
ReferenceCursor->SetSlicePoint(intersectPoint);
}
this->InvokeEvent(MOVE);
}
}
void ResliceCursorLegendActor::InvokeDragEvent() {
if (Rolling){
this->InvokeEvent(ROLL);
return;
}
if (Moving){
this->InvokeEvent(MOVE);
return;
}
}
void ResliceCursorLegendActor::UpdateCursor3DPoint(vtkRenderer * renderer) {
double pt1[3] = {.0, .0, .0};
linePolyData->GetPoints()->GetPoint(0, pt1);
double pt2[3] = {.0, .0, .0};
linePolyData->GetPoints()->GetPoint(1, pt2);
double worldPt1[4] = {.0,.0,.0,1.};
double worldPt2[4] = {.0,.0,.0,1.};
renderer->SetDisplayPoint(pt1);
renderer->DisplayToWorld();
renderer->GetWorldPoint(worldPt1);
renderer->SetDisplayPoint(pt2);
renderer->DisplayToWorld();
renderer->GetWorldPoint(worldPt2);
vtkNew<vtkPlane> plane;
plane->SetOrigin(GetSlicePoint());
plane->SetNormal(GetProjectDirectionVector());
double t;
double wpt_end[4] = {worldPt1[0] + 10000.0 * ProjectDirectionVector[0],
worldPt1[1] + 10000.0 * ProjectDirectionVector[1],
worldPt1[2] + 10000.0 * ProjectDirectionVector[2],
1.0};
double newPt1[4] = {.0,.0,.0,1.};
int ret = plane->IntersectWithLine(worldPt1,wpt_end,t,newPt1);
if (ret == 0 ) vtkErrorMacro("no intersect!");
double wpt_end2[4] = {worldPt2[0] + 10000.0 * ProjectDirectionVector[0],
worldPt2[1] + 10000.0 * ProjectDirectionVector[1],
worldPt2[2] + 10000.0 * ProjectDirectionVector[2],
1.0};
double newPt2[4] = {.0,.0,.0,1.};
ret = plane->IntersectWithLine(worldPt2,wpt_end2,t,newPt2);
if (ret == 0 ) vtkErrorMacro("no intersect!");
double vector[3] = {newPt2[0]-newPt1[0],newPt2[1]-newPt1[1],newPt2[2]-newPt1[2]};
vtkMath::Cross(vector, GetProjectDirectionVector(), vector);
SetSliceDirectionVector(vector);
}

View File

@@ -6,6 +6,8 @@
#define RENDERLAB_RESLICECURSORLEGENDACTOR_H
#include <vtkProp.h>
#include <vtkTimeStamp.h>
#include <vtkCommand.h>
class vtkRenderer;
class vtkPolyData;
@@ -26,6 +28,12 @@ public:
virtual void BuildShape(vtkRenderer *renderer);
enum EventType{
ROLL = vtkCommand::UserEvent+1000,
MOVE,
END_DRAG
};
vtkSetVector3Macro(SlicePoint,double);
vtkGetVector3Macro(SlicePoint,double);
@@ -35,6 +43,9 @@ public:
vtkSetVector3Macro(ProjectDirectionVector,double);
vtkGetVector3Macro(ProjectDirectionVector,double);
vtkGetVector2Macro(DragStartPosition, int);
vtkSetVector2Macro(DragStartPosition, int);
vtkProperty2D* GetProperty();
//@{
@@ -43,7 +54,7 @@ public:
*/
double *GetBounds() VTK_SIZEHINT(6) override { return nullptr; }
void GetActors(vtkPropCollection *) override {}
void GetActors(vtkPropCollection *) override;
void GetVolumes(vtkPropCollection *) override {}
@@ -68,8 +79,35 @@ public:
void UpdateMousePosition(int* pos);
void UpdateCursor3DPoint(vtkRenderer * renderer);
void Pick() override;
void StartDrag(){
dragging = true;
ControlPointActive = false;
if (ReferenceCursor){
ReferenceCursor->ControlPointActive = false;
}
}
void StopDrag(){
dragging = false;
ControlPointActive = true;
Moving = false;
Rolling = false;
if (ReferenceCursor){
ReferenceCursor->ControlPointActive = true;
ReferenceCursor->Moving = false;
}
}
void Drag(vtkRenderer* renderer);
void InvokeDragEvent();
vtkSetMacro(ReferenceCursor,ResliceCursorLegendActor*);
protected:
ResliceCursorLegendActor();
@@ -79,19 +117,32 @@ private:
void operator=(const ResliceCursorLegendActor &) = delete;
void ApplyRoll(vtkRenderer * renderer);
void ApplyMove(vtkRenderer* renderer);
vtkActor2D *LineActor;
ControlPointRActor *ControlPoint;
vtkActor2D *LineShadow;
vtkActor2D *senseArea;
vtkActor2D *ControlPoint;
vtkActor2D *ControlPointSenseArea;
vtkPolyData* linePolyData;
double LineHalfLength = 500.0;
double SlicePoint[3] = {.0, .0, .0};
double HandlePoint[4] = {.0, .0, .0, .0};
bool HandleUpdated = false;
bool firstRender = true;
bool SliceUpdated = false;
ResliceCursorLegendActor* ReferenceCursor = nullptr;
bool ControlPointActive = false;
bool dragging = false;
bool Moving = false;
bool Rolling = false;
int DragStartPosition[2] = {0,0};
double Handle2DPoint[2] = {.0, .0, };
double SliceDirectionVector[3] = {.0, .0, .0};
double ProjectDirectionVector[3] = {.0, .0, .0};
double SliceDisplayPoint[4] = {.0, .0, .0, .0};
double LastSliceDisplayPoint[2] = {.0, .0};
vtkTimeStamp LoadTime;
};

View File

@@ -41,7 +41,8 @@ ResliceImageViewer::ResliceImageViewer()
Mapper->SetResampleToScreenPixels(0);
Mapper->SetSeparateWindowLevelOperation(0);
Actor->SetMapper(Mapper);
cursor1->SetReferenceCursor(cursor2);
cursor2->SetReferenceCursor(cursor1);
OrientationMatrix->Identity();
}
@@ -145,11 +146,8 @@ void ResliceImageViewer::Render() {
Renderer->AddActor2D(cursor2);
cursor1->SetSlicePoint(Renderer->GetActiveCamera()->GetFocalPoint());
cursor2->SetSlicePoint(Renderer->GetActiveCamera()->GetFocalPoint());
double project[3] = {0,0.0,1.0};
project[DefaultOrientation] = 1.;
OrientationMatrix->MultiplyPoint(project,project);
cursor1->SetProjectDirectionVector(project);
cursor2->SetProjectDirectionVector(project);
cursor1->SetProjectDirectionVector(Renderer->GetActiveCamera()->GetDirectionOfProjection());
cursor2->SetProjectDirectionVector(Renderer->GetActiveCamera()->GetDirectionOfProjection());
double sliceDirection1[4]{.0, .0, .0, 1.};
double sliceDirection2[4]{.0, .0, .0, 1.};
switch (DefaultOrientation) {
@@ -170,7 +168,7 @@ void ResliceImageViewer::Render() {
case 2:{
sliceDirection1[0] = 1.0;
cursor1->GetProperty()->SetColor(1,0,0);
sliceDirection2[01] = 1.0;
sliceDirection2[1] = 1.0;
cursor2->GetProperty()->SetColor(0,1,0);
break;
}
@@ -180,6 +178,11 @@ void ResliceImageViewer::Render() {
cursor1->SetSliceDirectionVector(sliceDirection1);
cursor2->SetSliceDirectionVector(sliceDirection2);
this->InteractorStyle->AddObserver(vtkCommand::UserEvent+20,this,&ResliceImageViewer::updateHandle);
this->InteractorStyle->AddObserver(ResliceCursorLegendActor::END_DRAG,this,&ResliceImageViewer::updateSliceCursor);
cursor1->AddObserver(ResliceCursorLegendActor::ROLL,this, &ResliceImageViewer::handleRoll);
cursor1->AddObserver(ResliceCursorLegendActor::MOVE,this, &ResliceImageViewer::handleMove);
cursor2->AddObserver(ResliceCursorLegendActor::ROLL,this, &ResliceImageViewer::handleRoll);
cursor2->AddObserver(ResliceCursorLegendActor::MOVE,this, &ResliceImageViewer::handleMove);
//some first render logic
Render();
return;
@@ -231,3 +234,42 @@ void ResliceImageViewer::updateHandle(vtkObject* sender, unsigned long eventID,
cursor1->UpdateMousePosition(pos);
cursor2->UpdateMousePosition(pos);
}
double *ResliceImageViewer::GetCursorSlicePoint() {
return cursor1->GetSlicePoint();
}
double *ResliceImageViewer::GetCursorSliceDirection1() {
return cursor1->GetSliceDirectionVector();
}
double *ResliceImageViewer::GetCursorSliceDirection2() {
return cursor2->GetSliceDirectionVector();
}
void ResliceImageViewer::handleRoll() {
this->InvokeEvent(ResliceCursorLegendActor::ROLL);
}
void ResliceImageViewer::handleMove() {
this->InvokeEvent(ResliceCursorLegendActor::MOVE);
}
void ResliceImageViewer::ChangeSliceNormal(double *normal) {
auto camera = Renderer->GetActiveCamera();
double focalPt[3] = {.0, .0, .0};
camera->GetFocalPoint(focalPt);
vtkMath::Normalize(normal);
camera->SetPosition(focalPt[0]+30.0*normal[0],focalPt[1]+30.0*normal[1],focalPt[2]+30.0*normal[2]);
camera->OrthogonalizeViewUp();
Renderer->ResetCameraClippingRange();
}
void ResliceImageViewer::ChangeSlicePoint(double *point) {
}
void ResliceImageViewer::updateSliceCursor() {
cursor1->SetProjectDirectionVector(Renderer->GetActiveCamera()->GetDirectionOfProjection());
cursor2->SetProjectDirectionVector(Renderer->GetActiveCamera()->GetDirectionOfProjection());
}

View File

@@ -41,6 +41,12 @@ public:
void SetDefaultSliceOrientation(int orientation);
void SetCoordsTransformMatrix(vtkMatrix4x4* matrix4X4);
double* GetCursorSlicePoint();
double* GetCursorSliceDirection1();
double* GetCursorSliceDirection2();
void ChangeSlicePoint(double * point);
void ChangeSliceNormal(double * normal);
protected:
ResliceImageViewer();
@@ -51,10 +57,14 @@ protected:
virtual void UnInstallPipeline();
void updateHandle(vtkObject* sender, unsigned long eventID, void* callData);
void updateSliceCursor();
private:
ResliceImageViewer(const ResliceImageViewer &) = delete;
void operator=(const ResliceImageViewer &) = delete;
void handleRoll();
void handleMove();
vtkRenderWindow *RenderWindow;
vtkRenderer *Renderer;
vtkRenderer *MeasureRenderer;

View File

@@ -0,0 +1,55 @@
//
// Created by Krad on 2022/12/26.
//
#include "ResliceImageManager.h"
#include <vtkCommand.h>
#include "Rendering/Viewer/ResliceImageViewer.h"
ResliceImageManager::ResliceImageManager(QObject *parent) : QObject(parent) {
}
void ResliceImageManager::SetViewer(int index, ResliceImageViewer *viewer) {
if (!viewer) return;
switch (index){
case 0:{
viewerA = viewer;
break;
}
case 1:{
viewerC = viewer;
break;
}
case 2:{
viewerS = viewer;
}
}
}
void ResliceImageManager::InitEvents() {
viewerA->AddObserver(vtkCommand::UserEvent+1000,this,&ResliceImageManager::RollCallback);
viewerS->AddObserver(vtkCommand::UserEvent+1000,this,&ResliceImageManager::RollCallback);
viewerC->AddObserver(vtkCommand::UserEvent+1000,this,&ResliceImageManager::RollCallback);
}
void ResliceImageManager::RollCallback(vtkObject *sender, unsigned long eventID, void *data) {
auto viewer = ResliceImageViewer::SafeDownCast(sender);
if (viewer){
if (viewer!=viewerA){
viewerA->ChangeSliceNormal(viewer->GetCursorSliceDirection1());
viewerA->Render();
}
if (viewer!=viewerC){
viewerC->ChangeSliceNormal(viewer->GetCursorSliceDirection1());
viewerC->Render();
}
if (viewer!=viewerS){
viewerS->ChangeSliceNormal(viewer->GetCursorSliceDirection1());
viewerS->Render();
}
}
}

View File

@@ -0,0 +1,34 @@
//
// Created by Krad on 2022/12/26.
//
#ifndef OMEGAV_RESLICEIMAGEMANAGER_H
#define OMEGAV_RESLICEIMAGEMANAGER_H
#include <QObject>
#include <vector>
class ResliceImageViewer;
class vtkObject;
class ResliceImageManager:public QObject {
public :
ResliceImageManager(QObject *parent=nullptr);
~ResliceImageManager() override {
mViewers.clear();
};
void SetViewer(int index, ResliceImageViewer* viewer);
void InitEvents();
private:
std::vector<ResliceImageViewer*> mViewers;
ResliceImageViewer * viewerA;
ResliceImageViewer * viewerS;
ResliceImageViewer * viewerC;
void RollCallback(vtkObject* sender, unsigned long eventID, void* data);
};
#endif //OMEGAV_RESLICEIMAGEMANAGER_H

View File

@@ -15,6 +15,7 @@
#include "Common/SeriesImageSet.h"
#include "UI/Widget/ToolBar/ResliceMPRToolBar.h"
#include "Rendering/Viewer/ResliceImageViewer.h"
#include "UI/Manager/ResliceImageManager.h"
MPRResliceWindow::MPRResliceWindow(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) {
setObjectName("MPRWin");
@@ -62,6 +63,12 @@ MPRResliceWindow::MPRResliceWindow(QWidget *parent, Qt::WindowFlags f) : QDialog
window3->SetPolygonSmoothing(1);
mViewerS = ResliceImageViewer::New();
mWidgetSagittal->setRenderWindow(window3);
manager = new ResliceImageManager(this);
manager->SetViewer(0,mViewerA);
manager->SetViewer(1,mViewerC);
manager->SetViewer(2,mViewerS);
manager->InitEvents();
}
MPRResliceWindow::~MPRResliceWindow() {

View File

@@ -15,6 +15,7 @@ class QSplitter;
class SeriesImageSet;
class ResliceImageManager;
class MPRResliceWindow :public QDialog {
Q_OBJECT
@@ -40,6 +41,7 @@ private:
ResliceImageViewer *mViewerA = nullptr;
ResliceImageViewer *mViewerS = nullptr;
ResliceImageViewer *mViewerC = nullptr;
ResliceImageManager* manager = nullptr;
QSplitter* mMainSplitter= nullptr;
QSplitter* mAppendSplitter= nullptr;
int layoutType = 0;