首页 > 代码库 > 基于泊松方程的网格变形算法实现

基于泊松方程的网格变形算法实现

参考论文Mesh Editing withPoisson-Based Gradient Field Manipulation. Yi ZhouYu, KunZhou
需要源代码请联系我:duzjqhu@aliyun.com,发邮件的时候请说清楚三件事:你是谁? 你来自哪里? 用代码做什么?
 
实验效果:

基于泊松方程的网格变形算法实现基于泊松方程的网格变形算法实现



基于泊松方程的网格变形算法实现基于泊松方程的网格变形算法实现
基于泊松方程的网格变形算法实现
基于泊松方程的网格变形算法实现
这篇文章是发在SIGGRAPH2004上的,至今引用次数400+,可以说是几何处理领域一篇比较不错的文章,2003年PPére等人发了一篇关于图像处理的文章:Poisson ImageEditing,这篇文章的引用次数至今已经1000+!这篇文章就是将poisson图像处理的方法扩展到三维的几何处理。说来惭愧,花了一个月时间才实现了这篇论文,实现文章的时候给几位作者都发信问过一些细节,但是都没有回复。在实现论文的过程中,计算机系的LinGao博士给我提供了一些必要的帮助,特此感谢!
 
文章基于poisson方程,将整个网格当做一个标量场,该网格对应的梯度场作为变形指引场。通过改变三个网格对应的梯度场驱动变形。
Ax = b, A:网格对应的拉普拉斯坐标 b:三角网格的散度
1.拉普拉斯采用cot权
基于泊松方程的网格变形算法实现
核心代码:
doubleMeshBasicComputer::ComputeLaplaceWeight(Point3D v,Point3Dvleft,Point3D vmid,Point3D vright)
{
Vector3D l_v = v -vleft;
Vector3D l_m = vmid -vleft;
Vector3D r_v = v -vright;
Vector3D r_m = vmid -vright;
 
double cot1 =(l_v*l_m)/((l_v^l_m).mf_getLength());
double cot2 =(r_v*r_m)/((r_v^r_m).mf_getLength());
 
double result =0.5*(cot1+cot2);
return result;
}
 
2.散度计算
基于泊松方程的网格变形算法实现
w(T)指的是三角形T的梯度,计算如下:左图是某个具体的三角形的散度,经上式加和之后等同于右图的计算
 
基于泊松方程的网格变形算法实现
散度计算核心代码:
Vector3D PoissonDeformation::ComputeTriangleDiv(constPoint3D& source,const Point3D& vleft,const Point3D&vright,int v,int l,int r)
{
Vector3D s_l = source - vleft;
Vector3D s_r = source - vright;
Vector3D l_s = s_l*(-1);
Vector3D l_r = vleft - vright;
Vector3D r_s = s_r*(-1);
Vector3D r_l = vright - vleft;
 
//▽ΦiT
Vector3D ha = SimpleCompute::GetTriangleHeightVector(s_l,s_r);
Vector3D hb = SimpleCompute::GetTriangleHeightVector(l_r,l_s);
Vector3D hc = SimpleCompute::GetTriangleHeightVector(r_s,r_l);
 
//some vertex drop in fixedregion
if(!m_isFreeVertex[l]) l_s =Vector3D(source.m_x,source.m_y,source.m_z)*(-1);
if(!m_isFreeVertex[r]) r_s =Vector3D(source.m_x,source.m_y,source.m_z)*(-1);
 
//const vector field
Vector3D wx = hb*(l_s.m_x) + hc*(r_s.m_x);
Vector3D wy = hb*(l_s.m_y) + hc*(r_s.m_y);
Vector3D wz = hb*(l_s.m_z) + hc*(r_s.m_z);
 
//S△
double area =SimpleCompute::GetTriangleArea(source,vleft,vright);
 
//divergence
Vector3D div =Vector3D(wx*ha*area,wy*ha*area,wz*ha*area);
return div;
}
 
散度图的证明:
基于泊松方程的网格变形算法实现

 

基于泊松方程的网格变形算法实现