[vtkusers] Clipping problem when panning

John Platt jcplatt at dsl.pipex.com
Tue Aug 20 17:27:25 EDT 2013


SnippetHi Serge,

If it helps your sanity, I can repeat this clipping problem in VTK 5.10 using the default interactor with QVTKWidget, which I believe is trackball camera, and parallel projection on.

When this happens, I have a 'Fit' option which moves the focal point of the camera to the centre of the actors and adjusts the parallel scale to fill the view.

John.
  ----- Original Message ----- 
  From: Serge Lalonde 
  To: vtkusers at vtk.org 
  Sent: Tuesday, August 20, 2013 8:12 PM
  Subject: Re: [vtkusers] Clipping problem when panning


  Well, since I got no responses, I dug deeper and found the code in ParaView that does the rotation and spinning around the center of the visible actors, extracted it and put it into a vtkInteractorStyleTrackballCamera subclass. It hasn't been extensively tested yet, but it seems to work well.

  Here it is in case it helps save anybody else 3 days of work.


   // Our subclass of the trackball camera to change the center of rotation to be the average
   // center of all visible actors instead of the center of the viewport, which always gets clipped.
   // The default implementation is badly broken and doesn't look to be fixed anytime soon.
   // The clipping might be fixed with the changes I submitted: http://www.vtk.org/Bug/view.php?id=7823
   // The new rotation code was taken from ParaView. Specifically,
   // - Rotate(): vtkPVTrackballRotate.cxx OnMouseMove()
   // - Spin(): vtkPVTrackballRoll.cxx OnMouseMove()
   // - UpdateScreenCenterOfRotation(): vtkCameraManipulator.cxx ComputeDisplayCenter()
   class InteractorStyleTrackballCamera: public vtkInteractorStyleTrackballCamera
   {
   public:
      static InteractorStyleTrackballCamera *New();
      vtkTypeMacro(InteractorStyleTrackballCamera, vtkInteractorStyleTrackballCamera);
 
      // This only gets called is CurrentRenderer isn't NULL.
      virtual void StartRotate()
      {
         Superclass::StartRotate();
         UpdateCenterOfRotation(CurrentRenderer);
      }
 
      // This only gets called is CurrentRenderer isn't NULL.
      virtual void StartSpin()
      {
         Superclass::StartSpin();
         UpdateCenterOfRotation(CurrentRenderer);
         UpdateScreenCenterOfRotation(CurrentRenderer);
      }
 
      virtual void Rotate()
      {
         if (CurrentRenderer == NULL)
            return;
 
         vtkRenderer *ren= CurrentRenderer;
         vtkCamera *camera= ren->GetActiveCamera();
         vtkRenderWindowInteractor *rwi= Interactor;
         vtkTransform *transform= vtkTransform::New();

         double scale= vtkMath::Norm(camera->GetPosition());
         if (scale <= 0.0)
         {
            scale= vtkMath::Norm(camera->GetFocalPoint());
            if (scale <= 0.0)
               scale= 1.0;
         }
         double *temp= camera->GetFocalPoint();
         camera->SetFocalPoint(temp[0]/scale, temp[1]/scale, temp[2]/scale);
         temp= camera->GetPosition();
         camera->SetPosition(temp[0]/scale, temp[1]/scale, temp[2]/scale);

         double v2[3];
         // translate to center
         transform->Identity();
         transform->Translate(m_center[0]/scale, m_center[1]/scale, m_center[2]/scale);

         int dx= rwi->GetLastEventPosition()[0] - rwi->GetEventPosition()[0];
         int dy= rwi->GetLastEventPosition()[1] - rwi->GetEventPosition()[1];

         // azimuth
         camera->OrthogonalizeViewUp();
         double *viewUp= camera->GetViewUp();
         int *size= ren->GetSize();
         transform->RotateWXYZ(360.0*dx/size[0], viewUp[0], viewUp[1], viewUp[2]);

         // elevation
         vtkMath::Cross(camera->GetDirectionOfProjection(), viewUp, v2);
         transform->RotateWXYZ(-360.0*dy/size[1], v2[0], v2[1], v2[2]);

         // translate back
         transform->Translate(-m_center[0]/scale, -m_center[1]/scale, -m_center[2]/scale);

         camera->ApplyTransform(transform);
         camera->OrthogonalizeViewUp();

         // For rescale back.
         temp= camera->GetFocalPoint();
         camera->SetFocalPoint(temp[0]*scale, temp[1]*scale, temp[2]*scale);
         temp= camera->GetPosition();
         camera->SetPosition(temp[0]*scale, temp[1]*scale, temp[2]*scale);

         ren->ResetCameraClippingRange();

         rwi->Render();
         transform->Delete();
      }
 
      virtual void Spin()
      {
         if (CurrentRenderer == NULL)
            return;
 
         vtkRenderer *ren= CurrentRenderer;
         vtkCamera *camera= ren->GetActiveCamera();
         vtkRenderWindowInteractor *rwi= Interactor;
         double axis[3];

         // compute view vector (rotation axis)
         double *pos= camera->GetPosition();
         double *fp= camera->GetFocalPoint();

         axis[0]= fp[0] - pos[0];
         axis[1]= fp[1] - pos[1];
         axis[2]= fp[2] - pos[2];

         int x1, x2, y1, y2;
         x1= rwi->GetLastEventPosition()[0] - (int) m_display_center[0];
         x2= rwi->GetEventPosition()[0] - (int) m_display_center[0];
         y1= rwi->GetLastEventPosition()[1] - (int) m_display_center[1];
         y2= rwi->GetEventPosition()[1] - (int) m_display_center[1];
         if ((x2 == 0.0 && y2 == 0.0) || (x1 == 0.0 && y1 == 0.0))
         {
            //don't ever want to divide by zero
            return;
         }

         // - divide by magnitudes to get angle
         double angle= vtkMath::DegreesFromRadians((x1*y2 - y1*x2)/(sqrt(static_cast<double>(x1*x1 + y1*y1))*sqrt(static_cast<double>(x2*x2 + y2*y2))));

         // translate to center
         vtkTransform *transform= vtkTransform::New();
         transform->Identity();
         transform->Translate(m_center[0], m_center[1], m_center[2]);

         // roll
         transform->RotateWXYZ(angle, axis[0], axis[1], axis[2]);

         // translate back
         transform->Translate(-m_center[0], -m_center[1], -m_center[2]);

         camera->ApplyTransform(transform);
         camera->OrthogonalizeViewUp();
         ren->ResetCameraClippingRange();

         rwi->Render();
         transform->Delete();
      }
 
   protected:
      InteractorStyleTrackballCamera()
      {
         m_center[0]= m_center[1]= m_center[2]= m_display_center[0]= m_display_center[1]= 0;
      }
 
      // Calculate the center of the visible actors.
      void UpdateCenterOfRotation(vtkRenderer *ren)
      {
         vtkActorCollection *actors= ren->GetActors();
         vtkCollectionSimpleIterator cookie;
         vtkActor *actor;

         m_center[0]= m_center[1]= m_center[2]= 0;
         actors->InitTraversal(cookie);
         while ((actor= actors->GetNextActor(cookie)) != NULL)
         {
            if (actor->GetVisibility())
            {
               double *actor_center= actor->GetCenter();

               m_center[0]+= actor_center[0];
               m_center[1]+= actor_center[1];
               m_center[2]+= actor_center[2];
            }
         }
         m_center[0]/= actors->GetNumberOfItems();
         m_center[1]/= actors->GetNumberOfItems();
         m_center[2]/= actors->GetNumberOfItems();
      }
 
      // Updates the screen center of rotation. Must be called after UpdateCenterOfRotation(),
      void UpdateScreenCenterOfRotation(vtkRenderer *ren)
      {
         double *pt;

         // save the center of rotation in screen coordinates
         ren->SetWorldPoint(m_center[0], m_center[1], m_center[2], 1.0);
         ren->WorldToDisplay();
         pt= ren->GetDisplayPoint();
         m_display_center[0]= pt[0];
         m_display_center[1]= pt[1];
      }
 
   private:
      double m_center[3],         // In model coordinates.
             m_display_center[2]; // In display coordinates.
   };
   vtkStandardNewMacro(InteractorStyleTrackballCamera);



  On 8/13/2013 8:59 AM, Serge Lalonde wrote:

    I've gotten no replies to this question. Does that mean that no one else has had this problem?

    Can someone please confirm that they're using panning with vtkInteractorStyleTrackballCamera without any problems in 5.10?

    Thanks.


    On 8/6/2013 10:49 AM, Serge Lalonde wrote:

      I tried panning in ParaView and the clipping works properly. Is it using the vtkInteractorStyleTrackballCamera or something else?

      The problem is that it looks like the rotation center is wrong after panning, causing the model to be rotated out of the clipping range. It looks like the rotation center is the center of the window instead of the center of the model. Also, I have multiple actors in the scene. Could that be a problem?

      I'm not doing anything (that I can tell) to affect this. Could it be a bug in VTK 5.10? If so, does anyone know of a workaround?

      Thanks!


      On 8/2/2013 3:59 PM, Serge Lalonde wrote:

        I notice that when using the vtkInteractorStyleTrackballCamera panning, I'll subsequently see a clipping problem if I rotate the actors afterwards.
        Calling ResetCameraClippingRange() on the renderer has no effect. I'm using VTK 5.10.

        Is there a workaround for this? It seems like a pretty serious problem. I searched the archives without much success for a fix for this.

        Note: Back in October 2008 (5 years already!), when I was prototyping with VTK, I posted a fix to vtkusers and www.vtk.org/bug for vtkRenderer and vtkCamera that fixed a similar clipping problem in VTK 5.2. After examining the 5.10 source code, it looks like the fix was never integrated into VTK's official code branch. The page is http://www.vtk.org/Bug/view.php?id=7823 and I noticed that its status is expired. Other users commented in that bug report that it fixed their problems and some even improved the fix. 



      -- 
      www.infolytica.com 
      300 Leo Pariseau, Suite 2222, Montreal, QC, Canada, H2X 4B3
      (514) 849-8752 x236, Fax: (514) 849-4239 

       

_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Follow this link to subscribe/unsubscribe:
http://www.vtk.org/mailman/listinfo/vtkusers


    -- 
    www.infolytica.com 
    300 Leo Pariseau, Suite 2222, Montreal, QC, Canada, H2X 4B3
    (514) 849-8752 x236, Fax: (514) 849-4239 

     

_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Follow this link to subscribe/unsubscribe:
http://www.vtk.org/mailman/listinfo/vtkusers


  -- 
  www.infolytica.com 
  300 Leo Pariseau, Suite 2222, Montreal, QC, Canada, H2X 4B3
  (514) 849-8752 x236, Fax: (514) 849-4239 


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


  _______________________________________________
  Powered by www.kitware.com

  Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

  Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

  Follow this link to subscribe/unsubscribe:
  http://www.vtk.org/mailman/listinfo/vtkusers
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20130820/aae3d977/attachment.htm>


More information about the vtkusers mailing list