/*========================================================================= Program: Visualization Toolkit Module: vtkResliceImageViewerMeasurements.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkResliceImageViewerMeasurements.h" #include "vtkCamera.h" #include "vtkCommand.h" #include "vtkCallbackCommand.h" #include "vtkImageActor.h" #include "vtkResliceCursorWidget.h" #include "vtkResliceCursorLineRepresentation.h" #include "vtkDistanceRepresentation.h" #include "vtkDistanceWidget.h" #include "vtkCaptionWidget.h" #include "vtkCaptionRepresentation.h" #include "vtkAngleWidget.h" #include "vtkAngleRepresentation.h" #include "vtkHandleWidget.h" #include "vtkBiDimensionalWidget.h" #include "vtkBiDimensionalRepresentation.h" #include "vtkPointHandleRepresentation3D.h" #include "vtkSeedWidget.h" #include "vtkHandleWidget.h" #include "vtkSeedRepresentation.h" #include "vtkContourWidget.h" #include "vtkContourRepresentation.h" #include "vtkHandleRepresentation.h" #include "vtkResliceCursorActor.h" #include "vtkResliceCursorPolyDataAlgorithm.h" #include "vtkPlane.h" #include "vtkResliceCursor.h" #include "vtkImageData.h" #include "vtkObjectFactory.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkSmartPointer.h" #include "vtkPlane.h" #include "vtkResliceImageViewer.h" vtkStandardNewMacro(vtkResliceImageViewerMeasurements); //---------------------------------------------------------------------------- vtkResliceImageViewerMeasurements::vtkResliceImageViewerMeasurements() { this->ResliceImageViewer = nullptr; this->WidgetCollection = vtkCollection::New(); // Setup event processing this->EventCallbackCommand = vtkCallbackCommand::New(); this->EventCallbackCommand->SetClientData(this); this->EventCallbackCommand->SetCallback( vtkResliceImageViewerMeasurements::ProcessEventsHandler); this->ProcessEvents = 1; this->Tolerance = 6; } //---------------------------------------------------------------------------- vtkResliceImageViewerMeasurements::~vtkResliceImageViewerMeasurements() { // Remove any added observers if (this->ResliceImageViewer) { this->ResliceImageViewer->GetResliceCursor()-> RemoveObservers(vtkResliceCursorWidget::ResliceAxesChangedEvent, this->EventCallbackCommand ); } this->WidgetCollection->Delete(); this->EventCallbackCommand->Delete(); } //---------------------------------------------------------------------------- void vtkResliceImageViewerMeasurements ::SetResliceImageViewer( vtkResliceImageViewer *i ) { // Weak reference. No need to delete this->ResliceImageViewer = i; if(i) { // Add the observer i->GetResliceCursor() ->AddObserver( vtkResliceCursorWidget::ResliceAxesChangedEvent, this->EventCallbackCommand ); i->GetResliceCursor() ->AddObserver( vtkResliceCursorWidget::ResliceAxesChangedEvent, this->EventCallbackCommand ); } } //---------------------------------------------------------------------------- void vtkResliceImageViewerMeasurements::Render() { this->ResliceImageViewer->Render(); } //------------------------------------------------------------------------- void vtkResliceImageViewerMeasurements ::ProcessEventsHandler(vtkObject* , unsigned long, void* clientdata, void* ) { vtkResliceImageViewerMeasurements * self = reinterpret_cast( clientdata ); // if ProcessEvents is Off, we ignore all interaction events. if (!self->GetProcessEvents()) { return; } self->Update(); } //------------------------------------------------------------------------- void vtkResliceImageViewerMeasurements::Update() { if (this->ResliceImageViewer->GetResliceMode() != vtkResliceImageViewer::RESLICE_OBLIQUE) { return; // nothing to do. } const int nItems = this->WidgetCollection->GetNumberOfItems(); for (int i = 0; i < nItems; i++) { vtkAbstractWidget *a = vtkAbstractWidget::SafeDownCast( this->WidgetCollection->GetItemAsObject(i) ); vtkSeedWidget *s = vtkSeedWidget::SafeDownCast( a ); // seed is handled differently since its really a collection of several // markers which may exist on different planes. if (!s) { a->SetEnabled(this->IsItemOnReslicedPlane(a)); } } } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsItemOnReslicedPlane( vtkAbstractWidget * w ) { if (vtkDistanceWidget *dw = vtkDistanceWidget::SafeDownCast( w )) { return this->IsWidgetOnReslicedPlane(dw); } if (vtkAngleWidget *aw = vtkAngleWidget::SafeDownCast( w )) { return this->IsWidgetOnReslicedPlane(aw); } if (vtkBiDimensionalWidget *aw = vtkBiDimensionalWidget::SafeDownCast( w )) { return this->IsWidgetOnReslicedPlane(aw); } if (vtkCaptionWidget *capw = vtkCaptionWidget::SafeDownCast( w )) { return this->IsWidgetOnReslicedPlane(capw); } if (vtkContourWidget *capw = vtkContourWidget::SafeDownCast( w )) { return this->IsWidgetOnReslicedPlane(capw); } if (vtkSeedWidget *s = vtkSeedWidget::SafeDownCast( w )) { return this->IsWidgetOnReslicedPlane(s); } if (vtkHandleWidget *s = vtkHandleWidget::SafeDownCast( w )) { return this->IsWidgetOnReslicedPlane(s); } return true; } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsWidgetOnReslicedPlane( vtkDistanceWidget * w ) { if (w->GetWidgetState() != vtkDistanceWidget::Manipulate) { return true; // widget is not yet defined. } if (vtkDistanceRepresentation *rep = vtkDistanceRepresentation::SafeDownCast(w->GetRepresentation())) { return this->IsPointOnReslicedPlane( rep->GetPoint1Representation() ) && this->IsPointOnReslicedPlane( rep->GetPoint2Representation() ); } return true; } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsWidgetOnReslicedPlane( vtkAngleWidget * w ) { if (w->GetWidgetState() != vtkAngleWidget::Manipulate) { return true; // widget is not yet defined. } if (vtkAngleRepresentation *rep = vtkAngleRepresentation::SafeDownCast(w->GetRepresentation())) { return this->IsPointOnReslicedPlane( rep->GetPoint1Representation() ) && this->IsPointOnReslicedPlane( rep->GetPoint2Representation() ) && this->IsPointOnReslicedPlane( rep->GetCenterRepresentation() ); } return true; } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsWidgetOnReslicedPlane( vtkBiDimensionalWidget * w ) { if (w->GetWidgetState() != vtkBiDimensionalWidget::Manipulate) { return true; // widget is not yet defined. } if (vtkBiDimensionalRepresentation *rep = vtkBiDimensionalRepresentation::SafeDownCast(w->GetRepresentation())) { return this->IsPointOnReslicedPlane( rep->GetPoint1Representation() ) && this->IsPointOnReslicedPlane( rep->GetPoint2Representation() ) && this->IsPointOnReslicedPlane( rep->GetPoint3Representation() ) && this->IsPointOnReslicedPlane( rep->GetPoint4Representation() ); } return true; } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsWidgetOnReslicedPlane( vtkHandleWidget * w ) { return this->IsPointOnReslicedPlane(w->GetHandleRepresentation()); } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsWidgetOnReslicedPlane( vtkCaptionWidget * w ) { if (vtkCaptionRepresentation *rep = vtkCaptionRepresentation::SafeDownCast(w->GetRepresentation())) { return this->IsPointOnReslicedPlane( rep->GetAnchorRepresentation() ); } return true; } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsWidgetOnReslicedPlane( vtkContourWidget * w ) { if (w->GetWidgetState() != vtkContourWidget::Manipulate) { return true; // widget is not yet defined. } if (vtkContourRepresentation *rep = vtkContourRepresentation::SafeDownCast(w->GetRepresentation())) { const int nNodes = rep->GetNumberOfNodes(); for (int i = 0; i < nNodes; i++) { double p[3]; rep->GetNthNodeWorldPosition(i,p); if (this->IsPositionOnReslicedPlane(p) == false) { return false; } } } return true; } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsWidgetOnReslicedPlane( vtkSeedWidget * w ) { if (vtkSeedRepresentation *rep = vtkSeedRepresentation::SafeDownCast(w->GetRepresentation())) { const int nNodes = rep->GetNumberOfSeeds(); for (int i = 0; i < nNodes; i++) { w->GetSeed(i)->GetHandleRepresentation()->SetVisibility( w->GetEnabled() && this->IsPointOnReslicedPlane( w->GetSeed(i)->GetHandleRepresentation())); } } return true; } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsPointOnReslicedPlane( vtkHandleRepresentation * h ) { double pos[3]; h->GetWorldPosition(pos); return this->IsPositionOnReslicedPlane(pos); } //------------------------------------------------------------------------- bool vtkResliceImageViewerMeasurements ::IsPositionOnReslicedPlane( double p[3] ) { if (vtkResliceCursorRepresentation *rep = vtkResliceCursorRepresentation::SafeDownCast( this->ResliceImageViewer->GetResliceCursorWidget() ->GetRepresentation())) { const int planeOrientation = rep->GetCursorAlgorithm()->GetReslicePlaneNormal(); vtkPlane *plane = this->ResliceImageViewer-> GetResliceCursor()->GetPlane(planeOrientation); const double d = plane->DistanceToPlane(p); return (d < this->Tolerance); } return true; } //------------------------------------------------------------------------- void vtkResliceImageViewerMeasurements::AddItem( vtkAbstractWidget * w ) { this->WidgetCollection->AddItem(w); } //------------------------------------------------------------------------- void vtkResliceImageViewerMeasurements::RemoveItem( vtkAbstractWidget * w ) { this->WidgetCollection->RemoveItem(w); } //------------------------------------------------------------------------- void vtkResliceImageViewerMeasurements::RemoveAllItems() { this->WidgetCollection->RemoveAllItems(); } //---------------------------------------------------------------------------- void vtkResliceImageViewerMeasurements::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "ResliceImageViewer: " << this->ResliceImageViewer << "\n"; os << indent << "WidgetCollection: " << this->WidgetCollection << endl; this->WidgetCollection->PrintSelf(os,indent.GetNextIndent()); os << indent << "ProcessEvents: " << (this->ProcessEvents? "On" : "Off") << "\n"; os << indent << "Tolerance: " << this->Tolerance << endl; }