Open Mesh
Using STL algorithms
STL for_each구문을 사용하는 방법을 보여준다.
STL 구문은 손으로 작성한 루프보다 읽기 쉽고 효율적일 수 있기 때문이다.
SmootherT 클래스에는 두 개의 함수가 있습니다. 하나는 주어진 정점에 대한 무게 중심을 계산하는 함수이고, 다른 하나는 정점 위치를 해당 무게 중심으로 설정하는 함수다.
다음은 함수 객체(operator())를 정의하는 것으로, 이 함수 객체는 OpenMesh의 Vertex Handle에 대해 중심점을 계산하고 해당 속성을 설정하는 역할을 수행한다.
void operator()(const typename Mesh::VertexHandle& _vh)
{
typename Mesh::VertexVertexIter vv_it; // 이웃 정점 반복자
typename Mesh::Scalar valence(0.0); // 인접 정점 수를 나타내는 변수
mesh_.property(cog_, _vh) = typename Mesh::Point(0.0, 0.0, 0.0); // 중심점 속성 초기화
for (vv_it = mesh_.vv_iter(_vh); vv_it.is_valid(); ++vv_it)
{
mesh_.property(cog_, _vh) += mesh_.point(*vv_it); // 이웃 정점 위치 누적
++valence; // 인접 정점 수 증가
}
mesh_.property(cog_, _vh) /= valence; // 중심점 계산 및 속성 설정
}
full code
template <class Mesh>
class SmootherT
{
public:
typedef typename Mesh::Point cog_t;
typedef OpenMesh::VPropHandleT< cog_t > Property_cog;
public:
explicit SmootherT(Mesh& _mesh) : mesh_(_mesh)
{
mesh_.add_property(cog_);
}
~SmootherT()
{
mesh_.remove_property(cog_);
}
void smooth(unsigned int _iterations)
{
for (unsigned int i = 0; i < _iterations; ++i)
{
for_each(mesh_.vertices_begin(), mesh_.vertices_end(), ComputeCOG(mesh_, cog_));
for_each(mesh_.vertices_begin(), mesh_.vertices_end(), SetCOG(mesh_, cog_));
}
}
private:
class ComputeCOG
{
public:
ComputeCOG(Mesh& _mesh, Property_cog& _cog) : mesh_(_mesh), cog_(_cog)
{}
void operator()(const typename Mesh::VertexHandle& _vh)
{
typename Mesh::VertexVertexIter vv_it;
typename Mesh::Scalar valence(0.0);
cog_[_vh] = typename Mesh::Point(0.0, 0.0, 0.0);
for (vv_it = mesh_.vv_iter(_vh); vv_it.is_valid(); ++vv_it)
{
cog_[_vh] += mesh_.point(*vv_it);
++valence;
}
cog_[_vh] /= valence;
}
private:
Mesh& mesh_;
Property_cog& cog_;
};
class SetCOG
{
public:
SetCOG(Mesh& _mesh, Property_cog& _cog) : mesh_(_mesh), cog_(_cog) {}
void operator()(const typename Mesh::VertexHandle& _vh)
{
if (!mesh_.is_boundary(_vh))
mesh_.set_point(_vh, cog_[_vh]);
}
private:
Mesh& mesh_;
Property_cog& cog_;
};
private:
Mesh& mesh_;
Property_cog cog_;
};
foreach(mesh.verticesbegin(), mesh.verticesend(), ComputeCOG(mesh, cog_));
for_each를 처음 봐서 for와 다른 점이 뭐지? 했는데
for_each는 주로 범위 내요소에 대해 특정 동작을 적용하는 것이다.
for_each(start_iter, end_iter, function_or_function_object);
for (initialization; condition; update)
하지만 생성자에 아무것도 구현하지 않고 operator를 추가로 구현한 이유를... 잘 모르겠음... ㅜㅜ
.....흠...................
SmootherT 클래스는 메시를 입력으로 받아 그 메시의 정점들을 부드럽게 조정하는 기능을 제공하며, 내부적으로 ComputeCOG와 SetCOG 클래스를 사용하여 스무딩 작업을 구현한다는데 잘... 와닿지는 않음.
다시 공부하기...