天天看點

VTK筆記——多邊形剪切(vtkClipPolyData)

在三維圖形中,往往會涉及到對多邊形的處理,多邊形剪切就是其中之一。什麼是多邊形剪切?打個比方,如果把多邊形比作西瓜的話,那剪切就相當于用水果刀切西瓜,一刀下去,西瓜就被切成兩塊。當然,也可以切兩下,三下,甚至更多。水果刀也可以是任意形狀的。

vtkClipPolyData

vtkClipPolyData,一個用于多邊形剪切模型的方法類。

關于它的用法,引用一段描述:

clip polygonal data with user-specified implicit function or input scalar data

vtkClipPolyData is a filter that clips polygonal data using either any subclass of vtkImplicitFunction, or the input scalar data. Clipping means that it actually “cuts” through the cells of the dataset, returning everything inside of the specified implicit function (or greater than the scalar value) including “pieces” of a cell. (Compare this with vtkExtractGeometry, which pulls out entire, uncut cells.) The output of this filter is polygonal data.

To use this filter, you must decide if you will be clipping with an implicit function, or whether you will be using the input scalar data. If you want to clip with an implicit function, you must: 1) define an implicit function 2) set it with the SetClipFunction method 3) apply the GenerateClipScalarsOn method If a ClipFunction is not specified, or GenerateClipScalars is off (the default), then the input’s scalar data will be used to clip the polydata.

You can also specify a scalar value, which is used to decide what is inside and outside of the implicit function. You can also reverse the sense of what inside/outside is by setting the InsideOut instance variable. (The cutting algorithm proceeds by computing an implicit function value or using the input scalar data for each point in the dataset. This is compared to the scalar value to determine inside/outside.)

This filter can be configured to compute a second output. The second output is the polygonal data that is clipped away. Set the GenerateClippedData boolean on if you wish to access this output data.

描述清楚的表明,多邊形剪切,有兩種基本方式,指定隐函數和輸入标量資料。

隐函數

數學中的定義是這樣,

隐函數是由隐式方程所隐含定義的函數。設F(x,y)是某個定義域上的函數。如果存在定義域上的子集D,使得對每個x屬于D,存在相應的y滿足F(x,y)=0,則稱方程确定了一個隐函數。

VTK中,繼承vtkImplicitFunction類的子類都可以用作隐函數,如稍後示例用到的vtkPlane。

不一一列舉了,用一幅圖來表示:

VTK筆記——多邊形剪切(vtkClipPolyData)

标量資料

在實體學中,标量定義,

标量(scalar),亦稱“無向量”。有些實體量,隻具有數值大小,而沒有方向,部分有正負之分。實體學中,标量(或作純量)指在坐标變換下保持不變的實體量。用通俗的說法,标量是隻有大小,沒有方向的量。

vtk中,标量資料是資料集裡的每個位置具有單值的資料,它隻表示資料的大小,如溫度、壓力、密度、高度。是屬性資料的一種。

示例

下面簡單的用隐函數vtkPlane将圓球vtkSphereSource剪切成兩部分。

主要代碼

構造切割工具

vtkPlane *plane = vtkPlane::New();
	vtkSmartPointer<vtkPlane> plane =
		vtkSmartPointer<vtkPlane>::New();
	plane->SetOrigin(0, 3, 0);
	plane->SetNormal(0, -1, 0);
           

設定隐函數

vtkSmartPointer<vtkClipPolyData> clipPolyData =
		vtkSmartPointer<vtkClipPolyData>::New();
	clipPolyData->SetInputConnection(sphereSource->GetOutputPort());
	clipPolyData->SetClipFunction(plane);
	clipPolyData->GenerateClippedOutputOn();
	clipPolyData->Update();
           

SetGenerateClippedOutput用于設定是否生成被剪切掉的部分,預設是不生成的。

擷取剪切資料

剪切留下的部分:

clipPolyData->GetClippedOutputPort();

被剪切掉的部分(如果GenerateClippedOutput是off,将無法擷取):

clipPolyData->GetOutputPort();

效果

VTK筆記——多邊形剪切(vtkClipPolyData)

ClipPolydata.cxx

#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkSmartPointer.h>
#include <vtkCamera.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkNamedColors.h>
#include <vtkClipPolyData.h>
#include <vtkProperty.h>
#include <vtkPlane.h>

int main(int, char *[])
{
	vtkSmartPointer<vtkSphereSource> sphereSource =
		vtkSmartPointer<vtkSphereSource>::New();
	sphereSource->SetCenter(0.0, 0.0, 0.0);
	sphereSource->SetRadius(5.0);
	sphereSource->Update();

	vtkPlane *vPlane = vtkPlane::New();
	vtkSmartPointer<vtkPlane> plane =
		vtkSmartPointer<vtkPlane>::New();
	plane->SetOrigin(0, 3, 0);
	plane->SetNormal(0, -1, 0);

	vtkSmartPointer<vtkClipPolyData> clipPolyData =
		vtkSmartPointer<vtkClipPolyData>::New();
	clipPolyData->SetInputConnection(sphereSource->GetOutputPort());
	clipPolyData->SetClipFunction(plane);
	clipPolyData->GenerateClippedOutputOn();
	clipPolyData->Update();

	vtkSmartPointer<vtkPolyDataMapper> mapper1 =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper1->SetInputConnection(clipPolyData->GetOutputPort());

	vtkSmartPointer<vtkActor> actor1 =
		vtkSmartPointer<vtkActor>::New();
	actor1->SetMapper(mapper1);

	vtkSmartPointer<vtkPolyDataMapper> mapper2 =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper2->SetInputConnection(clipPolyData->GetClippedOutputPort());

	vtkSmartPointer<vtkActor> actor2 =
		vtkSmartPointer<vtkActor>::New();
	actor2->SetMapper(mapper2);

	vtkSmartPointer<vtkNamedColors> colors =
		vtkSmartPointer<vtkNamedColors>::New();

	vtkSmartPointer<vtkRenderer> renderer1 =
		vtkSmartPointer<vtkRenderer>::New();
	renderer1->SetBackground(colors->GetColor3d("Slate_grey").GetData());
	renderer1->AddActor(actor1);
	renderer1->SetViewport(0, 0, 0.5, 1);

	vtkSmartPointer<vtkRenderer> renderer2 =
		vtkSmartPointer<vtkRenderer>::New();
	renderer2->SetBackground(colors->GetColor3d("Slate_blue").GetData());
	renderer2->AddActor(actor2);
	renderer2->SetViewport(0.5, 0, 1, 1);

	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->SetSize(600, 300);
	renderWindow->AddRenderer(renderer1);
	renderWindow->AddRenderer(renderer2);

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

	vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
		vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
	renderWindowInteractor->SetInteractorStyle(style);

	renderWindow->Render();
	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}
           

Ref

vtkClipPolyData Class Reference

VTK筆記——多邊形剪切(vtkClipPolyData)

繼續閱讀