利用泊松变形实现平面浅浮雕生成

本文介绍了利用泊松变形方法生成平面浅浮雕的过程,涉及泊松等式、数值求解和线性压缩等步骤。通过参考论文,详细阐述了预处理、泊松方程的数学原理及其在网格变形中的应用,最终实现模型的浅浮雕效果。在实现过程中,作者指出了使用pmp-library库遇到的问题,并分享了完整的代码链接。
摘要由CSDN通过智能技术生成

利用泊松变形实现平面浅浮雕生成

**参考论文:**Zhang Y W , Zhou Y Q , Li X L , et al. Bas-Relief Generation and Shape Editing through Gradient-Based Mesh Deformation[J]. IEEE Transactions on Visualization and Computer Graphics, 2015, 21(3):328-338.

这篇论文主要利用通过求解泊松方程来实现浅浮雕的生成,这是我读研以来实现的第二篇论文,实现的过程中由于数学知识的不足还是遇到了不少的障碍。

准备

  1. pmp-library :该类库提供了简便的三角形网格框架,除了基本的三角形网格数据结构之外,还提供了许多网格处理有关的算法,如网格简化、remesh等,我在体验之后感到的缺点主要是虽然该库的矩阵系统是基于Eigen的,但是他的矩阵与Eigen的并不兼容,并且他提供的矩阵初始化很麻烦,我在github上和作者反映了这个问题,他说今后会考虑将矩阵系统整个换成Eigen的。
  2. Eigen:十分有名的C++类库了,提供可线性代数,矩阵和矢量运算以及数值分析等算法。

预处理阶段

  1. 准备一个三角形网格模型

  2. 将其放入maya中进行编辑,如图所示

在这里插入图片描述

图1:网格模型

​ 随后手动编辑取一半作为输入,如图所示
在这里插入图片描述

图2:浅浮雕输入
  1. 在代码中调用pmp中提供的remesh方法对网格进行remesh,remesh的参数取网格的平均边长

    /**
     * remesh,取网格的平均边长作为参数
     * @param mesh
     * @return
     */
    Scalar remeshing(SurfaceMesh &mesh) {
        cout << "正在进行remesh" << endl;
        SurfaceRemeshing remesh(mesh);
        Scalar avg_scalar = 0;
        for (auto e : mesh.edges()) {
            avg_scalar += mesh.edge_length(e);
        }
        avg_scalar /= mesh.n_edges();
        cout << "average edge length = " << avg_scalar << endl;
        remesh.uniform_remeshing(avg_scalar);
        cout << "remesh完成" << endl;
        cout << "vertices:" << mesh.n_vertices() << ", edges:" << mesh.n_edges() << ", faces:" << mesh.n_faces()
             << endl;
        return avg_scalar;
    }
    
  2. 网格简化,调用pmp的网格简化算法,将面片数大于一定值的网格进行简化

    /**
     * 简化网格,当三角形面片数量大于门限值时对网格进行简化
     * @param mesh
     * @param avg_scalar
     * @return
     */
    int simplification(SurfaceMesh &mesh, const Scalar avg_scalar) {
        cout << "正在进行simplification" << endl;
        SurfaceSimplification simplification1(mesh);
        simplification1.initialize(5, avg_scalar, 10, 10, 0.001);
        int n = mesh.n_vertices() <= 10e3 ? mesh.n_vertices() : 5e3 + mesh.n_vertices() / 2;
        cout << "simplify之后的顶点数量为:" << n << endl;
        simplification1.simplify(n);
        cout << "simplify完成" << endl;
        cout << "vertices:" << mesh.n_vertices() << ", edges:" << mesh.n_edges() << ", faces:" << mesh.n_faces()
             << endl;
        return 0;
    }
    

利用泊松变形(Poison Deformation)生成浅浮雕

泊松等式

具有狄利克雷条件的泊松等式定义如(1)式:
(1) ∇ 2 f = ∇ ⋅ w ,   f ∣ ∂ Ω = f ∗ ∣ ∂ Ω \nabla^2f=\nabla \cdot \boldsymbol{w}, \ f|_{\partial\Omega} = f^*|_{\partial\Omega} \tag{1} 2f=w, fΩ=fΩ(1)
其中 f f f是一个未知的标量函数, w \boldsymbol w w是一个梯度矢量场, f ∗ f^* f为边界约束, ∇ 2 \nabla^2 2为拉普拉斯算子,即梯度的散度,而 ∇ ⋅ w \nabla \cdot \boldsymbol{w} w 为梯度矢量场 w = ( w x , w y , w z ) \boldsymbol w = (w_x,w_y,w_z) w=(wx,wy,wz)的散度,泊松等式的意义在于,一个网格的拉普拉斯坐标值等于其网格面片的梯度场的散度,也就是说我们可以通过操纵网格的梯度场反过来去求出对应网格顶点的位置从而达到变形的目的。表示成矩阵形式就是:
(2) L x = b Lx = b \tag{2} Lx=b(2)
其中L为三角形网格的拉普拉斯矩阵,可以通过下式求得:
(3) L i j = { ∑ ( i , k ) ∈ E w i k i = j − w i j ( i , j ) ∈ E

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值