程序示例精選
VS+QT+VTK三維網(wǎng)格顯示-點面選擇-法線法向量顯示-配準(zhǔn)-分割窗體程序
如需安裝運行環(huán)境或遠(yuǎn)程調(diào)試,見文章底部個人QQ名片,由專業(yè)技術(shù)人員遠(yuǎn)程協(xié)助!
前言
這篇博客針對<<VS+QT+VTK三維網(wǎng)格顯示-點面選擇-法線法向量顯示-配準(zhǔn)-分割窗體程序>>編寫代碼,代碼整潔,規(guī)則,易讀。 學(xué)習(xí)與應(yīng)用推薦首選。
功能:讀取三維網(wǎng)格數(shù)據(jù),包括*.obj、*.stl、*.off,通過單擊網(wǎng)格表面高亮顯示單個頂點和多個頂點以及單個面和面法線,顯示帶/不帶線框的網(wǎng)格數(shù)據(jù),顯示點數(shù)、面數(shù)和邊數(shù),ICP算法與半自動分割算法的實現(xiàn)。
文章目錄
一、所需工具軟件
二、使用步驟
????????1. 引入庫
????????2. 代碼實現(xiàn)
? ? ? ? 3. 運行結(jié)果
三、在線協(xié)助
一、所需工具軟件
1. VS, Qt
2. VTK
二、使用步驟
1.引入庫
#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. 代碼實現(xiàn)
代碼如下:
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("請檢查目前讀入的網(wǎng)格數(shù)是否為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("請檢查目前讀入的網(wǎng)格數(shù)是否為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("請檢查目前選中的網(wǎng)格數(shù)是否為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("請檢查目前讀入的網(wǎng)格數(shù)是否為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. 運行結(jié)果
面選擇?
法線顯示?
?多點選擇
配準(zhǔn)?
三、在線協(xié)助:
如需安裝運行環(huán)境或遠(yuǎn)程調(diào)試,見文章底部個人 QQ 名片,由專業(yè)技術(shù)人員遠(yuǎn)程協(xié)助!
1)遠(yuǎn)程安裝運行環(huán)境,代碼調(diào)試
2)Qt, C++, Python入門指導(dǎo)
3)界面美化
4)軟件制作
當(dāng)前文章連接:Python+Qt桌面端與網(wǎng)頁端人工客服溝通工具_(dá)alicema1111的博客-CSDN博客
博主推薦文章:python人臉識別統(tǒng)計人數(shù)qt窗體-CSDN博客
博主推薦文章:Python Yolov5火焰煙霧識別源碼分享-CSDN博客
? ? ? ? ? ? ? ? ? ? ? ? ?Python OpenCV識別行人入口進出人數(shù)統(tǒng)計_python識別人數(shù)-CSDN博客
個人博客主頁:alicema1111的博客_CSDN博客-Python,C++,網(wǎng)頁領(lǐng)域博主文章來源:http://www.zghlxwxcb.cn/news/detail-498403.html
博主所有文章點這里:alicema1111的博客_CSDN博客-Python,C++,網(wǎng)頁領(lǐng)域博主文章來源地址http://www.zghlxwxcb.cn/news/detail-498403.html
到了這里,關(guān)于VS+QT+VTK三維網(wǎng)格顯示-點面選擇-法線法向量顯示-配準(zhǔn)-分割窗體程序的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!