程序示例精选
C++ OpenMesh拉普拉斯光顺平滑网格模型2
如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助!
前言
这篇博客针对《C++ OpenMesh拉普拉斯光顺平滑网格模型2》编写代码,代码整洁,规则,易读。 学习与应用推荐首选。
文章目录
一、所需工具软件
二、使用步骤
1. 主要代码
2. 运行结果
三、在线协助
一、所需工具软件
1. VS, Qt
2. C++
二、使用步骤
代码如下(示例):
vtkSmartPointer<vtkPolyData> polyDataOut = vtkSmartPointer<vtkPolyData>::New();
namespace {
class MyCallback : public vtkCommand
{
public:
static MyCallback* New()
{
return new MyCallback;
}
MyCallback()
{
}
vtkNew<vtkPolyData> data;
virtual void Execute(vtkObject* caller, unsigned long, void*)
{
vtkContourWidget* contourWidget = reinterpret_cast<vtkContourWidget*>(caller);
vtkContourRepresentation* rep = static_cast<vtkContourRepresentation*>(contourWidget->GetRepresentation());
vtkContourRepresentationNode* node = rep->GetNthNode(rep->GetNumberOfNodes() - 1);
std::cout << "There are " << rep->GetNumberOfNodes() << " nodes." << std::endl;
int saveFile = rep->GetNumberOfNodes();
std::cout << "saveFile: " << saveFile << std::endl;
std::cout << "most recent node is " << std::to_string(node->WorldPosition[0]) << " " << std::to_string(node->WorldPosition[1]) << " " << std::to_string(node->WorldPosition[2]) << std::endl;
std::string valueData1 = std::to_string(node->WorldPosition[0]);
std::string valueData2 = std::to_string(node->WorldPosition[1]);
std::string valueData3 = std::to_string(node->WorldPosition[2]);
//QFile filetxt(QString::fromStdString("nodes"+saveFile.toStdString()+".txt"));
QFile filetxt(QString::fromStdString("nodes") + QString("%1").arg(saveFile) + QString::fromStdString((".txt")));
if (filetxt.open(QIODevice::WriteOnly))
{
QTextStream out(&filetxt);
//out << QString::fromStdString(valueData1)<<"," << QString::fromStdString(valueData2)<< "," << QString::fromStdString(valueData3);
out << QString::fromStdString(valueData1) << endl;
out << QString::fromStdString(valueData2) << endl;
out << QString::fromStdString(valueData3) << endl;
out.setCodec("UTF-8");
out.flush();
}
filetxt.close();
//save to nodesPointAll.txt
QFile filetxt2(QString::fromStdString("nodesPointAll.txt"));
if (filetxt2.open(QIODevice::WriteOnly | QIODevice::Append))
{
QTextStream out(&filetxt2);
//out << QString::fromStdString(valueData1)<<"," << QString::fromStdString(valueData2)<< "," << QString::fromStdString(valueData3);
out << QString::fromStdString(valueData1) << ", " << QString::fromStdString(valueData2) << ", " << QString::fromStdString(valueData3) << endl;
out.setCodec("UTF-8");
out.flush();
}
filetxt2.close();
rep->GetNodePolyData(data);
}
void SetSphereSource(vtkSmartPointer<vtkSphereSource> sphere)
{
this->SphereSource = sphere;
}
private:
vtkSmartPointer<vtkSphereSource> SphereSource;
};
class myInteractorStyle : public vtkInteractorStyleTrackballCamera
{
public:
static myInteractorStyle* New();
vtkTypeMacro(myInteractorStyle, vtkInteractorStyleTrackballCamera);
int pointNum = 0;
bool contourwidgetenabled = false;
vtkContourWidget* widget;
MyCallback* callback;
virtual void OnRightButtonDown() override
{
vtkInteractorStyleTrackballCamera::OnRightButtonDown();
}
void OnMiddleButtonDown() override {
if (contourwidgetenabled == false)
{
this->widget->EnabledOn();
contourwidgetenabled = true;
}
else
{
this->widget->EnabledOff();
contourwidgetenabled = false;
}
vtkInteractorStyleTrackballCamera::OnMiddleButtonDown();
}
void setContourWidget(vtkContourWidget* widget)
{
this->widget = widget;
}
void setPolyCallback(MyCallback* callback)
{
this->callback = callback;
}
};
vtkStandardNewMacro(myInteractorStyle);
} // namespace
//多格式文件打开定义
namespace {
vtkSmartPointer<vtkPolyData> ReadPolyData(const char* fileName)
{
vtkSmartPointer<vtkPolyData> polyData;
std::string extension =
vtksys::SystemTools::GetFilenameLastExtension(std::string(fileName));
// Drop the case of the extension
std::transform(extension.begin(), extension.end(), extension.begin(),
::tolower);
if (extension == ".ply")
{
vtkNew<vtkPLYReader> reader;
reader->SetFileName(fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".vtp")
{
vtkNew<vtkXMLPolyDataReader> reader;
reader->SetFileName(fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".obj")
{
vtkNew<vtkOBJReader> reader;
reader->SetFileName(fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".stl")
{
vtkNew<vtkSTLReader> reader;
reader->SetFileName(fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".vtk")
{
vtkNew<vtkPolyDataReader> reader;
reader->SetFileName(fileName);
reader->Update();
polyData = reader->GetOutput();
}
else
{
vtkNew<vtkSphereSource> source;
source->Update();
polyData = source->GetOutput();
}
return polyData;
}
}
vtkviewer2::vtkviewer2(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
QObject::connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(OnOpenFile()));
QObject::connect(ui.pushButton_2, SIGNAL(clicked()), this, SLOT(smooth()));
}
void vtkviewer2::IntialWindow()
{
//初始化窗口第一次打开时的颜色
vtkNew<vtkNamedColors> colors;
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderer->SetBackground(colors->GetColor3d("CadetBlue").GetData());
ui.qvtkWidget->SetRenderWindow(renderWindow);
ui.qvtkWidget->GetRenderWindow()->AddRenderer(renderer);
//初始化窗口第一次打开时的颜色_END
}
void vtkviewer2::OnOpenFile()
{
IntialWindow();
QString fileNamePath = QFileDialog::getOpenFileName(this, QString::fromLocal8Bit("打开文件"), "./model/", tr(" All_files(*.*)"));
QFileInfo fi = QFileInfo(fileNamePath);
QString fileName = fi.fileName();
QString fileSuffix = fi.suffix();
QString fileAbsolutePath = fi.absolutePath();
QString title = fileName.remove(".stl");
std::cout << "fileNamePath: " << fileNamePath.toStdString() << std::endl;
std::cout << "fileName: " << fileName.toStdString() << std::endl;
std::cout << "title: " << title.toStdString() << std::endl;
std::cout << "fileSuffix: " << fileSuffix.toStdString() << std::endl;
std::cout << "fileAbsolutePath: " << fileAbsolutePath.toStdString() << std::endl;
int controlPointsX = 5;
int controlPointsY = 5;
vtkNew<vtkNamedColors> colors;
vtkNew<vtkRenderWindowInteractor> contourWidgetinteractor;
vtkSmartPointer<vtkPolyDataMapper> bezierSurfacemapper = vtkSmartPointer<vtkPolyDataMapper>::New();
auto polyData = ReadPolyData(fileNamePath.toStdString().c_str());
polyDataOut->DeepCopy(polyData);
//vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
//reader->SetFileName(fileNamePath.toStdString().c_str());
//reader->Update();
//vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
//polyData->SetPoints(reader->GetOutput()->GetPoints());
//std::string saveFileName = "model/"+title.toStdString() +"Save.stl";
vtkSmartPointer<vtkPLYWriter> stlWriter = vtkSmartPointer<vtkPLYWriter>::New();
//stlWriter->SetFileName(saveFileName.c_str());
stlWriter->SetInputData(polyData);
stlWriter->SetFileName("temp/temp.ply");
//stlWriter->SetInputConnection(reader->GetOutputPort());
stlWriter->Write();
std::cout << "stlWriter sucessful " << std::endl;
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputData(polyData);
//mapper->SetInputConnection(reader->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());
actor->GetProperty()->SetOpacity(1);
// Create the RenderWindow, Renderer
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("PolygonalSurfacePointPlacer");
contourWidgetinteractor->SetRenderWindow(renderWindow);
renderer->AddActor(actor);
renderer->SetBackground(colors->GetColor3d("CadetBlue").GetData());
//display
ui.qvtkWidget->SetRenderWindow(renderWindow);
ui.qvtkWidget->GetRenderWindow()->AddRenderer(renderer);
//display-end
//mouse rotation
vtkNew<vtkContourWidget> contourWidget;
contourWidget->SetInteractor(contourWidgetinteractor);
//class defination
vtkNew<myInteractorStyle> contourWidgetinteractorstyle;
contourWidgetinteractorstyle->setContourWidget(contourWidget);
contourWidgetinteractor->SetInteractorStyle(contourWidgetinteractorstyle);
contourWidget->EnabledOff();
renderer->ResetCamera();
renderWindow->Render();
contourWidgetinteractor->Initialize();
contourWidgetinteractor->Start();
//mouse rotation-end
}
void vtkviewer2::smooth()
{
// Load mesh from file
std::string input_path = "temp/temp.ply";
Mesh mesh;
if (!OpenMesh::IO::read_mesh(mesh, input_path))
{
std::cerr << "Error: Cannot read mesh from " << input_path << std::endl;
return ;
}
// Smooth mesh
const int iterations = 10; // 光顺程度参数
// Save smoothed mesh to file
std::string output_path = "temp/tempSmooth.ply";
if (!OpenMesh::IO::write_mesh(mesh, output_path))
{
std::cerr << "Error: Cannot write mesh to " << output_path << std::endl;
return ;
}
//显示
IntialWindow();
int controlPointsX = 5;
int controlPointsY = 5;
vtkNew<vtkNamedColors> colors;
vtkNew<vtkRenderWindowInteractor> contourWidgetinteractor;
vtkSmartPointer<vtkPolyDataMapper> bezierSurfacemapper = vtkSmartPointer<vtkPolyDataMapper>::New();
auto polyData = ReadPolyData("temp/tempSmooth.ply");
polyDataOut->DeepCopy(polyData);
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputData(polyData);
//mapper->SetInputConnection(reader->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->GetProperty()->SetColor(colors->GetColor3d("MistyRose").GetData());
actor->GetProperty()->SetOpacity(1);
// Create the RenderWindow, Renderer
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer);
renderWindow->SetWindowName("PolygonalSurfacePointPlacer");
contourWidgetinteractor->SetRenderWindow(renderWindow);
renderer->AddActor(actor);
renderer->SetBackground(colors->GetColor3d("CadetBlue").GetData());
//display
ui.qvtkWidget->SetRenderWindow(renderWindow);
ui.qvtkWidget->GetRenderWindow()->AddRenderer(renderer);
//display-end
//mouse rotation
vtkNew<vtkContourWidget> contourWidget;
contourWidget->SetInteractor(contourWidgetinteractor);
//class defination
vtkNew<myInteractorStyle> contourWidgetinteractorstyle;
contourWidgetinteractorstyle->setContourWidget(contourWidget);
contourWidgetinteractor->SetInteractorStyle(contourWidgetinteractorstyle);
contourWidget->EnabledOff();
renderer->ResetCamera();
renderWindow->Render();
contourWidgetinteractor->Initialize();
contourWidgetinteractor->Start();
}
运行结果
三、在线协助:
如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Visual Studio, Qt, C++, Python编程语言入门指导
3)界面美化
4)软件制作
5)云服务器申请
6)网站制作
当前文章连接:https://blog.csdn.net/alicema1111/article/details/132666851
个人博客主页:https://blog.csdn.net/alicema1111?type=blog
博主所有文章点这里:https://blog.csdn.net/alicema1111?type=blog
博主推荐:
Python人脸识别考勤打卡系统:
https://blog.csdn.net/alicema1111/article/details/133434445
Python果树水果识别:https://blog.csdn.net/alicema1111/article/details/130862842
Python+Yolov8+Deepsort入口人流量统计:https://blog.csdn.net/alicema1111/article/details/130454430
Python+Qt人脸识别门禁管理系统:https://blog.csdn.net/alicema1111/article/details/130353433
Python+Qt指纹录入识别考勤系统:https://blog.csdn.net/alicema1111/article/details/129338432
Python Yolov5火焰烟雾识别源码分享:https://blog.csdn.net/alicema1111/article/details/128420453
Python+Yolov8路面桥梁墙体裂缝识别:https://blog.csdn.net/alicema1111/article/details/133434445
Python+Yolov5道路障碍物识别:https://blog.csdn.net/alicema1111/article/details/129589741
Python+Yolov5跌倒检测 摔倒检测 人物目标行为 人体特征识别:https://blog.csdn.net/alicema1111/article/details/129272048