C++ OpenMesh拉普拉斯光顺平滑网格模型

news2024/11/29 22:42:46

程序示例精选

C++ OpenMesh拉普拉斯光顺平滑网格模型

如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助!

前言

这篇博客针对<<C++ OpenMesh拉普拉斯光顺平滑网格模型>>编写代码,代码整洁,规则,易读。 学习与应用推荐首选。


文章目录

一、所需工具软件

二、使用步骤

        1. 引入库

        2. 代码实现

        3. 运行结果

三、在线协助

一、所需工具软件

1. VS,Qt

2. OpenMesh

二、使用步骤

1.引入库

#include <iostream>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
typedef OpenMesh::PolyMesh_ArrayKernelT<> Mesh;

2. 代码实现

代码如下:


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 smooth_mesh(Mesh& mesh, const int iterations)
{
    for (int i = 0; i < iterations; ++i) // 迭代指定次数
    {
        Mesh::VertexIter v_it, v_end = mesh.vertices_end();
        for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it)
        {

            float n = 0.0f;
            for (Mesh::VertexVertexIter vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it)
            {
                p += mesh.point(*vit);
                ++n;
            }
            p /= n;
            mesh.set_point(*v_it);
        }
    }
}

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; // 光顺程度参数
    smooth_mesh(mesh, iterations);

    // 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();


}

3. 运行结果

三、在线协助:

如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Qt, C++, Python入门指导
3)界面美化
4)软件制作

博主推荐文章:python人脸识别统计人数qt窗体-CSDN博客

博主推荐文章:Python Yolov5火焰烟雾识别源码分享-CSDN博客

                         Python OpenCV识别行人入口进出人数统计_python识别人数-CSDN博客

个人博客主页:alicema1111的博客_CSDN博客-Python,C++,网页领域博主

博主所有文章点这里:alicema1111的博客_CSDN博客-Python,C++,网页领域博主

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/523653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HTML5系列】第一章 · HTML5新增语义化标签

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

面试题打卡30天-day28

1、什么是 Git 的 fork 命令&#xff1f;它和 clone 命令有什么区别&#xff1f; 回答一&#xff1a; 在 Git 中&#xff0c;fork 命令是指将其他用户的代码仓库完全复制一份到当前用户自己的账户下&#xff0c;成为一个新的独立代码仓库。与此相对&#xff0c;clone 命令是指…

【CNN】深度卷积神经网络(AlexNet)是什么?如何实现AlexNet?

系列文章目录 第二章 深度学习 CNN中的深度卷积神经网络&#xff08;AlexNet&#xff09; 目录 系列文章目录 文章目录 前言 一、深度卷积神经网络&#xff08;AlexNet&#xff09;是什么&#xff1f; 二、AlexNet的网络结构 三、实现AlexNet模型 总结 前言 本文主要是…

在autoDL上运行github的代码

大佬们的教程&#xff1a;(249条消息) AutoDL使用教程&#xff1a;1&#xff09;创建实例 2&#xff09;配置环境上传数据 3&#xff09;PyCharm2021.3专业版下载安装与远程连接完整步骤 4&#xff09;实时查看tensorboard曲线情况_孟孟单单的博客-CSDN博客 (227条消息) 「炼丹…

智能的本质人工智能与机器人领域的64个问题

以艾伦纽厄尔&#xff08;Allen Newell&#xff09;和赫伯特西蒙&#xff08;Herbert Simon&#xff09;为代表&#xff0c;他们基本上倾向于智能已经达到数理逻辑的最高形式&#xff0c;并将符号处理作为研究重点&#xff0c;他们共同发表了著名论文《逻辑理论家》&#xff08…

“灵光一现”的动态特征:EEG研究

导读 尤里卡效应(Eureka effect&#xff1b;灵光一现)是指突然解决问题的常见经验。在这里&#xff0c;本文以一种模式识别范式来研究这种效应&#xff0c;该范式要求在格式塔规则和先验知识的基础上分割复杂场景和识别物体。受试者必须在模糊的场景中检测物体&#xff0c;并通…

【刷题】栈与队列:滑动窗口的最大值

题目 首先先来看题目描述&#xff1a; 这是一道栈与队列相关的题&#xff0c;给定我们一个整型数组&#xff0c;有一个长度为k的滑动窗口&#xff0c;让我们计算每次窗口的最大值。 我们的想法可以是得到一队列数据结构&#xff0c;让进入这个队列的第一个数据一定是最大的&a…

使用无线传感器网络进行源定位(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 本文提出了一种用于反狙击应用的源定位过程&#xff1a;​使用广义互相关&#xff08;GCC&#xff09;方法确定到达时间差&…

uboot fatal error: configs/.h: No such file or directory 解决方法

环境 Win10 64位 ubuntu 20.04 虚拟机 VMware Workstation 16 Pro 开发板&#xff1a;NK-980IOT&#xff08;NUC980DK61Y&#xff09; gcc 交叉编译工具链&#xff1a; ARM 官方 gcc version 11.2.1 20220111 NUC980 uboot 版本 &#xff1a;尝试移植到 u-boot-2019.10&am…

【游戏逆向】《某山奇缘》发包函数

一个游戏我们拿来以后第一件事肯定是要去分析发包函数。 因为发包函数可以给我们很多有用的信息。 第一&#xff0c;所有的功能都可以通过发包实现。 第二&#xff0c;发包中的参数可以获悉游戏中的数据形式&#xff0c;例如某些参数是类型&#xff0c;ID是什么样的值。 第…

Java 中同步机制的几种方式及使用

在Java中&#xff0c;同步机制是用来解决多线程并发访问共享资源的问题。如果多个线程同时访问共享资源&#xff0c;可能会导致数据不一致、死锁等问题。Java中提供了多种同步机制&#xff0c;例如synchronized关键字、Lock接口、Semaphore类、CountDownLatch类等。本文将介绍J…

Vivado综合属性系列之二 SRL_STYLE

目录 一、前言 二、SRL_STYLE 2.1 移位寄存器实现方式 2.2 工程代码 2.3 参考资料 一、前言 移位寄存器SRL在工程中属于使用频率较高个模块&#xff0c;可用于存储数据&#xff0c;实现串并转换&#xff1b; 根据数据移动方向可分为左移寄存器&#xff0c;右移寄存器&#x…

Vue3-黑马(八)

目录&#xff1a; &#xff08;1&#xff09;vue3-进阶-antdv-分页 &#xff08;2&#xff09;vue3-进阶-antdv-搜索 &#xff08;3&#xff09;vue3-进阶-antdv-删除1 &#xff08;1&#xff09;vue3-进阶-antdv-分页 分页显示不对&#xff0c;修改下方分页条&#xff1a; …

Web 自动化笔记-第一章 Selenium 环境搭建

1.自动化测试能解决什么问题&#xff1f; 1. 解决-回归测试 2. 解决-压力测试 3. 解决-兼容性测试 4. 提高测试效率,保证产品质量 回归测试&#xff1a; 项目在发新版本之后对项目之前的功能进行验证 压力测试&#xff1a; 可以理解多用户同时去操作软件&#xff0c; 统计软件服…

近1500支队伍、6000名开发者齐聚,第三届Light技术公益创造营收官

在很多老年人看来&#xff0c;融入数字生活并不容易&#xff0c;经常误点广告、不时接到诈骗电话、不会操作智能手机……但有些老年人并不担心这些&#xff0c;“误点了付款&#xff0c;有人会打电话过来&#xff0c;提醒我不要被骗了。”一位老人放心地进行着“网上冲浪”。而…

Python程序员该如何提高薪资水平?我来谈谈实用的五大方法

今天我要跟小伙伴们讨论的话题是&#xff1a;Python程序员该如何提升自己的价值&#xff1f;换句话说&#xff0c;程序员该如何逐渐增加自己的薪资&#xff1f;我想这是大家都关心的一个问题。首先&#xff0c;我们要明确一点&#xff0c;程序员的价值所在是什么&#xff1f;关…

深度学习之图像分类(一):AlexNet

本专栏介绍基于深度学习进行图像识别的经典和前沿模型&#xff0c;将持续更新&#xff0c;包括不仅限于&#xff1a;AlexNet&#xff0c; ZFNet&#xff0c;VGG&#xff0c;GoogLeNet&#xff0c;ResNet&#xff0c;DenseNet&#xff0c;SENet&#xff0c;MobileNet&#xff0c…

var、let、const和执行上下文

let/const/var let 基本语法 ES6新增了let命令&#xff0c;用于声明变量&#xff0c;其语法类似于var&#xff0c;但是所声明的变量只在let命令所在的代码块内有效 不存在变量提升 var命令会发生“变量提升”现象&#xff0c;即变量可以在声明之前使用&#xff0c;值为und…

【部署jar包到服务器】

部署打好的jar包到服务器 首先需要安装对应版本的jdk 查看所有可安装的jdk版本 yum -y list java 选择对应的安装 例如 yum install -y java-1.8.0-openjdk-devel.x86_64 安装好之后&#xff0c;查看jdk版本 java -version 默认安装位置在 usr/lib/jvm之中 倘若你之前的版本不对…

引爆海外市场:ChatGPT带来定制化营销活动的奇迹

在定制一场海外营销活动时&#xff0c;需要首先了解海外市场和定制营销活动的关键是研究目标市场的文化和消费习惯。这包括但不限于&#xff1a; 目标市场的语言和文化背景当地消费者的购买习惯和偏好该领域的市场趋势和竞争情况目标市场的法律法规、行业标准和规范推广渠道和…