Gitlab.kitware.com will be offline between 8am and midnight (EST/UTC-0500) on Saturday, December 15th.

Commit 8e4f2f7c authored by Johan Andruejol's avatar Johan Andruejol

Fix picking through a disabled widget with picking manager on

With picking manager on, it was impossible to pick a widget if a disabled
widget was in front of it.
To fix this, we have:
  - In the old style widgets (derived only from vtkInteractorObserver), we
went through all the implementation and added the unregistration/registration
of the pickers in the SetEnabled() method.
 - In new style widgets (derived from vtkAbstractWidget and
vtkWidgetRepresentation) the method RegisterPickers and UnRegisterPickers
have been moved into the representation public API to be able to be called
by the widget's SetEnabled() method. This allows the widget to register and
unregisters the pickers as necessary when enabled and disabled.

In both cases we also implemented the SetPickingManaged method as previously
the PickingManaged property was never used anywhere in the code base.
Similarly, the PickersModified() method was removed as its purpose seemed
redundant to SetPickingManaged().

The test TestPickingManagerSeedWidget2 was added to demonstrate/test the
picking behind a disabled widget.

For more background information, see https://issues.slicer.org/view.php?id=3808Co-Authored-by: Ken Martin's avatarKen Martin <ken.martin@kitware.com>
Co-Authored-by: Jean-Christophe Fillion-Robin's avatarJean-Christophe Fillion-Robin <jchris.fillionr@kitware.com>
Thanks: Steve Pieper <pieper@bwh.harvard.edu>
parent c68bae18
......@@ -45,6 +45,7 @@ vtk_add_test_cxx(vtkInteractionWidgetsCxxTests tests
TestOrthoPlanes.cxx
TestParallelopipedWidget.cxx
TestPickingManagerSeedWidget.cxx
TestPickingManagerSeedWidget2.cxx
TestPlaybackWidget.cxx
TestPointHandleRepresentation3D.cxx
TestProgrammaticPlacement.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestPickingManagerSeedWidget.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.
=========================================================================*/
/*==============================================================================
Library: MSVTK
Copyright (c) Kitware Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
//
// This example tests the PickingManager using a scene full of seed widgets.
// It makes sure that the picking works when some widgets are disabled.
//
// The test depends on:
// * vtkSeedWidget
// * vtkSphereHandleRepresentation
//
// By default the Picking Manager is enabled.
// Press 'Alt' to enable/disable some of seeds.
// Press 'Space' to restore the cube
// VTK includes
#include "vtkCommand.h"
#include "vtkHandleWidget.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkNew.h"
#include "vtkPickingManager.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRendererCollection.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSeedRepresentation.h"
#include "vtkSeedWidget.h"
#include "vtkSmartPointer.h"
#include "vtkSphereHandleRepresentation.h"
#include "vtkStdString.h"
#include "vtkTimerLog.h"
// STL includes
#include <iostream>
#include <fstream>
#include <list>
const char eventLogTestPickingManagerSeedWidget2[] = ""
"# StreamVersion 1\n"
"EnterEvent 599 295 0 0 0 0 0\n"
"MouseMoveEvent 599 295 0 0 0 0 0\n"
"MouseMoveEvent 419 243 0 0 0 0 0\n"
"MouseMoveEvent 417 243 0 0 0 0 0\n"
"LeftButtonPressEvent 417 243 0 0 0 0 0\n"
"StartInteractionEvent 417 243 0 0 0 0 0\n"
"MouseMoveEvent 414 243 0 0 0 0 0\n"
"MouseMoveEvent 412 243 0 0 0 0 0\n"
"MouseMoveEvent 294 228 0 0 0 0 0\n"
"LeftButtonReleaseEvent 294 228 0 0 0 0 0\n"
"KeyPressEvent 297 223 0 0 0 1 Alt_L\n"
"RenderEvent 297 225 0 0 0 0 Alt_L\n"
"KeyReleaseEvent 299 225 0 0 0 1 Alt_L\n"
"LeftButtonPressEvent 324 237 0 0 0 0 Alt_L\n"
"RenderEvent 324 237 0 0 0 0 Alt_L\n"
"MouseMoveEvent 324 237 0 0 0 0 Alt_L\n"
"MouseMoveEvent 324 235 0 0 0 0 Alt_L\n"
"MouseMoveEvent 324 233 0 0 0 0 Alt_L\n"
"MouseMoveEvent 349 113 0 0 0 0 Alt_L\n"
"MouseMoveEvent 347 113 0 0 0 0 Alt_L\n"
"LeftButtonReleaseEvent 347 113 0 0 0 0 Alt_L\n"
"MouseMoveEvent 347 113 0 0 0 0 Alt_L\n"
"MouseMoveEvent 347 115 0 0 0 0 Alt_L\n"
"MouseMoveEvent 347 118 0 0 0 0 Alt_L\n"
"MouseMoveEvent 344 120 0 0 0 0 Alt_L\n"
"MouseMoveEvent 322 323 0 0 0 0 Alt_L\n"
"MouseMoveEvent 322 325 0 0 0 0 Alt_L\n"
"LeftButtonPressEvent 322 325 0 0 0 0 Alt_L\n"
"MouseMoveEvent 324 325 0 0 0 0 Alt_L\n"
"MouseMoveEvent 324 328 0 0 0 0 Alt_L\n"
"MouseMoveEvent 324 330 0 0 0 0 Alt_L\n"
"MouseMoveEvent 314 423 0 0 0 0 Alt_L\n"
"MouseMoveEvent 314 425 0 0 0 0 Alt_L\n"
"LeftButtonReleaseEvent 314 425 0 0 0 0 Alt_L\n"
"MouseMoveEvent 314 425 0 0 0 0 Alt_L\n"
"MouseMoveEvent 314 423 0 0 0 0 Alt_L\n"
"MouseMoveEvent 317 420 0 0 0 0 Alt_L\n"
"MouseMoveEvent 554 568 0 0 0 0 Alt_L\n"
"MouseMoveEvent 564 580 0 0 0 0 Alt_L\n"
"MouseMoveEvent 574 595 0 0 0 0 Alt_L\n"
"ExitEvent 574 595 0 0 0 0 Alt_L\n"
;
//------------------------------------------------------------------------------
// Press 'Space' to reorganize the cube of seeds
class vtkPickingManagerSeedWidgetTest2Callback : public vtkCommand
{
public:
static vtkPickingManagerSeedWidgetTest2Callback *New()
{ return new vtkPickingManagerSeedWidgetTest2Callback; }
void Execute(vtkObject *caller, unsigned long, void*) override
{
vtkRenderWindowInteractor *iren =
static_cast<vtkRenderWindowInteractor*>(caller);
// Reorganize the cube
if(vtkStdString(iren->GetKeySym()) == "space")
{
const int baseCube =
static_cast<int>(pow(this->Seeds.size(), 1./3.) / 2 + 0.5);
std::list<vtkSmartPointer<vtkHandleWidget> >::iterator it =
this->Seeds.begin();
for(int i=-baseCube; i<baseCube; ++i)
{
for(int j=-baseCube; j<baseCube; ++j)
{
for(int k=-baseCube; k<baseCube; ++k)
{
vtkSphereHandleRepresentation* newHandleRep =
vtkSphereHandleRepresentation::SafeDownCast(
(*it)->GetRepresentation());
double pos[3] = {static_cast<double>(i),
static_cast<double>(j),
static_cast<double>(k)};
newHandleRep->SetWorldPosition(pos);
++it;
}
}
}
}
// Disable every other seed
if (vtkStdString(iren->GetKeySym()) == "Alt_L" ||
vtkStdString(iren->GetKeySym()) == "Alt_R")
{
const int baseCube =
static_cast<int>(pow(this->Seeds.size(), 1. / 3.) / 2 + 0.5);
int n = 0;
for (int i =-baseCube; i<baseCube; ++i)
{
for (int j =-baseCube; j<baseCube; ++j)
{
for (int k =-baseCube; k<baseCube; ++k)
{
if (n % 2 == 0)
{
vtkHandleWidget* w = this->Widget->GetSeed(n);
w->SetEnabled(!w->GetEnabled());
}
++n;
}
}
}
this->Widget->GetCurrentRenderer()->Render();
}
}
std::list<vtkSmartPointer<vtkHandleWidget> > Seeds;
vtkSeedWidget* Widget;
};
//------------------------------------------------------------------------------
// Test Picking Manager with a lot of seeds
//------------------------------------------------------------------------------
int TestPickingManagerSeedWidget2(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
{
// Create the RenderWindow, Renderer and both Actors
//
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> interactor;
vtkNew<vtkInteractorStyleTrackballCamera> interactorStyle;
interactor->SetRenderWindow(renderWindow);
interactor->SetInteractorStyle(interactorStyle);
/*--------------------------------------------------------------------------*/
// PICKING MANAGER
/*--------------------------------------------------------------------------*/
interactor->GetPickingManager()->EnabledOn();
/*--------------------------------------------------------------------------*/
// SEEDS
/*--------------------------------------------------------------------------*/
// Representations
double pos[3] = {0, 0, 0};
vtkNew<vtkSphereHandleRepresentation> handle;
//handle->SetHandleSize(15.0);
handle->GetProperty()->SetRepresentationToWireframe();
handle->GetProperty()->SetColor(1,1,1);
vtkNew<vtkSeedRepresentation> seedRepresentation;
seedRepresentation->SetHandleRepresentation(handle);
// Settings
vtkNew<vtkSeedWidget> seedWidget;
seedWidget->SetRepresentation(seedRepresentation);
seedWidget->SetInteractor(interactor);
seedWidget->EnabledOn();
// Create a cube full of seeds
// base correspond to the side of the cube --> (2*base)^3 seeds
const int baseCube = 2;
std::list <vtkSmartPointer<vtkHandleWidget> > seeds;
for(int i=-baseCube; i<baseCube; ++i)
{
for(int j=-baseCube; j<baseCube; ++j)
{
for(int k=-baseCube; k<baseCube; ++k)
{
vtkHandleWidget* newHandle = seedWidget->CreateNewHandle();
newHandle->SetEnabled(1);
vtkSphereHandleRepresentation* newHandleRep =
vtkSphereHandleRepresentation::SafeDownCast(
newHandle->GetRepresentation());
pos[0] = i;
pos[1] = j;
pos[2] = k;
newHandleRep->GetProperty()->SetRepresentationToWireframe();
newHandleRep->GetProperty()->SetColor(1,1,1);
newHandleRep->SetWorldPosition(pos);
seeds.push_back(newHandle);
}
}
}
seedWidget->CompleteInteraction();
// Callback to reorganize the cube when space is pressed
vtkNew<vtkPickingManagerSeedWidgetTest2Callback> callback;
callback->Seeds = seeds;
callback->Widget = seedWidget;
interactor->AddObserver(vtkCommand::KeyPressEvent, callback);
/*--------------------------------------------------------------------------*/
// Rendering
/*--------------------------------------------------------------------------*/
// Add the actors to the renderer, set the background and size
renderer->SetBackground(0.1, 0.2, 0.4);
renderWindow->SetSize(600, 600);
// Record
vtkNew<vtkInteractorEventRecorder> recorder;
recorder->SetInteractor(interactor);
recorder->ReadFromInputStringOn();
recorder->SetInputString(eventLogTestPickingManagerSeedWidget2);
// render the image
interactor->Initialize();
double extent[6] = {-7, 7, -7, 7, -1, 1};
renderer->ResetCamera(extent);
renderWindow->Render();
recorder->Play();
recorder->Off();
interactor->Start();
return EXIT_SUCCESS;
}
......@@ -121,8 +121,12 @@ vtkAbstractPolygonalHandleRepresentation3D
//----------------------------------------------------------------------
void vtkAbstractPolygonalHandleRepresentation3D::RegisterPickers()
{
this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
->AddPicker(this->HandlePicker, this);
vtkPickingManager* pm = this->GetPickingManager();
if (!pm)
{
return;
}
pm->AddPicker(this->HandlePicker, this);
}
//----------------------------------------------------------------------
......
......@@ -182,6 +182,11 @@ public:
vtkBooleanMacro( SmoothMotion, vtkTypeBool );
//@}
/*
* Register internal Pickers within PickingManager
*/
void RegisterPickers() override;
protected:
vtkAbstractPolygonalHandleRepresentation3D();
~vtkAbstractPolygonalHandleRepresentation3D() override;
......@@ -201,9 +206,6 @@ protected:
int WaitCount;
vtkTypeBool HandleVisibility;
// Register internal Pickers within PickingManager
void RegisterPickers() override;
// Methods to manipulate the cursor
virtual void Translate(double *p1, double *p2);
virtual void Scale(double *p1, double *p2, double eventPos[2]);
......
......@@ -62,6 +62,7 @@ vtkAbstractWidget::~vtkAbstractWidget()
this->CurrentRenderer->RemoveViewProp(this->WidgetRep);
}
this->WidgetRep->Delete();
this->WidgetRep = nullptr;
}
this->EventTranslator->Delete();
......@@ -134,6 +135,7 @@ void vtkAbstractWidget::SetEnabled(int enabling)
this->Enabled = 1;
this->CreateDefaultRepresentation();
this->WidgetRep->SetRenderer(this->CurrentRenderer);
this->WidgetRep->RegisterPickers();
// listen for the events found in the EventTranslator
if ( ! this->Parent )
......@@ -187,6 +189,10 @@ void vtkAbstractWidget::SetEnabled(int enabling)
this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
this->SetCurrentRenderer(nullptr);
if (this->WidgetRep)
{
this->WidgetRep->UnRegisterPickers();
}
}
// We no longer call render when enabled state changes. It's the applications
......
......@@ -185,14 +185,20 @@ void vtkBalloonWidget::SetPicker(vtkAbstractPropPicker *picker)
this->Picker = picker;
this->Picker->Register(this);
this->PickersModified();
this->UnRegisterPickers();
this->RegisterPickers();
this->Modified();
}
//----------------------------------------------------------------------
void vtkBalloonWidget::RegisterPickers()
{
this->Interactor->GetPickingManager()->AddPicker(this->Picker, this);
vtkPickingManager* pm = this->GetPickingManager();
if (!pm)
{
return;
}
pm->AddPicker(this->Picker, this);
}
//----------------------------------------------------------------------
......
......@@ -173,6 +173,11 @@ public:
vtkGetObjectMacro(Picker,vtkAbstractPropPicker);
//@}
/*
* Register internal Pickers within PickingManager
*/
void RegisterPickers() override;
protected:
vtkBalloonWidget();
~vtkBalloonWidget() override;
......@@ -187,9 +192,6 @@ protected:
// Support for picking
vtkAbstractPropPicker *Picker;
// Register internal Pickers within PickingManager
void RegisterPickers() override;
// The vtkProp that is being hovered over (which may be nullptr)
vtkProp *CurrentProp;
......
......@@ -1724,10 +1724,13 @@ void vtkBoxRepresentation::HighlightOutline(int highlight)
//------------------------------------------------------------------------------
void vtkBoxRepresentation::RegisterPickers()
{
this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
->AddPicker(this->HandlePicker, this);
this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
->AddPicker(this->HexPicker, this);
vtkPickingManager* pm = this->GetPickingManager();
if (!pm)
{
return;
}
pm->AddPicker(this->HandlePicker, this);
pm->AddPicker(this->HexPicker, this);
}
//----------------------------------------------------------------------------
......
......@@ -270,6 +270,11 @@ public:
void StepBackward();
//@}
/*
* Register internal Pickers within PickingManager
*/
void RegisterPickers() override;
protected:
vtkBoxRepresentation();
~vtkBoxRepresentation() override;
......@@ -319,9 +324,6 @@ protected:
int CurrentHexFace;
vtkCellPicker *LastPicker;
// Register internal Pickers within PickingManager
void RegisterPickers() override;
// Transform the hexahedral points (used for rotations)
vtkTransform *Transform;
......
......@@ -267,6 +267,7 @@ void vtkBoxWidget::SetEnabled(int enabling)
this->CurrentRenderer->AddActor(this->Handle[j]);
this->Handle[j]->SetProperty(this->HandleProperty);
}
this->RegisterPickers();
this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
}
......@@ -301,6 +302,7 @@ void vtkBoxWidget::SetEnabled(int enabling)
this->CurrentHandle = nullptr;
this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
this->SetCurrentRenderer(nullptr);
this->UnRegisterPickers();
}
this->Interactor->Render();
......
......@@ -280,6 +280,7 @@ void vtkBrokenLineWidget::SetEnabled( int enabling )
}
this->BuildRepresentation();
this->SizeHandles();
this->RegisterPickers();
this->InvokeEvent( vtkCommand::EnableEvent,nullptr );
}
......@@ -310,6 +311,7 @@ void vtkBrokenLineWidget::SetEnabled( int enabling )
this->CurrentHandle = nullptr;
this->InvokeEvent( vtkCommand::DisableEvent,nullptr );
this->SetCurrentRenderer( nullptr );
this->UnRegisterPickers();
}
this->Interactor->Render();
......
......@@ -174,10 +174,13 @@ void vtkCurveRepresentation::SetClosed(vtkTypeBool closed)
//----------------------------------------------------------------------
void vtkCurveRepresentation::RegisterPickers()
{
this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
->AddPicker(this->HandlePicker, this);
this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
->AddPicker(this->LinePicker, this);
vtkPickingManager* pm = this->GetPickingManager();
if (!pm)
{
return;
}
pm->AddPicker(this->HandlePicker, this);
pm->AddPicker(this->LinePicker, this);
}
//----------------------------------------------------------------------------
......
......@@ -226,6 +226,11 @@ public:
*/
void SetLineColor(double r, double g, double b);
/*
* Register internal Pickers within PickingManager
*/
void RegisterPickers() override;
protected:
vtkCurveRepresentation();
~vtkCurveRepresentation() override;
......@@ -267,9 +272,6 @@ protected:
vtkActor *CurrentHandle;
int CurrentHandleIndex;
// Register internal Pickers within PickingManager
void RegisterPickers() override;
// Methods to manipulate the curve.
void MovePoint(double *p1, double *p2);
void Scale(double *p1, double *p2, int X, int Y);
......
......@@ -155,8 +155,12 @@ void vtkEllipsoidTensorProbeRepresentation
//----------------------------------------------------------------------
void vtkEllipsoidTensorProbeRepresentation::RegisterPickers()
{
this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
->AddPicker(this->CellPicker, this);
vtkPickingManager* pm = this->GetPickingManager();
if (!pm)
{
return;
}
pm->AddPicker(this->CellPicker, this);
}
//----------------------------------------------------------------------
......
......@@ -66,6 +66,11 @@ public:
void ReleaseGraphicsResources(vtkWindow *) override;
//@}
/*
* Register internal Pickers within PickingManager
*/
void RegisterPickers() override;
protected:
vtkEllipsoidTensorProbeRepresentation();
~vtkEllipsoidTensorProbeRepresentation() override;
......@@ -73,9 +78,6 @@ protected:
// Get the interpolated tensor at the current position
void EvaluateTensor( double t[9] );
// Register internal Pickers within PickingManager
void RegisterPickers() override;
vtkActor * EllipsoidActor;
vtkPolyDataMapper * EllipsoidMapper;
vtkPolyData * TensorSource;
......
......@@ -217,6 +217,11 @@ public:
Pushing
};
/*
* Register internal Pickers within PickingManager
*/
void RegisterPickers() override;
protected:
vtkFinitePlaneRepresentation();
~vtkFinitePlaneRepresentation() override;
......@@ -226,9 +231,6 @@ protected:
// Size the glyphs representing hot spots (e.g., handles)
virtual void SizeHandles();
// Register internal Pickers within PickingManager
void RegisterPickers() override;
void SetHighlightNormal(int highlight);
void SetHighlightPlane(int highlight);
void SetHighlightHandle(vtkProp *prop);
......
......@@ -321,6 +321,7 @@ void vtkImagePlaneWidget::SetEnabled(int enabling)
// Add the image data annotation
this->CurrentRenderer->AddViewProp(this->TextActor);
this->RegisterPickers();
this->TexturePlaneActor->PickableOn();
this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
......@@ -360,6 +361,7 @@ void vtkImagePlaneWidget::SetEnabled(int enabling)
this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
this->SetCurrentRenderer(nullptr);
this->UnRegisterPickers();
}
this->Interactor->Render();
......
......@@ -272,6 +272,7 @@ void vtkImageTracerWidget::SetEnabled(int enabling)
this->CurrentRenderer->AddViewProp(this->LineActor);
this->LineActor->SetProperty(this->LineProperty);
this->LineActor->PickableOff();
this->RegisterPickers();
this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
}
......@@ -312,6 +313,7 @@ void vtkImageTracerWidget::SetEnabled(int enabling)
this->CurrentHandle = nullptr;
this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
this->SetCurrentRenderer(nullptr);
this->UnRegisterPickers();
}
this->Interactor->Render();
......
......@@ -377,6 +377,11 @@ public:
vtkGetMacro(RepresentationState, int);
//@}
/*
* Register internal Pickers within PickingManager
*/
void RegisterPickers() override;
protected:
vtkImplicitCylinderRepresentation();
~vtkImplicitCylinderRepresentation() override;
......@@ -460,9 +465,6 @@ protected:
vtkCellPicker *Picker;
vtkCellPicker *CylPicker;
// Register internal Pickers within PickingManager
void RegisterPickers() override;
// Transform the normal (used for rotation)
vtkTransform *Transform;
......
......@@ -303,6 +303,7 @@ void vtkImplicitPlaneWidget::SetEnabled(int enabling)
this->UpdateRepresentation();
this->SizeHandles();
this->RegisterPickers();
this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
}
......@@ -332,6 +333,7 @@ void vtkImplicitPlaneWidget::SetEnabled(int enabling)
this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
this->SetCurrentRenderer(nullptr);
this->UnRegisterPickers();
}
this->Interactor->Render();
......
......@@ -303,6 +303,7 @@ void vtkLineWidget::SetEnabled(int enabling)
this->BuildRepresentation();
this->SizeHandles();
this->RegisterPickers();
this->InvokeEvent(vtkCommand::EnableEvent,nullptr);
}
......@@ -338,6 +339,7 @@ void vtkLineWidget::SetEnabled(int enabling)
this->CurrentHandle = nullptr;
this->InvokeEvent(vtkCommand::DisableEvent,nullptr);
this->SetCurrentRenderer(nullptr);
this->UnRegisterPickers();
}
this->Interactor->Render();
......
......@@ -142,8 +142,12 @@ vtkMeasurementCubeHandleRepresentation3D
//----------------------------------------------------------------------
void vtkMeasurementCubeHandleRepresentation3D::RegisterPickers()
{
this->Renderer->GetRenderWindow()->GetInteractor()->GetPickingManager()
->AddPicker(this->HandlePicker, this);
vtkPickingManager* pm = this->GetPickingManager();
if (!pm)
{
return;
}
pm->AddPicker(this->HandlePicker, this);
}
//----------------------------------------------------------------------
......