vtkInteractorStyleTrackballCamera下移動單個Actor

在VTK中,對於vtkInteractorStyle類繼承類,常用的有2中,vtkInteractorStyleTrackballCamera和
vtkInteractorStyleTrackballActor.第一個類是通過修改相機來該表觀察角度和物體大小。第二個類是通過改變actor來改變物體的位置和大小。
但有時我們希望在第一個類下可以通過操作actor來實現actor位置的改變,這樣就需要重寫vtkInteractorStyleTrackballCamera.
代碼如下:`#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkSphereSource.h>
#include <vtkRendererCollection.h>
#include <vtkCellArray.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkObjectFactory.h>
#include <vtkPlaneSource.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkPropPicker.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include “vtkTransform.h”
// Handle mouse events
bool move = true;
vtkActor* a = nullptr;
class MouseInteractorStyle2 : public vtkInteractorStyleTrackballCamera
{
public:
static MouseInteractorStyle2* New();
vtkTypeMacro(MouseInteractorStyle2, vtkInteractorStyleTrackballCamera);

virtual void OnLeftButtonDown()
{
	int* clickPos = this->GetInteractor()->GetEventPosition();

	// Pick from this location.
	vtkSmartPointer<vtkPropPicker>  picker =
		vtkSmartPointer<vtkPropPicker>::New();
	picker->Pick(clickPos[0], clickPos[1], 0, this->GetDefaultRenderer());

	double* pos = picker->GetPickPosition();
	std::cout << "Pick position (world coordinates) is: "
		<< pos[0] << " " << pos[1]
		<< " " << pos[2] << std::endl;

	std::cout << "Picked actor: " << picker->GetActor() << std::endl;
	//Create a sphere
	vtkSmartPointer<vtkSphereSource> sphereSource =
		vtkSmartPointer<vtkSphereSource>::New();
	sphereSource->SetCenter(pos[0], pos[1], pos[2]);
	sphereSource->SetRadius(0.1);

	//Create a mapper and actor
	vtkSmartPointer<vtkPolyDataMapper> mapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputConnection(sphereSource->GetOutputPort());

	vtkSmartPointer<vtkActor> actor =
		vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);
	if (a == picker->GetActor())
	{
		move = true;
		return;
	}

	//this->GetInteractor()->GetRenderWindow()->GetRenderers()->GetDefaultRenderer()->AddActor(actor);
	this->GetDefaultRenderer()->AddActor(actor);
	// Forward events
	vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
}
virtual void OnMouseMove()
{
	vtkRenderWindowInteractor *rwi = this->Interactor;
	if (move == true)
	{
		double *obj_center = a->GetCenter();
		double disp_obj_center[3], new_pick_point[4];
		double old_pick_point[4], motion_vector[3];
		this->ComputeWorldToDisplay(obj_center[0], obj_center[1], obj_center[2],
			disp_obj_center);

		this->ComputeDisplayToWorld(rwi->GetEventPosition()[0],
			rwi->GetEventPosition()[1],
			disp_obj_center[2],
			new_pick_point);

		this->ComputeDisplayToWorld(rwi->GetLastEventPosition()[0],
			rwi->GetLastEventPosition()[1],
			disp_obj_center[2],
			old_pick_point);

		motion_vector[0] = new_pick_point[0] - old_pick_point[0];
		motion_vector[1] = new_pick_point[1] - old_pick_point[1];
		motion_vector[2] = new_pick_point[2] - old_pick_point[2];
		if (a->GetUserMatrix() != NULL)
		{
			vtkTransform *t = vtkTransform::New();
			t->PostMultiply();
			t->SetMatrix(a->GetUserMatrix());
			t->Translate(motion_vector[0], motion_vector[1], motion_vector[2]);
			a->GetUserMatrix()->DeepCopy(t->GetMatrix());
			t->Delete();
		}
		else
		{
	      a->AddPosition(motion_vector[0],
			motion_vector[1],
			motion_vector[2]);
		}

		rwi->Render();
	}
	vtkInteractorStyleTrackballCamera::OnMouseMove();
}
virtual void OnLeftButtonUp()
{
	move = false;
	vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
}

private:

};

vtkStandardNewMacro(MouseInteractorStyle2);

// Execute application.
int main(int, char [])
{
vtkSmartPointer planeSource =
vtkSmartPointer::New();
planeSource->SetCenter(0, 0, 0);
planeSource->SetRadius(2);
planeSource->Update();
// Create a polydata object
vtkPolyData
polydata = planeSource->GetOutput();

// Create a mapper
vtkSmartPointer<vtkPolyDataMapper> mapper =
	vtkSmartPointer<vtkPolyDataMapper>::New();

#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(polydata);
#else
mapper->SetInputData(polydata);
#endif

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

std::cout << "Actor address: " << actor << std::endl;
vtkSmartPointer<vtkSphereSource> planeSource1 =
	vtkSmartPointer<vtkSphereSource>::New();
planeSource1->SetCenter(10, 10, 10);
planeSource1->SetRadius(2);
planeSource1->Update();
// Create a polydata object
vtkPolyData* polydata1 = planeSource1->GetOutput();

// Create a mapper
vtkSmartPointer<vtkPolyDataMapper> mapper1 =
	vtkSmartPointer<vtkPolyDataMapper>::New();

#if VTK_MAJOR_VERSION <= 5
mapper->SetInput(polydata);
#else
mapper1->SetInputData(polydata1);
#endif

// Create an actor
vtkSmartPointer<vtkActor> actor1 =
	vtkSmartPointer<vtkActor>::New();
actor1->SetMapper(mapper1);
a = actor1;
std::cout << "Actor1 address: " << actor1 << std::endl;
std::cout << "a address: " << a << std::endl;
// A renderer and render window
vtkSmartPointer<vtkRenderer> renderer =
	vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
	vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);

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

// Set the custom stype to use for interaction.
vtkSmartPointer<MouseInteractorStyle2> style =
	vtkSmartPointer<MouseInteractorStyle2>::New();
style->SetDefaultRenderer(renderer);

renderWindowInteractor->SetInteractorStyle(style);

// Add the actors to the scene
renderer->AddActor(actor);
renderer->AddActor(actor1);
renderer->SetBackground(0, 0, 1);

// Render and interact
renderWindow->Render();
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();

return EXIT_SUCCESS;

}`

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章