Rotate a cube and move it.

Replay the event by shortcut key in the following simple example.

We will start by decomposing the matrix into a rotation matrix and a translation matrix, then perform linear interpolation, and finally calculate a new matrix based on the number of steps.

main.cpp

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkTransform.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkAxesActor.h>
#include <vtkLine.h>
#include <vtkPlane.h>
#include <vtkSTLWriter.h>
#include <vtkPointLocator.h>
#include <vtkProperty.h>
#include <vtkSphereSource.h>
#include <vtkCubeSource.h>
#include <vtkAxesActor.h>

#include "point.hpp"
#include "CustomIteractorStyle.h"

using namespace std;


int main()
{
    vtkSPtrNew( source, vtkCubeSource );
    source->Update();

    vtkSPtrNew( mapper, vtkPolyDataMapper );
    mapper->SetInputData( source->GetOutput() );

    vtkSPtrNew( actor, vtkActor );
    actor->SetMapper( mapper );

    vtkSPtrNew( moveTrans, vtkTransform );
    moveTrans->Translate( -1, 0, 0 );
    moveTrans->Update();
    vtkSPtrNew( moveTrans1, vtkTransform );
    moveTrans1->Translate( 0, 2, 0 );
    moveTrans1->Update();
    vtkSPtrNew( finalMoveTrans, vtkTransform );
    finalMoveTrans->Concatenate( moveTrans1 );
    finalMoveTrans->Concatenate( moveTrans );
    finalMoveTrans->Update();

    vtkSPtrNew( rotateTrans, vtkTransform );
    rotateTrans->RotateY( 30 );
    rotateTrans->RotateZ( 40 );
    rotateTrans->Update();

    vtkSPtrNew( scaleTrans, vtkTransform );
    scaleTrans->Scale( 3, 1, 1 );
    scaleTrans->Scale( 1, 2, 1 );
    scaleTrans->Update();

    vtkSPtrNew( scaleTransInv, vtkTransform );
    scaleTransInv->DeepCopy( scaleTrans );
    scaleTransInv->Inverse();

    vtkSPtrNew( finalTrans, vtkTransform );
    // world system's move matrix
    // finalTrans->Concatenate( finalMoveTrans );
    // finalTrans->Concatenate( scaleTrans );
    // finalTrans->Concatenate( rotateTrans );

    // move on local trans direction.
    finalTrans->Concatenate( rotateTrans );
    finalTrans->Concatenate( finalMoveTrans );
    finalTrans->Update();

    actor->SetUserTransform( finalTrans );

    vtkSPtrNew( axesActor, vtkAxesActor );
    axesActor->AxisLabelsOff();

    vtkSPtrNew( renderer, vtkRenderer );
    renderer->AddActor( actor );
    renderer->AddActor( axesActor );
    renderer->SetBackground( 0, 0, 0 );

    vtkSPtrNew( renderWindow, vtkRenderWindow );
    renderWindow->AddRenderer( renderer );

    vtkSPtrNew( iStyle, CustomIteractorStyle );
    iStyle->Setm_Actor( actor );
    iStyle->Setm_RenderWindow( renderWindow );

    vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
    renderWindowInteractor->SetInteractorStyle( iStyle );
    renderWindowInteractor->SetRenderWindow( renderWindow );

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();

    return 0;
}

CustomIteractorStyle.h

#pragma once

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkTransform.h>
#include <vtkRenderWindow.h>

#include "point.hpp"

#define CPP_SET_MACRO(name,type) \
  void Set##name(type _arg) \
  { \
    if (this->name != _arg) \
    { \
    this->name = _arg; \
    } \
  }

#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();


class CustomIteractorStyle: public vtkInteractorStyleTrackballCamera
{
public:
    static CustomIteractorStyle *New(){ return new CustomIteractorStyle(); }
    virtual void OnKeyDown();

    CPP_SET_MACRO( m_Actor, vtkSPtr<vtkActor> )
    CPP_SET_MACRO( m_RenderWindow, vtkSPtr<vtkRenderWindow> )
protected:
    CustomIteractorStyle();
    ~CustomIteractorStyle() override;
    void DecomposeActorTrans();
    void PlayFrame(int stepIndex);

    vtkSPtr<vtkRenderer> m_Renderer;
    vtkSPtr<vtkActor> m_Actor;
    vtkSPtr<vtkRenderWindow> m_RenderWindow;
    int m_StepCount, m_StepIndex;
    double m_AngleStep, m_XYZ[3];
    Point m_MoveStep;
};

CustomIteractorStyle.cpp

#include "CustomIteractorStyle.h"
#include "point.hpp"

#include <string>
#include <vtkCamera.h>
#include <vtkTransform.h>
#include <vtkLinearTransform.h>

void CustomIteractorStyle::OnKeyDown()
{
    std::string str = Interactor->GetKeySym();
    std::cout << "key: " << str << std::endl;
    if( str == "Up" )
    {
        DecomposeActorTrans();
    }
    else if(str == "Down"){
        PlayFrame( m_StepIndex );
        m_StepIndex = (m_StepIndex+1)%m_StepCount;
    }
}

CustomIteractorStyle::CustomIteractorStyle()
{
    m_Actor = nullptr;
    m_StepCount = 11;
    m_StepIndex = 0;
}

CustomIteractorStyle::~CustomIteractorStyle()
{
    m_Actor = nullptr;
}

void CustomIteractorStyle::DecomposeActorTrans()
{
    vtkSmartPointer<vtkTransform> userTrans = (vtkTransform*)( m_Actor->GetUserTransform() );
    double wxyz[4];
    userTrans->GetOrientationWXYZ( wxyz );
    m_AngleStep = wxyz[0] / (m_StepCount - 1.0);
    m_XYZ[0] = wxyz[1];
    m_XYZ[1] = wxyz[2];
    m_XYZ[2] = wxyz[3];

    Point origin( 0, 0, 0 );
    Point newOrigin;
    userTrans->TransformPoint( origin.point, newOrigin.point );
    Point vec = newOrigin - origin;
    m_MoveStep = vec / (double(m_StepCount - 1.0));

}

void CustomIteractorStyle::PlayFrame(int stepIndex)
{
    vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();

    vtkSmartPointer<vtkTransform> rotateTrans = vtkSmartPointer<vtkTransform>::New();
    rotateTrans->RotateWXYZ( stepIndex*m_AngleStep, m_XYZ[0], m_XYZ[1], m_XYZ[2] );
    rotateTrans->Update();

    vtkSmartPointer<vtkTransform> moveTrans = vtkSmartPointer<vtkTransform>::New();
    moveTrans->Translate( (m_MoveStep*stepIndex).point );
    moveTrans->Update();

    trans->Concatenate( moveTrans ); // direction refer to world coordinate system axis.
    trans->Concatenate( rotateTrans );
    trans->Update();

    m_Actor->SetUserTransform( trans );
    m_RenderWindow->Render();
}

Result:

Categories: VTK

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

XML To JSON
: Input your strings, the tool can convert XML to JSON for you.

X
0
Would love your thoughts, please comment.x
()
x