Using (custom) properties

xx.xx·2023년 8월 28일
2

오픈매쉬

목록 보기
3/5

open mesh

Using (custom) properties


이전 포스팅에서 정점의 이웃한 정점들의 무게중심을 계산하고 이를 배열에 저장하였다. 이 데이터를 메시에 저장하고 openMesh가 데이터를 관리할 수 있도록 하면 더욱 편리하고 오류가 줄어들 것이다. 따라서 이러한 속성을 메쉬에 동적으로 넣는 것을 목표로 한다.

OpenMesh는 각 메시 개체(정점, 면, 가장자리, 절반 가장자리 및 메시 자체)에 연결할 수 있는 동적 속성을 제공한다.

add_property 메소드를 사용하여 정점 속성을 메쉬에 추가한다.

OpenMesh::VPropHandleT<MyMesh::Point> cogs; //Vertex Property Handle Type
mesh.add_property(cogs);
for (vv_it=mesh.vv_iter( *v_it ); vv_it; ++vv_it)
      {
        mesh.property(cogs,*v_it) += mesh.point( *vv_it );
        ++valence;
      }
      mesh.property(cogs,*v_it) /= valence;
      
.
.
mesh.set_point( *v_it, mesh.property(cogs,*v_it) );

마지막 줄 mesh.set_point( v_it, mesh.property(cogs,v_it) ); 는 해당 정점의 위치를 cogs 속성으로 설정된 값으로 변경하는 작업을 수행한다

full code

#include <iostream>
#include <vector>
// --------------------
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
typedef OpenMesh::TriMesh_ArrayKernelT<>  MyMesh;
int main(int argc, char **argv)
{
  MyMesh  mesh;
  // check command line options
  if (argc != 4) 
  {
    std::cerr << "Usage:  " << argv[0] << " #iterations infile outfile\n";
    return 1;
  }
  // read mesh from stdin
  if ( ! OpenMesh::IO::read_mesh(mesh, argv[2]) )
  {
     std::cerr << "Error: Cannot read mesh from " << argv[2] << std::endl;
     return 1;
  }
  // this vertex property stores the computed centers of gravity
  OpenMesh::VPropHandleT<MyMesh::Point> cogs;
  mesh.add_property(cogs);
  // smoothing mesh argv[1] times
  MyMesh::VertexIter          v_it, v_end(mesh.vertices_end());
  MyMesh::VertexVertexIter    vv_it;
  MyMesh::Point               cog;
  MyMesh::Scalar              valence;
  unsigned int                i, N(atoi(argv[1]));
  
  for (i=0; i < N; ++i)
  {
    for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it)
    {      
      mesh.property(cogs,*v_it).vectorize(0.0f);
      valence = 0.0;
      
      for (vv_it=mesh.vv_iter( *v_it ); vv_it; ++vv_it)
      {
        mesh.property(cogs,*v_it) += mesh.point( *vv_it );
        ++valence;
      }
      mesh.property(cogs,*v_it) /= valence;
    }
    
    for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it)
      if ( !mesh.is_boundary( *v_it ) )
        mesh.set_point( *v_it, mesh.property(cogs,*v_it) );
  }
  // write mesh to stdout
  if ( ! OpenMesh::IO::write_mesh(mesh, argv[3]) )
  {
    std::cerr << "Error: cannot write mesh to " << argv[3] << std::endl;
    return 1;
  }
  return 0;
}

작성 중인 프로젝트에 함수로 넣은 코드 (나중에 참고용...)

void addProperty(MyMesh& mesh, MyMesh::VertexIter v_it, MyMesh::VertexVertexIter vv_it, MyMesh::VertexIter v_end, OpenMesh::VPropHandleT<MyMesh::Point> cogs, MyMesh::Scalar valence) {
	
	// 메쉬의 모든 정점을 반복하면서, 각 정점에 대한 중심점 속성을 초기화하고 이웃 정점들의 위치를 누적하여 중심점을 계산
	for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) {
		mesh.property(cogs, *v_it).vectorize(0.0f); //속성 부분 초기화
		valence = 0.0;
		for (vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) {
			mesh.property(cogs, *v_it) += mesh.point(*vv_it); //중심점 누적하고
			++valence;
		}
		mesh.property(cogs, *v_it) /= valence;
	}
	for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) {
		if (!mesh.is_boundary(*v_it)) //경계 부분 제외하고 돌면서
			mesh.set_point(*v_it, mesh.property(cogs, *v_it));
	}
	//속성 출력 부분
	for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) {
		MyMesh::Point cog = mesh.property(cogs, *v_it);
		std::cout << "Vertex " << *v_it << " COG: (" << cog[0] << ", " << cog[1] << ", " << cog[2] << ")" << std::endl;
	}
}

0개의 댓글