[vtkusers] Res: vtkSeedWidget
Karthik Krishnan
karthik.krishnan at kitware.com
Tue Aug 12 09:28:21 EDT 2008
Wagner Sales wrote:
> Hi,
>
> I'm on the same problem (using vtkSeedWidget and points does not
> disappear after slice change), and after a lot of google search, this
> message appears ( :) ). But I have some questions:
>
> From Karthik:
I worte the following example code to display an volume, a slice slider,
and a handle widget on a particular slice.
The Handle Widget should appear on slice 43 and does disappear with the
slice change. The seed widget is just implemented as a collection of
handle widgets, so if one works, the other should too. This example
should get your started.
You are probably missing the
interactorStyle->AutoAdjustCameraClippingRangeOff().
The AutoAdjustCameraClippingRange ensures that it displays all the props
in the scene (in so far as possible). You don't want that when you are
displaying just a slice with an ImageViewer.
--------
#include "vtkImageData.h"
#include "vtkVolume16Reader.h"
#include "vtkImageShiftScale.h"
#include "vtkImageViewer2.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSliderRepresentation.h"
#include "vtkSliderRepresentation2D.h"
#include "vtkSliderWidget.h"
#include "vtkCommand.h"
#include "vtkHandleWidget.h"
#include "vtkImageActorPointPlacer.h"
#include "vtkPointHandleRepresentation3D.h"
#include "vtkInteractorStyleImage.h"
#include "vtkCamera.h"
#include "vtkInteractorEventRecorder.h"
#include "vtkTestUtilities.h"
#include "vtkRenderWindow.h"
#include "vtkRegressionTestImage.h"
#include "vtkProperty.h"
class vtkSliderCallback2 : public vtkCommand
{
public:
static vtkSliderCallback2 *New()
{ return new vtkSliderCallback2; }
void SetImageViewer(vtkImageViewer2 *viewer)
{ m_Viewer = viewer; }
virtual void Execute(vtkObject *caller, unsigned long , void* )
{
vtkSliderWidget *slider = (vtkSliderWidget *)caller;
vtkSliderRepresentation *sliderRepres = (vtkSliderRepresentation
*)slider->GetRepresentation();
int pos = (int)sliderRepres->GetValue();
m_Viewer->SetSlice(pos);
}
protected:
vtkImageViewer2 *m_Viewer;
};
int main(int argc, char *argv[])
{
char fname[] = "/home/karthik/Data/VTKData/Data/headsq/quarter";
vtkVolume16Reader* v16 = vtkVolume16Reader::New();
v16->SetDataDimensions(64, 64);
v16->SetDataByteOrderToLittleEndian();
v16->SetImageRange(1, 93);
v16->SetDataSpacing(3.2, 3.2, 1.5);
v16->SetFilePrefix(fname);
v16->ReleaseDataFlagOn();
v16->SetDataMask(0x7fff);
v16->Update();
double range[2];
v16->GetOutput()->GetScalarRange(range);
vtkImageShiftScale* shifter = vtkImageShiftScale::New();
shifter->SetShift(-1.0*range[0]);
shifter->SetScale(255.0/(range[1]-range[0]));
shifter->SetOutputScalarTypeToUnsignedChar();
shifter->SetInputConnection(v16->GetOutputPort());
shifter->ReleaseDataFlagOff();
shifter->Update();
vtkImageViewer2 *ImageViewer = vtkImageViewer2::New();
ImageViewer->SetInput(shifter->GetOutput());
ImageViewer->SetColorLevel(127);
ImageViewer->SetColorWindow(255);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
ImageViewer->SetupInteractor(iren);
ImageViewer->Render();
ImageViewer->GetRenderer()->ResetCamera();
// Important. If you don't have this, the camera clipping range will
be adjusted
// to display both the handle and the image actor almost always. We
want the
// clipping range to include just the slice being shown.
ImageViewer->GetInteractorStyle()->AutoAdjustCameraClippingRangeOff();
ImageViewer->Render();
vtkSliderRepresentation2D *SliderRepres =
vtkSliderRepresentation2D::New();
int min = ImageViewer->GetSliceMin();
int max = ImageViewer->GetSliceMax();
SliderRepres->SetMinimumValue(min);
SliderRepres->SetMaximumValue(max);
SliderRepres->SetValue((int)((min + max) / 2));
SliderRepres->SetTitleText("Slice");
SliderRepres->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
SliderRepres->GetPoint1Coordinate()->SetValue(0.3, 0.05);
SliderRepres->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
SliderRepres->GetPoint2Coordinate()->SetValue(0.7, 0.05);
SliderRepres->SetSliderLength(0.02);
SliderRepres->SetSliderWidth(0.03);
SliderRepres->SetEndCapLength(0.01);
SliderRepres->SetEndCapWidth(0.03);
SliderRepres->SetTubeWidth(0.005);
SliderRepres->SetLabelFormat("%3.0lf");
SliderRepres->SetTitleHeight(0.02);
SliderRepres->SetLabelHeight(0.02);
vtkSliderWidget *SliderWidget = vtkSliderWidget::New();
SliderWidget->SetInteractor(iren);
SliderWidget->SetRepresentation(SliderRepres);
SliderWidget->KeyPressActivationOff();
SliderWidget->SetAnimationModeToAnimate();
SliderWidget->SetEnabled(true);
vtkSliderCallback2 *SliderCb = vtkSliderCallback2::New();
SliderCb->SetImageViewer(ImageViewer);
SliderWidget->AddObserver(vtkCommand::InteractionEvent, SliderCb);
ImageViewer->SetSlice((int)SliderRepres->GetValue());
vtkHandleWidget *HandleWidget = vtkHandleWidget::New();
vtkPointHandleRepresentation3D *rep =
vtkPointHandleRepresentation3D::New();
HandleWidget->SetRepresentation(rep);
double bounds[6];
v16->GetOutput()->GetBounds( bounds );
double worldPos[] = { (bounds[0] + bounds[1])/2.0, (bounds[2] +
bounds[3])/2.0, (bounds[4] + bounds[5])/2.0 };
rep->SetWorldPosition( worldPos );
rep->GetProperty()->SetColor(0,1,1);
rep->Delete();
HandleWidget->SetInteractor(iren);
HandleWidget->SetEnabled(true);
HandleWidget->ProcessEventsOn();
ImageViewer->GetRenderWindow()->SetSize(500, 500);
// render the image
//
iren->Initialize();
ImageViewer->Render();
int retVal = vtkRegressionTestImage( ImageViewer->GetRenderWindow() );
if ( retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
SliderRepres->Delete();
SliderCb->Delete();
HandleWidget->Delete();
v16->Delete();
ImageViewer->Delete();
shifter->Delete();
SliderWidget->Delete();
iren->Delete();
return EXIT_SUCCESS;
}
HTH
--
karthik
> What is the output display bounds of the result of vtkImageReslice. I
> presume you are passing it through to vtkImageActor. If the display
> bounds, as you scroll through slices do change, the seeds should
> appear and disappear automatically.
> Since the ImageActor doesn't have a SetBounds() method and
> ImageReslice doesn't have a GetBounds() method, how to do this? .
>
> Another question:
> When I call a the following on my callback, on Execute(vtkObject*,
> unsigned long, void*) method:
> if( event == vtkCommand::PlacePointEvent)
> {
> std::cout << "A point are placed!"<< std::endl;
> cout << "Point placed, total of:" <<
> this->SeedRepresentation->GetNumberOfSeeds() << "\n";
> double vc[3];
> double wc[3];
>
> this->SeedRepresentation->GetSeedWorldPosition(this->SeedRepresentation->GetNumberOfSeeds()
> - 1, vc);
>
> this->SeedRepresentation->GetSeedDisplayPosition(this->SeedRepresentation->GetNumberOfSeeds()
> - 1, wc);
> std::cout << "Printing the word coordinate: " << vc[0] << ", " <<
> vc[1] << ", " << vc[2] << std::endl;
> std::cout << "Printing the display coordinate: " << wc[0] << ", "
> << wc[1] << ", " << wc[2] << std::endl;
> }
> The output never show a valid Z value. If are in display coordinate,
> are every times 0 ( which I think are correct, since I'm are using a
> 2D viewer ).
> But and in world coordinate? My access of this value of course are
> wrong. Can someone help me with these?
>
> Sorry by the newbie question and thanks in advance,
>
> Wagner Sales
>
>
> ----- Mensagem original ----
> De: Ken Urish <ken.urish at gmail.com>
> Para: Karthik Krishnan <karthik.krishnan at kitware.com>; vtkusers at vtk.org
> Enviadas: Terça-feira, 29 de Abril de 2008 13:44:07
> Assunto: Re: [vtkusers] vtkSeedWidget
>
> Karthik
>
> Yes I am passing vtkImageReslice through an actor.
> No, I am not declaring any bounds on the reslice. I am using the
> example based off the ImageReslice test file. I assume I should set
> the bounds in the Reslice callback (below). Could you offer me what
> command to use? I dont see object that looks like it will set bounds?
> I really appreciate your help with this, I was up most of last night
> trying to power through it.
> Thanks, Ken
>
> //------------------------------------------------------------------------------
> // IMAGE RESLICE CALLBACK
> // The mouse motion callback, to turn "Slicing" on and off
> //-------------------------------------------------------------------------------
> class vtkImageInteractionCallback : public vtkCommand
> {
> public:
>
> static vtkImageInteractionCallback *New() {
> return new vtkImageInteractionCallback; };
>
> vtkImageInteractionCallback() {
> this->Slicing = 0;
> this->ImageReslice = 0;
> this->Interactor = 0; };
>
> void SetImageReslice(vtkImageReslice *reslice) {
> this->ImageReslice = reslice; };
>
> vtkImageReslice *GetImageReslice() {
> return this->ImageReslice; };
>
> void SetInteractor(vtkRenderWindowInteractor *interactor) {
> this->Interactor = interactor; };
>
> vtkRenderWindowInteractor *GetInteractor() {
> return this->Interactor; };
>
> virtual void Execute(vtkObject *, unsigned long event, void *)
> {
> vtkRenderWindowInteractor *interactor = this->GetInteractor();
>
> int lastPos[2];
> interactor->GetLastEventPosition(lastPos);
> int currPos[2];
> interactor->GetEventPosition(currPos);
>
> if (event == vtkCommand::LeftButtonPressEvent)
> {
> this->Slicing = 1;
> }
> else if (event == vtkCommand::LeftButtonReleaseEvent)
> {
> this->Slicing = 0;
> }
> else if (event == vtkCommand::MouseMoveEvent)
> {
> if (this->Slicing)
> {
> vtkImageReslice *reslice = this->ImageReslice;
>
> // Increment slice position by deltaY of mouse
> int deltaY = (lastPos[1] - currPos[1]);
>
> reslice->GetOutput()->UpdateInformation();
> double sliceSpacing = reslice->GetOutput()->GetSpacing()[2];
> vtkMatrix4x4 *matrix = reslice->GetResliceAxes();
> // move the center point that we are slicing through
> double point[4];
> double center[4];
> point[0] = 0.0;
> point[1] = 0.0;
> point[2] = sliceSpacing * deltaY;
> point[3] = 1.0;
> std::cout<<point[2]<<std::endl;
> matrix->MultiplyPoint(point, center);
> matrix->SetElement(0, 3, center[0]);
> matrix->SetElement(1, 3, center[1]);
> matrix->SetElement(2, 3, center[2]);
> interactor->Render();
> }
> else
> {
> vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(
> interactor->GetInteractorStyle());
> if (style)
> {
> style->OnMouseMove();
> }
> }
> }
> };
>
>
> On Tue, Apr 29, 2008 at 8:31 AM, Karthik Krishnan
> <karthik.krishnan at kitware.com <mailto:karthik.krishnan at kitware.com>>
> wrote:
> > The Seed widget uses a vtkHandleWidget internally for each seed, with
> > the default representation being the 3D vtkPointHandleRepresentation3D
> > class. The resulting primitives exist in world coordinates (and not on
> > the overlay plane). So they should disappear when you move to the next
> > slice.
> >
> > What is the output display bounds of the result of vtkImageReslice. I
> > presume you are passing it through to vtkImageActor. If the display
> > bounds, as you scroll through slices do change, the seeds should
> > appear and disappear automatically.
> >
> > HTH
> > --
> > karthik
> >
> >
> >
> > On Tue, Apr 29, 2008 at 9:30 AM, Ken Urish <ken.urish at gmail.com
> <mailto:ken.urish at gmail.com>> wrote:
> > > Hey all,
> > >
> > > Im using vtkSeedWidget on a 3D image that I am viewing through
> > > ImageReslice. When I place my seed points on a 2D slice, how can I
> > > have the seed points disappear when I move to the next slice? Im
> > > moving through ~100 slices and I dont want them building up. Is this
> > > even possible? I appreciate the help.
> > >
> > > Thanks
> > > --Ken--
> > > _______________________________________________
> > > This is the private VTK discussion list.
> > > Please keep messages on-topic. Check the FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
> > > Follow this link to subscribe/unsubscribe:
> > > http://www.vtk.org/mailman/listinfo/vtkusers
> >
> _______________________________________________
> This is the private VTK discussion list.
> Please keep messages on-topic. Check the FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>
> ------------------------------------------------------------------------
> Novos endereços, o Yahoo! que você conhece. Crie um email novo
> <http://br.rd.yahoo.com/mail/taglines/mail/*http://br.new.mail.yahoo.com/addresses>
> com a sua cara @ymail.com ou @rocketmail.com.
--
Karthik Krishnan
R & D Engineer,
Kitware Inc,
Ph: +1 518 3713971 x119
Fax: +1 518 3714573
More information about the vtkusers
mailing list