[vtkusers] need desperately any help with interactor and MFC

Renaud Isabelle renauisa at yahoo.fr
Tue Aug 23 09:12:54 EDT 2005


Hi John,
 
Thanks for answering so quickly. 

John Platt <jcplatt at lineone.net> a écrit :

Hi Isabelle,

 

I am not sure where you are calling Pipeline(). Perhaps you could try all your interactor stuff in your CView’s OnInitialUpdate() – assuming it needs to be done only once.

 

  interactor->SetRenderWindow(m_RenderWindow);

  interactor->SetInteractorStyle(NULL);

  interactor->SetInstallMessageProc(false);

  interactor->Initialize();

 

--> In fact, my Pipeline function is called only after having loaded my image.

 

  // Change the size of the VTK window to match the client area of the View.

  CRect rect;

  GetClientRect( &rect );

  interactor->UpdateSize( rect.right-rect.left, rect.bottom-rect.top );             

 

--> I can't extend my vtk window's size to fit the client area because I have buttons too in my CView window.

 

Also, can you check if you are getting LBDown in your WindowProc(). 

 

--> I ckeched out if left button down was really caught and this is the case actually.

 

Now, my things work but only once out of 2!!! it seems that my CView is having the control when I clicked left, I don't know why, but after a while only, my render window is having the control and everything works fine except that I can't retrieve control and give it to the main wondow. Really so strange!

 

Isabelle



 

HTH

 

John.

 

-----Original Message-----
From: Renaud Isabelle [mailto:renauisa at yahoo.fr] 
Sent: 22 August 2005 21:34
To: John Platt
Cc: vtkusers at vtk.org
Subject: RE: [vtkusers] need desperately any help with interactor and MFC

 

Hi John,


 


Thanks for having replied. 


 


- First of all, sure that I am very interested in your vtkGlyph2DMapper; I think this is very convenient to use and is exactly what I am looking for. 


 


- Then, my actual work is inspiring from the example LiverTumorSegmentation application and I think that maybe I don't really need to use vtkPointPicker but just handling LeftButtonPressEvent event instead. Indeed, I took a look on the Pick() method of this class and it calls SetDisplayPoint(), DisplayToWorld() and GetWorldPoint() methods as I was already doing in my own class. 


 


- So, this is what is done for now: as in LiverTumorSegmentation, I have 2 classes: one for MFC handling CView and the other for viewing slices vtkSliceViewer:


 


void CView::Pipeline()
{
 viewer.SetInput(image); //vtkSliceViewer viewer


 viewer.SetInteractor( interactor ); 
 interactor->SetInstallMessageProc(false);
 interactor->Initialize();


}


 


LRESULT CView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if(message == WM_LBUTTONDOWN)


{


  if ( this->interactor->GetInitialized() )
  {
   return vtkHandleMessage2(this->m_hWnd, message, wParam, lParam, this->interactor);
  }


 }


else 
 return CFormView::WindowProc(message, wParam, lParam);
}


 


the other class vtkSliceviewer:


 


void vtkSliceViewer::SetInteractor( vtkRenderWindowInteractor * interactor )
{
  interactor->SetRenderWindow(m_RenderWindow);


  interactor->SetInteractorStyle(NULL);


 


 //create a callback for the left mouseclick
  MyInteractorCallback* m_pInteractorCallback = MyInteractorCallback::New();
  m_pInteractorCallback->SetImageSliceViewer(this); 
  interactor->AddObserver( vtkCommand::LeftButtonPressEvent, m_pInteractorCallback);
}


 


class MyInteractorCallback : public vtkCommand
{
public:
 static MyInteractorCallback *New() { return new MyInteractorCallback;}
 
    virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
    {
  vtkWin32RenderWindowInteractor  *interactor = reinterpret_cast<vtkWin32RenderWindowInteractor *>(caller);
        int x = interactor->GetEventPosition()[0];
        int y = interactor->GetEventPosition()[1];
  m_viewer->SelectPoint(x,y);
    }
 
 void SetImageSliceViewer(vtkSliceViewer* viewer){m_viewer = viewer;}


private:
    MyInteractorCallback(){m_viewer = NULL;}
    vtkSliceViewer* m_viewer; 
};


 


void vtkSliceViewer::SelectPoint( int x, int y )
{
  TRACE("ds SelectPoint\n"); //check if my observer is called


        --> displayed only when point clicked is outside the render window!!!!!!!!


 


 // Convert display point to world point


  double world_point[4];
  m_Renderer->SetDisplayPoint( x, y, 0 );
  m_Renderer->DisplayToWorld();
  m_Renderer->GetWorldPoint( world_point );


  double realz = m_SliceNum * spacing[2] + origin[2];
  world_point[2] = realz;


  //mark point clicked on viewer
  this->SelectPoint(world_point[0], world_point[1], world_point[2]);
}



- But I am really confused with something strange: my renderwindow is just a part of the MFC window (CView). Yet, when I pressed left button mouse in the window class, SelectPoint() is called only when my clicked point is not in the render window. I checked out if my interactor size was set to correct dimensions and it is actually the case. But I can't figure out why my function is called only when I clicked outside the render window. 


 


Any idea???


 


Isabelle


 



John Platt <jcplatt at lineone.net> a écrit :


Hi Isabelle,

 

As far as I can see, the pick events are fired by the Pick() method of the interactor’s picker. If you want to observe these events, you must add the observers to the picker, not the interactor. You must also arrange for the Pick() method to be called.

 

As a start, in the check for LeftButtonPressEvent, call Pick() with the current mouse event position and then get the point id -

 

         int x = interactor->GetEventPosition()[0];

         int y = interactor->GetEventPosition()[1];

         vtkPointPicker* picker = interactor->GetPicker(); 

         picker->Pick( (double)x, (double)y, 0, renderer );

         int pointId = picker->GetPointId();

 

and print the point Id using the TRACE macro. If you cannot get the LeftButtonPressEvent, see the recent thread on “handle right mouse click”.

 

I have drawn various 2D shapes, by first creating a polydata object, and then, as each point is clicked, add the point as a vertex to the polydata. The polydata is set as input to vtkGlyph2DMapper (very similar to vtkTextMapper). This mapper takes vtkGlyphSource2D as a source and copies the specified shape (diamond, circle, square etc.) to each of the points in the polydata. The mapper then feeds a single vtkActor2D. Something like 


 

   vtkGlyphSource2D* vtkGlyphSource = vtkGlyphSource2D::New();

   vtkGlyphSource->SetGlyphTypeToCircle();

   m_vtkGlyphMapper = vtkGlyph2DMapper::New();

   m_vtkGlyphMapper->SetInput( m_vtkInputPolyData );

   m_vtkGlyphMapper->SetSource( vtkGlyphSource->GetOutput() );

   vtkGlyphSource->Delete();

   m_vtkGlyphActor = vtkActor2D::New();

   m_vtkGlyphActor->SetMapper( m_vtkGlyphMapper );

 

I can let you have the mapper if you think it would be helpful.

 

John.

 

-----Original Message-----
From: vtkusers-bounces+jcplatt=lineone.net at vtk.org [mailto:vtkusers-bounces+jcplatt=lineone.net at vtk.org] On Behalf Of Renaud Isabelle
Sent: 18 August 2005 16:32
To: vtkusers at public.kitware.com
Subject: [vtkusers] help with interactor and MFC

 

Hi guys, 


 


I have to implement user interaction with my renderwindow in MFC: 


 


user picks points on the displayed medical image and notices them with spheres. I saw that I have to use vtkHandleMessage2 with vtkWin32RenderWindowInteractor to handle a left button mouse click and interactor->AddObserver() to call a function to handle it. 


 


But now, I see that vtkPointPicker exists and that is doing the same thing. I am really a bit confused with all the options. Here is what I did:


 


  interactor->SetRenderWindow(m_RenderWindow);


  interactor->SetInteractorStyle(NULL);


 


  vtkPointPicker *picker = vtkPointPicker::New();


  interactor->SetPicker(picker);


  


  vtkMyCallback* how_execute = vtkMyCallback::New();
  interactor->AddObserver( vtkCommand::LeftButtonPressEvent, how_execute );
  interactor->AddObserver( vtkCommand::EndPickEvent,  how_execute);
  


  interactor->SetInstallMessageProc(false);
  interactor->Initialize();


 


LRESULT CMyView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
 // TODO: Add your specialized code here and/or call the base class
 switch ( message )
 {
 case WM_LBUTTONDOWN:
  if ( this->interactor->GetInitialized() )
  {
   return vtkHandleMessage2(this->m_hWnd, message, wParam, lParam, this->interactor);
  }
  break;
 }
 return CFormView::WindowProc(message, wParam, lParam);
}


 


class vtkMyCallback : public vtkCommand
{


public:


  static vtkMyCallback *New()  { return new vtkMyCallback; }
  
  virtual void Execute(vtkObject *caller, unsigned long eventId, void*)
    {
      vtkRenderWindowInteractor* interactor = reinterpret_cast<vtkRenderWindowInteractor*>(caller);


      


     if(eventId == vtkCommand::LeftButtonPressEvent)
     {  
          int point[2];
          interactor->GetEventPosition(point);
          m_viewer->SelectPoint(point[0],point[1]);
   }


 


   if(eventId == vtkCommand::EndPickEvent)
   {  
          vtkPointPicker* picker = (vtkPointPicker*) interactor->GetPicker();
          if(picker->GetPointId() != -1)
         {
            float* position = picker->GetPickPosition();


            m_sphereActor->SetPosition(position);
         }
   }
}


 


- This seems not to work. I think that I have to choose between handling one of the event: LeftButtonPressEvent or EndPickEvent. But I don't know what is the best option. Could someone tell me what is best? 


 


- Btw, my purpose is to add a circle on each point that user picked. Do I have to handle a array of vtkSphereSource to display so many spheres?


 


Thanks for replyiong, guys,


 


Isabelle


---------------------------------



Appel audio GRATUIT partout dans le monde avec le nouveau Yahoo! Messenger
Téléchargez le ici ! 

---------------------------------


Appel audio GRATUIT partout dans le monde avec le nouveau Yahoo! Messenger
Téléchargez le ici ! 


		
---------------------------------
 Appel audio GRATUIT partout dans le monde avec le nouveau Yahoo! Messenger
 Téléchargez le ici !  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20050823/160fd311/attachment.htm>


More information about the vtkusers mailing list