IT/기초 지식

vtk 파일 포맷

개발자 두더지 2022. 8. 3. 11:59
728x90

vtk 파일이란?


 vtl 파일은 형태나 속성을 포함한다. 파일명의 확장자가 ".vtk"이다. 텍스트와 바이너리로 기재되어 있지만, 이번 포스트에서는 텍스트로 기재된 경우에 대해서만 설명하도록 하겠다.

 참고로 파일의 모든 대문자 단어는 키워드로, 소문자 단어는 유저 지정을 의미한다.

 

 

헤더


파일의 맨 앞 머리는 다음과 같이 작성되어 있다.

# vtk DataFile Version 2.0
Header
ASCII
DATASET UNSTRUCTURED_GRID

 첫 번째 행은 파일의 종류를 나타내고 있다. Header의 부분은 임의의 문자열을 쓸 수 있다. "ASCII"는 모두 텍스트로 기재되도록 지정하는 것이다. "DATASET" 의 "UNSTRUCTURE_GRID"는 비구조 격자 데이터라는 것을 의미한다.

 

 

형태


UNSTRUCTURED_GRID의 형태는 아래와 같은 형식으로 기재한다.

POINTS NumPoints DataType
x0 y0 z0 x1 y1 z1 ...

CELLS NumCells DataSize
num0 p00 p01 ... num1 p10 p11 ...

CELL_TYPES NumCells
TypeNum0 TypeNum1 ..

 Numpoints는 점의 수, DataType은 "int"나 "float"를 지정한다. NumCells는 셀의 수, DataSize는 그 뒤를 잇는 수치의 개수를 지정한다.

 numi는 셀 i를 구성하는 점의 수, pi0, pi1...가 그러한 점이다. 점의 ID는 0부터 시작한다. TypeNumi는 셀 i의 셀 타입 번호이다. 주요 셀 타입 번호는 다음과 같다.

  • 1 : 점
  • 5 : 삼각형
  • 9 : 마름모(사변형)
  • 10 : 사면체
  • 12 : 육면체
  • 13 : 삼각기둥
  • 14 : 피라미드

 실제 예로 살펴보자.

 삼각형의 예 triangle.vtk이다.

# vtk DataFile Version 2.0
triangle
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 3 float
0 0 0
1 0 0
1 1 0
CELLS 1 4
3 0 1 2
CELL_TYPES 1
5

마름모(사변형) quad.vtk

# vtk DataFile Version 2.0
quad
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 4 float
0 0 0
1 0 0
1 1 0
0 1 0
CELLS 1 5
4 0 1 2 3
CELL_TYPES 1
9

사면체 tera.vtk

# vtk DataFile Version 2.0
tetra
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 4 float
0 0 0
1 0 0
1 1 0
0.8 0.2 1
CELLS 1 5
4 0 1 2 3
CELL_TYPES 1
10

육면체 hexahedron.vtk

# vtk DataFile Version 2.0
hexahedron
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 8 float
0 0 0
1 0 0
1 1 0
0 1 0
0 0 1
1 0 1
1 1 1
0 1 1
CELLS 1 9
8 0 1 2 3 4 5 6 7
CELL_TYPES 1
12

삼각체 wedge.vtk

# vtk DataFile Version 2.0
wedge
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 6 float
0 0 0
1 0 0
1 1 0
0 0 1
1 0 1
1 1 1
CELLS 1 7
6 0 1 2 3 4 5
CELL_TYPES 1
13

피라미드 pyramid.vtk

# vtk DataFile Version 2.0
pyramid
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 5 float
0 0 0
1 0 0
1 1 0
0 1 0
0.5 0.5 1
CELLS 1 6
5 0 1 2 3 4
CELL_TYPES 1
14

 

 

 

속성


 속성이란 예를 들어 시뮬레이션 데이터에서 말하는 유속이나 압력과 같은 데이터로 점과 셀 각각의 속성에 지정할 수 있다.

POINT_DATA numPoints
...
CELL_DATA numCells
...

 점과 셀 각각에 스칼라 데이터와 벡터 데이터를 지정할 수 있다.

SCALARS Name DataType
LOOKUP_TABLE default
...
VECTORS Name DataType
...

 Name에는 임의의 이름을 지정할 수 있다(공백은 입력하면 안 된다).

 예를 살펴보자.

스칼라 scalar.vtk

# vtk DataFile Version 2.0
scalar
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 4 float
0 0 0
1 0 0
1 1 0
0 1 0
CELLS 1 5
4 0 1 2 3
CELL_TYPES 1
9
POINT_DATA 4
SCALARS point_scalars float
LOOKUP_TABLE default
1
2
3
4
CELL_DATA 1
SCALARS cell_scalars float
LOOKUP_TABLE default
5

벡터 데이터 vector.vtk

# vtk DataFile Version 2.0
vector
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 4 float
0 0 0
1 0 0
1 1 0
0 1 0
CELLS 1 5
4 0 1 2 3
CELL_TYPES 1
9
POINT_DATA 4
VECTORS point_vectors float
1 1 0
-1 1 0
-1 -1 0
1 -1 0
CELL_DATA 1
VECTORS cell_vectors float
1 1 0

 

 

 

구조격자


 구조격자를 표시하기 위한 DATASET의 종류로 "STRUCTURED_POINTS" 와 "STRUCTURED_GRID"가 있다. 점의 간격이 균일하게 하는 경우는 "STRUCTURED_POINTS" 를 사용할 수 있다.

DATASET STRUCTURED_POINTS
DIMENSIONS nx ny nz
ORIGIN x0 y0 z0
SPACING dx dy dz

nx, ny, nz은 점의 수, x0, y0, z0는 점의 좌표, dx, dy, dz는 점과 점의 간격 넓이이다.

 셀 값도 다룰 수 있지만, nx, ny, nz는 점의 수이므로, 셀의 분할 수를 고려하기 위해서는 각각 1을 더할 필요가 있다. 셀 수를 추가로 작성할 경우, 루프는 z, y, z 순으로 돌아간다. ((0,0,0),(1,0,0)...의 순서로 돌아간다)

 점의 간격이 균일하지 않은 경우,  "STRUCTURED_GRID"를 사용할 수 있다.

DATASET STRUCTURED_GRID
DIMENSIONS nx ny nz
POINTS NumPoints DataType
x0 y0 z0 x1 y1 z1 ...

 

 

XML 포맷


 위의 legacy 포맷과는 다른 XML 형식도 있다. 예를 들어 위에서 본 triangle.vtk quad.vtk를 XML 포맷으로 작성하면 다음과 같이 된다.

triangle.vtu

<VTKFile type="UnstructuredGrid" version="1.0">
<UnstructuredGrid>
<Piece NumberOfPoints="3" NumberOfCells="1">
<Points>
<DataArray type="Float64" NumberOfComponents="3" format="ascii">
0 0 0
1 0 0
1 1 0
</DataArray>
</Points>
<Cells>
<DataArray type="Int32" Name="offsets" format="ascii">
3
</DataArray>
<DataArray type="Int32" Name="connectivity" format="ascii">
0 1 2
</DataArray>
<DataArray type="UInt8" Name="types" format="ascii">
5
</DataArray>
</Cells>
</Piece>
</UnstructuredGrid>
</VTKFile>

quad.vtu

<VTKFile type="UnstructuredGrid" version="1.0">
<UnstructuredGrid>
<Piece NumberOfPoints="4" NumberOfCells="1">
<Points>
<DataArray type="Float64" NumberOfComponents="3" format="ascii">
0 0 0
1 0 0
1 1 0
0 1 0
</DataArray>
</Points>
<Cells>
<DataArray type="Int32" Name="offsets" format="ascii">
4
</DataArray>
<DataArray type="Int32" Name="connectivity" format="ascii">
0 1 2 3
</DataArray>
<DataArray type="UInt8" Name="types" format="ascii">
9
</DataArray>
</Cells>
</Piece>
</UnstructuredGrid>
</VTKFile>

 XML 포맷의 경우, 데이터의 타입에 따라 확장자가 바뀐다. UnstructuredGrid는 .vtu, StructuedGrid는 .vts와 같은 방식으로 말이다.

 위의 예에서 Cells의 DataArray "offsets"의 값은 셀 마다의 데이터의 마지막 위치로 예를 들어 육면체 데이터의 경우는 8, 16, 24, ...가 된다.

 legacy의  STRUCTURED_POINTS 에 상응하는것이 ImageData(.vti)이다.

grid.vti

<VTKFile type="ImageData" version="1.0">
<ImageData WholeExtent="0 10 0 10 0 10" Origin="0 0 0" Spacing="0.1 0.1 0.1">
<Piece Extent="0 10 0 10 0 10">
</Piece>
</ImageData>
</VTKFile>

WholeExtent는 DIMENSIONS에 대응되는 것으로, x, y, z 각각의 기점의 인덱스 범위를 지정하고 있다.(11 기점이 필욕하면0 와 10를 지정한다).

StructuredGrid는 다음과 같이 된다.

grid.vts

<VTKFile type="StructuredGrid" version="1.0">
<StructuredGrid WholeExtent="0 1 0 1 0 1">
<Piece Extent="0 1 0 1 0 1">
<Points>
<DataArray type="Float64" NumberOfComponents="3" format="ascii">
0 0 0
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1
</DataArray>
</Points>
</Piece>
</StructuredGrid>
</VTKFile>

 위의 스칼라 데이터 scalar.vtk와 벡터 데이터 vector.vtk의 XML판은 다음과 같다.

scalar.vtu

<VTKFile type="UnstructuredGrid" version="1.0">
<UnstructuredGrid>
<Piece NumberOfPoints="4" NumberOfCells="1">
<Points>
<DataArray type="Float64" NumberOfComponents="3" format="ascii">
0 0 0
1 0 0
1 1 0
0 1 0
</DataArray>
</Points>
<Cells>
<DataArray type="Int32" Name="offsets" format="ascii">
4
</DataArray>
<DataArray type="Int32" Name="connectivity" format="ascii">
0 1 2 3
</DataArray>
<DataArray type="UInt8" Name="types" format="ascii">
9
</DataArray>
</Cells>
<PointData">
<DataArray type="Float64" Name="point_scalars" format="ascii">
1
2
3
4
</DataArray>
</PointData>
<CellData">
<DataArray type="Float64" Name="cell_scalars" format="ascii">
5
</DataArray>
</CellData>
</Piece>
</UnstructuredGrid>
</VTKFile>

vector.vtu

<VTKFile type="UnstructuredGrid" version="1.0">
<UnstructuredGrid>
<Piece NumberOfPoints="4" NumberOfCells="1">
<Points>
<DataArray type="Float64" NumberOfComponents="3" format="ascii">
0 0 0
1 0 0
1 1 0
0 1 0
</DataArray>
</Points>
<Cells>
<DataArray type="Int32" Name="offsets" format="ascii">
4
</DataArray>
<DataArray type="Int32" Name="connectivity" format="ascii">
0 1 2 3
</DataArray>
<DataArray type="UInt8" Name="types" format="ascii">
9
</DataArray>
</Cells>
<PointData>
<DataArray type="Float64" Name="point_vectors" NumberOfComponents="3" format="ascii">
1 1 0
-1 1 0
-1 -1 0
1 -1 0
</DataArray>
</PointData>
<CellData>
<DataArray type="Float64" Name="cell_vectors" NumberOfComponents="3" format="ascii">
1 1 0
</DataArray>
</CellData>
</Piece>
</UnstructuredGrid>
</VTKFile>

 

병렬판

XML 포맷에서는 병렬형식으로도 기재할 수 있다. UnstructuredGrid의 병렬판의 확장판이 .pvtu로, 다음과 같이 작성된다.

multi.pvtu

<VTKFile type="PUnstructuredGrid" version="1.0">
<PUnstructuredGrid>
<PPoints>
<DataArray type="Float64" NumberOfComponents="3" format="ascii"/>
</PPoints>
<Piece Source="file_0.vtu"/>
<Piece Source="file_1.vtu"/>
<PCellData>
<DataArray type="Float64" Name="cell_scalars" NumberOfComponents="3" format="ascii"/>
</PCellData>
</PUnstructuredGrid>
</VTKFile>

 Piece 요소의 Source에서 다른 .vtu 파일을 지정하고 있다. 셀 값이 필요한 경우는 PCellData요소와  PDataArray요소에서 지정하면 된다.

 

멀티 블록

여러 개의 데이터를 합친 멀티 블록이라는 데이터 세트(vtkMultiBlockDataSet, 확장자.vtm)도 있다.

multi.vtm

<VTKFile type="vtkMultiBlockDataSet" version="1.0">
<vtkMultiBlockDataSet>
<DataSet index="0" name="file_0" file="file_0.vtu"/>
<DataSet index="1" name="file_1" file="file_1.vtu"/>
<Block index="2" name="block">
<DataSet index="0" name="file_2" file="file_2.vti"/>
<DataSet index="1" name="file_3" file="file_3.vti"/>
</Block>
</vtkMultiBlockDataSet>
</VTKFile>

 외부의 파일을 지정하고 있는 곳이 병렬판과 비슷하지만, 다른 타입의 데이터가 섞여있거나, Block으로 단계적 구조로 만들거나 할 수 있다.

 

 

시계열 데이터의 시간 지정


ParaView 5.6.0 버전 이후에는 아래와 같이 JSON 형식으로 파일과 시간과 관련된 대응을 기재할 수 있게 됐다. 

files.vti.series

{
    "file-series-version" : "1.0",
    "files" : [
        { "name" : "file_0.vti", "time" : 0 },
        { "name" : "file_1.vti", "time" : 0.5 },
        { "name" : "file_2.vti", "time" : 1 }
    ]
}

 파일명은 vti의 세트라면 "*.vti.series", vtu세트라면 "*.vtu.series"이 된다. 


 참고자료

http://penguinitis.g1.xrea.com/study/ParaView/VTK/VTK.html

728x90