I will show how to use vtkOBBTree to calculate X, Y and Z axis of the 3D model in the article. Create a simple cone.

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLight.h>
#include <vtkCamera.h>
#include <vtkOBBTree.h>
#include <vtkActor2D.h>
#include <vtkMath.h>
#include <vtkTransform.h>
#include <vtkTransformFilter.h>
#include <vtkMatrix4x4.h>
#include <vtkInteractorObserver.h>

#include "tool.h"

using namespace std;

int main()
{
    setbuf( stdout, nullptr );
    vtkSmartPointer<vtkConeSource> cone =
            vtkSmartPointer<vtkConeSource>::New();
    cone->SetDirection( 1, 1, 0 );
    cone->Update();

    vtkSmartPointer<vtkPolyDataMapper> mapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    //mapper->SetInputData( polydata );
    mapper->SetInputData( cone->GetOutput() );

    vtkSmartPointer<vtkActor> actor =
            vtkSmartPointer<vtkActor>::New();
    actor->SetMapper( mapper );

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

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

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

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}

output:

center: PointStruct [-0.603023, 0.603023, -0.522233]
max: PointStruct [1, 6.76661e-18, 1.5783e-16]
mid: PointStruct [6.76661e-18, -1, 9.23786e-10]
min: PointStruct [-1.5783e-16, 9.23786e-10, 1]

==>


center: PointStruct [-0.603023, 0.603023, -0.522233]
max: PointStruct [1, 0, 0] (x)
mid: PointStruct [0, -1, 0] (y)
min: PointStruct [0, 0, 1] (z)

Rotate the cone:

cone->SetDirection( 1, 1, 0 );

output:

center: PointStruct [-0.852803, -1.67779e-08, -0.522233]
max: PointStruct [0.707107, 0.707107, -3.50393e-09]
mid: PointStruct [0.707107, -0.707107, 4.19309e-08]
min: PointStruct [-2.7172e-08, 3.21273e-08, 1]

==>


center: PointStruct [-0.852803, -1.67779e-08, -0.522233]
max: PointStruct [0.707107, 0.707107, 0] (x)
mid: PointStruct [0.707107, -0.707107, 0] (y)
min: PointStruct [0, 0, 1] (z)

The result tells us if we change the points’ position (not change transform), obbTree can also calculate three axes of the 3D model because vtkConeSource::SetDirection will rewrite points of polydata.
Test code (rewrite polydata):

int main()
{
    setbuf( stdout, nullptr );
    vtkSmartPointer<vtkConeSource> cone =
            vtkSmartPointer<vtkConeSource>::New();
    cone->Update();

    vtkSmartPointer<vtkPolyData> polydata =
            vtkSmartPointer<vtkPolyData>::New();
    polydata->DeepCopy( cone->GetOutput() );

    vtkSmartPointer<vtkTransform> transform =
            vtkSmartPointer<vtkTransform>::New();
    vtkSmartPointer<vtkMatrix4x4> matrix =
            vtkSmartPointer<vtkMatrix4x4>::New();
    matrix->Identity();
    transform->SetMatrix( matrix );
    transform->RotateZ( 45 );

    vtkSmartPointer<vtkTransformFilter> transformFilter =
            vtkSmartPointer<vtkTransformFilter>::New();
    transformFilter->SetInputData( polydata );
    transformFilter->SetTransform( transform );
    transformFilter->Update();

    polydata->GetPoints()->DeepCopy( transformFilter->GetOutput()->GetPoints() );
    polydata->GetPoints()->Modified();

    vtkSmartPointer<vtkPolyDataMapper> mapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputData( polydata );

    vtkSmartPointer<vtkActor> actor =
            vtkSmartPointer<vtkActor>::New();
    actor->SetMapper( mapper );

    vtkSmartPointer<vtkOBBTree> obbTree =
            vtkSmartPointer<vtkOBBTree>::New();

    PointStruct center, max, mid, min, size;
    obbTree->ComputeOBB( polydata, center.point, max.point, mid.point, min.point, size.point );
    vtkMath::Normalize( center.point );
    vtkMath::Normalize( max.point );
    vtkMath::Normalize( mid.point );
    vtkMath::Normalize( min.point );

    cout << "center: " << center;
    cout << "max: " << max;
    cout << "mid: " << mid;
    cout << "min: " << min;

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

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

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

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}

Output:

center: PointStruct [-0.852803, -1.30216e-08, -0.522233]
max: PointStruct [0.707107, 0.707107, 3.50393e-09]
mid: PointStruct [0.707107, -0.707107, 2.47509e-08]
min: PointStruct [-1.99792e-08, 1.50239e-08, 1]

==>

center: PointStruct [-0.852803, -1.30216e-08, -0.522233]
max: PointStruct [0.707107, 0.707107, 0]
mid: PointStruct [0.707107, -0.707107, 0]
min: PointStruct [0, 0, 1]


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page