Reslice hair cross temp1.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
55
src/src/UI/Manager/ResliceImageManager.cpp
Normal file
55
src/src/UI/Manager/ResliceImageManager.cpp
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
34
src/src/UI/Manager/ResliceImageManager.h
Normal file
34
src/src/UI/Manager/ResliceImageManager.h
Normal 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
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user