VTK003_vtk-交互&屬性

VTK基礎交互:

      VTK交互使用vtkRenderWindowInteractor,它將負責某個vtkRenderWindow窗口的監聽,包括鼠標、鍵盤、時鐘等消息,通過vtk中的Command/Observer設計模式進行處理。vtkRenderWindowInteractor會自動創建一個默認的vtkInteraactorStyle類對象(交互器樣式)進行消息的處理,完成用戶交互作用於實際的3D模型功能。通常,我們會自己創建一個交互器樣式來處理消息,也可以重載已有的樣式進行功能擴展。

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";
	}
};

// ------------------------------------------main中------------------------------------

	this->renderer = vtkRenderer::New();		// 渲染器
	this->renWin = vtkRenderWindow::New();		// 渲染窗口
	this->renWin->AddRenderer(this->renderer);	// 向渲染窗口添加渲染器

	//this->renWin->SetParentId(hwnd);			// 設置vtkRenderWindow的父窗口,可以使MFC/Win32窗口的HWND
	this->iren = vtkRenderWindowInteractor::New();		// 交互器
	this->iren->SetRenderWindow(this->renWin);			// 將vtkRenderWindow設置到交互器
	this->m_style = vtkInteractorStyleTrackballCamera::New();
	this->iren->SetInteractorStyle(m_style);
 	this->iren->Initialize();

	//Data  
	this->cone = vtkConeSource::New();		// 圓錐數據源
	this->cone->SetHeight(4.0);				// 圓錐高度
	this->cone->SetRadius(2.0);				// 圓錐半徑
	this->cone->SetResolution(20);			// 圓錐精度(多邊形模擬的圓)

	this->coneMapper = vtkPolyDataMapper::New();	// 幾何繪圖器(幾何原始數據)
	this->coneMapper->SetInputConnection(this->cone->GetOutputPort());		// 獲取到剛纔的圓錐的幾何原始數據
	this->coneActor1 = vtkActor::New();		// 演員對象
	this->coneActor1->SetMapper(this->coneMapper);	// 演員對象使用繪圖器(裏面裝的圓錐數據, 所以是畫圓錐)
	this->coneActor2 = vtkActor::New();		// 演員對象
	this->coneActor2->SetMapper(this->coneMapper);	// 演員對象使用繪圖器(裏面裝的圓錐數據, 所以是畫圓錐)
	coneActor1->GetProperty()->SetColor(0.2, 0.63, 0.79);	// vtk屬性,顏色
	coneActor1->GetProperty()->SetDiffuse(0.7);				// 設置漫反射分量		兩者共同可表示材質
	coneActor1->GetProperty()->SetSpecular(0.4);			// 設置鏡面反射分量
	coneActor1->GetProperty()->SetSpecularPower(20);		// 設置鏡面反射強度
	vtkProperty* coneProperty = vtkProperty::New();		// 屬性對象
	coneProperty->SetColor(0.5, 0.0, 0.0);
	coneProperty->SetDiffuse(0.7);
	coneProperty->SetSpecular(0.4);
	coneProperty->SetSpecularPower(20);
	coneActor2->GetProperty()->SetColor(0.0, 0.5, 0.0);
	coneActor2->SetProperty(coneProperty);
	coneActor2->SetOrigin(0, 0, -5);	// 原點設置?旋轉中心?
	coneActor2->SetPosition(3.0, 3.0, -3.0);	// 直接設置位置
	vtkTransform* trans = vtkTransform::New();
	trans->Translate(3.0, 3.0, -3.0);		// 在原來位置上再變化的
	trans->RotateY(30);
	//coneActor2->SetUserMatrix(trans->GetMatrix());
	coneActor2->SetUserTransform(trans);	// 兩者效果一樣
	trans->Delete();


	////////  
	this->renderer->AddActor(this->coneActor1);		// 渲染器添加這個演員
	this->renderer->AddActor(this->coneActor2);		// 渲染器添加這個演員
	this->renderer->SetBackground(0.1, 0.1, 0.1);	// 渲染器背景色
	this->renderer->SetViewport(0.0, 0.0, 1.0, 1.0);	// 分配窗口比例
	this->renWin->SetSize(800, 600);				// 渲染窗口大小

	vtkMyCallback* mol = vtkMyCallback::New();
	this->renderer->AddObserver(vtkCommand::StartEvent, mol);	// 爲渲染器添加觀察器(回調函數)
	mol->Delete();
	// 通過實時過去相機位置,不難看出,模型不動相機動,座標系方向與OpenGL是一樣的

	this->renWin->Render();			// 渲染窗口開始渲染
	this->iren->Start();		// 實際就是事件循環了,就不需要在外面添加事件循環了
// 	int i;
// 	for (i = 0; i < 360; ++i)
// 	{
// 		// render the image
// 		renWin->Render();
// 		// rotate the active camera by one degree
// 		(this->renderer)->GetActiveCamera()->Azimuth(1);
// 	}

      上述代碼,展示了vtk交互及屬性設置,在HelloWorld這篇,我們只使用了vtkRenderWindowInteractor,沒有創建自己的交互器樣式,在實際操作中,可發現,只要鼠標點擊就可以使模型移動(實際上是相機移動),然而,在這篇中,需要鼠標點擊並移動才能看到模型移動(相機移動),這是因爲,交互器的參數不一樣。

vtkRenderWindowInteractor消息響應:

      在沒有使用我們自己的交互器樣式到窗口交互對象時,vtkRenderWindowInteractor會生成一個默認的交互器,此時,可以響應比較多的消息,使用不同的交互器樣式,響應的消息也會不一樣,例如,上面程序中,我們使用了vtkInteractorStyleTrackballCamera,此時麼就不能響應鍵盤按鍵t和按鍵j,但在默認的樣式中,t和j可以設置交互模式,t設置動作敏感型(數遍按下後拖動才移動等消息),j設置位置敏感型(按下鼠標及響應移動等消息)。此外,無論是默認的交互器還是vtkInteractorStyleTrackballCamera交互器,都可以響應鼠標左鍵旋轉,中鍵移動和放大縮小,右鍵放大縮小的消息(實際上是相機的移動和旋轉,這裏爲了方便理解)。

      默認交互樣式下,響應的消息有如下幾種:

      (1)、按鍵 t、j

            按鍵t同於設置動作敏感型,j設置位置敏感型,主要體現爲鼠標操作移動相機的方式的更改。默認爲位置敏感型。

      (2)、按鍵c、a

            相機和對象之間的切換,c爲相機,a爲對象,用於改變交互作用對象,作用於相機時,鼠標操作的相機移動旋轉等,作用於對象時,鼠標操作3D對象移動旋轉縮放等。

      (3)、鼠標左鍵

            在相機模式下,左鍵用於旋轉相機,旋轉點爲相機的焦點,對象模式下,用於旋轉模型對象,繞世界空間原點旋轉。不同敏感型操作,對於這個也是有影響的,位置敏感型表現爲與窗口中心距離越遠,旋轉越快,動作敏感型表現爲移動多少,改變多少。

      (4)、鼠標中鍵

            可以在當前相機方向的垂直平面上移動相機(上下左右移動),滾輪滾動可以在前後方向上移動相機。對象模式下,可做用於模型。

      (5)、鼠標右鍵

            相機模式可改變相機前後位置,對象模式下改變對象大小。不同敏感模式效果也會不一樣。

      (6)、按鍵3

            可用於激活或者取消立即渲染模式。

      (7)、其他按鍵

            按鍵e/q:可以關閉窗口,退出應用程序。

            按鍵f:移動actor到光標當前位置,設置當前光標所在的位置爲焦點,而且會以該點爲旋轉中心。

             按鍵p:執行拾取操作,渲染窗口交互器內部有一個vtkPropPicker實例,可實現拾取功能。

            按鍵r:沿着當前方向重置相機,自動移動相機到合適的位置使所有對象可見。

            按鍵s:改變所有actor的顯示形式爲表面模型(與下面按鈕w相對應)。

            按鍵u:調用用於自定義方法(回調),通常彈出窗口提供命令交互功能。

            按鍵w:改變所有actor顯示爲線框模式(比較有趣的顯示)。

vtk屬性:

      vtkActor對象繼承與vtkProp,vtkProp除了可設置位置大小等信息外,其內部還包含了一個vtkMapper對象和一個vtkProperty對象,前者存放數據,後者存放屬性信息。

      此外,vtkActor最終設置到vtkRender中,用於渲染,一個vtkRender中可以包含多個actor對象,可以一次渲染裏面的全部actor,上面代碼中就添加了兩個不同的actor對象(方位顏色不同)。vtkRender最終也設置到vtkRenderWindow中,一個vtkRenderWindow也可以包含多個vtkRender,即一個渲染窗口可以包含多個渲染器,但是,需要給每個渲染器指定一個範圍(SetViewport),上面代碼中 this->renderer->SetViewport(0.0, 0.0, 1.0, 1.0);就是分配整個渲染窗口給這個渲染器。

      vtkActor可通過GetProperty來獲取屬性信息也可通過SetProperty來設置屬性信息改變一個Actor的屬性通常可以像上面代碼演示的那樣,直接獲取屬性對象再對其設置某些屬性,還可以創建一個屬性對象,最後將其設置到Actor中去

 

 

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