VS+QT+VTK三维网格图像显示GUI

如需安装运行环境或远程调试,可加QQ905733049, 或QQ2945218359由专业技术人员远程协助!

运行结果如下:

主代码如下:

#include <QtCore/QStringList>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMessageBox>

#include <vtkAppendPolyData.h>
#include <vtkCellData.h>
#include <vtkExtractEdges.h>
#include <vtkIdTypeArray.h>
#include <vtkMath.h>
#include <vtkLineSource.h>
#include <vtkLookupTable.h>
#include <vtkMatrix4x4.h>
#include <vtkNew.h>
#include <vtkOBJReader.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkScalarBarActor.h>
#include <vtkSphereSource.h>
#include <vtkSTLReader.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>

#include <iomanip>
#include <sstream>

#include "icp_algorithm.h"
#include "mesh_operation.h"
#include "mesh_segmenter.h"
#include "vtkOFFReader.h"

MeshProcessing::MeshProcessing(QWidget *parent) : QMainWindow(parent) {
	ui.setupUi(this);

	this->mesh_processing_data_model_ = MeshProcessingDataModel::getInstance();
	this->color_table_handler_ = nullptr;
	this->vtk_widget_ = ui.vtk_widget;
	this->open_file_action_ = ui.open_file_action;
	this->read_color_table_action_ = ui.read_color_table_action;
	this->write_color_table_action_ = ui.write_color_table_action;
	this->wireframe_mode_action_ = ui.wireframe_mode_action;
	this->observe_mode_action_ = ui.observe_mode_action;
	this->vertex_mode_action_ = ui.vertex_mode_action;
	this->face_mode_action_ = ui.face_mode_action;
	this->multi_vertex_mode_action_ = ui.multi_vertex_mode_action;
	this->display_normal_action_ = ui.display_normal_action;
	this->default_mode_action_ = ui.default_mode_action;
	this->discrete_mode_action_ = ui.discrete_mode_action;
	this->continuous_mode_action_ = ui.continuous_mode_action;
	this->icp_registration_action_ = ui.icp_registraion_action;
	this->segment_action_ = ui.segment_action;
	this->fill_region_three_vertices_action_ = ui.fill_region_three_vertices_action;
	this->fill_region_two_vertices_action_ = ui.fill_region_two_vertices_action;
	this->list_widget_model_ = ui.list_widget_model;
	this->register_scroll_area_ = ui.register_scroll_area;
	this->segment_scroll_area_ = ui.segment_scroll_area;
	this->tab_widget_ = ui.tab_widget;
	this->max_iter_spin_box_ = ui.max_iter_spin_box;
	this->min_error_double_spin_box_ = ui.min_error_double_spin_box;
	this->move_center_radio_button_ = ui.move_center_radio_button;
	this->run_icp_button_ = ui.run_icp_button;
	this->iter_num_label_ = ui.iter_num_label;
	this->error_label_ = ui.error_label;
	this->matrix_label_ = ui.matrix_label;
	this->exit_icp_button_ = ui.exit_icp_button;
	this->cancel_icp_button_ = ui.cancel_icp_button;
	this->seed_num_spin_box_ = ui.seed_num_spin_box;
	this->phy_ratio_double_spin_box_ = ui.phy_ratio_double_spin_box;
	this->cluster_num_slider_ = ui.cluster_num_slider;
	this->run_segment_button_ = ui.run_segment_button;
	this->exit_segment_button_ = ui.exit_segment_button;
	this->cancel_segment_button_ = ui.cancel_segment_button;

	this->wireframe_mode_action_->setChecked(true);
	this->default_mode_action_->setEnabled(false);
	this->discrete_mode_action_->setEnabled(false);
	this->continuous_mode_action_->setEnabled(false);
	this->register_scroll_area_->setVisible(false);
	this->segment_scroll_area_->setVisible(false);
	this->tab_widget_->setTabEnabled(1, false);

	connect(this->open_file_action_, SIGNAL(triggered()), this, SLOT(OnOpenFile()));
	connect(this->read_color_table_action_, SIGNAL(triggered()), this, SLOT(OnReadColorTable()));
	connect(this->write_color_table_action_, SIGNAL(triggered()), this, SLOT(OnWriteColorTable()));
	connect(this->wireframe_mode_action_, SIGNAL(triggered()), this, SLOT(OnWireframeMode()));
	connect(this->observe_mode_action_, SIGNAL(triggered()), this, SLOT(OnObserveMode()));
	connect(this->vertex_mode_action_, SIGNAL(triggered()), this, SLOT(OnVertexMode()));
	connect(this->face_mode_action_, SIGNAL(triggered()), this, SLOT(OnFaceMode()));
	connect(this->multi_vertex_mode_action_, SIGNAL(triggered()), this, SLOT(OnMultiVertexMode()));
	connect(this->display_normal_action_, SIGNAL(triggered()), this, SLOT(OnDisplayNormal()));
	connect(this->default_mode_action_, SIGNAL(triggered()), this, SLOT(OnDefaultMode()));
	connect(this->discrete_mode_action_, SIGNAL(triggered()), this, SLOT(OnDiscreteMode()));
	connect(this->continuous_mode_action_, SIGNAL(triggered()), this, SLOT(OnContinuousMode()));
	connect(this->icp_registration_action_, SIGNAL(triggered()), this, SLOT(OnICPRegistration()));
	connect(this->segment_action_, SIGNAL(triggered()), this, SLOT(OnSegment()));
	connect(this->fill_region_three_vertices_action_, SIGNAL(triggered()), this, SLOT(OnFillRegionThreeVertices()));
	connect(this->fill_region_two_vertices_action_, SIGNAL(triggered()), this, SLOT(OnFillRegionTwoVertices()));
	connect(this->list_widget_model_, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(OnListWidgetModelItemChanged(QListWidgetItem *)));
	connect(this->run_icp_button_, SIGNAL(clicked()), this, SLOT(OnRunICP()));
	connect(this->exit_icp_button_, SIGNAL(clicked()), this, SLOT(OnExitICP()));
	connect(this->cancel_icp_button_, SIGNAL(clicked()), this, SLOT(OnCancelICP()));
	connect(this->cluster_num_slider_, SIGNAL(valueChanged(int)), this, SLOT(OnClusterNumChanged(int)));
	connect(this->run_segment_button_, SIGNAL(clicked()), this, SLOT(OnRunSegment()));
	connect(this->exit_segment_button_, SIGNAL(clicked()), this, SLOT(OnExitSegment()));
	connect(this->cancel_segment_button_, SIGNAL(clicked()), this, SLOT(OnCancelSegment()));

	connect(this->vtk_widget_->style, SIGNAL(selectVertex(vtkIdType)), this, SLOT(OnSelectVertex(vtkIdType)));
	connect(this->vtk_widget_->style, SIGNAL(selectFace(vtkIdType)), this, SLOT(OnSelectFace(vtkIdType)));
	connect(this->vtk_widget_->style, SIGNAL(selectMultiVertex(const std::vector<vtkIdType> &)), this, SLOT(OnSelectMultiVertex(const std::vector<vtkIdType> &)));
}

void MeshProcessing::OnOpenFile() {
	QStringList file_paths = QFileDialog::getOpenFileNames(this, QString::fromLocal8Bit("´ò¿ªÎļþ"), "./objs/", tr("OBJ files(*.obj);; OFF files(*.off);; STL files(*.stl)"));
	if (file_paths.size() == 0) return;

	this->default_mode_action_->setEnabled(false);
	this->discrete_mode_action_->setEnabled(false);
	this->continuous_mode_action_->setEnabled(false);

	this->removeMeshActors();
	this->removeVertexActors();
	this->removeFaceActors();
	this->removeMultiVertexActors();
	this->removeFillRegionFaceActors();
	this->mesh_processing_data_model_->mesh_vec_.clear();
	this->mesh_processing_data_model_->neighbor_vertex_actor_vec_.clear();
	this->mesh_processing_data_model_->actor_vec_.clear();
	this->mesh_processing_data_model_->highlight_vec_.clear();
	this->mesh_processing_data_model_->mean_edge_length_vec_.clear();
	this->list_widget_model_->clear();

	this->mesh_processing_data_model_->display_mode_ = MeshProcessingDataModel::DEFAULT;

	int number_of_points = 0, number_of_faces = 0, number_of_edges = 0;
	for (int i = 0; i < file_paths.size(); ++i) {
		QString file_name = file_paths[i];
		QString extension_name = file_name.split('/').back().split('.').back();

		vtkSmartPointer<vtkPolyData> mesh =
			vtkSmartPointer<vtkPolyData>::New();
		if (extension_name == QString::fromLocal8Bit("obj")) {
			vtkNew<vtkOBJReader> objReader;
			objReader->SetFileName(file_name.toLocal8Bit());
			objReader->Update();
			mesh->DeepCopy(objReader->GetOutput());
		} else if (extension_name == QString::fromLocal8Bit("off")) {
			vtkNew<vtkOFFReader> offReader;
			offReader->SetFileName(file_name.toLocal8Bit());
			offReader->Update();
			mesh->DeepCopy(offReader->GetOutput());
		} else {
			vtkNew<vtkSTLReader> stlReader;
			stlReader->SetFileName(file_name.toLocal8Bit());
			stlReader->Update();
			mesh->DeepCopy(stlReader->GetOutput());
		}

		QString only_name = file_name.split('/').back().split('.').front();
		QListWidgetItem * item = new QListWidgetItem(only_name);
		item->setCheckState(Qt::Checked);
		this->list_widget_model_->addItem(item);

		auto actor = this->vtk_widget_->addActor(mesh);
		this->vtk_widget_->highlightMesh(actor);

		auto wireframe_actor = this->vtk_widget_->addWireFrameActor(mesh);

		this->mesh_processing_data_model_->wireframe_actor_vec_.push_back(wireframe_actor);
		this->mesh_processing_data_model_->mesh_vec_.push_back(mesh);
		this->mesh_processing_data_model_->actor_vec_.push_back(actor);
		this->mesh_processing_data_model_->highlight_vec_.push_back(1);

		if (!this->wireframe_mode_action_->isChecked())
			this->mesh_processing_data_model_->wireframe_actor_vec_.back()->VisibilityOff();

		number_of_points += mesh->GetNumberOfPoints();
		number_of_faces += mesh->GetNumberOfCells();

		vtkNew<vtkExtractEdges> extractEdges;
		extractEdges->SetInputData(mesh);
		extractEdges->Update();

		vtkSmartPointer<vtkPolyData> mesh_edge =
			vtkSmartPointer<vtkPolyData>::New();
		mesh_edge->DeepCopy(extractEdges->GetOutput());

		this->mesh_processing_data_model_->mesh_edge_vec_.push_back(mesh_edge);

		vtkSmartPointer<vtkIdList> pts =
			vtkSmartPointer<vtkIdList>::New();
		double mean_edge_length = 0.0;
		while (extractEdges->GetOutput()->GetLines()->GetNextCell(pts)) {
			double p0[3], p1[3];
			mesh_edge->GetPoint(pts->GetId(0), p0);
			mesh_edge->GetPoint(pts->GetId(1), p1);
			mean_edge_length += std::sqrt(vtkMath::Distance2BetweenPoints(p0, p1));
		}
		mean_edge_length /= mesh_edge->GetNumberOfLines();

		this->mesh_processing_data_model_->mean_edge_length_vec_.push_back(mean_edge_length);
		number_of_edges += mesh_edge->GetNumberOfLines();
	}

	this->resetParameters();


void MeshProcessing::OnDiscreteMode() {
	if (this->mesh_processing_data_model_->actor_vec_.size() != 1) {
		QMessageBox::critical(this, QString::fromLocal8Bit("´íÎó"), QString::fromLocal8Bit("Çë¼ì²éÄ¿Ç°¶ÁÈëµÄÍø¸ñÊýÊÇ·ñΪ1£¡"));
		return;
	}

	this->mesh_processing_data_model_->display_mode_ = MeshProcessingDataModel::DISCRETE;
	this->mesh_processing_data_model_->mesh_vec_[0] = this->color_table_handler_->turnToDiscrete();

	this->mesh_processing_data_model_->hueLut = vtkSmartPointer<vtkLookupTable>::New();
	this->mesh_processing_data_model_->hueLut->SetNumberOfTableValues(this->color_table_handler_->maxScalar() - this->color_table_handler_->minScalar() + 1);
	this->mesh_processing_data_model_->hueLut->Build();

	for (int i = 0; i < this->color_table_handler_->maxScalar() - this->color_table_handler_->minScalar() + 1; ++i) {
		double hue = i * 1.0 / (this->color_table_handler_->maxScalar() - this->color_table_handler_->minScalar() + 1);
		double r, g, b;
		vtkMath::HSVToRGB(hue, 1.0, 1.0, &r, &g, &b);
		this->mesh_processing_data_model_->hueLut->SetTableValue(i, r, g, b, 1);
	}



void MeshProcessing::removeMeshActors() {
	for (const auto & actor : this->mesh_processing_data_model_->actor_vec_)
		this->vtk_widget_->removeActor(actor);
	for (const auto & actor : this->mesh_processing_data_model_->wireframe_actor_vec_)
		this->vtk_widget_->removeActor(actor);
}

void MeshProcessing::removeVertexActors() {
	this->vtk_widget_->removeActor(this->mesh_processing_data_model_->selected_vertex_actor_);
	for (const auto & actor : this->mesh_processing_data_model_->neighbor_vertex_actor_vec_)
		this->vtk_widget_->removeActor(actor);
	for (const auto & actor : this->mesh_processing_data_model_->neighbor_face_actor_vec_)
		this->vtk_widget_->removeActor(actor);
}

void MeshProcessing::removeFaceActors() {
	this->vtk_widget_->removeActor(this->mesh_processing_data_model_->selected_face_actor_);
	for (const auto & actor : this->mesh_processing_data_model_->neighbor_face2_actor_vec_)
		this->vtk_widget_->removeActor(actor);
	this->vtk_widget_->removeActor(this->mesh_processing_data_model_->selected_face_normal_actor_);
}

void MeshProcessing::removeMultiVertexActors() {
	for (const auto & actor : this->mesh_processing_data_model_->selected_multi_vertex_actor_vec_)
		this->vtk_widget_->removeActor(actor);
}

void MeshProcessing::removeFillRegionFaceActors() {
	for (const auto & actor : this->mesh_processing_data_model_->fill_region_face_actor_vec_)
		this->vtk_widget_->removeActor(actor);
}

void MeshProcessing::enableAllActions() {
	this->open_file_action_->setEnabled(true);
	this->read_color_table_action_->setEnabled(true);
	this->wireframe_mode_action_->setEnabled(true);
	this->observe_mode_action_->setEnabled(true);
	this->vertex_mode_action_->setEnabled(true);
	this->face_mode_action_->setEnabled(true);
	this->multi_vertex_mode_action_->setEnabled(true);
	this->display_normal_action_->setEnabled(true);
	this->icp_registration_action_->setEnabled(true);
	this->fill_region_three_vertices_action_->setEnabled(true);
	this->fill_region_two_vertices_action_->setEnabled(true);
	this->segment_action_->setEnabled(true);
}

void MeshProcessing::disableAllActions() {
	this->open_file_action_->setEnabled(false);
	this->read_color_table_action_->setEnabled(false);
	this->wireframe_mode_action_->setEnabled(false);
	this->observe_mode_action_->setEnabled(false);
	this->vertex_mode_action_->setEnabled(false);
	this->face_mode_action_->setEnabled(false);
	this->multi_vertex_mode_action_->setEnabled(false);
	this->display_normal_action_->setEnabled(false);
	this->icp_registration_action_->setEnabled(false);
	this->fill_region_three_vertices_action_->setEnabled(false);
	this->fill_region_two_vertices_action_->setEnabled(false);
	this->segment_action_->setEnabled(false);
}

运行结果如下:

 

C++学习参考实例

C++实现图形界面五子棋游戏源码:

https://blog.csdn.net/alicema1111/article/details/90035420

C++实现图形界面五子棋游戏源码2:

https://blog.csdn.net/alicema1111/article/details/106479579

C++ OpenCV相片视频人脸识别统计人数:

https://blog.csdn.net/alicema1111/article/details/105833928

VS2017+PCL开发环境配置:

https://blog.csdn.net/alicema1111/article/details/106877145

VS2017+Qt+PCL点云开发环境配置:

https://blog.csdn.net/alicema1111/article/details/105433636

C++ OpenCV汽车检测障碍物与测距:

https://blog.csdn.net/alicema1111/article/details/105833449

Windows VS2017安装配置PCL点云库:

https://blog.csdn.net/alicema1111/article/details/105111110

VS+VTK+Dicom(dcm)+CT影像切片窗体界面显示源码

https://blog.csdn.net/alicema1111/article/details/106994839

 

Python学习参考实例

Python相片更换背景颜色qt窗体程序:

https://blog.csdn.net/alicema1111/article/details/106919140

OpenCV汽车识别检测数量统计:

https://blog.csdn.net/alicema1111/article/details/106597260

OpenCV视频识别检测人数跟踪统计:

https://blog.csdn.net/alicema1111/article/details/106113042

OpenCV米粒检测数量统计:

https://blog.csdn.net/alicema1111/article/details/106089697

opencv人脸识别与变形哈哈镜:

https://blog.csdn.net/alicema1111/article/details/105833123

OpenCV人脸检测打卡系统:

https://blog.csdn.net/alicema1111/article/details/105315066

Python+OpenCV摄像头人脸识别:

https://blog.csdn.net/alicema1111/article/details/105107286

Python+Opencv识别视频统计人数:

https://blog.csdn.net/alicema1111/article/details/103804032

Python+OpenCV图像人脸识别人数统计

https://blog.csdn.net/alicema1111/article/details/105378639

python人脸头发身体部位识别人数统计

https://blog.csdn.net/alicema1111/article/details/116424942

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐