2016. 10. 18. 19:48

CKMSceneDataSeries *pSeries = g_Doc.m_pSceneData->GetDefaultSeries();

CKMVolume *pVol = pSeries->m_pVolume;


short *pVolData = (short*)(pVol->GetDataSource());

int nDim[3] = {pVol->m_nDim[0], pVol->m_nDim[1], pVol->m_nDim[2]};

m_fPixelSpacing[0] = (float)(pVol->m_fSpacing[0]);

m_fPixelSpacing[1] = (float)(pVol->m_fSpacing[1]);

m_fPixelSpacing[2] = (float)(pVol->m_fSpacing[2]);


m_volumeData->data.setValue(SbVec3i32(dimension), SbDataType(SbDataType::SIGNED_SHORT), 0, pData, SoSFArray::COPY);

m_volumeData->extent.setValue(-(spacing[0] * dimension[0])/2, -(spacing[1] * dimension[1])/2, -(spacing[2] * dimension[2])/2, 

                                 (spacing[0] * dimension[0])/2,  (spacing[1] * dimension[1])/2,  (spacing[2] * dimension[2])/2);

SbVec3i32 dimension = pVolumeData->data.getSize();



/*SoVolumeData* volumeData = new SoVolumeData();

short* rawData = (short*)m_pSceneData->GetDefaultSeries()->m_pVolume->GetDataSource();

int dimension[3] = { m_pVolume->m_nDim[0], m_pVolume->m_nDim[1], m_pVolume->m_nDim[2] };

float spacing[3] = { m_pVolume->m_fSpacing[0], m_pVolume->m_fSpacing[1], m_pVolume->m_fSpacing[2] };

volumeData->data.setValue(SbVec3i32(dimension), SbDataType(SbDataType::SIGNED_SHORT), 0, rawData, SoSFArray::COPY);

volumeData->extent.setValue(-(spacing[0] * dimension[0])/2, -(spacing[1] * dimension[1])/2, -(spacing[2] * dimension[2])/2, 

                           (  spacing[0] * dimension[0])/2,  (spacing[1] * dimension[1])/2,  (spacing[2] * dimension[2])/2);

m_pRootSeparator->addChild(volumeData);*/


#define SO_MOUSE_PRESS_EVENT(EVENT,BUTTON) \

    (SoMouseButtonEvent::isButtonPressEvent(EVENT,SoMouseButtonEvent::BUTTON))


#define SO_MOUSE_RELEASE_EVENT(EVENT,BUTTON) \

    (SoMouseButtonEvent::isButtonReleaseEvent(EVENT,SoMouseButtonEvent::BUTTON))



extent : -130 -130 -56.25 130 130 56.25
ROIManip : 0 0 0 255 255 74

getDimension

GetSeriesFilePathList( );

Sb - Scene basic
So - Scene object

right-handed coordinate system for 3D data
with +z comming out of the screen
all angles are specified in radians
object coordinate space



2016. 1. 27. 00:48

- Open Inventor가 입력 이벤트를 어떻게 처리하는지 설명

Open Inventor의 내장된 선택 정책 중 하나를 사용하요 씬에서 객체 선택

- 이벤트 콜백 노드를 생성함으로써 자신만의 선택 정책 구현

- 씬에서 선택된 객체 강조(Highlight)

- 선택 리스트가 변할 때 응용 프로그램이 어떤 연산을 수행하기 위해선택 콜백 함수 작성


Open Inventor 이벤트 모델 설명

- 처리를 위해 데이터 베이스에서 객체에 키 누름 또는 마우스 움직임과 같은 이벤트를 처리하기 위한 간단한 메커니즘을 제공

- 윈도우 시스템은 클라이언트 윈도우에 이벤트를 전달하는 같은 방법으로,

Inventor는 그것을 처리할 수 있는 데이터 베이스 객체에 이벤트를 전달한다

- 이벤트를 처리하기 위한 Inventor 프로그래밍 모델과 SoXtRenderArea의 사용, 렌더링을 수행하는 위젯, Inventor 데이터 베이스에 이벤트를 처리를 포함

- 이벤트 콜백함수, 선택 노드, 강조의 개념뿐만 아니라 SoHandleEventAction을 자세하게 논의

- 씬 매니저가 특별한 이벤트를 위한 이벤트 처리기를 어떻게 찾는지와 다른 노드들은 이벤트를 어떻게 처리하는지 배운다


* 이벤트 처리를 위한 일반적인 프로그래밍 모델


- 이벤트( SoEvent 로부터 파생)

- 씬 매니저

- 이벤트 액션 처리

- 이벤트 콜백 함수

- 선택 노드(Selection node)



* Inventor 이벤트 처리


1. 씬 매니저에 의해 제공되는 Inventor의 자동 이벤트 처리 메커니즘 사용


2. Inventor의 이벤트 콜백 메커니즘 사용, 여기에서 사용자가 쓴 콜백 노드는 이벤트를 처리

- 이 함수는 한 객체 당 이벤트 처리

- 구현하기 꽤 쉬움


3. Inventor의 이벤트 처리 메커니즘을 전체적으로 오버라이딩하고 모든 이벤트를 직접적으로 응용 프로그램에 전달


4. Inventor의 일반적은 콜백 메커니즘 사용, 여기에서 사용자 정의 콜백 노드는 모든 액션을 처리(SoCallback)

















2016. 1. 14. 16:46

* 4가지 Inventor 이벤트 처리 메커니즘


1. 씬 매니저에 의해 제공되는 Inventor의 자동 이벤트 처리 메커니즘 사용

- 이벤트를 처리하는 노드들의 몇 가지 종류를 포함

- 사용하기 가장 쉬운 메커니즘

- How Nodes Handle Evnets: SoHandleEventAction


2. Inventor의 이벤트 콜백 메커니즘 사용

- 이벤트를 처리하는 사용자 콜백 노드 사용

- 이 방법은 객체 당 이벤트를 처리하고 꽤 구현하기 쉽다

- 단점 : 어떤 패스가 모니터 되는지 또는 어떤 이벤트가 관심있는지에 대해 설명하는 필드를 가질 수 없다

- Using Event Callback Nodes


3. Inventor의 이벤트 처리 메커니즘을 전적으로 오버라이딩

- 응용 프로그램에 직접적으로 모든 이벤트를 전달

- 만약 객체당 이벤트를 처리할 필요가 없고 X 이벤트를 직접적으로 적용하는 걸 선호한다면 이 방법을 사용해라

- 이 벙법은 씬 순환에 직접 통과하고 오직 윈도우 이벤트만 처리한다

- Sending Events Directly to the Application


4. Inventor의 일반적인 콜백 메커니즘을 사용

- 사용자 작성 콜백 노드는 모든 액션을 다룬다

- 렌더링과 같은 또다른 액슨을 구현하기를 원하고 이벤트를 처리하기를 원하면 이 메커니점을 사용해라

- 만약 오직 이벤트만 처리하기를 원하면 2번을 사용해라

- 이벤트 콜백 노드는 당신에게 더 많은 일을 하기 때문이다

- SoCallback 노드의 예제에 관한 17장을 봐라


- 1, 2, 4 를 추천한다

- 윈도우 시스템에 독립적이다

- 더 유연하다

- 1, 2 번은 아마 가장 쉽다

2016. 1. 14. 16:33

- 어떻게 Open Inventor가 입력 이벤트를 처리하는지 설명

- Inventor의 내장 선택 정책 중 하나를 선택하여 객체를 선택

- 이벤트 콜백 노드를 생성함으로써 자신만의 선택 정책 구현

- 씬에서 선택된 객체를 하이라이트

- 선택 리스트가 변할 때 응용 프로그램이 어떤 연산을 수행하도록 허락하는 선택 콜백 함수 작성


* Open Inventor 이벤트 모델 설명

- 이것은 처리를 위해 데이터 베이스 안에서 객체에 대해 키 누르기 또는 마우스 움직임과 같은 이벤트를 보내는 간단한 메커니즘을 제공

- 윈도우 시스템이 클라이언트 윈도우에 이벤트를 보내는 것과 같은 대다수의 방식처럼, Inventor는 그것들을 처리할 수 있는 데이터 베이스 객체에 이벤트를 보낸다

- 중요한 개념은 이벤트 처리, SoXtRenderArea의 사용, 렌더링을 사용하는 위젯 그리고 Inventor 데이터베이스에서 이벤트 처리에 대한 Inventor 프로그래밍 모델을 포함한다

- SoHandelEventAction뿐만 아니라, 이벤트 콜백 함수의 개념, 선택 노드, 하이라이팅에 대해 자세하게 묘사한다


* 개요

- 사용자가 처리 박스 조종자에 마우스 버튼을 클릭하거나 스크린 상에서 새로운 위치에 물체를 드래그할 때, Inventor는 마우스로부터 사용자 입력을 어떻게 받고 그에 따라 객체를 이동할 수 있는가?

- 어떤 물체를 포함하지 않는 런더링된 이미지에서 공간을 마우스 클릭하면 무슨 일이 일어나는가?

- Inventor는 여러 개의 사용자 선택 객체를 어떻게 추적하는가?

- 이것들은 당신이 상호적인 Inventor 응용 프로그램을 작성하기 전에 대답되어야 할 모든 질문들이다


- 여기서는 어떻게 윈도우에 구체화된 이벤트가 Inventor 이벤트로 번역되는지에 대한 짧은 설명을 제겅한다

- Inventor 이벤트의 다른 종류와 그것들과 연관된 함수들을 설명한다

- 어떻게 씬 매니저가 구체적인 이벤트에 대해 이벤트 처리기를 찾고 어떻게 다른 노드들이 이벤트를 다루는지에 대해 배운다


* 이벤트 처리기에 대한 일반적인 프로그래밍 모델


- Inventor는 씬 데이터 베이스에 대해 내장 이벤트 모델을 포함한다

- 이 모델은 어떤 구체적인 윈도우 시스템 또는 툴킷에 기초하지 않는다.

- Inventor 프로그램을 작성할 때 당신은 X 윈도우 프로그래밍 모델을 선택할 수 있고 윈도우를 열기 위해 윈도우 시스템에 의해 제공되는 도구를 사용할 수 있고 Inventor로 이벤트를 보낼 수 있다

- Inventor는 X로부터의 이벤트 번역을 Inventor 이벤트 클래스로 제공한다

- 아래 그림은 X 이벤트가 렌더링 영역에 어떻게 통과하는지 보여준다

- Inventor 씬 매니저에 의해 처리되는 Inventor 이벤트로 번역되는지 보여준다

- Inventor는 윈도우 시스템에 독립적이기 때문에 다른 윈도우 시스템을 선택할 수 있고 자신만의 이벤트 번역기를 작성할 수 있다






* X 윈도우 시스템 사용하기


- Inventor는 X 윈도우 시스템과 함께 사용할 수 있는 Xt 유틸리티 집합 제공

- 렌더링 영역 "위젯"

- 메인 루프와 초기화 함수

- 이벤트 번역기 유틸리티


- 이 특징들에 추가하여 Inventor 컴포넌트 라이브러리는 또한 Xt 컴포넌트의 집합을 포함한다

- 이 컴포넌트들은 씬 데이터 베이스를 직접적으로 변경하기 위한 사용자 인터페이스에 관한 뷰어와 편집기를 포함한다


- 윈도우 시스템에 독립적인 Inventor의 측면에 초점

- 이벤트 ( SoEvent 로부터 파생 )

- 씬 매니저

- 이벤트 액션 처리

- 이벤트 콜백 함수

- 선택 노드


* Render Area

- 윈도우가 리사이즈 되거나 노출되거나 씬이 변화할 때 윈도우를 다시 그리는 내장 센서

- 내장 이벤트 처리기

- 투명도 타입과 안티 앨리어싱의 양과 같은 제어


Inventor 이벤트( SoEvent )


- 타입 정보( SoType )

- 이벤트가 발생한 시간

- 이벤트가 발생했을 때 커서 위치

- 이벤트가 발생했을 때 변경 키(Shift, Control, Alt)의 상태


- SoEvent의 하위 클래스는 추가 정보 포함

- 예를 들어 SoButtonEvent는 이벤트가 발생했을 때 버튼이 눌렸는지 아닌지에 대한 정보를 포함

- SoMouseButtonEvent 는 버튼이 눌렸을 때 어떤 버튼이 눌렸는지에 관한 정보를 포함


- 매크로 사용

- SO_MOUSE_PRESS_EVENT() : SoEvent와 버튼 숫자를 넣는다

                                   버튼이 눌렸을 때 TRUE 를 리턴

- SO_MOUSE_RELEASE_EVENT() : 버튼을 떼었을 때 TRUE 리턴


- SoKeyboardEvent 는 어떤 키가 눌렸는지에 관한 정보를 포함한다


- SoLocation2Event 는 커서가 움직였을 때마다 발생한다

- 이 이벤트는 윈도우 좌표에서 커서의 절대 위치를 포함한다

- (0, 0) 은 왼쪽 아래 코너로 시작한다


- SoMotion3Event 는 공간 볼과 같은 3D 입력 장치가 움직일 때마다 발생

- 이 이벤트는 장치의 이전 위치에 관한 상대적인 회전과 이동을 포함한다


* 씬 매니저

- SoSceneManager는 윈도우-시스템 독립적인 렌더링 영역에 속한 Inventor에서 사용되는 공통적인 클래스이다

- 렌더링 영역은 씬 그래프를 처리하기 위해 씬 매니저를 사용한다

- 씬 매니저는 렌더링과 이벤트 처리 둘 다 처리한다

- 어떤 특정한 윈도우 시스템에 독립적이다




























2016. 1. 14. 10:37

- 오버레이 평면은 Inventor에서 특별한 목적을 위해 사용될 수 있는 비트 평   면의 separate 집합이다

- 주요 이미지의 최상위에 나타나는 씬에서  물체를 위해 사용되고, 독립적으로 다시 그려진다

- 오버레이 평면에서 위치한 씬 그래프의 색상과 복잡도에 관한 한계가 있지만, 그것들을 사용하는 것은 완전한 씬 그래프를 다시 그리는 것 없이 간단한 씬 그래프를 빠르게 다시 그릴 수 있다

- 오버레이 평면은 사용자 피드백을 제공하기 위해 유용한 메커니즘을 제공한다

- 예를 들면 커서를 따라다니는 지오메트리를 빠르게 그릴 수 있다


- 오버레이 평면에서 씬 그래프를 위치시키는 다음 함수들을 사용하라

- setOverlaySceneGraph()

- 오버레이 평면에서 렌더링 하기 위한 씬 그래프 설정

- setOverlayColorMap()

- 오버레이 비트 평면을 위해 사용하는 색상 설정

- 오버레이 평면은 보통 색상-인덱스 모드 사용

- setOverlayBackgroundIndex()

- 오버레이 이미지를 위한 배경색 인덱스 설정(디폴트 0, 클리어 색상)


오버레이 씬 그래프는 자신만의 다시 그리는 센서를 가지고, 이 제한 조건을 가진 "일반적인" 씬 그래프와 유사하다

- 만약 몇 개의 오버레이 평면을 가지고 있으면, SoLightModel의 model 필드에 대해 BASE_COLOR 를 설정하라

- 씬 그래프를 간단하게 유지하라.

- 빨리 그릴 수 있는 라인 그리기-스타일, 직사각형, 2D 텍스트를 사용하라

- 텍스처를 사용하지 말아라

- 왜냐하면 오버레이 평면은 싱글 버퍼이기 때문에 만약 씬이 너무 복잡하면 다시 그릴 때 깜빡거릴 수 있다

- 색상 맵을 로딩하는 걸 확실히 해라. 오버레이 평면에 대해 디폴트 색상 맵은 없다

- 오버레이 평면에 대한 색상 맵은 색들의 한계 수를 포함한다

- 색상 0 은 클리어이고 변할 수 없다

- 두 개의 비트 평면을 가지고, 색상을 위해 1부터 3까지 인덱스를 사용할 수 있다


 

2016. 1. 12. 23:04

SoRayPickAction은 View Volume 의 near 평면에서 점을 통해 카메라로부터 광선을 따라 물체를 찾는다

이 광선은 전형적으로 윈도우-공간 픽셀의 좌표를 줌으로써 구체화된다

SoRayPickAction은 액션을 적용한 신 그래프를 순환한다

그 후에 가장 가까운 거부터 가장 먼 거까지 정렬된, 찍은 광선을 따라 모든 도형에 대한 경로를 리턴한다

찍는 액션은 주로 지오메트리, 변형, 모양 노드에 관심있다


SoSelection 노드는 자동적으로 객체를 찍는다



* Picking Style

- 디폴트로 신 그래프에서 모든 물체는 찍음 가능하다

- 심지어 투명하거나 안 보이는 물체도 가능하다

- 찍음 액션에 보이지 않는 객체의 그룹 또는 물체를 만들기 위해

SoPickStyle 을 신 그래프에 삽입하고, style 필드를 UNPICKABLE로 설정

_ SHAPE, BOUNDING_BOX


- 액션의 인스턴스 생성


* SoRayPickAction 의 인스턴스 생성 예제


SbViewportRegion viewport;

SoRayPickAction pickAction(viewport);


뷰 포트 영역은 SoText2와 같은 스크린 정렬 물체에 대한 경계 박스를 계산하기 위해 사용


* 파라미터 설정


- 찍음 액션을 적용하기 전에 다음 파라미터를 설정할 수 있음

- 찍을 광선

- 오직 가까운 물체만 리턴할지 또는 광선에 따른 모든 물체를 리턴할지


- 찍음 광선은 두 방법 중에 하나로 구체화할 수 있다.

- 윈도우 점과 반경을 구체화 하든지

- 점과 세계 공간에 대한 방향을 구체화 하든지

- 첫 번째 방법이 상호 작용 프로그램에 대해 더 전형적이다

- 왜냐하면 일반적으로 커서 아래의 영역에 대부분 관심이 있기 때문


* 윈도우 점을 가진 찍음 광선 구체화

- setPoint(), setRadius() 함수를 찍음 광선을 설정하기 위해 사용

























2016. 1. 12. 22:32

신 그래프에 어떤 액션을 수행하는 것은 일반적인 모델을 따른다


1. 액션 클래스의 인스턴스를 생성하므로써 액션을 초기화하라.


SbViewportRegion region(300, 200);

SoGLRenderAction renderAction(region);


액션의 인스턴스를 할당하기 위한 new 연산자를 이용할 수도 있다


renderAction = new SoGLRenderAction(region);


new를 가지고 액션을 생성하면, 끝내기 전에 액션을 삭제하는 걸 잊지 마라


2. 액션에 대한 특별한 파라미터를 설정하라

예를 들어, SoGLRenderAction 에 대한 생성자는 뷰포트 영역을 설정하는 것 뿐만 아니라 OpenGL 설정을 상속받을 것인지 결정할 수 있다


SoGLRenderAction renderAction(region, TRUE);


3. 노드, 패스 또는 패스 리스트 에 액션을 적용하라


renderAction->apply(root);


4. 액션에 대한 결과를 얻어라

어떤 액션들은 그것들을 사용하기 위해 추가 함수를 가진다


예를 들어 SoGetBoundingBoxAction 은 다음 함수를 가진다

getBoundingBox() - 액션에 의해 계산된 경계 박스

getCenter() - 계산된 중심 반환



2016. 1. 7. 17:52

- 대부분 Volume 품질 설정은 SoVolumeRenderingQuality 노드의 부분

- 그러나 전체는 아님

- 예를 들면, 샘플의 수(the number of samples)와 관련된 설정은 SoVolumeRender 노드의 일부


* SoVolumeRenderingQuality

- lighting

2016. 1. 7. 16:05



2016. 1. 7. 14:47

- 슬라이스 렌더링과 비교하여, 직접적인 Volume 렌더링은 이미지를 생성하는 것의 완전히 다른 방법이다

- 다른 Open Inventor 렌더링 노드들과는 다르게 Volume 렌더링은 점, 선, 삼각형과 같은 전통적인 컴퓨터 그래픽스 도형의 어떤 것도 사용하지 않음

Volume 데이터 : 3D 스칼라 필드, 스칼라 값 셀의 일반 그리드로 고려

- 2D 픽셀과 유사하게, 각각 3D 셀은 "Voxel"로 불린다 : volume element

Volume 렌더링은 어떤 지오메트리 사용없이 Volume 데이터 가시화 가능

- VolumeViz는 Volume Ray-casting 기술을 이용하여 보여줌

- Ray는 Volume을 통해 던져지고 규칙적인 또는 적절한 간격을 샘플링 함

- 각 샘플 점에서 데이터 값들은 보간

- 결과 스칼라 값은 transfer function을 통해 색과 투명도에 맵핑

- 이것은 RGBA 값을 결과로 출력

- 개념적으로 이 값은 Volume을 통해 Voxel이 빛 투과에 어떻게 영향받는지 결정

- RGBA 값은 Ray를 따라 이전 값에 합쳐지(composite)

- 최종 합성된 ray의 값은 화면에서 대응되는 픽셀의 색상을 결정

- 다른 렌더링 노드와 마찬가지로 이 알고리즘은 최대 성능을 위해 

  완전히GPU에서 구현


Volume 렌더링은 유일한 렌더링 기술이고 슬라이스 기반 렌더링보다 더 강력함(powerful)

- 그러나 사용하는데 훨씬 더 복잡하고 GPU에서 요구되는 거대한 계산량 때문에 일반적으로 슬라이스 렌더링보다 덜 상호적(interactive)

- 슬라이스 렌더링은 Volume의 내부 구조에 대한 단서 제공하는 반면에

  Volume 렌더링은 직접ㅈ적으로 내부 구조의 모양을 가시화


-SoVolumeRender 노드를 지오메트리 노드의 한 종류로 생각하는 것이 편리

- VolumeViz는 가능한 많이 표준 Open Inventor 속성(attribute)과 연산(operations)을 적용

- 예를 들어 Voxel에 빛을 적용할 수 있고, 그림자를 주고 받을 수 있음

- 유사하게 SoRayPickAction을 Volume 렌더링을 포함하는 신(scene)에 적용할 때, 액션은 첫 번째 불투명 voxel을 찾음



* Ray Casting

- 이 알고리즘은 빛의 방사(emission), 반사(reflection) 그리고 흡수(absorption)에 기반한 고전 컴퓨터 그래픽스 렌더링 방정식을 구현

Volume으로 ray cast의 수가 스크린에 렌더링되어야 하는 픽셀에 수의 의존하기 때문에 이미지 기반 기술

- ray에 따른 샘플링은 성능과 이미지 품질을 증가시키기 위해 Volume에서 데이터에 적용할 수 있기 때문 텍스처 폴리곤 기반보다 유연(flexible)

- VolumeViz ray-casting 엔진은 GPU에서 실행

- 그래픽 보드에서 프로세서의 수에 따라 스케일되는 훌륭한 성능을 수행하기 위해 GPU의 거대한 평행(parallelism)을 활용

- GPU 구현은 표준 GLSL 언어에서 쓰이는 셰이더 함수를 사용해서 응용 프로그램에 확장(extented)할 수 있고 편집(customized)할 수 있음


The four basic steps of volume ray casting: 1. Ray Casting 2. Sampling 3. Shading 4. Compositing.

Figure 1.29. The four basic steps of volume ray casting: 1. Ray Casting 2. Sampling 3. Shading 4. Compositing.


(Volume에 의해 영향을 받을 수도 있는) 최종 이미지에서 각 픽셀에 대해,

"ray"는 신 과 Volume을 통해 직선으로 던져진다

- 이 ray를 따라 간 계산은 평행하게 수행될 수 있음

- 각 ray에 대해 Volume의 잘리지 않은 부분과 교차되는 점이 계산됨

Volume은 clip plane, region of interest, polygons 그리고 다른 기술에 의해 잘릴 수 있음

- 교차점을 시작으로 ray에 따른 샘플링 점들은 선택된다

- 각 샘플 점들에 대해 데이터 값은 주변 voxel과 함께 보간에 기반되어 계산

- 응용 프로그램은 데이터에 필터를 적용하거나 여러 개의 Volume을 혼합하여 이 계산을 편집(customize)할 수 있음

- 만약 빛(lighting) 또는 모서리 검출(edge detection)과 같은 렌더링 기술이 가능하면, 그래디언트(gradient)는 계산됨

- 이것은 표면 범선 벡터(surface normal vector)와 유사하게 Volume 렌더링을 표현

- 응용 프로그램은 정확성과 성능의 거래(trade-off)에 따라 여러 그래디언트 알고리즘을 선택 가능

- 샘플 값과 그래디언트를 사용하여, 색과 투명도가 계산

- VolumeViz 는 라이팅(lighting), 모서리 색상(edge coloring) 그리고 경계 투명도(boundary opacity)와 같은 추가 렌더링 효과를 제공

- 최종적으로 샘플링된 색생과 투명도는 ray에서 출발한 각 픽셀에 대해 최종 색상과 투명도를 계산하기 위해 ray에 따른 다른 샘플들과 함께 혼합됨

- 응용 프로그램은 여러 혼합 알고리즘 중에서 선택


- VolumeViz는 호환성(compatibility)을 위해 이전의 렌더링 알고리즘 제공

- 이 알고리즘은 Volume 데이터에 텍스처를 입힌 폴리곤의 스택을 그림으로써 Volume 렌더링에 근사화 한다

- 폴리곤 렌더링 알고리즘은 SoVolumeRenderingQuality 노드에서 raycasting 필드를 false 로 설정하면 행해짐


* Rendering

- 슬라이스 렌더링과 마찬가지로, Volume 렌더링의 색과 투명도는 주로 

SoMaterial, SoDataRange 그리고 SoTransferFunction(color map) 노드에 의해 결정

Volume 렌더링의 결과는 슬라이스 객체(primitive)와는 약간 다른 옵션을 제외하고 보간에 의해 영향을 받음

- 기본 색과 투명도가 결정된 후에 라이팅과 렌더링은 슬라이스 렌더링보다 훨씬 더 복잡하다

Volume 렌더링의 최종 결과는 다음 항목에 영향을 받음

-- LDM 메모리 설정

-- 렌더링 품질 설정(Rendering Quality Setting) 

-- 렌더링 효과 (Rendering Effect)

-- 렌더링 모드(Rendering Mode)


- 렌더링 품질 설정(Volume Rendering Quality Settings)

- SoVolumeRender

- SoVolumeRenderingQuality

- 샘플링 수(Number of samples)

- 이전 통합 렌더링(Preintegrated rendering)

- 지터링(Jittering)

- 3차원 보간(Cubic Interpolation)


- 풀 해상도에서 메모리에 로딩될 수 없는 매우 큰 Volume에 대해 Volume 렌더링의 결과(appearance)는 SoLDMResourceParameters의 필드를 사용한 LDM 파라미터 설정에 의해 영향을 받음

Volume에 대한 SoLDMResourceParameters 객체는 SoVolumeData 노드의 ldmResourceParameters 필드로부터 요구(query)할 수 있다

- 관계있는 필드는 maxMainMemory 와 maxTexMemory를 포함한다


- 렌더링 효과(Volume Rendering Effects)

- SoVolumeRenderingQuality

- 라이팅과 같은 사실 효과와 에지 컬러링과 같은 NPR(non-photorealistic) 효과 둘 다 포함

- Lighting

- Edge coloring

- Boundary opacity

- Edge detection (2D)


Volume의 Lighting 

- SoVolumeRenderingQuality 노드를 사용하여 옵션 설정

- Gradient quality

- Gradient threshold

- Surface scalar exponent

- Ambient occlusion


Volume 렌더링의 성능

- Volume의 크기

- 샘플의 수

- 선택된 품질 설정(quality settings)

- 렌더링 효과(Rendering effects)

- SoVolumeRender 노드에서 구체적인 옵션

-- lowResMode

-- lowScreenResolutionScale

-- subDivideTile

-- gpuVertexGen


* 렌더링 모드(Volume rendering modes)

- 다양한 노드를 사용하여 대체적인 렌더링 모드를 사용한 이미지 생성

- Maximum Intensity Projection ( and other composition styles)

- Isosurface rendering

- Voxelized("Sugar cube") rendering

- Mask boundary rendering












2016. 1. 7. 01:16

- Volume 데이터는 응용 프로그램의 메모리에 저장되어 있다고 가정

- VolumeViz에서 사용 가능한 Volume 데이터를 만드는 것

Volume 데이터를 묘사할 파라미터 설정


- VolumeViz가 시스템 메모리에 저장된 Volume에 접근하는 방법

Volume 차원 : 256 x 256 x 256

- 데이터 값은 부호없는 8비트 정수(bytes : unsigned 8-bit integers)

- 데이터와 특성은 SoVolumeData 노드의 setValue() 함수를 사용해서 데이터 필드를 설정

- 이 함수의 세 번째 파라미터는 numSigBits(각 데이터 값에서 중요 비트의 수)

- 이 경우에 우리는 모든 8비트를 사용하므로 이 파라미터를 0으로 설정하고, 이것은 모든 비트를 사용한다는 의미

- 다른 경우의 예에서 16비트 값에서 오직 12 비트를 사용하는 DICOM 데이터의 경우 이 파리미터를 12 로 설정

- 만약 VolumeViz가 데이터의 복사본을 만들면, 응용 프로그램은 메모리를 해제할 수 있음


// Pointer to Volume data

unsigned char* pData = new unsigned char [numVoxels];

...


// Volume Characteristics

SbVec3i32 volDim(256, 256, 256);

SbDataType dataType = SbDataType::UNSIGNED_BYTE;


SoVolumeData* pVolData = new SoVolumeData();

pVolData->data.setValue(volDim, dataType, 0, 

                             (void*)pData, SoSFArray::NO_COPY);

2016. 1. 7. 00:50

Volume의 특성

- 차원(dimension)

- 범위(extent)

- Voxel 크기(size)/공간(spacing)

- 데이터 타입(data type)

- 데이터 범위(data range)

- GPU에서의 data


* 차원(Dimensions)

- Volume의 차원(각 축에 대한 Voxel의 수)은 보통 데이터 파일에서의 정보로부터 Volume 리더에 의해 결정

- 스택에서의 이미지 수

- 데이터 필드를 이용해서 Volume 차원을 쿼리할 수 있다


SbVec3i32 volumeDimension = pVolumeData->data.getSize();


* 범위(Extent)

- 3D에서 Volume의 기하학적 범위는 Volume 리더에 의해 초기에 결정

- extent 필드를 사용하여 설정 가능

- Volume 범위는 월드 공간에서 Volume의 경계 박스(bounding box)

- 종종 3D에서 Volume 범위는 Volume의 차원과 같게 설정됨

- 또는 Volume 차원에 비례하여 값을 설정

- Volume 범위는 어떤 범위든 될 수 있음

- Volume 범위는 간접적으로 Voxel 크기/공간을 지정

- extent 필드를 사용하여 Volume 범위를 쿼리


SbBox3f volumeExtent = pVolumeData->extent.getValue();


* Voxel 크기(size)/공간(spacing)

- 만약 Volume 데이터가 균일하게 샘플링되면, Voxel 크기는 Volume 범위를 Volume 차원으로 나눈 값

- Voxel 크기는 각 축에 따라 여전히 균일하지만, 최소한 한 축에 따라 다름

- 이것은 Volume Z 축을 따라 더 큰 공간을 가지는 의료 스캐너 Volume 의 전형

- 그러나 Volume 범위는 응용 프로그램에 의해 정해지고 심지어 실시간으로 바뀜

- VolumeViz는 균일적으로 Voxel에 한계가 있지 않음

- VolumeViz는 또한 "직사각 좌표"(rectilinear coordinates) 를 지원

 여기서 각축에  따라 비균일(non-uniform) voxel위치가 구체적으로 주어짐

- 이 정보는 Volume 리더에 의해 제공

- 쿼리 방법

SoVolumeData의 함수 getCoordinateType() 과 getRectilinearCoordinates() 함수를 사용


* 데이터 타입(Data Type)

- VolumeViz는 부호 있고(signed)와 부호 없는(unsigned) 정수 값

(byte, short, int) 또는 부동 소수점 값을 지원

- VolumeViz는 32비트에 알파 값을 포함하는 RGBA Volume 을 지원

- 데이터 타입은 리더(reader)에 의해 결정 (data 필드를 설정할 때)

- 쿼리 방법(데이터 타입, Voxel당 바이트 수)


int bytesPerVoxel = pVolumeData->getDataSize();

SoDataSet::DataType type = pVolumeData->getDataType();



* 데이터 범위(Data Range)

- 바이트보다 더 큰 데이터 타입을 사용하는 Volume에서, 데이터 값의 실제 범위는 보통 데이터 타입의 범위보다 더 작음

- 응용프로그램은 transfer function에 매핑될 값의 범위를 정하기 위해 SoDataRange 노드를 사용

- 쿼리 방법


double minVal, maxVal;

SbBool ok = pVolumeData->getMinMax(minVal, maxVal);


- 만약 getMinMax( ) 쿼리가 반응하지 않으면, 이 함수는 전체 데이터 집합을 메모리로 로딩시키는 것을 VolumeViz에 강제시키고, 

최소, 최대 값을 계산하기 위해 모든 voxel을 통해 스캔함



* GPU에서의 데이터

- 디폴트적으로, VolumeViz는 8비트보다 더 큰 모든 타입의 데이터 값을 8 비트 부호없는 정수(8-bit unsigned integer) 값으로 GPU에 스케일링함

- 렌더링 목적을 위해 이것은 보통 충분하고 

 작은 데이터 타입을 사용하는 것은 GPU 위의 사용가능한 메모리에서 

로딩될 수 있는 데이터의 양을 최대화함

- 만약 필요하다면 SoVolumeData 노드의 texturePrecision 필드를 

  설정함으로써 12 비트 정수 값을 사용할 수 있음

- 주의 : 12 비트 옵션은 실질적으로 데이터를 저장하기 위해 16비트 텍스처를 사용한다. 그래서 이 경우에는 GPU에서 필요한 메모리는 2배가 됨

- 개념적으로 고려할 이슈는 (데이터 타입과 데이터 범위(range)에 의존하여) 실질적인 데이터 값의 범위는 각 GPU 값 위에 "aliased" 될 수 있음

- 예를 들어 32 에서 47까지의 범위에 있는 모든 데이터 값은 GPU 메모리에서 32로 끝날 수 있음

- 렌더링을 위해 GPU에서 더 큰 데이터 타입을 사용하는 것의 주요 장점은 더 크고 더 정확한 컬러 맵을 이용하기 위해서임

- 요약하면, 디폴트 데이터 저장공간은 256개의 다른 값을 허락하고 12 비트 저장공간은 4096의 값을 허락한다



2016. 1. 6. 17:44

- 관련있는 노드, 필드, 함수와 관련 있는 다양한 특징의 링크


* Volume Data

- volume 데이터에 접근하기 위한 SoVolumeData 노드를 사용하라


* 데이터 Volume 은 다음에 의해 주어질 수 있다

- 파일 이름

- Volume 리더

- 메모리 블럭

- LDM 포맷으로 변경


* Volume 속성

- 크기(Size) : 각 축에서 Voxel의 개수

- 범위(Extent) : 3D 공간에서 Volume의 기하학적 범위

- Voxel 크기(size)/공간(spacing) : 각 축에 따라 균일할 수도 있고, 

                                       다를 수도 있음

- Data 타입 : 정수 또는 소수점 스칼라 값, RGBA 값, boolean 값(mask)

- 중요한(significant) 비트 들의 수 : 16 비트 워드 안에서 12 비트 값

- Data Range : 색상 테이블에 맵핑되는 값들의 실제 영역



* VolumeViz Scene Graph


2016. 1. 6. 15:52

* Volume 데이터를 로딩하는 가장 간단한 방법

Volume은 디스크에 저장

- SoVolumeReader 클래스를 이용

- 응용 프로그램은 각자 자신의 Volume 리더 클래스를 생성할 수 있음

- 파일 확장자에 기초한 Volume 리더 클래스 선택

- ".ldm" 파일을 위해 SoVRLdmFileReader 클래스 사용

- SoVolumeData::filename 필드에 설정 예제


* 논의할 내용

- 파일 포맷

- 비표준 확장자를 가진 파일 로딩

- "raw" 데이터(no header) 로딩

- 이미지 스택 로딩

- RGBA 데이터


* 파일 포맷

- VolumeViz 파일 리더

- 파일 이름 확장자에 리더 클래스가 관련


File extensionReader classDescription
.amSoVRAmFileReaderAvizo Mesh file format
.dc3, .dic, .dicomSoVRDicomFileReaderDICOM file format
.fldSoVRAvsFileReaderAVS field file format
.ldmSoVRLdmFileReader

Large Data Management format

.sgy or .segySoVRSegyFileReaderSEG Y revision 1 file format
.volSoVRVolFileReaderVol file format
.voxSoVRVoxFileReaderVox file format
.lstSoVRRasterStackReader

Lst file format


* 비표준 확장자

- 만약 파일 이름이 확장자를 가지고 있지 않거나 적당한 확장자를 가지고 있지 않다면, 응용 프로그램은 파일을 로딩하기 위해 여전히 특별한 Volume 리더를 사용할 수 있다

- 그러나 SoVolumeData 노드의 setReader() 함수를 이용하여 구체적으로 Volume 리더를 설정해야 한다


- 예를 들어 Volume 파일이 VOL 포맷을 가진 데이터를 포함하지만 파일 이름이 정확한 확장자를 가지고 있지 않다면,

VolumeViz는 VOL 포맷으로 데이터를 읽게 하기 위해 다음 코드는 강제한다





* Raw 데이터

- 만약 파일이 VolumeViz가 직접적으로 지원하는 포맷이 아니지만,

행 x 행 으로 조직된 값들의 연속적인 블럭으로 Volume 데이터를 포함하면

일반적인 리더 SoVRGenericFileReader 를 이용할 수 있다

- 이것은 보통 "raw" 데이터파일로 불린다

Volume의 범위(extent), 데이터 타입, 차원(dimension)을 구체화할 필요

- 다음 코드는 일반 리더(generic reader)를 이용하여 데이터를 로드





*  이미지 스택

- Volume이 여러 개(multiple)의 이미지 파일로 저장되었다면,

  SoVRRasterStackReader 클래스를 사용

- 이미지 스택을 로딩하는데 유용

- Open Inventor가 지원하는 이미지 파일 : JPEG, PNG, TIFF

- 이미지들의 포맷은 다를 수 있어도 같은 사이즈여야만 함

- 이미지 크기는 X, Y dimension

- Z dimension은 슬라이스의 수


- 이미지 스택을 로딩하기 위해 이미지 파일 이름들의 리스트를 포함하는 파일이 존재해야 함

- 이미지 파일 이름은 간단한 파일 이름이 될 수도 있고, 완전한 파일 경로가 될 수도 있다

- 만약 이미지 파일 이름이 간단한 파일 이름이라면, VolumeViz는 리스트 파일을 포함하는 디렉토리에서 오픈할 수 있다

- 리스트 파일에서 파일 이름의 순서는 어떻게 슬라이스를 로딩할지를 결정

- VolumeViz는 첫 번째 이미지가 슬라이스 0이고, Volume의 "뒤"이고 연속적인 슬라이스가 Z 값이 증가하는 순서로 로딩한다고 가정


- 테디 베어 예제 데이터

- 리스트 파일은 다음과 같고, 여기에서 "Size" 파라미터는 범위를 의미

Parameters {
  Size 10.000000 10.000000 10.000000 1250.000000 1250.000000 500.000000
}
teddybear000.jpg
teddybear001.jpg
teddybear002.jpg
teddybear003.jpg
teddybear004.jpg
...

- 일단 리스트 파일을 가지면, 데이터를 로딩하는 것은 이전 예제와 같다




* RGBA 데이터

- RGBA Volume에서 Voxel은 UNSIGNED_INT32 값이다

- 각 값은 8bit Red, Green, Blue 그리고 Alpha 값을 포함

- 모든 렌더링 노드(slices, volume rendering, 등등)는 RGBA volume을 가지고 작업

- Region of Interest, Clipping 그리고 다른 특징들도 또한 RGBA volume을 가지고 작업

- Volume은 이미 렌더링에 사용될 색을 지정했기 때문에, 

Data Range와 Transfer Function은 무시한다





2015. 11. 12. 13:41

오른손 좌표계 사용

+z : 화면 밖으로 나오는 방향

모든 각은 radian으로 표시

객체는 자신의 로컬 좌표 공간에서 묘사(object coordinate space)

신 그래프에서 모든 변환이 객체에 적용된 후에 월드 좌표 공간으로 변환

월드 좌표 공간에서 카메라와 빛(light)을 포함