vtk를 이용한 contour plot 구현

vtk를 이용하여 contour plot을 구현한 것입니다.
ne.dat라는 파일에 저장되어 있는 값을 읽어 각 열의 최대값과 최소값을 추출하여
축(axes)에 할당하였고, 결과값의 크기에 따라 파란색부터 빨간색까지 변환된 것 입니다.
첨부된 contour.png는 구현된 결과이고, noname01.jpg는 VTK에서 사용되는 주요 객체간의 연관관계를 나타낸 것입니다. Visualization pipeline은 일반 데이터를 그래픽 데이터로 변환하는 과정이고, graphic object는 이렇게 생성된 그래픽 데이터를 이미지로 변환하는 렌더링 과정과 연관된 객체를 의미합니다.

Contour plot을 구현하기 위해서 vtkFloatArray와 vtkLookUpTable, 그리고 vtkRectilinearGrid를 이용하여 visulization popeline을 구성하였고, graphic object는 vtkMapper, vtkActor, vtkRenderer 그리고 vtkRenderWindow를 이용하여 구성하였습니다.
일반 데이터로 저장되어 있는 계산 결과는 vtkFloatArray에 각각의 좌표 값과 스칼라 값을 배열로 가지고 있습니다. 이 값을 vtkRectilinearGrid로 넘겨줌으로써 셀을 구성하고 셀이 가지고 있는 모든 정보는 vtkLookUpTable을 통해 크기에 따라 색으로 변환됩니다. 이렇게 구성된 visualization pipeline의 그래픽 데이터는 graphic object의 vtkActor를 통해 각각의 객체로 나타내어지고 vtkRenderer와 vtkRenderWindow를 통해 이미지로 변환되어 시각화 되는것 입니다. Vector plot의 구현을 위해서는 각각의 좌표 값과 벡터 값을 vtkFloatArray에 저장하고 벡터를 표현하는 vtkGlyph3D, vtkArrowSource를 이용하여 visualization pipeline에 추가 하였습니다.

급하게 하느라 내용정리가 제대로 안되었네요. 자세한 코드에 대한 설명은 천천히 하도록 하겠습니다.

package require vtk
package require vtkinteraction
package require tile


set R 0
set Z 0

set in [open vtka.in r]

gets $in line
scan $line "%d %d" R Z
close $in

vtkFloatArray rcoords
vtkFloatArray zcoords
vtkFloatArray scalars

vtkRectilinearGrid rgrid
        rgrid SetDimensions $R $Z 1
vtkScalarBarActor scalarBar
vtkCubeAxesActor2D axes

set f [open ne.dat r]

for {set i 1} {$i <= [expr ($R+$Z)*($Z-1)]} {incr i 1} {
                gets $f line
                foreach j {1 2 3} {
                        set arr($i,$j) [lindex $line [expr $j - 1]]
                }       
        }
       
set n 1
set m 1
for {set a 1} {$a <= $Z} {incr a 1} {
        for {set b 1} {$b <= $R} {incr b 1} {          
               
                if {$b == 1} {
                        foreach y $arr($m,1) {
                                puts $y
                        }
                        zcoords InsertNextValue $y
                }
                if {$a == 1} {
                        foreach x $arr($b,2) {
                                puts $x
                        }
                        rcoords InsertNextValue $x
                }
                foreach s $arr($n,3) {
                        puts $s
                }
                scalars InsertNextValue $s
                incr n 1
               
        }
        incr m [expr $R+1]
        incr n 1
       
}                              
                              
close $f

set min [scalars GetValue 0]
        set max [scalars GetValue 0]

        for {set i 0} {$i < [expr $R*$Z]} { incr i 1 } {
                if { [scalars GetValue $i] < $min } {          
                        set min [scalars GetValue $i]
                }
        }
        for {set i 0} {$i < [expr $R*$Z]} { incr i 1 } {
                if { [scalars GetValue $i] > $max } {          
                        set max [scalars GetValue $i]
                }
        }

        set rmin [rcoords GetValue 0]
        set rmax [rcoords GetMaxNorm]

        for {set i 0} {$i < $R} {incr i 1} {
                if { [rcoords GetValue $i] < $rmin } {
                        set rmin [rcoords GetValue $i]
                }
        }

        set zmin [zcoords GetValue 0]
        for {set i 0} {$i < $Z} {incr i 1} {
                if { [zcoords GetValue $i] < $zmin } {
                        set zmin [zcoords GetValue $i]
                }
        }
        set zmax [zcoords GetValue 0]
        for {set i 0} {$i < $Z} {incr i 1} {
                if { [zcoords GetValue $i] > $zmax } {
                        set zmax [zcoords GetValue $i]
                }
        }

rgrid SetXCoordinates rcoords
rgrid SetYCoordinates zcoords
[rgrid GetPointData] SetScalars scalars

vtkLookupTable lut
        lut SetNumberOfColors 256
        lut SetHueRange 0.667 0.0
        lut Build

vtkDataSetMapper mapper
        mapper SetInput rgrid
        mapper SetLookupTable lut
        mapper SetScalarRange $min $max
vtkActor actor
        actor SetMapper mapper

#

vtkRenderer renderer
        renderer SetBackground 0 0 0
        renderer AddActor actor
        renderer AddActor2D scalarBar
        renderer AddActor2D axes
        [renderer GetActiveCamera] SetPosition 13.0 5.0 50.0
        [renderer GetActiveCamera] SetFocalPoint 13.0 5.0 0.0

#create ScalarBar
scalarBar SetLookupTable lut
scalarBar SetTitle "Density"
[scalarBar GetPositionCoordinate] SetCoordinateSystemToNormalizedViewport
[scalarBar GetPositionCoordinate] SetValue 0.1 0.01
scalarBar SetOrientationToHorizontal
scalarBar SetWidth 0.8
scalarBar SetHeight 0.1

#create CubeAxes
axes SetInput rgrid
axes SetFlyModeToOuterEdges
axes SetFontFactor 0.7
axes ScalingOff
axes SetXLabel "R cm"
axes SetYLabel "Z cm"
axes SetCornerOffset 0.0
axes SetNumberOfLabels 5
axes SetCamera [renderer GetActiveCamera]
axes SetLabelFormat "%6.4g"
axes ZAxisVisibilityOff

vtkRenderWindow renwin
        renwin AddRenderer renderer
#       renwin SetSize 500 500

vtkRectilinearGridWriter writer
        writer SetInput rgrid
        writer SetFileName "rectilinear.vtk"
        writer Write

set vtkw [vtkTkRenderWidget .ren -width 500 -height 400 -rw renwin]

#Setup Tk bindings and vtk obserbers for that widget.
::vtk::bind_tk_render_widget $vtkw

frame .params

ttk::button .params.quit -text "Quit" -command ::vtk::cb_exit
pack .params.quit -side top -anchor nw -fill both
pack $vtkw .params -side top -fill both -expand yes

wm protocol . WM_DELETE_WINDOW ::vtk::cb_exit

tkwait window .

첨부 파일파일 크기
noname01.jpg16.99 KB
contour.png66.53 KB