/*========================================================================= 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 "vtkAngleRepresentation.h" #include "vtkAngleWidget.h" #include "vtkBiDimensionalRepresentation.h" #include "vtkBiDimensionalWidget.h" #include "vtkCallbackCommand.h" #include "vtkCamera.h" #include "vtkCaptionRepresentation.h" #include "vtkCaptionWidget.h" #include "vtkCommand.h" #include "vtkContourRepresentation.h" #include "vtkContourWidget.h" #include "vtkDistanceRepresentation.h" #include "vtkDistanceWidget.h" #include "vtkHandleRepresentation.h" #include "vtkHandleWidget.h" #include "vtkImageActor.h" #include "vtkImageData.h" #include "vtkObjectFactory.h" #include "vtkPlane.h" #include "vtkPointHandleRepresentation3D.h" #include "vtkRenderWindow.h" #include "vtkRenderWindowInteractor.h" #include "vtkRenderer.h" #include "vtkResliceCursor.h" #include "vtkResliceCursorActor.h" #include "vtkResliceCursorLineRepresentation.h" #include "vtkResliceCursorPolyDataAlgorithm.h" #include "vtkResliceCursorWidget.h" #include "vtkResliceImageViewer.h" #include "vtkSeedRepresentation.h" #include "vtkSeedWidget.h" #include "vtkSmartPointer.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)) { 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; }