VTK将二维图像向三维空间中无参数化的曲面表面进行纹理映射(含代码)

2024-01-08 13:42:32

实现纹理映射主要是建立纹理空间与模型空间、模型空间与屏幕空间之间的映射关系(见图 6-28):

? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

????????其中纹理空间可以定义为u-v 空间,每个轴标范围为 (0.1)。其中对于一个纹理图像,其左下角 v 标为 0.0),右上角标为 1.1)。而对于简单的参数模型,可以方便地建立模型与纹理空间的映射关系,例如球面、圆柱面等。

????????而根据图形学三维空间变换容易实现模型空间到屏幕空间的变换,因此最终显示在计算机屏幕上的图像即是纹理映射后的结果。

????????而对于无参数化曲面的纹理映射技术,通常需要将纹理空间到模型空间的映射分解为两个简单映射。这里需要引入一个包围景物的中介三维曲面作为中介映射媒介,主要实现步骤如下:

? ? ? ? 1.先将二维纹理空间映射为一个简单的三维物体表面,例如球面、圆柱面等;

? ? ? ? 2.然后将上述中介物体表面的纹理映射到模型表面,例如以模型表面法线与中介模型的交点作为映射点。这样即可实现由纹理空间到模型空间的映射。
????????VTK中定义了多个类实现纹理空间到模型空间的映射,例如vtkTextureMapToPlane通过一个平面建立纹理空间到模型空间的映射关系;

????????vtkTextureMapToCylinder 通过圆柱面建立映射关系;

????????vtkTextureMapToSphere 通过球面建立映射关系。

????????vtkTexture 则实现加载纹理(在第2章中已经介绍过)。另外,vtkTransformTextureCoords 也是一个非常有用的类,可以实现纹理坐标的平移和缩放,例如,如果要实现重复纹理,只需通过vtkTransformTextureCoords::SetScale()将纹理坐标每个方向进行放大,如由[0,1]变换到[0,101即可。

下例中使用vtkTextureMapToCylinder 来建立纹理映射(TextureMap.cpp):

#include <vtkSmartPointer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkTransformTextureCoords.h>
#include <vtkTexture.h>
#include <vtkTextureMapToSphere.h>
#include <vtkTextureMapToCylinder.h>
#include <vtkBMPReader.h>
#include <vtkTexturedSphereSource.h>
#include <vtkXMLPolyDataReader.h>

//测试:../data/masonry.bmp ../data/cow.vtp
int main (int argc, char *argv[])
{
	if (argc < 3)
	{
		std::cout << "Usage: " << argv[0]
		<< "texture(.png)"
			<< "model(.vtp)" <<std::endl;
		return EXIT_FAILURE;
	}

	double translate[3];
	translate[0] = 10.0;
	translate[1] = 0.0;
	translate[2] = 0.0;
	std::cout << translate[0] << ", "
		<< translate[1] << ", "
		<< translate[2] << "\n";

	vtkSmartPointer<vtkBMPReader> texReader =
		vtkSmartPointer<vtkBMPReader>::New();
	texReader->SetFileName(argv[1]);

	vtkSmartPointer<vtkTexture> texture =
		vtkSmartPointer<vtkTexture>::New();
	texture->SetInputConnection(texReader->GetOutputPort());

	vtkSmartPointer<vtkXMLPolyDataReader> modelReader =
		vtkSmartPointer<vtkXMLPolyDataReader>::New();
	modelReader->SetFileName(argv[2]);

	vtkSmartPointer<vtkTextureMapToCylinder> texturemap = 
		vtkSmartPointer<vtkTextureMapToCylinder>::New();
	texturemap->SetInputConnection(modelReader->GetOutputPort());

	vtkSmartPointer<vtkPolyDataMapper> mapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputConnection(texturemap->GetOutputPort());

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

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

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

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

	renderWindow->SetSize(640, 480);
	renderWindow->Render();
	renderWindow->SetWindowName("TextureMap");
	renderWindow->Render();
	renderWindow->Render();
	renWinInteractor->Start();

	return EXIT_SUCCESS;
}

代码中先使用vtkTexture 来加载纹理图像,并通过vtkActor::SetTexture()设置纹理:然后
使用vtkTextureMapToCylinder 来建立纹理空间与模型空间的映射关系;最后通过VTK 渲染
引擎进行渲染,执行结果如图 6-29所示:

文章来源:https://blog.csdn.net/weixin_55035144/article/details/135454672
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。