在Opencascade项目中使用VTK可视化窗口

3 篇文章 0 订阅

项目场景:

实现IGES文件、点云文件(.txt、.pcd)、STL文件的读取显示、STL模型及点云模型在三维空间中的旋转(这里使用的是使用旋转矩阵)。

将该这些功能集成到QT中。

问题描述:

问题一

有关三维模型文件读取不成功的可能问题:
VTK进行IGES文件读取及显示遇到的文件路径不正确问题的解决方法

问题二

在窗口中进行交互操作时并不是我们常用的交互方式。
常用方式:
鼠标左键按住不动拖动旋转
鼠标右键按住不动拖动移动
鼠标滚轮对模型进行放大

问题三

在将VS中的代码移植到QT Creator中时,因为在VS中添加四个初始化操作,在VS中如果不添加会出现:

Error: no override found for ‘vtkRenderWindow’.
Error: no override found for ‘vtkRenderer’.
Error: no override found for ‘vtkPolyDataMapper’.

这三个错误。

问题四

在我将PCL中的VTK8.1换成我自己编译的VTK8.2后(因为想使用QVTKWidgetPlugin),构建工程的时候报错:

ImmediateModeRenderingOff 不是vtkMapper的成员


原因分析:

问题二

没有添加渲染窗口交互操作的样式导致

问题三

寻找合适的位置放置四个初始化代码


解决方案:

问题二

添加如下代码:

	vtkInteractorStyleTrackballCamera *style =
		vtkInteractorStyleTrackballCamera::New();

	renderWindowInteractor->SetInteractorStyle(style);

问题三

在QT工程文件中的mainwindow.cpp文件中添加如下代码:
在这里插入图片描述
同时在.cpp文件最前面添加头文件

#include <vtkAutoInit.h>

问题四

直接双击报错的位置,自动寻找到报错的行数,然后将那几行注释掉即可。


VS全部代码

//#define WNT
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>


#include <gp_Circ.hxx>
#include <gp_Elips.hxx>
#include <gp_Sphere.hxx>

#include <Poly_Polygon3D.hxx>
#include <Poly_Triangulation.hxx>

#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_HSequenceOfShape.hxx>

#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>

#include <IGESControl_Controller.hxx>
#include <IGESControl_Writer.hxx>
#include <IGESControl_Reader.hxx>

#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS.hxx>

#include <BRep_Tool.hxx>
#include <BRepMesh.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>

#include <BRepAdaptor_Curve.hxx>
#include <GCPnts_TangentialDeflection.hxx>
#include <TopExp_Explorer.hxx>
#include <Standard_TypeDef.hxx>


//vtk lib
#include <vtkSmartPointer.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkAutoInit.h>
//VTK显示坐标轴
#include <vtkAxesActor.h>
#include <vtkLineSource.h>
#include <vtkAxis.h>
#include <vtkAxes.h>
#include <vtkConeSource.h>
#include <vtkCaptionActor2D.h>

#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackball.h>  
#include <vtkInteractorStyleTrackballCamera.h>  
#include <vtkProperty.h>
#include <vtkTriangle.h>
#include <vtkSTLReader.h>

//进行旋转操作所需的头文件
//vtkTransform, vtkTransformFilter, vtkMatrix4x4
#include <vtkTransform.h>
#include <vtkTransformFilter.h>
#include <vtkMatrix4x4.h>

VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);

Standard_Integer ReadIGES(const Standard_CString& aFileName,
	Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
{

	IGESControl_Reader Reader;

	Standard_Integer status = Reader.ReadFile(aFileName);

	if (status != IFSelect_RetDone)
	{
		return status;
	}

	Reader.TransferRoots();

	TopoDS_Shape aShape = Reader.OneShape();
	aHSequenceOfShape->Append(aShape);


	return status;
}


void BuildMesh(vtkRenderer* render,
	const TopoDS_Face& face, double deflection = 0.1)
	//这里的0.1是默认参数,如果配合header使用那么只需要在header中写即可,在CPP文件中是不需要的
{
	TopLoc_Location location;
	//BRepMesh::Mesh(face, deflection);该函数已经弃用
	BRepMesh_IncrementalMesh(face, deflection);

	Handle_Poly_Triangulation triFace = BRep_Tool::Triangulation(face, location);

	Standard_Integer nTriangles = triFace->NbTriangles();

	gp_Pnt vertex1;
	gp_Pnt vertex2;
	gp_Pnt vertex3;

	Standard_Integer nVertexIndex1 = 0;
	Standard_Integer nVertexIndex2 = 0;
	Standard_Integer nVertexIndex3 = 0;

	TColgp_Array1OfPnt nodes(1, triFace->NbNodes());
	Poly_Array1OfTriangle triangles(1, triFace->NbTriangles());

	nodes = triFace->Nodes();
	triangles = triFace->Triangles();

	vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
	vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
	vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
	points->Allocate(nTriangles * 3);
	cells->Allocate(nTriangles);

	int id = 0;

	for (Standard_Integer i = 1; i <= nTriangles; i++)
	{
		Poly_Triangle aTriangle = triangles.Value(i);

		aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);

		vertex1 = nodes.Value(nVertexIndex1).Transformed(location.Transformation());
		vertex2 = nodes.Value(nVertexIndex2).Transformed(location.Transformation());
		vertex3 = nodes.Value(nVertexIndex3).Transformed(location.Transformation());

		points->InsertNextPoint(vertex1.X(), vertex1.Y(), vertex1.Z());
		points->InsertNextPoint(vertex2.X(), vertex2.Y(), vertex2.Z());
		points->InsertNextPoint(vertex3.X(), vertex3.Y(), vertex3.Z());

		vtkSmartPointer<vtkTriangle> triangle = vtkSmartPointer<vtkTriangle>::New();
		triangle->GetPointIds()->SetId(0, id * 3);
		triangle->GetPointIds()->SetId(1, id * 3 + 1);
		triangle->GetPointIds()->SetId(2, id * 3 + 2);

		// Add the triangle to a cell array
		cells->InsertNextCell(triangle);
		id++;
	}

	polyData->SetPoints(points);
	polyData->SetPolys(cells);

	vtkSmartPointer<vtkPolyDataMapper> sourceMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	//setInput函数已经弃用
	sourceMapper->SetInputData(polyData);

	vtkSmartPointer<vtkActor> sourceActor = vtkSmartPointer<vtkActor>::New();
	sourceActor->SetMapper(sourceMapper);
	sourceActor->GetProperty()->SetColor(1, 0, 0);

	render->AddActor(sourceActor);

}

void createAxes(vtkSmartPointer<vtkRenderer> renderer)
{
	//轴
	vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
	axes->SetTotalLength(150.0, 100.0, 50.0);
	axes->SetShaftType(vtkAxesActor::CYLINDER_SHAFT);//设置轴类型圆柱形状
	axes->SetCylinderRadius(0.01);
	
	axes->GetXAxisCaptionActor2D()->SetWidth(0.03);
	axes->GetYAxisCaptionActor2D()->SetWidth(0.03);
	axes->GetZAxisCaptionActor2D()->SetWidth(0.03);

	renderer->AddActor(axes);
}

void BuildScene(vtkRenderer *renderer, Handle(TopTools_HSequenceOfShape)& aHSequenceOfShape)
{
	Standard_Integer index = aHSequenceOfShape->Length();
	TopoDS_Shape theCompSolid = aHSequenceOfShape->ChangeValue(index);
	
	
	for (TopExp_Explorer faceExp(theCompSolid, TopAbs_FACE); faceExp.More(); faceExp.Next())
	{
		// The 3d-mesh of the FACE is assembled to form the
		// boundary of the SOLID.

		const TopoDS_Face& theFace = TopoDS::Face(faceExp.Current());
		BuildMesh(renderer, theFace);

	}


}

//实现点云的显示
vtkSmartPointer<vtkActor> visualizePointCloud(std::string fileName) {
	vtkSmartPointer<vtkPoints> m_Points = vtkSmartPointer<vtkPoints>::New();
	vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();   //_存放细胞顶点,用于渲染(显示点云所必须的)  
	vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
	vtkSmartPointer<vtkPolyDataMapper> pointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	vtkSmartPointer<vtkActor> pointActor = vtkSmartPointer<vtkActor>::New();
	//_读进点云数据信息  

	FILE *fp = NULL;
	fp = fopen(fileName.c_str(), "r"); //3DpointDatas.txt  
	double x = 0, y = 0, z = 0;
	int i = 0;
	while (!feof(fp))
	{
		fscanf(fp, "%lf %lf %lf", &x, &y, &z);
		m_Points->InsertPoint(i, x, y, z);      //_加入点信息  
		vertices->InsertNextCell(1);     //_加入细胞顶点信息----用于渲染点集  
		vertices->InsertCellPoint(i++);

	}
	fclose(fp);
	polyData->SetPoints(m_Points);       //_设置点集  
	polyData->SetVerts(vertices);        //_设置渲染顶点  
	pointMapper->SetInputData(polyData);
	pointActor->SetMapper(pointMapper);
	pointActor->GetProperty()->SetColor(0.0, 0.1, 1.0);
	pointActor->GetProperty()->SetAmbient(0.5);
	pointActor->GetProperty()->SetPointSize(2);

	return pointActor;
}

//实现STL模型的显示
vtkSmartPointer<vtkActor> visualizeSTL(std::string aFileName) {
	vtkSmartPointer<vtkSTLReader> readerSTL =
		vtkSmartPointer<vtkSTLReader>::New();
	readerSTL->SetFileName(aFileName.c_str());

	// Visualize
//用来代表多边形数据的模型
	vtkSmartPointer<vtkPolyDataMapper> mapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	mapper->SetInputConnection(readerSTL->GetOutputPort());
	//这里的actor用来表示需要渲染的实体模型
	vtkSmartPointer<vtkActor> actor =
		vtkSmartPointer<vtkActor>::New();
	/*
	setmapper的含义:这是用于将执行组件连接到可视化管道的末尾(即映射器)的方法。
	这应该是 vtkMapper 的子类。
	render:渲染
	*/
	actor->SetMapper(mapper);
	return actor;
}

//实现IGES模型的显示
void visualizeIGES(const Standard_CString fileName, vtkSmartPointer<vtkRenderer> renderer) {
	Handle(TopTools_HSequenceOfShape) aHSequenceOfShape =
		new TopTools_HSequenceOfShape();
	Standard_Integer status =
		ReadIGES(fileName, aHSequenceOfShape);
	cout << "return status:" << status << endl;
	//向渲染三维空间中添加IGES的渲染对象
	BuildScene(renderer, aHSequenceOfShape);
}

#define LINE_LEN .5



int main(void)

{
	//新建一个渲染对象所存放的窗口
	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	//新建一个用来存放渲染对象的三维空间
	vtkSmartPointer<vtkRenderer> renderer =
		vtkSmartPointer<vtkRenderer>::New();


	//创建一个点云的actor对象
	std::string pointCloudFileName = 
		"E:\\Research\\test resource\\STL.txt";
	vtkSmartPointer<vtkActor> pointActor = 
		visualizePointCloud(pointCloudFileName);

	/*STL文件的读取*/
	std::string aFileName = 
		"E:\\Research\\test resource\\STL_8836.stl";
	vtkSmartPointer<vtkActor> actorSTL =  
		visualizeSTL(aFileName);

	//IGES的读取
	//相当于const const char* IGESFileName
	const Standard_CString IGESFileName = "E:\\Research\\test resource\\zhizuo_1.igs";
	visualizeIGES(IGESFileName, renderer);


	//向显示窗口中添加一个渲染对象的三维空间
	renderWindow->AddRenderer(renderer);

	//设置一个窗口渲染交互的对象并添加到渲染显示窗口中
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);
	
	//粗配准矩阵和精配准矩阵
	double preTrsf[] = 
	{ 0.154145	,-0.268736		,-0.9508	,90.2438	,
	-0.50864	,0.803412		,-0.309539	,0.332563	,
	0.847068	,0.531329		,-0.0128478	,-155.794	,
	0			,0				,0			,1			};

	double ICPTrsf[] = 
	{ 0.952493	,0.304157		,0.0149612	,-11.551,
	 -0.30439   ,0.949638		,0.0744341	,8.09676,
	  0.00843305,-0.0754527		,0.997108   ,5.34397,
	  0			,0				,0			,1		};

	vtkMatrix4x4 *mat = vtkMatrix4x4::New();
	double finalTrsf[16];
	vtkMatrix4x4::Multiply4x4(ICPTrsf, preTrsf, finalTrsf);//获得最终旋转矩阵
	mat->DeepCopy(finalTrsf);
	//std::cout << *mat << std::endl;//直接打印出旋转矩阵得到信息
	//将某个渲染对象actor右乘一个旋转矩阵mat
	//actor->SetUserMatrix(mat);
	pointActor->SetUserMatrix(mat);
	//相当于在renderer图像中添加了一个actor
	

	renderer->AddActor(actorSTL);
	renderer->AddActor(pointActor);
	createAxes(renderer);
	renderer->SetBackground(1, 1, 1);

	// Render and interact
	renderWindow->Render();
	

	//无限的执行循环,避免自己去写
	vtkInteractorStyleTrackballCamera *style =
		vtkInteractorStyleTrackballCamera::New();

	renderWindowInteractor->SetInteractorStyle(style);
	renderWindowInteractor->Start();

	return 0;

}

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值