PMP 라이브러리 Half Edge 테스트

폴리곤 메시 처리 라이브러리중 PMP 라이브러리가 있음..

https://www.pmp-library.org/

OpenMesh 와 비교하여 비교적 심플한 사용법과..상당히 구조적으로 잘 짜여져 있음..
근데 사실.. half edge 의 특성상 half edge 한개가 2개 이상의 face를 공유할수 없는 문제로..
실제 mesh 편집 프로그램에서는 사용하기가 어렵다..

예를 들어 Solid 메시는 한개의 half edge를 두고 2개 이상을 공유해야 하는 문제가 허다하고..
shell 메세중.. 2개이상을 지원해야 하는 경우도 종종있다..

암튼.. 난 이런 사실을 모른체.. 이걸 써야겠다하고.. 맘먹고 테스트해본 코드임..
그냥 이런 라이브러리가 있구나.. 하는 정도만.. 기억할것임.
지금은 직접 만들어 쓰고 있다..

#include <SurfaceMesh.h>

int main(void)
{
	pmp::SurfaceMesh mesh;

	pmp::Vertex v0,v1,v2,v3;

    // add 4 vertices
    v0 = mesh.add_vertex(pmp::Point(0,0,0));
    v1 = mesh.add_vertex(pmp::Point(1,0,0));
    v2 = mesh.add_vertex(pmp::Point(0,1,0));
    v3 = mesh.add_vertex(pmp::Point(0,0,1));

	// temp 노드 셋팅
	pmp::VertexProperty<bool> vtmp;
    vtmp = mesh.add_vertex_property<bool>("v:temp", false);
	vtmp[v0] = true;
	vtmp[v2] = true;
	
	// solver id 셋팅
	pmp::VertexProperty<unsigned int> vsolver;
    vsolver = mesh.add_vertex_property<unsigned int>("v:solver");
	vsolver[v0] = 100;
	vsolver[v1] = 101;
	vsolver[v2] = 102;
	vsolver[v3] = 103;
    //mesh.remove_vertex_property(vsolver);

    auto points = mesh.get_vertex_property<bool>("v:temp");

    for (auto v : mesh.vertices())
    {
        if ( points[v] ) {
			printf("%d : temp node, solver id: %d\n", v.idx(), vsolver[v]);
		} else {
			printf("%d : node, solver id: %d\n", v.idx(), vsolver[v]);
		}
    }

    // add 4 triangular faces
	pmp::Face f0 = mesh.add_triangle(v0,v1,v3);
    mesh.add_triangle(v1,v2,v3);
    mesh.add_triangle(v2,v0,v3);
    mesh.add_triangle(v0,v2,v1);
	
	// face에 대한 solver id 셋팅
	pmp::FaceProperty<unsigned int> fsolver;
    fsolver = mesh.add_face_property<unsigned int>("f:solver");
	fsolver[f0] = 10000;
	
	// face에 대한 part id 셋팅
	pmp::FaceProperty<unsigned int> fpart;
    fpart = mesh.add_face_property<unsigned int>("f:part");
	fpart[f0] = 1001;

	// part 1001 번에 대한 opengl 출력용 tri indices
	std::map<unsigned int, std::vector<unsigned int>> indices;
	std::map<pmp::Face, unsigned int> offset;
	offset[f0].push_back(indices[1001].size());
	indices[1001].push_back(v0.idx());
	indices[1001].push_back(v1.idx());
	indices[1001].push_back(v3.idx());
	offset[f1].push_back(indices[1001].size());
	indices[1001].push_back(v1.idx());
	indices[1001].push_back(v2.idx());
	indices[1001].push_back(v3.idx());

    std::cout << "vertices: " << mesh.n_vertices() << std::endl;
    std::cout << "edges: "    << mesh.n_edges()    << std::endl;
    std::cout << "faces: "    << mesh.n_faces()    << std::endl;
}

‘좋은 Mesh’에 대한 5가지 오해

출처: https://support.functionbay.com/ko/technical-tip/single/33/%EC%A2%8B%EC%9D%80-mesh%EC%97%90-%EB%8C%80%ED%95%9C-5%EA%B0%80%EC%A7%80-%EC%A3%BC%EC%9A%94-%EC%98%A4%ED%95%B4

#1. 좋은 mesh는 CAD형상에 가까운 형상이어야 한다. (Good mesh must follow CAD model well.)
좋은 mesh는 CAD형상에 가까워야 하는 것이 아니라, 물리 문제를 풀 수 있어야 한다.
너무 세세한 부분은 해석에 필요하지 않으며 해석에 불필요한 영향을 끼칠 뿐이다.
따라서 좋은 Mesh는 CAD모델을 단순화하고 물리적인 요소에 기반하여 노드가 위치해야 한다.

예를 들어, 시뮬레이션에 별 영향을 주지 않는 구멍이나, 필렛(Fillet)을 비롯한 형상은 Mesh생성에 오히려 악영향을 줄 수 있다.
이러한 불필요한 형상 데이터를 단순화한 후 Mesh를 하면 좋다.
RecurDyn에서는 이를 위해 Delete Face, Delete Edge 등의 기능을 이용하여 불필요한 형상을 제거한 후 Mesh를 할 수 있게 해준다.

#2. 좋은 mesh는 언제나 좋다. (Good mesh is always good.)
많은 CAE 사용자들은 고품질의 mesh를 얻기 위해 meshing size를 변경하고, 형상을 나누고, mesh quality 체크 기능을 이용하여 품질을 확인한다.
이는 필요한 과정이지만, 과해서는 안된다.

예를 들어, 에어포일 주변의 유동과 힘을 완벽하게 계산할 수 있는 좋은 mesh를 생성했다고 하자.
그리고 만일 Attack angle을 0도에서 45도로 변경한다고 하면 동일한 mesh가 여전히 좋은 mesh라고 할 수 있는가? 그렇지 않을 것이다.

경계조건을 바꾸거나, 하중 조건을 바꾸거나, 해석 타입을 바꾸거나, 유동 모델을 바꾸게 되면 좋은 mesh가 안좋은 mesh가 될 수도 있다.

#3. 6면체(Hexa) 요소가 4면체(Tetra)요소보다 항상 좋다. (Hexahedron is always better than tetrahedron.)
대부분의 오래된 교과서에서는 hexa (quad) mesh가 tetra (tri) 보다 좋다고 이야기한다. 그리고 tetra (tri) 요소를 쓰면 더 큰 수치 에러가 발생할 수 있다는 것을 보여준다.
15~20년 전에는 이것이 참이었을 수도 있지만, 지금은 대부분의 경우 Hexa mesh에 장점이 없다.
tetra가 여전히 더 많은 계산 리소스를 사용하지만, 대신 mesh 생성 시간 절감을 통해 보상받을 수 있다.

대부분의 FEA, CFD 사용자에게 있어서, 만일 형상이 다소 복잡하다면, hexa mesh는 단순히 시간 낭비일 수 있다.

#4. auto-mesh로는 좋은 mesh를 생성할 수 없다. (Good mesh can only not be generated by automatic meshing.)
매일 소프트웨어를 사용하고, 수년간 비슷한 형상으로 작업을 하는 능숙한 사용자들의 경우에는 수작업을 활용한 Mesh생성이 유리할 수 있지만,
대부분의 비숙련 사용자들에게는 auto-mesh로도 상당히 좋은 품질의 mesh를 생성할 수 있다.

#5. 좋은 mesh는 cell과 node 수가 많아야 한다. ( Good mesh must have a large cell/node count.)
HPC에 대한 접근이 용이해지면서 학생들조차도 1천만~2천만개의 요소짜리 CFD 문제를 풀려고 한다. 대부분의 CAE사용자들의 눈에는 많은 수의 요소는 곧 높은 신뢰도를 의미하며 모든 물리 문제를 풀 수 있을 것처럼 보인다.
하지만 조밀한 mesh가 항상 좋은 mesh를 의미하진 않는다. mesh의 목적은 이상화된 위치에서 결과를 얻는 것이다. 좋은 mesh는 목적에 부합하는 mesh이다. 따라서 결과가 물리적으로 옳고, 목적에 맞는 정확도를 보여준다면 사용된 mesh는 충분히 좋다고 할 수 있다.
오히려 조밀한 mesh가 해석결과를 나쁘게 만들기도 한다.

현재 CAE는 여전히 mesh의 영향을 받고 있으며, 좋은 mesh는 다음과 같아야 한다.
– 타겟 물리 문제를 풀 수 있어야 함
– 솔버가 계산 실패하지 않을 정도의 합리적인 품질
– 물리문제에 기반한 형상 단순화
– 문제에 따라 품질을 결정해야 함
– 풀고자 하는 문제의 요구조건을 만족해야 함

NETGEN

출처: http://sourceforge.net/projects/netgen-mesher/

NETGEN is an automatic 3d tetrahedral mesh generator. It accepts input from constructive solid geometry (CSG) or boundary representation (BRep) from STL file format. The connection to a geometry kernel allows the handling of IGES and STEP files. NETGEN contains modules for mesh optimization and hierarchical mesh refinement. Netgen is open source based on the LGPL license. It is available for Unix/Linux and Windows.

Tcl/Tk Opengl 의 조합으로 만들어진 오픈소스 Mesh generator 프로그램.

코드를 파보면 Tk위에 OpenGL을 어떻게 붙이고.. 어떤 방향으로 코딩을 해야하는지 알 수 있을것임.

다운로드: netgen-5.1-RC.zip, Netgen_ext_libs.zip