3차원 공간상에 정의된 객체를 화면으로 투영하기 위해선 대표적으로 두 가지 방법이 있다. 하나는 Orthogonal과 또 하나는 Perspective 이다. 그 외에도 외곡된 projection field 를 정의하여 보다 극적인 가시화를 가능하게 할 수도 있으나 기본적으로 homogeneous 좌표계에서 4x4 matrix로 정의가 가능한 두 가지 mapping 을 기본적으로 다룬다. (이는 카메라 조작과 같은 기본적인 UI와도 직접적 관련이 있다.)
다음은 Orthogonal projection의 예이다.
그리고 다음은 Perspective projection의 예이다.
Overview 관점에서 Orthogonal 이나 Perspective나 큰 차이가 없음을 알 수 있다. 그러나 셰이딩으로 정의가 미흡한 부분의 깊이감을 Perspective에서 더 잘 표현함다는 점에서 혹자는 Perspective view를 선호할 수 있다.
그러나 가시화되는 화면 크기 대비 물체에 대한 과도한 깊이감은 Overview에서 이질감을 초래할 수 있어, 화면 전체적으로 균등하게 깊이 왜곡 없이 투영되는 Orthogonal view를 더 선호할 수도 있다.
이건 어디까지나 개인 취향의 문제이나 카메라 explore 모드에서는 이야기가 조금 달라진다. 객체 근처로 접근하여 일부분을 정밀히 관찰하는 경우, 마치 개미가 세상을 보듯, Perspective view가 훨씬 현실성이 있으며, 이 경우 Overview에서 문제가 되었던 "가시화되는 화면 크기 대비 물체에 대한 과도한 깊이감"의 요소는 배제되고 오히려 깊이감은 가시화 결과의 이질감을 줄이는 요소로 작용한다.
다음은 카메라 explore 모드의 가시화 결과이다.
[그림]
Thursday, July 07, 2011
Friday, June 10, 2011
Porosity View DVR with pre-processed sub-volume
DVR에서 sample position 의 voxel value를 다양한 metric으로 해석하여 optical property를 정의할 수 있다는 것은 Multi Metric for Optical Property 에서 이미 언급하였다.
이것의 연장선 상에서 DVR 이전에, 전처리를 통해 얻은 새로운 metric으로 지정된 sub-volume을 main-volume의 geometry 와 같게 설정하면 위의 방법을 통한 DVR 이 가능하다.
추가적으로, 여기에서는 sub-volume 을 '속성'이 아닌 태그의 개념으로 정의할 수 있고, 태그 ID를 통해 여러 1D OTF를 할당하여 태그 영역의 속성을 이해하는데 도움을 주는 DVR을 실현 수 있다. 그러나 이것은 main volume의 metric에 의존하지 않는다는 점에서 main volume에 "속성 의존적"인 결과를 도출하기가 어렵다.
하여, 이 방법은 주로 segmentation 된 결과 자체를 main volume의 기하학적 구조와 연계하여 분석하는 것에만 도움을 줄 수 있다.
(이 경우, OTF를 공유하지 않는 main and sub volume의 관계는 position 에 의해서만 결정된다는 점을 생각.)
따라서 이보다 더 심층적인 main volume과 sub volume의 연계성을 확인하기 위해서는, 각 volume의 value가 sample 지점의 optical property를 결정하는데 영향을 주도록 modulation을 사용하거나 두 volume의 metric으로부터 정의되는 2D OTF를 사용하면 된다.
여기서는 두 volume의 관계를 선형적 분석이 아닌 비선형적 분석이 가능한 2D OTF 방법을 사용하도록 한다. (추가적으로 , 2D OTF는 2D histogram을 통한 value의 분포를 확인할 수도 있다는 점에서 매력적이다.)
다음은 여기서 실험할 기공(porosity)를 많이 포함하고 있는 industrial data의 DVR이다.
이것을 voxel 단위로 size를 추출(volume 의 surface 내부로 판정되는 곳에서 비슷한 value를 갖는 연결된 크기를 각 voxel 단위로 계산)하는 전처리 과정으로 새로운 volume 을 생성한다.
실험 data의 전체 실루엣만 나타나게 하는 반투명 가시화 widget에, 특정 main volume의 value 영역에서 임의의 size 영역대에 color widget을 설정하여 DVR을 진행한다.
다음은 하나의 volume으로 빠르게 구할 수 있는 density&Gradient Magnitude를 이용한 예이다.
비교적 비싼 전처리를 통해 얻은 sub volume 기반보다 porosity를 확인하기 어렵다.
따라서, 정리하자면... 다음은 위에서 언급한 두 개의 볼륨 속성을 보는 방법을 고려해 볼 때
이것의 연장선 상에서 DVR 이전에, 전처리를 통해 얻은 새로운 metric으로 지정된 sub-volume을 main-volume의 geometry 와 같게 설정하면 위의 방법을 통한 DVR 이 가능하다.
추가적으로, 여기에서는 sub-volume 을 '속성'이 아닌 태그의 개념으로 정의할 수 있고, 태그 ID를 통해 여러 1D OTF를 할당하여 태그 영역의 속성을 이해하는데 도움을 주는 DVR을 실현 수 있다. 그러나 이것은 main volume의 metric에 의존하지 않는다는 점에서 main volume에 "속성 의존적"인 결과를 도출하기가 어렵다.
하여, 이 방법은 주로 segmentation 된 결과 자체를 main volume의 기하학적 구조와 연계하여 분석하는 것에만 도움을 줄 수 있다.
(이 경우, OTF를 공유하지 않는 main and sub volume의 관계는 position 에 의해서만 결정된다는 점을 생각.)
따라서 이보다 더 심층적인 main volume과 sub volume의 연계성을 확인하기 위해서는, 각 volume의 value가 sample 지점의 optical property를 결정하는데 영향을 주도록 modulation을 사용하거나 두 volume의 metric으로부터 정의되는 2D OTF를 사용하면 된다.
여기서는 두 volume의 관계를 선형적 분석이 아닌 비선형적 분석이 가능한 2D OTF 방법을 사용하도록 한다. (추가적으로 , 2D OTF는 2D histogram을 통한 value의 분포를 확인할 수도 있다는 점에서 매력적이다.)
다음은 여기서 실험할 기공(porosity)를 많이 포함하고 있는 industrial data의 DVR이다.
이것을 voxel 단위로 size를 추출(volume 의 surface 내부로 판정되는 곳에서 비슷한 value를 갖는 연결된 크기를 각 voxel 단위로 계산)하는 전처리 과정으로 새로운 volume 을 생성한다.
실험 data의 전체 실루엣만 나타나게 하는 반투명 가시화 widget에, 특정 main volume의 value 영역에서 임의의 size 영역대에 color widget을 설정하여 DVR을 진행한다.
다음은 하나의 volume으로 빠르게 구할 수 있는 density&Gradient Magnitude를 이용한 예이다.
비교적 비싼 전처리를 통해 얻은 sub volume 기반보다 porosity를 확인하기 어렵다.
따라서, 정리하자면... 다음은 위에서 언급한 두 개의 볼륨 속성을 보는 방법을 고려해 볼 때
- Main volume => On the fly computation => 2D OTF
- Main volume => Sub volume 생성 => 2D OTF
- Main Volume에 대한 1D OTF와 Subvolume 에 대한 modulation
- Main Volume에 대한 1D OTF와 Subvolume 에 대한 sub 1D OTF
만약... 이 외의 방법이 존재 한다면?! -_-?
thanks for jun and victory
thanks for jun and victory
TObject for OTF archive and TF setting module
그동안 여러 시행착오를 반복하면서, VXFramework의 자료구조와 이를 기반으로 하는 각종 Interface가 안정화 되었지만 유독 찝찝함을 내제하고 있는 인터페이스가 바로 OTF 정의에 대한 것이었다.
사실 OTF를 정의하는 자료구조 자체는 큰 문제가 없었지만, 이를 설정하는 범위를 Native Frame에서 어느 범위까지로 하는가는 Managed Frame에서의 overhead와 직결되는 문제로 이해 했었다.
그러나 이는 "OTF 설정"의 범위를 광범위하게 정의하고, 작은 부분까지 Native 모듈에서 처리하게 하려는 욕심에서 비롯된 생각이었다. 그러나 OTF 설정을 다음과 같이 네 가지로 나누고
Managed 와 Native 모듈에서 맡아야 할 설정 범위를 생각해 보면, 이 모두를 Native 모듈에서 다 다뤄야 할 필요가 없음을 알 수 있다.
특히 Control Point 지정은 사용자 컨트롤과 자동 설정의 두 가지 방법을 통해 가능하며, 전자를 통한 지정 시 사용자 interaction 작업이 용이한 Managed Frame에서 작업하는 것이 더 효율적이라는 판단을 내릴 수 있다.
나머지 2,3,4번은 모두 Native TF Module에서 작업하되, 2번은 기능의 확장성을 고려하여 3번과 연계해 Default Manipulator 모듈에서 작업한다. 4번은 그 overhead를 고려하여 기존의 TObject를 정의하는 Archive 자료 구조 외에 CustomList object를 TF 모듈의 in/output 으로 이용한다.
위에서 설명한 부분 외에 Managed Frame 에서 TObject 조작을 위한 Component 설정을 편리하게 하기 위해, 내부에서 OTF 설정을 위한 VXFunctionScenario를 추가한다.
이를 통해 다음의 Managed Component 설정 코드가
이렇게 한 줄로 줄어든다. (설마 두 줄이라고 우기는 사람은 없겠지..)
-_-v 그러나 문제는........... 자료구조의 정리 및 Interface 변화로 OTF 모듈과 Managed Component 코드를 수정해야 하는 대작업을 해야 한다는 것! ㅠㅠ
이를 통해 다시 한 번 느끼는 것이지만 부적절한 자료 구조 및 interface 설계는 대재앙을 몰고 온다는 것..
사실 OTF를 정의하는 자료구조 자체는 큰 문제가 없었지만, 이를 설정하는 범위를 Native Frame에서 어느 범위까지로 하는가는 Managed Frame에서의 overhead와 직결되는 문제로 이해 했었다.
그러나 이는 "OTF 설정"의 범위를 광범위하게 정의하고, 작은 부분까지 Native 모듈에서 처리하게 하려는 욕심에서 비롯된 생각이었다. 그러나 OTF 설정을 다음과 같이 네 가지로 나누고
- Control Point를 통한 Optical Color Array 지정
- 지정된 Optical Color Array의 TObject Archive 할당
- Optical Color Array의 Refinement (for adv. DVR)
- 볼륨 분석을 통한 자동 Optical Color Array 지정
Managed 와 Native 모듈에서 맡아야 할 설정 범위를 생각해 보면, 이 모두를 Native 모듈에서 다 다뤄야 할 필요가 없음을 알 수 있다.
특히 Control Point 지정은 사용자 컨트롤과 자동 설정의 두 가지 방법을 통해 가능하며, 전자를 통한 지정 시 사용자 interaction 작업이 용이한 Managed Frame에서 작업하는 것이 더 효율적이라는 판단을 내릴 수 있다.
나머지 2,3,4번은 모두 Native TF Module에서 작업하되, 2번은 기능의 확장성을 고려하여 3번과 연계해 Default Manipulator 모듈에서 작업한다. 4번은 그 overhead를 고려하여 기존의 TObject를 정의하는 Archive 자료 구조 외에 CustomList object를 TF 모듈의 in/output 으로 이용한다.
위에서 설명한 부분 외에 Managed Frame 에서 TObject 조작을 위한 Component 설정을 편리하게 하기 위해, 내부에서 OTF 설정을 위한 VXFunctionScenario를 추가한다.
이를 통해 다음의 Managed Component 설정 코드가
이렇게 한 줄로 줄어든다. (설마 두 줄이라고 우기는 사람은 없겠지..)
-_-v 그러나 문제는........... 자료구조의 정리 및 Interface 변화로 OTF 모듈과 Managed Component 코드를 수정해야 하는 대작업을 해야 한다는 것! ㅠㅠ
이를 통해 다시 한 번 느끼는 것이지만 부적절한 자료 구조 및 interface 설계는 대재앙을 몰고 온다는 것..
Wednesday, June 08, 2011
Clipping Boundary Unshading Mode
불투명에 가까운 Surface Rendering 에서 볼륨의 내부 구조를 보기 위한 대표적인 방법으로 Clipping 이 있다. 그러나 볼륨 내부가 Iso-value 영역 (또는 homogeneous Region) 일 경우 Gradient normal vector가 불균형하게 정의되어 Shading 이 제대로 안 되는 문제가 발생한다.
반투명 DVR 에서 Clipped 표면의 투명도가 높을 경우 해당 표면의 Shading 이 최종 Rendering 결과에 미치는 영향이 미비하여 이를 무시할 수 있다. 그러나 Clipped 표면이 반투명에 가깝게 가시화될 경우, 다음과 같이 경계가 지저분하게 가시화된다.

이 경우 Clipped 단면을 '깨끗히' 가시화하기 위해 단면의 Voxel 이 정의하는 normal vector를 Clipping plane의 normal vector 로 사용하여 가시화하거나, normal vector에 영향을 받는 shading factor를 적용 안 한 Unshading mode를 사용하는 방법있다.
전자의 경우 Clipping Box가 회전함에 따라 Shading 이 Clipped 표면에서 일괄적으로 바뀌는 가시화가 이루어지는데, Clipped 표면 자체에 집중할 경우 보기가 불편할 수 있다는 단점이 있다.
하여, 여기서는 후자인 Unshading mode를 사용하였다.
그러나 문제는 큰 사이즈의 볼륨을 가시화하기 위해 Chunk 자료 구조를 사용할 경우, 다음과 같이 예기치 못한 문제에 봉착할 수 있다는 것이다.
물론 학술적으로 전혀 의미가 없지만 프로그램의 완성도를 위해 이를 처리할 필요가 있었다.
Chunk 단위의 가시화를 위해 Sample Box를 Chunk와 Clipping Box의 교집합으로 정의할 경우, 이러한 Chunk 경계에서 예기치 않은 unshading 으로 인한 줄무늬가 발생한다.
이를 해결하기 위해 Chunk 경계가 Clipping Box 안에 있는가를 확인하는 루팅을 두었고, 이는 최초 Sample Box의 시작점에 대해서만 판정해 주면 되기 때문에 별도의 overhead도 거의 없는 효과적인 방법이다.
다음은 이 문제를 해결한 최종 결과이다.
반투명 DVR 에서 Clipped 표면의 투명도가 높을 경우 해당 표면의 Shading 이 최종 Rendering 결과에 미치는 영향이 미비하여 이를 무시할 수 있다. 그러나 Clipped 표면이 반투명에 가깝게 가시화될 경우, 다음과 같이 경계가 지저분하게 가시화된다.

<타이어 휠 데이터에 대한 Clipping 가시화>
이 경우 Clipped 단면을 '깨끗히' 가시화하기 위해 단면의 Voxel 이 정의하는 normal vector를 Clipping plane의 normal vector 로 사용하여 가시화하거나, normal vector에 영향을 받는 shading factor를 적용 안 한 Unshading mode를 사용하는 방법있다.
전자의 경우 Clipping Box가 회전함에 따라 Shading 이 Clipped 표면에서 일괄적으로 바뀌는 가시화가 이루어지는데, Clipped 표면 자체에 집중할 경우 보기가 불편할 수 있다는 단점이 있다.
하여, 여기서는 후자인 Unshading mode를 사용하였다.
<Unshading Mode를 적용한 가시화 결과>
그러나 문제는 큰 사이즈의 볼륨을 가시화하기 위해 Chunk 자료 구조를 사용할 경우, 다음과 같이 예기치 못한 문제에 봉착할 수 있다는 것이다.
물론 학술적으로 전혀 의미가 없지만 프로그램의 완성도를 위해 이를 처리할 필요가 있었다.
Chunk 단위의 가시화를 위해 Sample Box를 Chunk와 Clipping Box의 교집합으로 정의할 경우, 이러한 Chunk 경계에서 예기치 않은 unshading 으로 인한 줄무늬가 발생한다.
이를 해결하기 위해 Chunk 경계가 Clipping Box 안에 있는가를 확인하는 루팅을 두었고, 이는 최초 Sample Box의 시작점에 대해서만 판정해 주면 되기 때문에 별도의 overhead도 거의 없는 효과적인 방법이다.
다음은 이 문제를 해결한 최종 결과이다.
![]() |
-_-v |
Friday, June 03, 2011
Multi Metric for Optical Property
XYZ 의 위치에 Scalar value 로 정의되는 4차원 데이터를 샘플하고 이를 광학 이론에 적용하여 가시화 하는 것을 Direct Volume Rendering (DVR)이라고 한다.
짧은 문구지만 여기에는 물리적으로 검증된 광학 모델, 대용량 데이터의 Sampling Theorem, 다차원 데이터를 효과적으로 보이기 위한 Information Visualization (외의 HCI 기술), 삼차원 가시화 조작과 관련된 CAD 기술 등... 많은 내용을 함축하고 있다.
전통적으로 삼차원 공간에 정의된 Scalar filed 에서 "의미 있는" 영역을 보기 위해 Scalar value 를 RGBA 의 광학적 속성으로 바꿔 주는 1D Optical Transfer Function (OTF) 을 사용해 왔다.
[옆의 그림에서 하단에 있는 것이 Gaussian Kernel 기반의 1D Color OTF 이다.]
그러나 DVR은 볼륨데이터에 직접적으로 정의되어 있는 Scalar value 와 같은 Metric 외에 간접적으로 정의된 Metric (예. Scalar Field 가 정의하는 Gradient Magnitude Field) 을 이용하여 정의된 볼륨의광학적 속성을 가시화로 연결할 수 있다.
그리고 이것은 불투명한 표면의 삼차원 가시화가 갖는 근본적 한계인 "가려진 중요 부분"의 직관적 파악을 위한 효과적 가시화의 핵심 기술로 활용될 수 있다.
이 경우 추가적인 볼륨 정보 (위에서 언급한 간접적으로 정의된 Metric )는 1. Modulation, 2. Multi Dimension OTF 를 통해 볼륨의 광학적 속성 정의에 사용되며, 이것은 DVR 을 통해 전체적인 Context 및 내부의 숨겨진 Context를 삼차원으로 가시화 하는 데에 사용된다.
위의 그림은 Gradient Magnitude, Shading을 위해 쉽게 구할 수 있는 몇몇 factor를 기반으로 1D OTF 결과(왼쪽)의 Alpha 에 modulation을 적용한 결과(오른쪽)이다.
위의 그림은 2D OTF 를 기반으로 가시화한 결과이며, Volume 의 Scalar value 와 이것이 정의하는 Gradient Magnitude 를, 3개의 Colored Widget 을 통해 볼륨에 광학적 속성을 부여한 결과이다.
이외에도 내/외부 구조를 한번에 직관적으로 볼 수 있는 몇몇 방법이 있지만 사용자 컨트롤에 대한 한계, 가시화 속도에 대한 한계 등으로 잘 사용하지 않고 위의 두 방법을 가장 많이 이용한다.
Thx for Victory
짧은 문구지만 여기에는 물리적으로 검증된 광학 모델, 대용량 데이터의 Sampling Theorem, 다차원 데이터를 효과적으로 보이기 위한 Information Visualization (외의 HCI 기술), 삼차원 가시화 조작과 관련된 CAD 기술 등... 많은 내용을 함축하고 있다.

[옆의 그림에서 하단에 있는 것이 Gaussian Kernel 기반의 1D Color OTF 이다.]
그러나 DVR은 볼륨데이터에 직접적으로 정의되어 있는 Scalar value 와 같은 Metric 외에 간접적으로 정의된 Metric (예. Scalar Field 가 정의하는 Gradient Magnitude Field) 을 이용하여 정의된 볼륨의광학적 속성을 가시화로 연결할 수 있다.
그리고 이것은 불투명한 표면의 삼차원 가시화가 갖는 근본적 한계인 "가려진 중요 부분"의 직관적 파악을 위한 효과적 가시화의 핵심 기술로 활용될 수 있다.
이 경우 추가적인 볼륨 정보 (위에서 언급한 간접적으로 정의된 Metric )는 1. Modulation, 2. Multi Dimension OTF 를 통해 볼륨의 광학적 속성 정의에 사용되며, 이것은 DVR 을 통해 전체적인 Context 및 내부의 숨겨진 Context를 삼차원으로 가시화 하는 데에 사용된다.
위의 그림은 Gradient Magnitude, Shading을 위해 쉽게 구할 수 있는 몇몇 factor를 기반으로 1D OTF 결과(왼쪽)의 Alpha 에 modulation을 적용한 결과(오른쪽)이다.
위의 그림은 2D OTF 를 기반으로 가시화한 결과이며, Volume 의 Scalar value 와 이것이 정의하는 Gradient Magnitude 를, 3개의 Colored Widget 을 통해 볼륨에 광학적 속성을 부여한 결과이다.
이외에도 내/외부 구조를 한번에 직관적으로 볼 수 있는 몇몇 방법이 있지만 사용자 컨트롤에 대한 한계, 가시화 속도에 대한 한계 등으로 잘 사용하지 않고 위의 두 방법을 가장 많이 이용한다.
Thx for Victory
Thursday, June 02, 2011
Scene Background Setting & Blending
그동안 Native Engine 의 Rendering 결과를 Managed Frame 에서 보여 주기 위해 File Memory 를 매개로 Interoperation 을 해 왔다.
이를 위해 Common Control에서 "InteropBitmap"을 이용해 왔는데, 이것이 .net framework 과 연계되어 Control 에 Image Source 형식으로 붙을 수 있다는 점에서 WPF designer 이나 Brush Control 로 쉽게 코딩할 수 있는 Background 와 Blending 할 수 있겠다는 생각을 늘 해 왔다.
실제로 Native Engine 의 Rendering 결과가 RGBA 채널을 갖고 있고, A 채널 역시 계산되므로 .net framework의 기본 blending 을 활용할 수 있는 가능성이 높았다.
다음과 같이 수정함으로써
bitmapSource = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(ipFileMapSection, iWidth, iHeight, PixelFormats.Bgra32, iRawStride, 0);
다음과 같이 세팅된 Panel에 대하여
이를 위해 Common Control에서 "InteropBitmap"을 이용해 왔는데, 이것이 .net framework 과 연계되어 Control 에 Image Source 형식으로 붙을 수 있다는 점에서 WPF designer 이나 Brush Control 로 쉽게 코딩할 수 있는 Background 와 Blending 할 수 있겠다는 생각을 늘 해 왔다.
실제로 Native Engine 의 Rendering 결과가 RGBA 채널을 갖고 있고, A 채널 역시 계산되므로 .net framework의 기본 blending 을 활용할 수 있는 가능성이 높았다.
하여 그동안 다음과 같이 WPF designer 에서 Panel 의 Background 를 정의했었으나 Rendering 결과가 Blending 되지 않고 Background 부분이 Native의 RGB 색으로 (여기서는 검정) 다음과 같이 나왔다.
그러나 "InteropBitmap" 을 생성하는 코드를
bitmapSource = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(ipFileMapSection, iWidth, iHeight, PixelFormats.Bgr32, iRawStride, 0);다음과 같이 수정함으로써
bitmapSource = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(ipFileMapSection, iWidth, iHeight, PixelFormats.Bgra32, iRawStride, 0);
다음과 같이 세팅된 Panel에 대하여
이것이 의미하는 것은 Rendering 결과를 나타내는 component 에 .net framework 을 통해 쉽게 Background 를 지정하고 이것에 Blending 함으로써 전체적으로 완성도 높은 이미지를 도출할 수 있다는 것이다.
Thanks for Victory...

Wednesday, May 25, 2011
Module's Common Interface
모듈은 function이 정의되어 있는 레고의 블록으로 정의할 수 있다.
이것이 의미하는 것은 레고에서 블록을 조합하여 하나의 시나리오를 갖는 큰 블록을 만들 수 있으며 큰 블록을 조합하여 하나의 완결된 스토리를 갖는 완성품을 쉽게 만들 수 있다는 것이다.
이를 위해 생각해야 할 것은 모듈의 "독립성"이다.
그러나 아이러니 하게도 독립적 모듈을 쉽게 조립/조합하기 위해선 하나의 공통된 자료구조가 정의되어 있어야 하고 이것에 의존해야 한다.
마치 레고의 모양은 형형색색 다르지만 접합하는 부분은 쉽게 끼우고 뺄 수 있도록 모든 블록이 통일된 것을 생각해 보면 쉽게 이해할 수 있다.
이러한 이해를 바탕으로 실제 모듈 통합을 염두에 둔 모듈 설계를 해 보면 하나의 궁극적 딜레마에 빠지게 된다. 그것은 바로 모듈 독립성의 범위와 모듈 인터페이스 및 Helper를 위한 공통 자료구조를 어디까지 정의할 것인가에 대한 것이다.
지난 오랜 시간의 경험을 통해 이 딜레마에서 가장 우선적으로 고려해야 할 것은 기능의 확장성과 유연성에 있음을 깨닫게 되었다. 이는 비단 본인의 경험뿐만 아니라 뭇 선현들에 의해서도 입증이 된 것인데, VXFramework에서는 이를 위해 모든 모듈의 interface를 완벽히 동일하게 정의하고 interface를 위한 자료구조를 타협할 수 있는 수준에서 추상화하는 방법을 선택하였다.
물론 "타협할 수 있는 수준"은 어디까지나 이를 설계하는 사람의 역량과 경험에 의해 결정되겠지만 지금 생각해 보면 Object과 Script화된 Parameter의 사용은 최상의 선택인 것 같다. 물론 이것이 추상화된 것만큼 모듈을 사용하는 component의 작업이 괴로워질 수 있으나 이 역시 합리적인 수준에서 마무리된 것으로 보인다.
VXFramework은 이 합리적인 수준을 위해
다음은 VXFramework에서 정의한 Module's Common Interface 이다.
이렇게 추상화된 interface를 효과적으로 사용하기 위해선 플랫폼에 가까운 상위 interface에서 직관적이고 구체적으로 정의된 인자를 이에 맞게 변환하여 주는 똑똑한 Wrapper / Arbiter가 정의되야 한다.
여기선 '똑똑한' 정의를 다음으로 미루며 위와 같은 Module's Common Interface가 VXframework에서 정의되어 있다는 것까지 정리하도록 한다.
이것이 의미하는 것은 레고에서 블록을 조합하여 하나의 시나리오를 갖는 큰 블록을 만들 수 있으며 큰 블록을 조합하여 하나의 완결된 스토리를 갖는 완성품을 쉽게 만들 수 있다는 것이다.
이를 위해 생각해야 할 것은 모듈의 "독립성"이다.
그러나 아이러니 하게도 독립적 모듈을 쉽게 조립/조합하기 위해선 하나의 공통된 자료구조가 정의되어 있어야 하고 이것에 의존해야 한다.
마치 레고의 모양은 형형색색 다르지만 접합하는 부분은 쉽게 끼우고 뺄 수 있도록 모든 블록이 통일된 것을 생각해 보면 쉽게 이해할 수 있다.
이러한 이해를 바탕으로 실제 모듈 통합을 염두에 둔 모듈 설계를 해 보면 하나의 궁극적 딜레마에 빠지게 된다. 그것은 바로 모듈 독립성의 범위와 모듈 인터페이스 및 Helper를 위한 공통 자료구조를 어디까지 정의할 것인가에 대한 것이다.
지난 오랜 시간의 경험을 통해 이 딜레마에서 가장 우선적으로 고려해야 할 것은 기능의 확장성과 유연성에 있음을 깨닫게 되었다. 이는 비단 본인의 경험뿐만 아니라 뭇 선현들에 의해서도 입증이 된 것인데, VXFramework에서는 이를 위해 모든 모듈의 interface를 완벽히 동일하게 정의하고 interface를 위한 자료구조를 타협할 수 있는 수준에서 추상화하는 방법을 선택하였다.
물론 "타협할 수 있는 수준"은 어디까지나 이를 설계하는 사람의 역량과 경험에 의해 결정되겠지만 지금 생각해 보면 Object과 Script화된 Parameter의 사용은 최상의 선택인 것 같다. 물론 이것이 추상화된 것만큼 모듈을 사용하는 component의 작업이 괴로워질 수 있으나 이 역시 합리적인 수준에서 마무리된 것으로 보인다.
VXFramework은 이 합리적인 수준을 위해
- 모듈의 common interface로 모듈에 들어오는 추상화된 인자를 구체화하여 확인하는 interface
- 최초/최후 모듈이 실행될 때 호출되는 interface
- 임의로 모듈과 통신할 수 있는 interface
- 모듈의 core 실행을 위한 interface
다음은 VXFramework에서 정의한 Module's Common Interface 이다.
이렇게 추상화된 interface를 효과적으로 사용하기 위해선 플랫폼에 가까운 상위 interface에서 직관적이고 구체적으로 정의된 인자를 이에 맞게 변환하여 주는 똑똑한 Wrapper / Arbiter가 정의되야 한다.
여기선 '똑똑한' 정의를 다음으로 미루며 위와 같은 Module's Common Interface가 VXframework에서 정의되어 있다는 것까지 정리하도록 한다.
Tuesday, May 24, 2011
Add new Module
VXFramework에서 엔진 모듈은 모두 DLL 로 이루어져 있다. Native COM 구조에서는 Module Arbiter 라는 클래스가 VXFramework의 Native API 에서 지정되는 모듈을 관리한다.
Managed Frame 까지 포함될 경우 개발자 편의를 위해 설계한 VXSceneStory 및 VXFunctionScenario의 자료구조에 다음의 네 가지로 나눈 모듈에 따라
먼저 DLL 솔루션으로 정의되는 모듈을 VXFramework 에 추가하기 위해, 다음의 단계를 따른다.
VXFramework은 모듈 SDK로서의 기능과 플랫폼 SDK로서의 기능을 고려하여 만든 Library 이므로, 모든 Frame(Platform Frame, Engine Frame, Module Frame)을 각각 독립적 솔루션으로 구성하였다.
하여, 위의 단계를 통해 추가된 모듈을 Platform 에서 사용하게 되었으면 모듈 개발을 위해 VXFramework을 SDK library로 활용하기 위한 프로젝트 세팅이 필요하다.
다음은 VS2010 에서의 프로젝트 생성 및 설정을 위한 방법이다.
현재 버젼은 Frame의 Math Helper로 DX9Math.lib을 사용하여 D3dx9.lib을 Link를 위한 Library로 추가하였지만 그 외의 DirectX 를 기본 자료구조로 삼고 있지 않으므로 DirectX SDK가 반드시 깔려 있을 필요는 없다. (이 경우 물론 D3dx9.lib 및 D3dx9math.h 는 있어야 한다.)
또한 특정 라이브러리 및 OS 플랫폼에 대한 종속성이 없으므로 CUDA 및 OpenGL, DirectX 등 여러 Library를 Static 이든 Dynamic 이든 프로젝트 설정에 적절히 추가하여 사용할 수 있다.
Managed Frame 까지 포함될 경우 개발자 편의를 위해 설계한 VXSceneStory 및 VXFunctionScenario의 자료구조에 다음의 네 가지로 나눈 모듈에 따라
- OTF Generator
- Reconstructor
- Renderer
- VObject Generator
먼저 DLL 솔루션으로 정의되는 모듈을 VXFramework 에 추가하기 위해, 다음의 단계를 따른다.
- Platform 에서 사용될 모듈을 지정하고 있는 text list(Platform을 build 할 때 binary로 추가됨)에 모듈 Name과 ID를 추가한다.
- Platform frame에서 모듈을 명시적으로 사용하기 위해 Managed 자료구조에 Module enumeration을 추가한다. (명시적으로 사용하지 않고 ID 로만 사용할 수도 있음.)
- 추가된 enumeration을 바탕으로 모듈의 행동을 검사하는 Engine Commander Center 의 코드를 추가한다. (해당 플랫폼에서 사용되지 않더라도 추가된 history가 있으면 언제든 사용 가능.)
VXFramework은 모듈 SDK로서의 기능과 플랫폼 SDK로서의 기능을 고려하여 만든 Library 이므로, 모든 Frame(Platform Frame, Engine Frame, Module Frame)을 각각 독립적 솔루션으로 구성하였다.
하여, 위의 단계를 통해 추가된 모듈을 Platform 에서 사용하게 되었으면 모듈 개발을 위해 VXFramework을 SDK library로 활용하기 위한 프로젝트 세팅이 필요하다.
다음은 VS2010 에서의 프로젝트 생성 및 설정을 위한 방법이다.
- Native C/C++ 기반으로 빈 프로젝트를 만든다.
- VXFramework의 Native 자료구조 및 Helper를 사용하기 위한 Main Header를 include한다.
- DLL에 대한 function import를 위한 키워드로 vxstatic 을 정의하고 모든 엔진 모듈에서 정의된 Function을 선언한다.
- 프로젝트 설정을 통해, 모듈을 DLL로 설정하며 모듈에서 사용할 Static 및 Dynamic Library를 위한 Link 설정을 한다.
- DLL 프로젝트의 Entry Point 로서의 플랫폼을 설정하고, 기타 프로젝트 생성 파일에 대한 폴더를 지정한다.
- 이를 x86/64, Debug/Release에 대해 적절히 설정한다.
<프로젝트 설정>
현재 버젼은 Frame의 Math Helper로 DX9Math.lib을 사용하여 D3dx9.lib을 Link를 위한 Library로 추가하였지만 그 외의 DirectX 를 기본 자료구조로 삼고 있지 않으므로 DirectX SDK가 반드시 깔려 있을 필요는 없다. (이 경우 물론 D3dx9.lib 및 D3dx9math.h 는 있어야 한다.)
또한 특정 라이브러리 및 OS 플랫폼에 대한 종속성이 없으므로 CUDA 및 OpenGL, DirectX 등 여러 Library를 Static 이든 Dynamic 이든 프로젝트 설정에 적절히 추가하여 사용할 수 있다.
Monday, May 23, 2011
VXSceneStory and VXFunctoinScenario
VXFramework에서 Platform의 직속 Component에 유저 컨트롤에 따른 Function Parameter를 효율적으로 전달하기 위해 무엇을 해야 하는가?
VXFramework의 Managed Frame을 처음 설계할 때 머릿속을 늘 맴돌던 질문이었다.
이 질문에 대한 답을 얻기 위해 그 동안의 경험을 바탕으로 내린 자료 구조는 다음을 만족해야 했다.
사실 여러 CAD 프로그램을 보면, 삼차원 상에 여러 객체를 조작하기 위해 Main Stage(또는 Scene)을 정의하게 된다. VXFramework도 큰 범주로 보자면 이런 부류이므로 Main Scene과 Scene을 이루는 각종 객체가 계층적으로 정의되야 함은 자명한 사실이다.
그렇다면 이 객체 간의 계층을 어떻게 구성해야 하며, 기왕이면 Volume Processing에 특화되면서 일반 CAD와의 호환성도 보장할 수 있는 구조는 어떻게 이루어져야 하는가 하는 질문에 도달하게 된다.
이를 위해 VXFramework에서는, 단순히 보여 주는 것 외에도 각종 데이터를 처리하는 "동작"을 Scene과 이를 이루는 객체 정의의 핵심으로 두었다. 그리고 이것을 바탕으로, 고안해 낸 것이 바로 객체(들)의 동작을 정의하는 Scenario이며, 이것들의 구성을 통해 Scene의 동작을 정의하는 Story라는 개념을 도입하였다.
이것이 바로 VXFunctionScenario 와 VXSceneStory 이다.
VXFunctionScenario 은 동작 모듈 ID, 모듈 동작을 위한 Custom Parameter, 모듈에서 사용될Resource들의 ID로 정의된다. VXSceneStory 는 이러한 VXFunctionScenario 들을 List로 갖고 있는 자료구조이며 각각은 편한 코딩을 위해 Helper를 제공하도록 구현되었다.
참 쉽죠잉~
VXFramework의 Managed Frame을 처음 설계할 때 머릿속을 늘 맴돌던 질문이었다.
이 질문에 대한 답을 얻기 위해 그 동안의 경험을 바탕으로 내린 자료 구조는 다음을 만족해야 했다.
- 계속되는 요청 사항 및 기능 개선에 대응하기 위해 확장 가능한 Parameter의 자료 구조
- 잦은 Parameter 변동에서 야기되는 Function Interface의 재정의 방지를 위한 자료구조
- 단일 모듈이 아닌 다양한 모듈의 조합을 위한 자료구조
사실 여러 CAD 프로그램을 보면, 삼차원 상에 여러 객체를 조작하기 위해 Main Stage(또는 Scene)을 정의하게 된다. VXFramework도 큰 범주로 보자면 이런 부류이므로 Main Scene과 Scene을 이루는 각종 객체가 계층적으로 정의되야 함은 자명한 사실이다.
그렇다면 이 객체 간의 계층을 어떻게 구성해야 하며, 기왕이면 Volume Processing에 특화되면서 일반 CAD와의 호환성도 보장할 수 있는 구조는 어떻게 이루어져야 하는가 하는 질문에 도달하게 된다.
이를 위해 VXFramework에서는, 단순히 보여 주는 것 외에도 각종 데이터를 처리하는 "동작"을 Scene과 이를 이루는 객체 정의의 핵심으로 두었다. 그리고 이것을 바탕으로, 고안해 낸 것이 바로 객체(들)의 동작을 정의하는 Scenario이며, 이것들의 구성을 통해 Scene의 동작을 정의하는 Story라는 개념을 도입하였다.
이것이 바로 VXFunctionScenario 와 VXSceneStory 이다.
VXFunctionScenario 은 동작 모듈 ID, 모듈 동작을 위한 Custom Parameter, 모듈에서 사용될Resource들의 ID로 정의된다. VXSceneStory 는 이러한 VXFunctionScenario 들을 List로 갖고 있는 자료구조이며 각각은 편한 코딩을 위해 Helper를 제공하도록 구현되었다.
참 쉽죠잉~
Sunday, May 22, 2011
VXFramework Overview
VXFramework은 다음의 세 가지 Frame으로 구성된다.
1. Engine Frame
2. Module Frame
Engine Frame은 Engine Module 및 플랫폼 프로세싱의 대상이 되는 Resource를 관리하는 역할을 하며, Module Frame은 Engine Module을 정의한다.
그리고 Platform Frame은 VXFramework 을 통해 구현하고자 하는 최종 Platform을 효율적으로 설계하기 위해 Native와 Managed Code의 Interoperation을 해 주고, 각종 사용자 컨트롤을 위한 Component로 구성되어 있다.
VXFramework에서는 자유도 높은 Function의 확장성 뿐만 아니라, 주로 사용하게 되는 방대한 용량의 Resource를 효율적으로 관리하기 위해 C#의 TreeViewItem을 상속 받는 ObjectTreeViewItem 이라는 자료구조를 정의하고 이를 단위로 Resource를 컨트롤한다.
이것은 WPF에서 제공하는 Object Browser인 TreeView 를 사용하여 현재 Resource 상황을 다음과 같이 확인할 수 있다.
Tree Item의 상속관계는 Resource 를 Platform의 Contents로 어떻게 사용하느냐에 따라 다르게 설계될 수 있으며 Resource에 대한 ObjectTreeViewItem 설정 및 해제는 다음의 규칙을 따른다.
VXFramework 은 위대하다. -_-b
1. Engine Frame
- Engine API for platform developer
- File Interface for importing and exporting data
- Data Structures for module development and resource management
- Module Arbiter and Resource Manager
2. Module Frame
- Base Interface Module Arbiter and Module
- CLI wrapper to convert C++ based-API into C# interface
- Global Header for Helper functions and Based Objects
- Engine Center for native resource/module items (as symbol) and engine commander based on CLI wrapper
- Common Controls for engine manipulation UI
- Main Window for integration (G)UIs
Engine Frame은 Engine Module 및 플랫폼 프로세싱의 대상이 되는 Resource를 관리하는 역할을 하며, Module Frame은 Engine Module을 정의한다.
그리고 Platform Frame은 VXFramework 을 통해 구현하고자 하는 최종 Platform을 효율적으로 설계하기 위해 Native와 Managed Code의 Interoperation을 해 주고, 각종 사용자 컨트롤을 위한 Component로 구성되어 있다.
VXFramework에서는 자유도 높은 Function의 확장성 뿐만 아니라, 주로 사용하게 되는 방대한 용량의 Resource를 효율적으로 관리하기 위해 C#의 TreeViewItem을 상속 받는 ObjectTreeViewItem 이라는 자료구조를 정의하고 이를 단위로 Resource를 컨트롤한다.
이것은 WPF에서 제공하는 Object Browser인 TreeView 를 사용하여 현재 Resource 상황을 다음과 같이 확인할 수 있다.
Tree Item의 상속관계는 Resource 를 Platform의 Contents로 어떻게 사용하느냐에 따라 다르게 설계될 수 있으며 Resource에 대한 ObjectTreeViewItem 설정 및 해제는 다음의 규칙을 따른다.
- Item 추가 : Native에 존재하고 있는 Resource를 Item으로 추가하여 Tree View에서 Story에 적합한 상속 구조를 구성할 수 있으며 이 경우 Native Resource ID를 Item이 공유하게 된다.
- Item 삭제 : 현재 노드 및 하위 노드의 모든 Item 을 recursive하게 삭제한다. Native Resource는 Reference Count 방식을 통해, 해당 Resource를 참조하고 있는 Item이 하나일 경우일 때만 삭제되어 최종적으로 메모리에서 제거된다.
VXFramework 은 위대하다. -_-b
Saturday, May 21, 2011
Managed code VS Native code
기존의 JAVA 를 선두로 익히 알려진 Managed 진영에 MS의 .net framework 이 발전하면서 Managed 언어는 프로그램의 양과 질, 두 마리 토끼를 모두 취할 수 있는 좋은 방법이 되었다. 특히 많은 개발자들이 (비)상용으로 수많은 관련 library를 공개함으로써 이것은 어느덧 대세가 되었다.
그러나 굉장히 성능에 민감한 하위 레벨 엔진을 구현하는 본인로서는 Managed 보다 훨씬 가볍고 최적화가 유리한 Native C/C++ 코드를 메인 언어로 사용해 왔고, 이것에 대해 확신과 자부심을 갖고 있었다.
그러나 엔진뿐만 아니라, 모듈의 통합 및 구성, 유저 시나리오를 포함하는 콘텐츠로 이루어진 "Platform"까지 만들어야 하는 상황으로 인해 시간과 노력이라는 한계에 봉착하고 말았다. 그러던 중 Native 와 Managed Code 간 Interoperation를 알게 되었고, 하위 레벨 엔진에서부터 상위 레벨 콘텐츠까지 지원할 수 있는 진정 OOP 다운 Library를 설계할 수 있게 되었다. (Thanks for Jun)
Native Code 기반은 기존에 해왔던
Managed code 기반에서는, 플랫폼을 구성하는 콘텐츠로 End User와 모듈 엔진을 이어 주는 Component 가 주를 이루게 하여 다음을 구현하도록 하였다.
Managed 부분의 GUI 부분은 C++ 에서 MFC 에 해당하는 WPF 기반으로 구현되었으며, 이것은 Silver Light 의 슈퍼셋으로 약간의 수정을 통해 추후 Web 기반 플랫폼으로 전이가 용이하다는 점에 굉장히 매력적 옵션이다.
이것을 생각하고 구현하는데 대략 1달이라는 시간이 소요되었으며, 이를 바탕으로 효율적인 Contents를 구성하기 위해 Managed 부분의 Function 자료구조를 생각하게 되었는데 이는 다음에 이야기하도록 하겠다.
Once again Thx for Jun
그러나 굉장히 성능에 민감한 하위 레벨 엔진을 구현하는 본인로서는 Managed 보다 훨씬 가볍고 최적화가 유리한 Native C/C++ 코드를 메인 언어로 사용해 왔고, 이것에 대해 확신과 자부심을 갖고 있었다.
그러나 엔진뿐만 아니라, 모듈의 통합 및 구성, 유저 시나리오를 포함하는 콘텐츠로 이루어진 "Platform"까지 만들어야 하는 상황으로 인해 시간과 노력이라는 한계에 봉착하고 말았다. 그러던 중 Native 와 Managed Code 간 Interoperation를 알게 되었고, 하위 레벨 엔진에서부터 상위 레벨 콘텐츠까지 지원할 수 있는 진정 OOP 다운 Library를 설계할 수 있게 되었다. (Thanks for Jun)
Native Code 기반은 기존에 해왔던
- 굉장히 성능에 민감한 엔진 : Rendering module, Volume Generating Module 등...
- 엔진 모듈 관리
- 현재 Managed 로 지원하지 않거나 최적화 시나리오가 난해한 Resource 관리
- Volume Processing에 특화된 자료 구조의 객체화
- 모듈을 위한 Helper Functions
- API의 직관적 구성 및 COM 구조화
- 모듈 추가 및 수정을 독립적으로 할 수 있도록 DLL 로 솔루션 구성
- 모듈의 OS 및 SDK 종속성에 대한 자유도 보장을 위한 기본 자료 구조 사용
<Native & CLR Interface>
Managed code 기반에서는, 플랫폼을 구성하는 콘텐츠로 End User와 모듈 엔진을 이어 주는 Component 가 주를 이루게 하여 다음을 구현하도록 하였다.
- Native Engine API 와 연동되는 Managed Engine Command Center (ECC)
- ECC 기반으로 GUI 를 통해 모듈 조작을 돕는 Common Control
- ECC 및 Common Control을 정의하기 위한 Managed 자료구조
- ECC 및 Common Control에 User Scenario를 더한 1차적 Custom Platform 인 View
<Managed Data Structure & API>
Managed 부분의 GUI 부분은 C++ 에서 MFC 에 해당하는 WPF 기반으로 구현되었으며, 이것은 Silver Light 의 슈퍼셋으로 약간의 수정을 통해 추후 Web 기반 플랫폼으로 전이가 용이하다는 점에 굉장히 매력적 옵션이다.
이것을 생각하고 구현하는데 대략 1달이라는 시간이 소요되었으며, 이를 바탕으로 효율적인 Contents를 구성하기 위해 Managed 부분의 Function 자료구조를 생각하게 되었는데 이는 다음에 이야기하도록 하겠다.
Once again Thx for Jun
Friday, May 20, 2011
4주 훈련 후
4주간의 전문연구원 훈련을 논산에서 마치고 온지 어느덧 2일째.
그리고 환복의 쓰라림... /-.- 추...웅 썽!
무한 인터넷 서핑을 하면서 드디어 현실로 복귀했구나 하는 생각이 든다.
지금 생각해 보면 정말 일순간의 꿈처럼 논산에서의 4주 훈련이 스쳐 지나간다.
참... 많은 것들이 생각이 나지만 훈련소 마지막날 아침 산 너머 보이던 일출의 광경은 평생 잊을 수 없을 것 같다.
그리고 환복의 쓰라림... /-.- 추...웅 썽!
Subscribe to:
Posts (Atom)