参考论文: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;
}
散度图的证明: