VS+QT+VTK 3D grid display-point surface selection-normal vector display-registration-split window program

Featured program examples

VS+QT+VTK 3D grid display-point surface selection-normal vector display-registration-split window program

If you need to install the operating environment or remote debugging, see the personal QQ business card at the bottom of the article, and professional and technical personnel will assist remotely!

foreword

This blog writes code for <<VS+QT+VTK 3D grid display-point surface selection-normal vector display-registration-split window program>>, the code is neat, regular and easy to read. The first choice for learning and application recommendation.

Function: read 3D mesh data, including *.obj, *.stl, *.off, highlight single vertex and multiple vertices and single face and face normal by clicking the mesh surface, display with/without The grid data of the wireframe, displaying the number of points, faces and edges, the realization of ICP algorithm and semi-automatic segmentation algorithm .


Article directory

1. Required tool software

2. Use steps

        1. Import library

        2. Code implementation

        3. Running results

3. Online assistance

1. Required tool software

1. VS, Qt

2. VTK

2. Use steps

1. Import library

#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"

2. Code implementation

code show as below:

void MeshProcessing::OnWireframeMode() {
	bool isChecked = this->wireframe_mode_action_->isChecked();
	for (auto actor : this->mesh_processing_data_model_->wireframe_actor_vec_)
		actor->SetVisibility(isChecked);
	this->vtk_widget_->update();
}

void MeshProcessing::OnObserveMode() {
	this->removeVertexActors();
	this->removeFaceActors();
	this->removeMultiVertexActors();
	this->removeFillRegionFaceActors();
	this->mesh_processing_data_model_->pick_mode_ = MeshProcessingDataModel::OBSERVE;
	this->vtk_widget_->updateTopText();
}

void MeshProcessing::OnVertexMode() {
	this->removeFaceActors();
	this->removeMultiVertexActors();
	this->removeFillRegionFaceActors();
	this->mesh_processing_data_model_->pick_mode_ = MeshProcessingDataModel::VERTEX;
	this->vtk_widget_->updateTopText();
}

void MeshProcessing::OnFaceMode() {
	this->removeVertexActors();
	this->removeMultiVertexActors();
	this->removeFillRegionFaceActors();
	this->mesh_processing_data_model_->pick_mode_ = MeshProcessingDataModel::FACE;
	this->vtk_widget_->updateTopText();
}

void MeshProcessing::OnMultiVertexMode() {
	this->removeVertexActors();
	this->removeFaceActors();
	this->removeFillRegionFaceActors();
	this->mesh_processing_data_model_->pick_mode_ = MeshProcessingDataModel::MULTI_VERTEX;
	this->vtk_widget_->updateTopText();
}

void MeshProcessing::OnDisplayNormal() {
	if (this->mesh_processing_data_model_->pick_mode_ != MeshProcessingDataModel::FACE ||
		this->mesh_processing_data_model_->selected_face_id_ == -1) {
		QMessageBox::warning(this, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("请在面拾取模式中选取一个面片!"));
		return;
	}

	int cellId = this->mesh_processing_data_model_->selected_face_id_;
	vtkCell * cell = this->mesh_processing_data_model_->combined_mesh_->GetCell(cellId);

	double p0[3], p1[3], p2[3];
	this->mesh_processing_data_model_->combined_mesh_->GetPoint(cell->GetPointId(0), p0);
	this->mesh_processing_data_model_->combined_mesh_->GetPoint(cell->GetPointId(1), p1);
	this->mesh_processing_data_model_->combined_mesh_->GetPoint(cell->GetPointId(2), p2);

	double c[3];
	for (int i = 0; i < 3; ++i) c[i] = (p0[i] + p1[i] + p2[i]) / 3;

	double p0p1[3], p0p2[3];
	vtkMath::Subtract(p1, p0, p0p1);
	vtkMath::Subtract(p2, p0, p0p2);

	double normal[3];
	vtkMath::Cross(p0p1, p0p2, normal);
	vtkMath::Normalize(normal);

	double constant = (
		std::sqrt(vtkMath::Distance2BetweenPoints(p0, p1)) +
		std::sqrt(vtkMath::Distance2BetweenPoints(p1, p2)) +
		std::sqrt(vtkMath::Distance2BetweenPoints(p2, p0))
	);
	double e[3];
	for (int i = 0; i < 3; ++i) e[i] = c[i] + constant * normal[i];

	vtkSmartPointer<vtkLineSource> lineSource =
		vtkSmartPointer<vtkLineSource>::New();
	lineSource->SetPoint1(c);
	lineSource->SetPoint2(e);
	lineSource->Update();

	this->mesh_processing_data_model_->selected_face_normal_actor_ = this->vtk_widget_->addActor(lineSource->GetOutput());
	this->mesh_processing_data_model_->selected_face_normal_actor_->GetProperty()->SetColor(.8, .8, .2);
	this->mesh_processing_data_model_->selected_face_normal_actor_->GetProperty()->SetLineWidth(5);

	this->vtk_widget_->update();
}

void MeshProcessing::OnDefaultMode() {
	this->mesh_processing_data_model_->display_mode_ = MeshProcessingDataModel::DEFAULT;
	if (this->mesh_processing_data_model_->highlight_vec_[0] == 1)
		this->vtk_widget_->highlightMesh(this->mesh_processing_data_model_->actor_vec_[0]);
	else
		this->vtk_widget_->unhighlightMesh(this->mesh_processing_data_model_->actor_vec_[0]);
	this->vtk_widget_->update();
}

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

	this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->SetScalarRange(0, this->color_table_handler_->maxScalar() - this->color_table_handler_->minScalar() + 1);
	this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->SetScalarModeToUseCellData();
	this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->SetColorModeToMapScalars();
	this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->SetLookupTable(this->mesh_processing_data_model_->hueLut);

	if (this->mesh_processing_data_model_->highlight_vec_[0] == 1)
		this->vtk_widget_->highlightMesh(this->mesh_processing_data_model_->actor_vec_[0]);
	else
		this->vtk_widget_->unhighlightMesh(this->mesh_processing_data_model_->actor_vec_[0]);
	this->vtk_widget_->update();
}

void MeshProcessing::OnContinuousMode() {
	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::CONTINUOUS;
	this->mesh_processing_data_model_->mesh_vec_[0] = this->color_table_handler_->turnToContinuous();

	this->mesh_processing_data_model_->hueLut = vtkSmartPointer<vtkLookupTable>::New();
	this->mesh_processing_data_model_->hueLut->SetTableRange(this->color_table_handler_->minScalar(), this->color_table_handler_->maxScalar() + 1);
	this->mesh_processing_data_model_->hueLut->SetHueRange(0, 1);
	this->mesh_processing_data_model_->hueLut->SetSaturationRange(1, 1);
	this->mesh_processing_data_model_->hueLut->SetValueRange(1, 1);
	this->mesh_processing_data_model_->hueLut->Build();

	this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->SetScalarRange(this->color_table_handler_->minScalar(), this->color_table_handler_->maxScalar() + 1);
	this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->SetScalarModeToUseCellData();
	this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->SetColorModeToMapScalars();
	this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->SetLookupTable(this->mesh_processing_data_model_->hueLut);

	if (this->mesh_processing_data_model_->highlight_vec_[0] == 1)
		this->vtk_widget_->highlightMesh(this->mesh_processing_data_model_->actor_vec_[0]);
	else
		this->vtk_widget_->unhighlightMesh(this->mesh_processing_data_model_->actor_vec_[0]);
	this->vtk_widget_->update();
}

void MeshProcessing::OnICPRegistration() {
	std::vector<int> active_ids;
	for (int i = 0; i < this->mesh_processing_data_model_->highlight_vec_.size(); ++i) {
		if (this->mesh_processing_data_model_->highlight_vec_[i])
			active_ids.push_back(i);
	}

	if (active_ids.size() != 2) {
		QMessageBox::warning(this, QString::fromLocal8Bit("警告"), QString::fromLocal8Bit("请检查目前选中的网格数是否为2!"));
		return;
	}

	this->wireframe_mode_action_->setChecked(false);
	OnWireframeMode();
	this->disableAllActions();
	this->OnObserveMode();
	this->register_scroll_area_->setVisible(true);

	this->mesh_processing_data_model_->source_id = active_ids.front();
	this->mesh_processing_data_model_->target_id = active_ids.back();

	this->mesh_processing_data_model_->actor_vec_[this->mesh_processing_data_model_->target_id]->GetProperty()->SetColor(.8, .2, .2);
	this->vtk_widget_->update();

	this->tab_widget_->setTabEnabled(0, false);
	this->tab_widget_->setTabEnabled(1, true);
	this->tab_widget_->setCurrentIndex(1);
}

void MeshProcessing::OnSegment() {
	if (this->mesh_processing_data_model_->mesh_vec_.size() != 1) {
		QMessageBox::critical(this, QString::fromLocal8Bit("错误"), QString::fromLocal8Bit("请检查目前读入的网格数是否为1!"));
		return;
	}

	this->wireframe_mode_action_->setChecked(false);
	OnWireframeMode();
	this->disableAllActions();
	this->OnObserveMode();

	if (this->color_table_handler_ != nullptr) {
		this->default_mode_action_->setEnabled(false);
		this->discrete_mode_action_->setEnabled(false);
		this->continuous_mode_action_->setEnabled(false);
		this->OnDefaultMode();
	}

	this->segment_scroll_area_->setVisible(true);
	this->cluster_num_slider_->setEnabled(false);

	this->mesh_processing_data_model_->segment_id = 0;

	this->tab_widget_->setTabEnabled(0, false);
	this->tab_widget_->setTabEnabled(1, true);
	this->tab_widget_->setCurrentIndex(1);
}

void MeshProcessing::OnFillRegionThreeVertices() {
	this->removeFillRegionFaceActors();

	for (int i = 0; i < this->mesh_processing_data_model_->combined_mesh_->GetNumberOfCells(); ++i) {
		vtkSmartPointer<vtkIdList> ptIds =
			vtkSmartPointer<vtkIdList>::New();
		this->mesh_processing_data_model_->combined_mesh_->GetCellPoints(i, ptIds);

		int validNum = 0;
		for (int k = 0; k < 3; ++k)
			validNum += this->mesh_processing_data_model_->selected_multi_vertex_set_.find(ptIds->GetId(k)) != this->mesh_processing_data_model_->selected_multi_vertex_set_.end() ? 1 : 0;

		if (validNum == 3) {
			this->mesh_processing_data_model_->fill_region_face_actor_vec_.push_back(this->vtk_widget_->highlightFace(this->mesh_processing_data_model_->combined_mesh_, i));
			this->mesh_processing_data_model_->fill_region_face_actor_vec_.back()->GetProperty()->SetColor(.8, .8, .2);
		}
	}

	this->vtk_widget_->update();
}

void MeshProcessing::OnFillRegionTwoVertices() {
	this->removeFillRegionFaceActors();

	for (int i = 0; i < this->mesh_processing_data_model_->combined_mesh_->GetNumberOfCells(); ++i) {
		vtkSmartPointer<vtkIdList> ptIds =
			vtkSmartPointer<vtkIdList>::New();
		this->mesh_processing_data_model_->combined_mesh_->GetCellPoints(i, ptIds);

		int validNum = 0;
		for (int k = 0; k < 3; ++k)
			validNum += this->mesh_processing_data_model_->selected_multi_vertex_set_.find(ptIds->GetId(k)) != this->mesh_processing_data_model_->selected_multi_vertex_set_.end() ? 1 : 0;

		if (validNum >= 2) {
			this->mesh_processing_data_model_->fill_region_face_actor_vec_.push_back(this->vtk_widget_->highlightFace(this->mesh_processing_data_model_->combined_mesh_, i));
			this->mesh_processing_data_model_->fill_region_face_actor_vec_.back()->GetProperty()->SetColor(.8, .8, .2);
		}
	}

	this->vtk_widget_->update();
}

void MeshProcessing::OnListWidgetModelItemChanged(QListWidgetItem * item) {
	int row_id = this->list_widget_model_->row(item);

	if (item->checkState() == Qt::Unchecked) {
		this->vtk_widget_->unhighlightMesh(this->mesh_processing_data_model_->actor_vec_[row_id]);
		this->mesh_processing_data_model_->highlight_vec_[row_id] = 0;
	} else {
		this->vtk_widget_->highlightMesh(this->mesh_processing_data_model_->actor_vec_[row_id]);
		this->mesh_processing_data_model_->highlight_vec_[row_id] = 1;
	}

	this->resetParameters();

	this->vtk_widget_->update();
}

void MeshProcessing::OnRunICP() {
	ICPAlgorithm icp;
	icp.setSource(this->mesh_processing_data_model_->mesh_vec_[this->mesh_processing_data_model_->source_id]);
	icp.setTarget(this->mesh_processing_data_model_->mesh_vec_[this->mesh_processing_data_model_->target_id]);
	if (this->move_center_radio_button_->isChecked())
		icp.moveCenterOn();
	else
		icp.moveCenterOff();
	icp.setMaxIter(this->max_iter_spin_box_->value());
	icp.setMinError(this->min_error_double_spin_box_->value());
	icp.registration();

	vtkMatrix4x4 * transform_matrix = icp.getTransformMatrix();
	
	std::ostringstream oss;
	oss << setprecision(2);
	for (int i = 0; i < 4; ++i) {
		for (int j = 0; j < 4; ++j) oss << transform_matrix->GetElement(i, j) << "\t";
		oss << std::endl;
	}

	this->iter_num_label_->setText(QString::number(icp.getIterNum()));
	this->error_label_->setText(QString::number(icp.getError()));
	this->matrix_label_->setText(QString::fromStdString(oss.str()));

	vtkSmartPointer<vtkTransform> transform =
		vtkSmartPointer<vtkTransform>::New();
	transform->SetMatrix(transform_matrix);
	transform->Update();

	vtkNew<vtkTransformPolyDataFilter> transformFilter;
	transformFilter->SetInputData(this->mesh_processing_data_model_->mesh_vec_[0]);
	transformFilter->SetTransform(transform);
	transformFilter->Update();

	vtkPolyDataMapper * mapper = vtkPolyDataMapper::SafeDownCast(this->mesh_processing_data_model_->actor_vec_[0]->GetMapper());
	mapper->SetInputData(transformFilter->GetOutput());

	this->vtk_widget_->resetCamera();
	this->vtk_widget_->update();
}

void MeshProcessing::OnExitICP() {
	this->tab_widget_->setTabEnabled(0, true);
	this->tab_widget_->setTabEnabled(1, false);
	this->tab_widget_->setCurrentIndex(0);

	this->iter_num_label_->setText("");
	this->error_label_->setText("");
	this->matrix_label_->setText("");

	this->enableAllActions();

	this->mesh_processing_data_model_->mesh_vec_[0]->DeepCopy(this->mesh_processing_data_model_->actor_vec_[0]->GetMapper()->GetInput());
	this->mesh_processing_data_model_->actor_vec_[this->mesh_processing_data_model_->target_id]->GetProperty()->SetColor(.0, .5, 1.);
	this->vtk_widget_->update();

	this->register_scroll_area_->setVisible(false);
	this->resetParameters();
}

void MeshProcessing::OnCancelICP() {
	this->tab_widget_->setTabEnabled(0, true);
	this->tab_widget_->setTabEnabled(1, false);
	this->tab_widget_->setCurrentIndex(0);

	this->iter_num_label_->setText("");
	this->error_label_->setText("");
	this->matrix_label_->setText("");

	this->enableAllActions();

	vtkPolyDataMapper * mapper = vtkPolyDataMapper::SafeDownCast(this->mesh_processing_data_model_->actor_vec_[0]->GetMapper());
	mapper->SetInputData(this->mesh_processing_data_model_->mesh_vec_[0]);

	this->mesh_processing_data_model_->actor_vec_[this->mesh_processing_data_model_->target_id]->GetProperty()->SetColor(.0, .5, 1.);
	this->vtk_widget_->update();

	this->register_scroll_area_->setVisible(false);
	this->resetParameters();
}

void MeshProcessing::OnClusterNumChanged(int n) {
	using std::vector;

	this->color_table_handler_ = new ColorTableHandler;
	this->color_table_handler_->setMesh(this->mesh_processing_data_model_->mesh_vec_[this->mesh_processing_data_model_->segment_id]);

	vector<double> color_value_vec;
	vtkSmartPointer<vtkDoubleArray> scalars = this->mesh_processing_data_model_->mesh_segmenter_->getSegmentScalar(n);
	this->mesh_processing_data_model_->mesh_vec_[this->mesh_processing_data_model_->segment_id]->GetCellData()->SetScalars(scalars);
	for (int i = 0; i < scalars->GetNumberOfValues(); ++i)
		color_value_vec.push_back(scalars->GetValue(i));
	this->color_table_handler_->readColorValueVec(color_value_vec);

	this->OnDiscreteMode();
}

void MeshProcessing::OnRunSegment() {
	this->mesh_processing_data_model_->mesh_segmenter_ = new MeshSegmenter(this->seed_num_spin_box_->value(), this->phy_ratio_double_spin_box_->value());
	this->mesh_processing_data_model_->mesh_segmenter_->vtk_widget_ = this->vtk_widget_;
	this->mesh_processing_data_model_->mesh_segmenter_->setMesh(this->mesh_processing_data_model_->mesh_vec_[this->mesh_processing_data_model_->segment_id]);
	this->mesh_processing_data_model_->mesh_segmenter_->segment();

	this->cluster_num_slider_->setEnabled(true);
	this->cluster_num_slider_->setValue(2);
	this->OnClusterNumChanged(2);

	this->cluster_num_slider_->setMinimum(2);
	this->cluster_num_slider_->setMaximum(this->seed_num_spin_box_->value());
}

void MeshProcessing::OnExitSegment() {
	using std::vector;

	this->tab_widget_->setTabEnabled(0, true);
	this->tab_widget_->setTabEnabled(1, false);
	this->tab_widget_->setCurrentIndex(0);

	this->iter_num_label_->setText("");
	this->error_label_->setText("");
	this->matrix_label_->setText("");

	this->enableAllActions();

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

	this->segment_scroll_area_->setVisible(false);
	this->resetParameters();
}

void MeshProcessing::OnCancelSegment() {
	this->tab_widget_->setTabEnabled(0, true);
	this->tab_widget_->setTabEnabled(1, false);
	this->tab_widget_->setCurrentIndex(0);

	this->iter_num_label_->setText("");
	this->error_label_->setText("");
	this->matrix_label_->setText("");

	this->enableAllActions();

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

	this->mesh_processing_data_model_->combined_mesh_->GetCellData()->SetScalars(nullptr);
	this->mesh_processing_data_model_->actor_vec_[this->mesh_processing_data_model_->segment_id]->GetProperty()->SetColor(.0, .5, 1.);
	this->mesh_processing_data_model_->actor_vec_[this->mesh_processing_data_model_->segment_id]->GetMapper()->ScalarVisibilityOff();
	this->vtk_widget_->update();

	this->segment_scroll_area_->setVisible(false);
	this->resetParameters();
}

void MeshProcessing::OnSelectVertex(vtkIdType id) {
	if (id == -1) return;

	this->removeVertexActors();

	this->mesh_processing_data_model_->selected_vertex_actor_ = this->vtk_widget_->highlightVertex(this->mesh_processing_data_model_->combined_mesh_, id);
	this->mesh_processing_data_model_->selected_vertex_actor_->GetProperty()->SetInterpolationToGouraud();
	this->mesh_processing_data_model_->selected_vertex_actor_->GetProperty()->SetColor(.8, .2, .2);

	auto neighborVertexIds = MeshOperation::getConnectedVertices(this->mesh_processing_data_model_->combined_mesh_, id);
	for (const auto & neighbor : neighborVertexIds) {
		this->mesh_processing_data_model_->neighbor_vertex_actor_vec_.push_back(this->vtk_widget_->highlightVertex(this->mesh_processing_data_model_->combined_mesh_, neighbor));
		this->mesh_processing_data_model_->neighbor_vertex_actor_vec_.back()->GetProperty()->SetInterpolationToGouraud();
		this->mesh_processing_data_model_->neighbor_vertex_actor_vec_.back()->GetProperty()->SetColor(.8, .8, .2);
	}

	auto neighborFaceIds = MeshOperation::getVertexConnectedFaces(this->mesh_processing_data_model_->combined_mesh_, id);
	for (const auto & neighbor : neighborFaceIds) {
		this->mesh_processing_data_model_->neighbor_face_actor_vec_.push_back(this->vtk_widget_->highlightFace(this->mesh_processing_data_model_->combined_mesh_, neighbor));
		this->mesh_processing_data_model_->neighbor_face_actor_vec_.back()->GetProperty()->SetColor(.8, .5, .2);
	}

	this->vtk_widget_->update();
}

void MeshProcessing::OnSelectFace(vtkIdType id) {
	if (id == -1) return;

	this->removeFaceActors();

	this->mesh_processing_data_model_->selected_face_actor_ = this->vtk_widget_->highlightFace(this->mesh_processing_data_model_->combined_mesh_, id);
	this->mesh_processing_data_model_->selected_face_actor_->GetProperty()->SetColor(.8, .2, .2);

	auto neighborFaceIds = MeshOperation::getFaceConnectedFaces(this->mesh_processing_data_model_->combined_mesh_, id);
	for (const auto & neighbor : neighborFaceIds) {
		this->mesh_processing_data_model_->neighbor_face2_actor_vec_.push_back(this->vtk_widget_->highlightFace(this->mesh_processing_data_model_->combined_mesh_, neighbor));
		this->mesh_processing_data_model_->neighbor_face2_actor_vec_.back()->GetProperty()->SetColor(.8, .8, .2);
	}

	this->mesh_processing_data_model_->selected_face_id_ = id;

	this->vtk_widget_->update();
}

void MeshProcessing::OnSelectMultiVertex(const std::vector<vtkIdType>& ids) {
	this->removeMultiVertexActors();

	this->mesh_processing_data_model_->selected_multi_vertex_set_.clear();
	for (const auto & id : ids) {
		this->mesh_processing_data_model_->selected_multi_vertex_actor_vec_.push_back(this->vtk_widget_->highlightVertex(this->mesh_processing_data_model_->combined_mesh_, id));
		this->mesh_processing_data_model_->selected_multi_vertex_actor_vec_.back()->GetProperty()->SetInterpolationToGouraud();
		this->mesh_processing_data_model_->selected_multi_vertex_actor_vec_.back()->GetProperty()->SetColor(.8, .2, .2);

		this->mesh_processing_data_model_->selected_multi_vertex_set_.insert(id);
	}

	this->vtk_widget_->update();
}

void MeshProcessing::resetParameters() {
	vtkSmartPointer<vtkAppendPolyData> appendFilter =
		vtkSmartPointer<vtkAppendPolyData>::New();
	int cnt = 0;
	int num_edges = 0;
	for (int i = 0; i < this->mesh_processing_data_model_->highlight_vec_.size(); ++i) {
		if (this->mesh_processing_data_model_->highlight_vec_[i]) {
			appendFilter->AddInputData(this->mesh_processing_data_model_->mesh_vec_[i]);
			num_edges += this->mesh_processing_data_model_->mesh_edge_vec_[i]->GetNumberOfLines();
			++cnt;
		}
	}
	if (cnt > 0) {
		appendFilter->Update();
		this->mesh_processing_data_model_->combined_mesh_ =
			vtkSmartPointer<vtkPolyData>::New();
		this->mesh_processing_data_model_->combined_mesh_->DeepCopy(appendFilter->GetOutput());

		vtkSmartPointer<vtkIdTypeArray> numberScalarArray =
			vtkSmartPointer<vtkIdTypeArray>::New();
		numberScalarArray->SetNumberOfComponents(1);
		numberScalarArray->SetName("number");
		numberScalarArray->SetNumberOfValues(this->mesh_processing_data_model_->combined_mesh_->GetNumberOfPoints());
		for (int i = 0; i < this->mesh_processing_data_model_->combined_mesh_->GetNumberOfPoints(); ++i)
			numberScalarArray->SetValue(i, i);

		this->mesh_processing_data_model_->combined_mesh_->GetPointData()->AddArray(numberScalarArray);

		int edge_count = 0;
		this->mesh_processing_data_model_->mean_edge_length = 0.0;
		for (int i = 0; i < this->mesh_processing_data_model_->highlight_vec_.size(); ++i) {
			if (this->mesh_processing_data_model_->highlight_vec_[i]) {
				this->mesh_processing_data_model_->mean_edge_length +=
					this->mesh_processing_data_model_->mesh_edge_vec_[i]->GetNumberOfLines() * this->mesh_processing_data_model_->mean_edge_length_vec_[i];
				edge_count += this->mesh_processing_data_model_->mesh_edge_vec_[i]->GetNumberOfLines();
			}
		}
		this->mesh_processing_data_model_->mean_edge_length /= edge_count;

		this->vtk_widget_->updateBottomText(
			this->mesh_processing_data_model_->combined_mesh_->GetNumberOfPoints(),
			this->mesh_processing_data_model_->combined_mesh_->GetNumberOfCells(),
			num_edges
		);
	} else {
		this->mesh_processing_data_model_->combined_mesh_ = nullptr;
		this->mesh_processing_data_model_->mean_edge_length = 0.0;
		this->vtk_widget_->updateBottomText(
			0, 0, 0
		);
	}
}

3. Running results

face selection 

normal display 

 multiple selection

Registration 

3. Online assistance:

If you need to install the operating environment or remote debugging, see the personal QQ business card at the bottom of the article, and professional and technical personnel will assist remotely!
1) Remote installation and operation environment, code debugging
2) Qt, C++, Python entry guide
3) Interface beautification
4) Software production

Current article link: Python+Qt desktop and webpage human customer service communication tool_alicema1111's blog-CSDN blog

Blogger recommended article: python face recognition statistics qt form - CSDN Blog

Blogger recommended article: Python Yolov5 flame smoke recognition source code sharing - CSDN blog

                         Python OpenCV recognizes the number of people entering and exiting the pedestrian entrance - python recognizes the number of people - CSDN Blog

Personal blog homepage: alicema1111's blog_CSDN blog-Python, C++, bloggers in the field of web pages

Click here for all the blogger's articles : alicema1111's blog_CSDN blog-Python, C++, bloggers in the field of web pages

Guess you like

Origin blog.csdn.net/alicema1111/article/details/131353207