[vtkusers] Using a boxwidgets transform to rotate a non-vtk 3D model?

Totte Karlsson totte at dunescientific.com
Thu Aug 6 17:09:44 EDT 2015



On 8/6/2015 1:52 PM, Cory Quammen wrote:
>
> I guess I don't see the problem here. You have a reference to the 
> actor here, and the actor has the orientation. Did you try this 
> approach out and it didn't work? vtkActor::SetOrientation(0, 0, 0) 
> will reset the rotation for you.
Tried SetOrientation(0,0,0) and as you say that works too. However, with 
my molecular model I can't do such a thing.
>
>
>     What I'm looking for is instead to perform incremental rotations,
>     avoiding the "transforming back", i.e. (reset) part.
>
>
> I don't know of a quick and easy way to get the incremental rotation 
> you are looking for, hence my suggestion.

Appreciate it! Your approach works fine. Now looking in to making it 
more efficient. Should be possible I think..

Thanks!
tk

Here is the full code in case. It is just the boxwidget example code 
modified.

#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkBoxWidget.h>
#include <vtkCamera.h>
#include <vtkCommand.h>
#include <vtkConeSource.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkTransform.h>

class vtkMyCallback : public vtkCommand
{
     public:
         static vtkMyCallback *New()
         {
             return new vtkMyCallback;
         }

         virtual void Execute(vtkObject *caller, unsigned long, void*)
         {
             static int callCount = 0;
             static double lastAngle = 0;

             vtkSmartPointer<vtkTransform> t = 
vtkSmartPointer<vtkTransform>::New();
             static vtkSmartPointer<vtkTransform> lastTransform = 
vtkSmartPointer<vtkTransform>::New();
             vtkBoxWidget *widget = reinterpret_cast<vtkBoxWidget*>(caller);
             widget->GetTransform(t);

             double *pos        = t->GetPosition();
             double *lastPos    = lastTransform->GetPosition();
             double *wxyz       = t->GetOrientationWXYZ();
             double *lastWXYZ   = lastTransform->GetOrientationWXYZ();

             if(anActor)
             {
                 cout<<"CallCount: "<<callCount<<"Current Angle 
"<<wxyz[0]<<" Effective angle:"<< wxyz[0] - lastAngle
                 <<" Position: "<<pos[0]<<", "<<pos[1]<<", "<<pos[2]<<endl;

                 //Transform 'back'
                 anActor->RotateWXYZ(-lastAngle, lastWXYZ[1], 
lastWXYZ[2], lastWXYZ[3]);
                 anActor->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
             }

             //Save transform data
             lastAngle = wxyz[0] ;
             lastTransform = t;
             callCount++;
         }

     vtkActor* anActor;
};


int main(int, char*[])
{
     vtkSmartPointer<vtkConeSource> cone = 
vtkSmartPointer<vtkConeSource>::New();
     cone->SetHeight( 3.0 );
     cone->SetRadius( 2.0 );
     cone->SetResolution( 50 );
     cone->Update();

     vtkSmartPointer<vtkPolyDataMapper> coneMapper = 
vtkSmartPointer<vtkPolyDataMapper>::New();
     coneMapper->SetInputConnection( cone->GetOutputPort() );

     vtkSmartPointer<vtkActor> coneActor = vtkSmartPointer<vtkActor>::New();
     coneActor->SetMapper( coneMapper );

     vtkSmartPointer<vtkRenderer> ren1= vtkSmartPointer<vtkRenderer>::New();
     ren1->AddActor( coneActor );
     ren1->SetBackground( 0.1, 0.2, 0.4 );

     coneActor->SetPosition(1,1,1);
     vtkSmartPointer<vtkRenderWindow> renWin = 
vtkSmartPointer<vtkRenderWindow>::New();
     renWin->AddRenderer( ren1 );
     renWin->SetSize( 300, 300 );

     vtkSmartPointer<vtkRenderWindowInteractor> iren = 
vtkSmartPointer<vtkRenderWindowInteractor>::New();
     iren->SetRenderWindow(renWin);

     vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = 
vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
     iren->SetInteractorStyle(style);

     // The place factor
     // controls the initial size of the widget with respect to the 
bounding box
     // of the input to the widget.
     vtkSmartPointer<vtkBoxWidget> boxWidget = 
vtkSmartPointer<vtkBoxWidget>::New();
     boxWidget->SetInteractor(iren);
     boxWidget->SetPlaceFactor(2.25);

     boxWidget->HandlesOff();
     boxWidget->SetTranslationEnabled(0);
     boxWidget->SetScalingEnabled(0);


     //For placement
     boxWidget->SetProp3D(coneActor);
     boxWidget->PlaceWidget();

     vtkSmartPointer<vtkMyCallback> callback = 
vtkSmartPointer<vtkMyCallback>::New();
     boxWidget->AddObserver(vtkCommand::InteractionEvent, callback);

     boxWidget->On();
     callback->anActor = coneActor;

     iren->Initialize();
     iren->Start();

     return EXIT_SUCCESS;
}


>
> Cory
>
>
>
>     tk
>
>>     On Thu, Aug 6, 2015 at 4:26 PM, Totte Karlsson
>>     <totte at dunescientific.com <mailto:totte at dunescientific.com>> wrote:
>>
>>         Hello Cory,
>>         I was able to use your suggestion and got some code to work,
>>         as follows:
>>
>>             virtual void Execute(vtkObject *caller, unsigned long, void*)
>>             {
>>                 static int callCount = 0;
>>                 static double lastAngle = 0;
>>                 static double lastVec[3] = {0,0,0};
>>         vtkSmartPointer<vtkTransform> t =
>>         vtkSmartPointer<vtkTransform>::New();
>>                 static vtkSmartPointer<vtkTransform> lastTransform =
>>         vtkSmartPointer<vtkTransform>::New();
>>                 vtkBoxWidget *widget =
>>         reinterpret_cast<vtkBoxWidget*>(caller);
>>                 widget->GetTransform(t);
>>
>>                 double* wxyz = t->GetOrientationWXYZ();
>>                 double* lastWXYZ = lastTransform->GetOrientationWXYZ();
>>
>>                 if(anActor)
>>                 {
>>                     cout<<"CallCount: "<<callCount<<"Current Angle
>>         "<<wxyz[0]<<" Effective angle:"<< wxyz[0] - lastAngle<<endl;
>>
>>                     //Transform 'back'
>>         anActor->RotateWXYZ(-lastAngle, lastWXYZ[1], lastWXYZ[2],
>>         lastWXYZ[3]);
>>         anActor->RotateWXYZ(wxyz[0], wxyz[1], wxyz[2], wxyz[3]);
>>                 }
>>
>>                 //Save transform data
>>                 lastAngle = wxyz[0] ;
>>                 lastVec[0] =wxyz[1];
>>                 lastVec[1] =wxyz[2];
>>                 lastVec[2] =wxyz[3];
>>
>>                 lastTransform = t;
>>                 callCount++;
>>             }
>>
>>         In the above code, two transformations of the actor are done,
>>         in order to follow the orientation of the widget. 1) to
>>         rotate the actor to its initial position, and 2), applying
>>         current transformation.
>>
>>         Although the above code works, is there a way to get the
>>         'incremental' transform somehow? I'm a novice about these
>>         things so sorry if asking something obvious...
>>
>>         tk
>>
>>
>>         On 8/6/2015 7:40 AM, Cory Quammen wrote:
>>>         TK,
>>>
>>>         You can get the orientation in angle-axis representation with
>>>
>>>         double wxyz[4];
>>>         t->GetOrientationWXYZ(wxyz);
>>>
>>>         From the docs [1]:
>>>
>>>         The angle (w) is in degrees and the axis (xyz) is a unit vector.
>>>
>>>         You should be able to apply this rotation to your molecule
>>>         model's RotateAboutVector function.
>>>
>>>         HTH,
>>>         Cory
>>>
>>>         [1]
>>>         http://www.vtk.org/doc/nightly/html/classvtkTransform.html#aa8244cbab95a2dbb20e94af6e7f16b7f
>>>
>>>
>>>         On Wed, Aug 5, 2015 at 8:54 PM, Totte Karlsson
>>>         <totte at dunescientific.com <mailto:totte at dunescientific.com>>
>>>         wrote:
>>>
>>>             Hello,
>>>             I'm using vtk to visualize 3D models of molecules.
>>>             The actual molecular model is decoupled from vtk code,
>>>             and visualization is implemented using a model-view kind
>>>             of design.
>>>
>>>             Currently I have the following challenge. If a user
>>>             wants to manipulate the absolute orientation of the
>>>             molecule, it is done by manipulating the underlying
>>>             model using rotation functions, like RotateX, RotateY,
>>>             RotateAboutVector, and translation functions TranslateX,
>>>             Y etc.
>>>
>>>             For now 3D rotations are simply done using two
>>>             scrollbars, one horizontal and one vertical, causing the
>>>             underlying model being rotated about the vtk viewUP
>>>             vector and the vtk cameraPlane normal respectively. 
>>>             This works fine, but is not so intuitive for the user.
>>>
>>>             Instead I believe allowing interaction with something
>>>             like a box widget that encapsulates the molecule view,
>>>             (with disabled handles), would be better.
>>>
>>>             The challenge is how to figure out how to capture the
>>>             boxwidgets orientation in a callback, and using this
>>>             information in order to manipulate the underlying
>>>             molecular model.
>>>
>>>             For example, a boxwidget callback (from boxwidget
>>>             example at
>>>             http://www.vtk.org/Wiki/VTK/Examples/Cxx/Widgets/BoxWidget):
>>>
>>>             class vtkMyCallback : public vtkCommand
>>>             {
>>>                 public:
>>>                     static vtkMyCallback *New()       { return new
>>>             vtkMyCallback;    }
>>>
>>>                 virtual void Execute(vtkObject *caller, unsigned
>>>             long, void*)
>>>                 {
>>>             vtkSmartPointer<vtkTransform> t =
>>>             vtkSmartPointer<vtkTransform>::New();
>>>                     vtkBoxWidget *widget =
>>>             reinterpret_cast<vtkBoxWidget*>(caller);
>>>             widget->GetTransform(t);
>>>
>>>                     double* angles?? = t->GetOrientation();
>>>                     if(aMoleculeModel)
>>>                     {
>>>                         //Use some secret(!) code to manipulate
>>>             orientation of a molecule to 'rotate' it together with
>>>             the boxWidget
>>>             aMoleculeModel->RotateZ(??);
>>>             aMoleculeModel->RotateY(??);
>>>             aMoleculeModel->RotateZ(??);
>>>                     }
>>>                 }
>>>                 Molecule* aMoleculeModel;
>>>
>>>             Anyone seeing how to do this or have some pointers?
>>>
>>>             Cheers,
>>>             tk
>>>
>>>             _______________________________________________
>>>             Powered by www.kitware.com <http://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
>>>
>>>             Search the list archives at:
>>>             http://markmail.org/search/?q=vtkusers
>>>
>>>             Follow this link to subscribe/unsubscribe:
>>>             http://public.kitware.com/mailman/listinfo/vtkusers
>>>
>>>
>>>
>>>
>>>         -- 
>>>         Cory Quammen
>>>         R&D Engineer
>>>         Kitware, Inc.
>>
>>         -- 
>>         ------------------------------------------------------------------------
>>         <http://www.dunescientific.com/> 				
>>         Totte Karlsson: totte at dunescientific.com
>>         <mailto:totte at dunescientific.com> or (425) 780-9648
>>         <tel:%20425%20%20780-9648>
>>         http://www.dunescientific.com/
>>         © 2015 Dune Scientific, LLC. All rights reserved.
>>
>>
>>
>>
>>
>>
>>     -- 
>>     Cory Quammen
>>     R&D Engineer
>>     Kitware, Inc.
>
>     -- 
>     ------------------------------------------------------------------------
>     <http://www.dunescientific.com/> 				
>     Totte Karlsson: totte at dunescientific.com
>     <mailto:totte at dunescientific.com> or (425) 780-9648
>     <tel:%20425%20%20780-9648>
>     http://www.dunescientific.com/
>     © 2015 Dune Scientific, LLC. All rights reserved.
>
>
>
>
>     _______________________________________________
>     Powered by www.kitware.com <http://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
>
>     Search the list archives at: http://markmail.org/search/?q=vtkusers
>
>     Follow this link to subscribe/unsubscribe:
>     http://public.kitware.com/mailman/listinfo/vtkusers
>
>
>
>
> -- 
> Cory Quammen
> R&D Engineer
> Kitware, Inc.

-- 
------------------------------------------------------------------------
<http://www.dunescientific.com/> 				
Totte Karlsson: totte at dunescientific.com 
<mailto:totte at dunescientific.com> or (425) 780-9648 
<tel:%20425%20%20780-9648>
http://www.dunescientific.com/
© 2015 Dune Scientific, LLC. All rights reserved.



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20150806/b1dc31b1/attachment-0001.html>


More information about the vtkusers mailing list