본문 바로가기
Computer Science/Computer Graphics

Mesh, OBJ File

by Gofo 2021. 4. 8.

Mesh

물체를 표현하는 방식에는 다양한 방법들이 있다.

어떠한 일을 처리하느냐에 따라서 적합한 방법을 선택해야한다.

 

이러한 방법들은 2가지 분류로 구분할 수 있다.

  • explicit
    • 물체가 여기에 있고 직접적으로 표현하는 것이다.
    • point cloud, polygon mesh, subdivision ...
  • implicit
    • 특정 조건들을 만족하는 점들을 찾아서 물체를 만드는 것이다.
    • level set, algebraic surface ...

 

가장 많이 사용되는 방법이 polygon mesh이다.

 

Polygon Mesh

어떠한 복잡한 물체이더라도 상대적으로 간단한 표현으로 나타낼 수 있고 렌더링이 빠르다.

 

기본 단위는 polygon과 polygon mesh이다.

  • polygon
    • 직선들로 이루어진 닫힌 모양
  • polygon mesh
    • polygon들이 모여서 어떠한 surface을 만들게 되는데 이 polygon들의 집합이다.
    • 주로 triangle과 quads(사각형)를 이용한다.
    • triangle을 이용한 polygon mesh를 trinagle mesh라 하고, quads을 이용한 polygon mesh를 quads mesh라 한다.

 

OpenGL에서 앞면을 보기 위해서 polygon들은 반시계방향(counterclockwise) 순으로 vertex들을 정의해야한다.

만약 시계방향으로 표현한다면 물체의 뒷면을 보게 된다.

 

Polygon Mesh Issues

아래 특징을 가지게 된다면 보정을 해야 하므로 빠른 렌더링에 적합하지 않다.

  • non-planar : N-polygon은 하나의 평면에 있지 않을 수도 있다.
  • non-convex : 볼록 다각형이 아닐 수도 있다.

 


Triangle Mesh

Triangle을 이용해서 만든 polygon mesh이다.

 

장점

아래와 같은 이유로 최근의 GPU들은 모든 것을 삼각형의 집합으로 표현한다.

  • 항상 모든 점들이 하나의 평면에 위치한다.
  • 항상 볼록 다각형이다.
  • 모든 N-polygon은 삼각형으로 나눌 수 있다.

 

Vertex 저장 방법

Triangle mesh을 표현하기 위해 vertex position 삼각형을 만드는 vertex들간의 관계을 메모리에 저장해야 한다.

  • Separate triangles : 가장 단순한 방법
  • Indexed triangle set : 가장 많이 사용되는 방법

 


Separate Triangles

Vertex들을 다 표시함으로써 하나의 삼각형을 이루는 vertex들의 관계를 명시한다.

이때 vertex들은 반시계방향 순으로 명시해야 앞면을 나타낼 수 있다.

 

단점

  • 메모리 공간 낭비
    • 모든 삼각형들에 대한 정보를 따로따로 표현해야하기 때문에 각 점들은 여러 번 중복 저장된다.
  • floating point 계산으로 인한 crack(유격) 발생
    • 각 점들이 같은 점이라고 명시하는 것이 아니라 하나의 삼각형을 이루는 좌표들을 저장할 뿐이다.
    • floating-point의 계산으로 인해 같은 vertex라 하더라도 차이가 발생할 수 있다.
  • 이웃하는 삼각형들을 찾기 힘듬
    • 하나의 삼격형에 이웃하는 삼각형을 찾기 위해서는 모든 점 사이의 거리를 따져봐야 한다.

 

 

glVertex*()

GL_TRIANGLES을 이용해서 vertex들을 3개씩 엮으면 각각의 삼각형들이 그려진다.

* 만약 GL_QURDS을 호출한 후 vertex들을 4개씩 엮으면 사각형들이 그려진다.

 

각 표면을 물체의 바깥쪽에서 바라봤을 때가 앞면이다!

그래서 4 → 5 → 6 / 4 → 6 → 7 의 순서로 밑면이 그려지게 되는 것이다.

 

Vertex Array

Vertex array는 vertex data을 모아놓은 array이다.

Vertex의 위치, 색상, normals, texture coordinates 등을 포함할 수 있다.

 

glVertex*()들을 이용해서 렌더링 하는 것보다 vertex array를 한번에 OpenGL의 함수를 이용해서 그릴 수 있다.

렌더링 속도가 매우 빨라진다.

 

Vertex array을 이용해서 mesh을 그리는 방법은 다음과 같다.

  1. mesh에 대한 vertex array 만들기
    • numpy.ndarray나 python list 사용
  2. OpenGL에게 현재 그려야 하는 vertex array를 알려준다.
    • C에서는 pointer을 이용하지만, 파이썬에서는 변수의 이름을 넘겨주면 된다.
    • <pre>glVertexPointer()</pre>을 이용한다.
  3. vertex array을 mesh로 그린다.
    • <pre>glDrawArrays()</pre>을 이용한다.

 

Vertex array을 이용해서 mesh을 그리기 위해서는 다음과 같은 함수를 사용한다.

Rending할 때 <pre>glEnableClientState(GL_VERTEX_ARRAY)</pre>을 해서 vertex array을 사용할 수 있게 한다.

 

  • <pre>glVertexPointer( size, type, stride, pointer )</pre>
    • vertex array의 위치 + vertex array 안의 data들이 어떤 식으로 이루어져있는지를 나타낸다. 
    • size
      • the number of vertex coordinate
      • 몇차원에서 그릴 것인가?
      • 2D point면 2, 3D point면 3
    • type
      • vertex coordinate value의 data type
      • GL_FLOAT, GL_SHORT, LGL_INT, GL_DOBULE
    • stride
      • byte offset to the next vertex
      • vertex들 사이의 byte offset
      • 하나의 vertex의 x 좌표에서 다음 vertex까지의 x 좌표까지 몇 바이트 차이나는가?
    • pointer
      • vertex array의 위치
      • 파이썬에서는 vertex array의 변수명
    • 예시 : <pre>glVertexPointer(3, GL_FLOAT, 3*varr.itemsize, varr)</pre>
  • <pre>glDrawArrays( mode, first, count )</pre>
    • glVertexPointer()로 지정된 vertex array를 이용해서 각 primitive를 그린다.
    • mode
      • primitives
      • GL_TRIANGLES, GL_QURDS ...
    • first
      • vertex array의 몇번재 index부터 그릴 것인가?
      • 그릴 vertex의 시작을 지정
    • count
      • vertex array안의 vertex 중 그려질 vertex가 총 몇개인가?
      • 그릴 vertex의 개수를 지정
      • vertex의 각 좌표의 개수가 아닌 vertex의 개수, 즉 array의 tuple의 개수이다!
    • 예시 : <pre>glDrawArrays(GL_TRIANGLE, 0, int(varr.size/3))</pre>

 


Indexed Triangle Set

각 vertex들과, 각 triangle의 정보(어떤 vertex로 구성되어있는지)를 저장한다. 

Vertex의 정보를 vertex array에, triangle의 정보를 index array에 저장한다.

 

가장 많이 사용되는 방법 중 하나이다.

 

장점

  • 메모리 효율성
    • 각 vertex들의 정보가 한번만 저장되기 때문에 효율적이다.
  • topology와 geometry를 따로 표현한다.
    • topology : index array
    • geometry : vertex array
  • 이웃을 찾는 방법이 well-defined 되어있다.
    • 같은 vertex를 포함하고 있으면 이웃한 삼각형이다.

 

방법

Indexed triangle set으로 mesh를 그리는 방법은 다음과 같다.

  1. vertex array와 index array를 만든다.
    • 하나의 vertex data는 한번만 나와야 한다.
    • seperate triagle 에서는 하나의 vertex가 이루는 triangle 만큼 반복되었다.
  2. vertex array에 대해 pointer를 지정한다.
    • <pre>glVertexPointer()</pre> 이용
  3. vertex pointer와 index array 정보를 넘겨서 rendering 한다.
    • <pre>glDrawElements()</pre> 이용

 

함수 설명

OpenGL에서 indexed set으로 mesh를 rendering하기 위해서는 다음과 같은 함수를 사용한다.

  • <pre>glVertexPointer( size, type, stride, pointer )</pre>
    • vertex array의 위치 + vertex array 안의 data들이 어떤 식으로 이루어져있는지를 나타낸다. 
    • size
      • the number of vertex coordinate
      • 몇차원에서 그릴 것인가?
      • 2D point면 2, 3D point면 3
    • type
      • vertex coordinate value의 data type
      • GL_FLOAT, GL_SHORT, LGL_INT, GL_DOBULE
    • stride
      • byte offset to the next vertex
      • vertex들 사이의 byte offset
      • 하나의 vertex의 x 좌표에서 다음 vertex까지의 x 좌표까지 몇 바이트 차이나는가?
    • pointer
      • vertex array의 위치
      • 파이썬에서는 vertex array의 변수명
    • 예시 : <pre>glVertexPointer(3, GL_FLOAT, 3*varr.itemsize, varr)</pre>
  • <pre>glDrawElements( mode, count, type, indices )</pre>
    • mode
      • primitive type
      • 예 : GL_POINTS, GL_TRIAGNLES, GL_QUADS
    • count
      • rendering 될 index들의 개수
      • 몇개의 index를 그릴 것인가
      • (1차원 기준) index array의 length
      • 예 : [(1, 2, 3), (0, 1, 2)] 라면 count는 6이다.
    • type
      • index value의 type
      • GL_UNSIGNED_INT, GL_UNSIGNED_SHORT, GL_UNSIGNED_BYTE
    • indices
      • index array에 대한 pointer
      • 파이썬에서는 array 이름으로 지정

 


OBJ File

제일 쉽고 보편적인 3D file format이다.

ASCII code로 구성된다.

 

Token

  • # some text : 주석
  • v float float float
    • space에서 하나의 vertex 정보
  • vn float float float
    • normal 정보
  • vt float float
    • texture coordinate
  • f int/int/int int/int/int int/int/int
    • 하나의 face에 대한 정보
    • 순서대로 vertex의 index, texture의 index, normal의 index 이다.
    • f int int int, f int/int int/int int/int 로 나타내기도 한다.

 


참고

본 포스트는 한양대학교 이윤상 교수님의 수업을 정리한 내용입니다.

출처: 한양대학교 이윤상 교수님 컴퓨터그래픽스 강의 강의자료 - https://cgrhyu.github.io/courses/2022-spring-cg.html

 

CGR LAB

Computer Graphics - 2022 Spring Instructor: Yoonsang Lee Teaching Assistant: Chaejun Sohn Undergraduate Mentor: Bokyoung Jang Time / Location: Mon 09:00-11:00 / Online (originally 207 IT.BT Building) - Lab Wed 09:00-11:00 / 508 IT.BT Building - Lecture Cou

cgrhyu.github.io

 

 

'Computer Science > Computer Graphics' 카테고리의 다른 글

Shading  (0) 2021.05.31
Lighting  (0) 2021.05.31
Rendering Pipeline, Transformation Pipeline  (0) 2021.04.07
Affine Frame  (0) 2021.03.23
[OpenGL] Transformation Matrix  (0) 2021.03.23

댓글