Measure for volume, attempt 1.
This commit is contained in:
@@ -9,13 +9,13 @@
|
||||
#include <vtkCallbackCommand.h>
|
||||
#include <vtkRenderWindow.h>
|
||||
#include <vtkRenderWindowInteractor.h>
|
||||
#include <vtkRenderer.h>
|
||||
#include <vtkVolume.h>
|
||||
#include <vtkPropCollection.h>
|
||||
#include <vtkAssemblyPath.h>
|
||||
#include <vtkVolumeProperty.h>
|
||||
#include <vtkPropPicker.h>
|
||||
#include <vtkPiecewiseFunction.h>
|
||||
#include <vtkFixedPointVolumeRayCastMapper.h>
|
||||
|
||||
#include "Rendering/Core/DraggableActor.h"
|
||||
|
||||
@@ -25,7 +25,7 @@ VolumeInteractorStyle::VolumeInteractorStyle():vtkInteractorStyleTrackballCamera
|
||||
,InteractionMode(VTKIS_VOLUME_ROTATE3D)
|
||||
,picker(vtkPropPicker::New())
|
||||
{
|
||||
|
||||
picker->SetPickFromList(1);
|
||||
}
|
||||
|
||||
VolumeInteractorStyle::~VolumeInteractorStyle() {
|
||||
@@ -42,39 +42,20 @@ void VolumeInteractorStyle::OnLeftButtonDown() {
|
||||
}
|
||||
|
||||
this->GrabFocus(this->EventCallbackCommand);
|
||||
if (selectedProp) {
|
||||
selectedProp->InvokeEvent(DraggableActor::DraggableActorEvents::UnSelectedEvent);
|
||||
selectedProp = nullptr;
|
||||
// un select last selected prop
|
||||
if (CurrentProp) {
|
||||
CurrentProp->InvokeEvent(DraggableActor::DraggableActorEvents::UnSelectedEvent);
|
||||
CurrentProp = nullptr;
|
||||
}
|
||||
if (dragProp) {
|
||||
selectedProp = dragProp;
|
||||
selectedProp->InvokeEvent(DraggableActor::DraggableActorEvents::SelectedEvent);
|
||||
if (this->Interactor->GetRepeatCount()) {
|
||||
dragProp->InvokeEvent(DraggableStyleEvents::PopPropEvent, nullptr);
|
||||
}
|
||||
DragStartOrigin[0] = x;
|
||||
DragStartOrigin[1] = y;
|
||||
this->StartDrag();
|
||||
return;
|
||||
}
|
||||
if (Interactor->GetRepeatCount()) {
|
||||
if (measure) {
|
||||
measure->SetPlacing(measure->onMeasureDoubleClick(this->Interactor));
|
||||
if (!measure->isMeasurePlacing()) {
|
||||
this->EndMeasure();
|
||||
auto temp = measure;
|
||||
measure = measure->GetNextMeasure();
|
||||
if (!temp->Valid()) {
|
||||
temp->ForceDelete();
|
||||
temp = nullptr;
|
||||
}
|
||||
}
|
||||
measure->SetPlacing(measure->onMeasureLeftButtonDown(this->Interactor));
|
||||
if (this->State != VTKIS_MEASURE) this->StartMeasure();
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch(this->InteractionMode) {
|
||||
case VTKIS_VOLUME_ROTATE3D: {
|
||||
this->StartRotate();
|
||||
ClearMeasure();
|
||||
break;
|
||||
}
|
||||
case VTKIS_VOLUME_PAN: {
|
||||
@@ -100,6 +81,27 @@ void VolumeInteractorStyle::OnLeftButtonDown() {
|
||||
|
||||
void VolumeInteractorStyle::OnLeftButtonUp() {
|
||||
switch (this->State) {
|
||||
case VTKIS_DRAG:
|
||||
DraggableActor::SafeDownCast(this->CurrentProp)->ApplyTransform();
|
||||
this->EndDrag();
|
||||
break;
|
||||
case VTKIS_MEASURE:
|
||||
measure->SetPlacing(measure->onMeasureLeftButtonUp(this->Interactor));
|
||||
if (!measure->isMeasurePlacing()) {
|
||||
this->EndMeasure();
|
||||
auto temp = measure;
|
||||
|
||||
measure = measure->GetNextMeasure();
|
||||
if (!temp->Valid()) {
|
||||
temp->ForceDelete();
|
||||
temp = nullptr;
|
||||
}
|
||||
else{
|
||||
picker->AddPickList(temp->GetProp());
|
||||
measureStore.push_back(temp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VTKIS_VOLUME_WINDOW:
|
||||
this->EndWindowLevel();
|
||||
if (this->Interactor) {
|
||||
@@ -111,19 +113,17 @@ void VolumeInteractorStyle::OnLeftButtonUp() {
|
||||
}
|
||||
|
||||
void VolumeInteractorStyle::StartWindowLevel() {
|
||||
if (this->State != VTKIS_NONE)
|
||||
{
|
||||
if (this->State != VTKIS_NONE) {
|
||||
return;
|
||||
}
|
||||
this->StartState(VTKIS_VOLUME_WINDOW);
|
||||
|
||||
if (this->HandleObservers &&
|
||||
this->HasObserver(vtkCommand::StartWindowLevelEvent))
|
||||
{
|
||||
this->HasObserver(vtkCommand::StartWindowLevelEvent)) {
|
||||
this->InvokeEvent(vtkCommand::StartWindowLevelEvent, this);
|
||||
}
|
||||
GetCurrentVolumeProperty();
|
||||
if(VolumeProperty){
|
||||
if (VolumeProperty) {
|
||||
auto opacity = VolumeProperty->GetScalarOpacity();
|
||||
if (opacity) {
|
||||
double range[2] = {0.0, 0.0};
|
||||
@@ -149,12 +149,41 @@ void VolumeInteractorStyle::EndWindowLevel() {
|
||||
void VolumeInteractorStyle::OnMouseMove() {
|
||||
int x = this->Interactor->GetEventPosition()[0];
|
||||
int y = this->Interactor->GetEventPosition()[1];
|
||||
switch (this->State) {
|
||||
case VTKIS_VOLUME_WINDOW:
|
||||
this->FindPokedRenderer(x,y);
|
||||
switch (this->State) {
|
||||
// window
|
||||
case VTKIS_VOLUME_WINDOW:
|
||||
this->WindowLevel();
|
||||
this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
|
||||
break;
|
||||
case VTKIS_MEASURE:
|
||||
MeasurePlace();
|
||||
// this->InvokeEvent(vtkCommand::InteractionEvent, nullptr);
|
||||
break;
|
||||
// no state pick
|
||||
default:{
|
||||
if (measureStore.size()){
|
||||
int ret = picker->PickProp(x,y,this->CurrentRenderer);
|
||||
if (ret){
|
||||
auto prop = picker->GetViewProp();
|
||||
if (prop->IsA("DraggableActor")) {
|
||||
//active highlight
|
||||
auto old = DraggableActor::SafeDownCast(this->CurrentProp);
|
||||
if (old) old->MouseLeave();
|
||||
this->CurrentProp = prop;
|
||||
auto newOne = DraggableActor::SafeDownCast(prop);
|
||||
if (newOne){
|
||||
newOne->MouseEntered();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this->CurrentProp) {
|
||||
DraggableActor::SafeDownCast(this->CurrentProp)->MouseLeave();
|
||||
this->CurrentProp = nullptr;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
vtkInteractorStyleTrackballCamera::OnMouseMove();
|
||||
|
||||
@@ -240,7 +269,7 @@ void VolumeInteractorStyle::GetCurrentVolumeProperty() {
|
||||
vtkPropCollection *props = this->CurrentRenderer->GetViewProps();
|
||||
vtkProp *prop = nullptr;
|
||||
vtkAssemblyPath *path;
|
||||
vtkVolume *volumeProp = nullptr;
|
||||
volumeProp = nullptr;
|
||||
vtkCollectionSimpleIterator pit;
|
||||
|
||||
for (int k = 0; k < 2; k++)
|
||||
@@ -287,3 +316,48 @@ void VolumeInteractorStyle::Drag() {
|
||||
this->Interactor->Render();
|
||||
}
|
||||
|
||||
void VolumeInteractorStyle::ActiveMeasure(Measure *m) {
|
||||
if (this->measure && nullptr == m) {
|
||||
this->measure->onTerminate(this->Interactor);
|
||||
this->measure->ForceDelete();
|
||||
}
|
||||
this->measure = m;
|
||||
}
|
||||
|
||||
void VolumeInteractorStyle::MeasurePlace() {
|
||||
if (measure)measure->onMeasureMouseMove(this->Interactor);
|
||||
}
|
||||
|
||||
void VolumeInteractorStyle::ClearMeasure() {
|
||||
|
||||
std::for_each(measureStore.begin(), measureStore.end(),[=](Measure* m){
|
||||
picker->DeletePickList(m->GetProp());
|
||||
m->ForceDelete();
|
||||
});
|
||||
|
||||
measureStore.clear();
|
||||
}
|
||||
|
||||
void VolumeInteractorStyle::StartMeasure() {
|
||||
this->StartState(VTKIS_MEASURE);
|
||||
if (!volumeProp){
|
||||
GetCurrentVolumeProperty();
|
||||
}
|
||||
auto mapper = vtkFixedPointVolumeRayCastMapper::SafeDownCast(this->volumeProp->GetMapper());
|
||||
if (mapper){
|
||||
mapper->SetAutoAdjustSampleDistances(0);
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeInteractorStyle::EndMeasure() {
|
||||
if (this->State != VTKIS_MEASURE) {
|
||||
return;
|
||||
}
|
||||
this->StopState();
|
||||
auto mapper = vtkFixedPointVolumeRayCastMapper::SafeDownCast(this->volumeProp->GetMapper());
|
||||
if (mapper){
|
||||
mapper->SetAutoAdjustSampleDistances(1);
|
||||
}
|
||||
this->InvokeEvent(EndMeasureEvent, this->measure);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ class vtkPropPicker;
|
||||
class vtkProp;
|
||||
class Measure;
|
||||
|
||||
#include <vector>
|
||||
#include <vtkRenderer.h>
|
||||
|
||||
class VolumeInteractorStyle:public vtkInteractorStyleTrackballCamera {
|
||||
@@ -39,7 +40,11 @@ public:
|
||||
|
||||
void WindowLevel();
|
||||
|
||||
void ActiveMeasure(Measure *m);
|
||||
|
||||
void ClearMeasure();
|
||||
protected:
|
||||
|
||||
VolumeInteractorStyle();
|
||||
|
||||
~VolumeInteractorStyle() override;
|
||||
@@ -56,18 +61,11 @@ protected:
|
||||
}
|
||||
|
||||
void Drag();
|
||||
void StartMeasure();
|
||||
|
||||
void StartMeasure() {
|
||||
this->StartState(VTKIS_MEASURE);
|
||||
}
|
||||
void EndMeasure();
|
||||
|
||||
void EndMeasure() {
|
||||
if (this->State != VTKIS_MEASURE) {
|
||||
return;
|
||||
}
|
||||
this->StopState();
|
||||
this->InvokeEvent(EndMeasureEvent, this->measure);
|
||||
}
|
||||
void MeasurePlace();
|
||||
private:
|
||||
VolumeInteractorStyle(const VolumeInteractorStyle &) = delete;
|
||||
|
||||
@@ -80,9 +78,9 @@ private:
|
||||
vtkVolumeProperty* VolumeProperty = nullptr;
|
||||
vtkPropPicker* picker;
|
||||
vtkProp *dragProp = nullptr;
|
||||
vtkProp *selectedProp = nullptr;
|
||||
Measure *measure = nullptr;
|
||||
vtkRenderer* MainRenderer;
|
||||
vtkVolume *volumeProp = nullptr;
|
||||
std::vector<Measure*> measureStore;
|
||||
int DragStartOrigin[2] = {0, 0};
|
||||
double WindowLevelInitial[2] = {0.0, 0.0};
|
||||
double WindowLevelStartPosition[2] = {0.0, 0.0};
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <vtkActor2D.h>
|
||||
|
||||
#include <vtkObjectFactory.h>
|
||||
#include <vtkRenderWindowInteractor.h>
|
||||
#include <vtkRenderer.h>
|
||||
#include <vtkRenderWindow.h>
|
||||
#include <vtkCamera.h>
|
||||
@@ -163,7 +164,9 @@ void DraggableActor::Pick() {
|
||||
}
|
||||
|
||||
void DraggableActor::Highlight(int highlightOn) {
|
||||
this->Highlighted = highlightOn > 0;
|
||||
bool temp = highlightOn > 0;
|
||||
if (temp == this->Highlighted) return;
|
||||
this->Highlighted = temp;
|
||||
RenderWithState();
|
||||
if (this->Renderer)this->Renderer->GetRenderWindow()->Render();
|
||||
}
|
||||
|
||||
@@ -94,4 +94,8 @@ bool ArrowAnnotationActor::onMeasureLeftButtonDown(vtkRenderWindowInteractor *in
|
||||
return true;
|
||||
}
|
||||
|
||||
vtkProp *ArrowAnnotationActor::GetProp() {
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ public:
|
||||
|
||||
bool onMeasureLeftButtonDown(vtkRenderWindowInteractor *) override;
|
||||
|
||||
vtkProp *GetProp() override;
|
||||
|
||||
protected:
|
||||
ArrowAnnotationActor();
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ Measure* GetNextMeasure() override\
|
||||
#include "Events/EventsCenter.h"
|
||||
|
||||
class vtkRenderWindowInteractor;
|
||||
class vtkProp;
|
||||
|
||||
class Measure {
|
||||
public:
|
||||
@@ -65,6 +66,8 @@ public:
|
||||
|
||||
virtual bool Valid() { return true; }
|
||||
|
||||
virtual vtkProp* GetProp(){return nullptr;}
|
||||
|
||||
protected:
|
||||
static bool Hidden;
|
||||
private:
|
||||
|
||||
@@ -319,7 +319,6 @@ void DICOMImageViewer::InstallPipeline() {
|
||||
|
||||
if (this->Renderer && this->ImageActor) {
|
||||
this->Renderer->AddViewProp(this->ImageStack);
|
||||
// this->Renderer->AddViewProp(this->ImageActor);
|
||||
this->Renderer->GetActiveCamera()->SetParallelProjection(1);
|
||||
this->Renderer->SetBackground(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "Interaction/VolumeInteractorStyle.h"
|
||||
#include "Rendering/Widget/ClickableOrientationMarkerWidget.h"
|
||||
#include "IO/DICOM/ExtendMedicalImageProperties.h"
|
||||
#include "Rendering/Measure/ArrowAnnotationActor.h"
|
||||
|
||||
namespace {
|
||||
enum ViewDirection{
|
||||
@@ -199,7 +200,7 @@ void VolumeRenderingViewer::InstallPipeline() {
|
||||
if (this->Renderer && this->VolumeActor) {
|
||||
this->Renderer->AddVolume(this->VolumeActor);
|
||||
this->Renderer->AddViewProp(annotation);
|
||||
Renderer->AddObserver(vtkCommand::EndEvent,this, &VolumeRenderingViewer::renderAnnotation);
|
||||
// Renderer->AddObserver(vtkCommand::EndEvent,this, &VolumeRenderingViewer::renderAnnotation);
|
||||
this->Renderer->SetBackground(0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
@@ -605,3 +606,28 @@ void VolumeRenderingViewer::pressedOrientationMarker(vtkObject* sender, unsigned
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeRenderingViewer::ActiveArrow() {
|
||||
auto style = VolumeInteractorStyle::SafeDownCast(this->InteractorStyle);
|
||||
if (style){
|
||||
style->ActiveMeasure(ArrowAnnotationActor::New());
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeRenderingViewer::UnActiveMeasure() {
|
||||
auto style = VolumeInteractorStyle::SafeDownCast(this->InteractorStyle);
|
||||
if (style){
|
||||
style->ActiveMeasure(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeRenderingViewer::PokeMeasureRender() {
|
||||
if(!MeasureRenderer) {
|
||||
MeasureRenderer = vtkRenderer::New();
|
||||
if (this->RenderWindow && this->MeasureRenderer) {
|
||||
this->RenderWindow->AddRenderer(this->MeasureRenderer);
|
||||
}
|
||||
}
|
||||
this->MeasureRenderer->SetLayer(1);
|
||||
this->Renderer->SetLayer(0);
|
||||
}
|
||||
|
||||
@@ -91,6 +91,10 @@ public:
|
||||
|
||||
void ResetZoomFitWindow();
|
||||
|
||||
void ActiveArrow();
|
||||
|
||||
void UnActiveMeasure();
|
||||
|
||||
protected:
|
||||
VolumeRenderingViewer();
|
||||
|
||||
@@ -103,14 +107,17 @@ protected:
|
||||
void renderAnnotation();
|
||||
private:
|
||||
VolumeRenderingViewer(const VolumeRenderingViewer &) = delete;
|
||||
|
||||
void operator=(const VolumeRenderingViewer &) = delete;
|
||||
|
||||
void DecreaseMaximumImageSampleDistance();
|
||||
void ResetMaximumImageSampleDistance();
|
||||
|
||||
void PokeMeasureRender();
|
||||
void PokeMainRender();
|
||||
|
||||
vtkRenderWindow *RenderWindow;
|
||||
vtkRenderer *Renderer;
|
||||
vtkRenderer *MeasureRenderer;
|
||||
vtkVolume * VolumeActor;
|
||||
vtkVolumeMapper *VolumeMapper;
|
||||
vtkInteractorStyle *InteractorStyle;
|
||||
|
||||
@@ -78,6 +78,9 @@ VolumeRenderingToolBar::VolumeRenderingToolBar(QWidget *parent) : QToolBar(paren
|
||||
addSeparator();
|
||||
auto btnMeasure = new QToolButton(this);
|
||||
addButton(btnMeasure, "measure");
|
||||
connect(btnMeasure,&QToolButton::clicked,[=](){
|
||||
emit activeArrow();
|
||||
});
|
||||
addSeparator();
|
||||
auto btnPreset = new QToolButton(this);
|
||||
addButton(btnPreset, "preset");
|
||||
|
||||
@@ -20,6 +20,7 @@ signals:
|
||||
void viewDirectionChanged(int id);
|
||||
void resetView();
|
||||
void fitWindow();
|
||||
void activeArrow();
|
||||
|
||||
private:
|
||||
QAction* addButton(QToolButton* button, const char* objectName);
|
||||
|
||||
@@ -40,12 +40,17 @@ VolumeRenderingWindow::VolumeRenderingWindow(QWidget *parent , Qt::WindowFlags f
|
||||
mViewer->ResetView();
|
||||
mViewer->Render();
|
||||
});
|
||||
connect(toolBar, &VolumeRenderingToolBar::activeArrow,[=](){
|
||||
mViewer->ActiveArrow();
|
||||
mViewer->Render();
|
||||
});
|
||||
connect(toolBar, &VolumeRenderingToolBar::fitWindow,[=](){
|
||||
mViewer->ResetZoomFitWindow();
|
||||
mViewer->Render();
|
||||
});
|
||||
connect(toolBar, &VolumeRenderingToolBar::modeButtonClicked,[=](int mode){
|
||||
mViewer->SetInteractorStyleMode(mode);
|
||||
mViewer->UnActiveMeasure();
|
||||
});
|
||||
|
||||
connect(toolBar, &VolumeRenderingToolBar::viewDirectionChanged, [=](int direction){
|
||||
|
||||
Reference in New Issue
Block a user