The following code comes from vtkFollower, we used it to make the original axes always face the camera.

#include <iostream>

#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkTriangleFilter.h>
#include <vtkRegularPolygonSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkCamera.h>
#include <vtkNamedColors.h>
#include <vtkImageActor.h>
#include <vtkImageViewer2.h>
#include <vtkPNGReader.h>
#include <vtkPlaneSource.h>
#include <vtkAxesActor.h>
#include <vtkTransform.h>

#include "tool.h"
using namespace std;

vtkSmartPointer<vtkTransform> m_UserTransform;
PointStruct Origin( 0, 0, 0 );
vtkCamera *Camera = nullptr;
vtkSmartPointer<vtkRenderWindow> renderWindow;
PointStruct Position( 0, 0, 0 );
vtkSmartPointer<vtkMatrix4x4> m_Matrix4x4;

void RebuildMatrix()
{
    double Orientation[3];
    m_UserTransform->GetOrientation( Orientation );
    m_UserTransform->Push();
    m_UserTransform->Identity();
    m_UserTransform->PostMultiply();
    m_UserTransform->Translate( -Origin[0], -Origin[1], -Origin[2]);

    // rotate
    m_UserTransform->RotateY(Orientation[1]);
    m_UserTransform->RotateX(Orientation[0]);
    m_UserTransform->RotateZ(Orientation[2]);

    double *pos, *vup, distance;
    double Rx[3], Ry[3], Rz[3];
    vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
    matrix->Identity();

    // do the rotation
    // first rotate y
    pos = Camera->GetPosition();
    vup = Camera->GetViewUp();
    printf( "pos: (%lf, %lf, %lf)\n", pos[0], pos[1], pos[2] );
    printf( "vup: (%lf, %lf, %lf)\n", vup[0], vup[1], vup[2] );

    if (Camera->GetParallelProjection())
    {
        Camera->GetDirectionOfProjection(Rz);
        Rz[0] = -Rz[0];
        Rz[1] = -Rz[1];
        Rz[2] = -Rz[2];
    }
    else
    {
        distance = sqrt(
          (pos[0] - Position[0])*(pos[0] - Position[0]) +
          (pos[1] - Position[1])*(pos[1] - Position[1]) +
          (pos[2] - Position[2])*(pos[2] - Position[2]));
        for (int i = 0; i < 3; i++)
        {
          Rz[i] = (pos[i] - Position[i])/distance;
        }
    }

    //instead use the view right angle:
    double dop[3], vur[3];
    Camera->GetDirectionOfProjection(dop);

    vtkMath::Cross(dop,vup,vur);
    vtkMath::Normalize(vur);

    vtkMath::Cross(Rz, vur, Ry);
    vtkMath::Normalize(Ry);
    vtkMath::Cross(Ry,Rz,Rx);

    matrix->Element[0][0] = Rx[0];
    matrix->Element[1][0] = Rx[1];
    matrix->Element[2][0] = Rx[2];
    matrix->Element[0][1] = Ry[0];
    matrix->Element[1][1] = Ry[1];
    matrix->Element[2][1] = Ry[2];
    matrix->Element[0][2] = Rz[0];
    matrix->Element[1][2] = Rz[1];
    matrix->Element[2][2] = Rz[2];

    printf( "================== matrix ===============\n" );
    matrix->PrintSelf( std::cout, vtkIndent() );

    m_UserTransform->Concatenate(matrix);
    m_UserTransform->GetMatrix()->PrintSelf( std::cout, vtkIndent() );
    m_UserTransform->Translate(Origin[0] + Position[0],
                               Origin[1] + Position[1],
                               Origin[2] + Position[2]);
    m_UserTransform->PreMultiply();
    m_UserTransform->GetMatrix( m_Matrix4x4 );
    m_UserTransform->Pop();

    renderWindow->Render();
    printf( "================== finished ===============\n" );
    m_UserTransform->GetMatrix()->PrintSelf( std::cout, vtkIndent() );
}

class vtkMyCallback : public vtkCommand
{
public:
    static vtkMyCallback *New()
    {
        return new vtkMyCallback;
    }
    virtual void Execute(vtkObject *caller, unsigned long, void*)
    {
        vtkRenderer *ren = reinterpret_cast <vtkRenderer*>(caller);
        cout << ren->GetActiveCamera()->GetPosition()[0] << " "
            << ren->GetActiveCamera()->GetPosition()[1] << " "
            << ren->GetActiveCamera()->GetPosition()[2] << "\n";
        RebuildMatrix();
    }
};

int main()
{
    setbuf( stdout, nullptr );

    m_Matrix4x4 = vtkSmartPointer<vtkMatrix4x4>::New();

    vtkSmartPointer<vtkAxesActor> axesActor =
            vtkSmartPointer<vtkAxesActor>::New();

    m_UserTransform = vtkSmartPointer<vtkTransform>::New();
    m_UserTransform->PreMultiply();
    m_UserTransform->Identity();
    axesActor->SetUserMatrix( m_Matrix4x4 );

    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor( axesActor );
    renderer->SetBackground( 0, 0, 0 );

    renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer( renderer );

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow( renderWindow );

    renderer->ResetCamera();
    Camera = renderer->GetActiveCamera();
    Camera->SetParallelProjection( true );
    renderWindow->Render();

    vtkSmartPointer<vtkMyCallback> myCallback =
            vtkSmartPointer<vtkMyCallback>::New();
    renderer->AddObserver( vtkCommand::StartEvent, myCallback );

    renderWindowInteractor->Start();
    return 0;
}
Categories: VTK

0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
A prohibited operation
0
Would love your thoughts, please comment.x
()
x