C++

Mesh smoothing with cotangent weight

돼지표 2021. 10. 8. 19:06

각 Vertex에 대한 cotangent weight를 구하여 Laplace smooting를 적용해보자

Cotangent weight 방식 laplace smooting 공식

Vec3<double> v1 = pos - vertices[i]->neighbor_vertices[p_prev]->pos;
Vec3<double> v2 = vertices[i]->neighbor_vertices[j]->pos - vertices[i]->neighbor_vertices[p_prev]->pos;
Vec3<double> v3 = pos - vertices[i]->neighbor_vertices[p_next]->pos;
Vec3<double> v4 = vertices[i]->neighbor_vertices[j]->pos - vertices[i]->neighbor_vertices[p_next]->pos;
double cotan_a = (v1.Dot(v2)) / ( (v1.Cross(v2)).GetNorm());
double cotan_b = (v3.Dot(v4)) / ( (v3.Cross(v4)).GetNorm());
double weight = (cotan_a + cotan_b) * 0.5;


sum += vertices[i]->neighbor_vertices[j]->pos * weight;
N += weight;

Mesh의 모든 Vertex의 neighber vertex에 대해 Cotangent weight를 구한 뒤 sum vector에 더해준 뒤

weight의 총합인 N으로 나누어 주었다.

 

점점 사라지는 붓따씨..

 

smooting 작업을 진행 할 수록 Vertex가 사라지는 문제가 생겼다.

 

어머니..

Vertex가 타노스 당하는 이 문제를 해결하기 위해 다른 분들이 작성한 코드를 염탐해보았는데 전부 같은 방법으로 Weight를 구하거나 내가 이해할 수 없는 고등기술을 사용하지만 brainexcerpts라는 분이 작성한 weight를 구하는 방법을 살펴보자.

double cotan_a = (v1.Dot(v2)) / ( (v1.Cross(v2)).GetNorm());
double cotan_b = (v3.Dot(v4)) / ( (v3.Cross(v4)).GetNorm());

->

double cotan_a = (v1.Dot(v2)) / ( 1e-6 + (v1.Cross(v2)).GetNorm());
double cotan_b = (v3.Dot(v4)) / ( 1e-6 + (v3.Cross(v4)).GetNorm());

의 방식으로 부동소수점을 더한 뒤 나누기 연산을 해주어서 weight 값이 nan이 되는 것을 방지한다.

타노스를 막아냈다.

 

정상적으로 Cotangent Weight Smooting이 되는 것을 확인할 수 있다.