STL 파일은 렌더링될 모델에 대한 정보를 담고 있는 파일이다!
저번 포스팅에서도 말했다 싶이 모델의 기본은 보통 삼각형(polygon)인데, 이 STL 파일에서는 어떻게 들어가 있는지 한번 살펴보도록 하자.
이 3D 에 대한 정보를 담고 있는 STL 파일은 ascii 로 인코딩 된 경우만 이렇게 메모 패드로 열어볼 수 있다. 만약 binary 로 인코딩 된 경우 절대 메모 패드를 통해 열어볼 수 없다. 설령 python의 open 을 이용해서 바이러니 파일을 열었다고 쳐도, 첫번째 문장인 solid teaset 말고는 읽을 수 있는 것이 하나도 없을 것이다. 그러니까 꼭 이 포스팅을 참고하기 전에 STL 파일이 ascii 파일인지, binary 파일인지 확인해보길 바란다... 만약 binary 파일인데 이 포스팅을 따라한다? 스스로 삽질을 파는 것이다.
이런 식으로 생겼다.
가장 먼저 면에 대한 normal인 facet normal 이 나온다. 이는 polygon의 세 꼭짓점을 cross product 해서 나온 값인데, 렌더링 할 때는 필요 없는 정보인 듯하다.
outerloop 안에 vertex 가 세 개의 열으로 되어 있는 것을 확인할 수 있다.
vertex (x좌표, y좌표, z 좌표) 이렇게 나열되어 있다.
그럼 우리가 할 일은 이 vertex 하나하나를 point 정보로 입력해 주고
outerloop 안의 point들을 polygon, 즉 하나의 셀로 만들어 주어야 한다.
그렇게 생성된 셀들을 합쳐서 cellarray로 만들게 된다.
뭐.. 쉽다!
나는 중복으로 point 위치 정보를 저장하기 싫어서 try except 구문을 통해, 유니크한 point 위치만 저장하도록 만들어줬다. 중복돼도 딱히 상관은 없을 것 같다.
filename = 'teapot.stl'
points_list = []
points_dict = {}
points = vtk.vtkPoints()
cellArray = vtk.vtkCellArray()
num_points = 0
with open(filename, 'r') as f:
InputLines = f.readlines()
for e, InputLine in enumerate(InputLines):
if e == 0 : continue
elif e % 7== 1:
#facet normal
cell = []
continue
elif e % 7 > 2 and e % 7 <6:
#vertex
InputLine = InputLine.strip('\n')
vertex = InputLine.split(' ')[-3:]
vertex = tuple(float(point) for point in vertex)
try:
vertex_id = points_dict[vertex]
except:
points.InsertNextPoint(vertex)
points_dict[vertex] = num_points
num_points += 1
vertex_id = points_dict[vertex]
cell.append(vertex_id)
elif e % 7 == 0:
#create cell
cellArray.InsertNextCell(3, tuple(cell))
polydata = vtk.vtkPolyData()
polydata.SetPoints(points)
polydata.SetPolys(cellArray)
'기타 > 3D 메쉬 데이터' 카테고리의 다른 글
[BBox] AABB vs OBB (0) | 2022.01.25 |
---|---|
[Autoencoder] Exploring Generative 3D Shapes Using Autoencoder Networks 요약 (0) | 2022.01.25 |
[Mesh]vtk 라이브러리로 polydata 만들기 (0) | 2022.01.12 |
[Mesh]vtk 라이브러리 전 normal이란 (0) | 2022.01.12 |
[Mesh] vtk 라이브러리 전 폴리곤 메쉬란 (0) | 2022.01.11 |
댓글