검색결과 리스트
프로그래밍/Open Inventor 에 해당되는 글 19건
- 2016.10.18 각 사용하는 방식 자투리
- 2016.01.27 이벤트 처리와 선택
- 2016.01.14 Inventor 이벤트 처리기
- 2016.01.14 이벤트 핸들링과 선택
- 2016.01.14 Overlay 평면 사용
- 2016.01.12 Picking
- 2016.01.12 Performing Action
- 2016.01.07 Volume 렌더링 품질 설정(Volume Rendering Quality Settings
- 2016.01.07 SoVolumeRender
- 2016.01.07 Volume Rendering 개요
- 2016.01.07 메모리로부터 로딩
- 2016.01.07 Volume의 특성
- 2016.01.06 VolumeViz 의 특징
- 2016.01.06 VolumeViz - 파일로부터 로딩
- 2015.11.12 Include Files
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))
- 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)
* 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 번은 아마 가장 쉽다
- 어떻게 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에서 사용되는 공통적인 클래스이다
- 렌더링 영역은 씬 그래프를 처리하기 위해 씬 매니저를 사용한다
- 씬 매니저는 렌더링과 이벤트 처리 둘 다 처리한다
- 어떤 특정한 윈도우 시스템에 독립적이다
- 오버레이 평면은 Inventor에서 특별한 목적을 위해 사용될 수 있는 비트 평 면의 separate 집합이다
- 주요 이미지의 최상위에 나타나는 씬에서 물체를 위해 사용되고, 독립적으로 다시 그려진다
- 오버레이 평면에서 위치한 씬 그래프의 색상과 복잡도에 관한 한계가 있지만, 그것들을 사용하는 것은 완전한 씬 그래프를 다시 그리는 것 없이 간단한 씬 그래프를 빠르게 다시 그릴 수 있다
- 오버레이 평면은 사용자 피드백을 제공하기 위해 유용한 메커니즘을 제공한다
- 예를 들면 커서를 따라다니는 지오메트리를 빠르게 그릴 수 있다
- 오버레이 평면에서 씬 그래프를 위치시키는 다음 함수들을 사용하라
- setOverlaySceneGraph()
- 오버레이 평면에서 렌더링 하기 위한 씬 그래프 설정
- setOverlayColorMap()
- 오버레이 비트 평면을 위해 사용하는 색상 설정
- 오버레이 평면은 보통 색상-인덱스 모드 사용
- setOverlayBackgroundIndex()
- 오버레이 이미지를 위한 배경색 인덱스 설정(디폴트 0, 클리어 색상)
오버레이 씬 그래프는 자신만의 다시 그리는 센서를 가지고, 이 제한 조건을 가진 "일반적인" 씬 그래프와 유사하다
- 만약 몇 개의 오버레이 평면을 가지고 있으면, SoLightModel의 model 필드에 대해 BASE_COLOR 를 설정하라
- 씬 그래프를 간단하게 유지하라.
- 빨리 그릴 수 있는 라인 그리기-스타일, 직사각형, 2D 텍스트를 사용하라
- 텍스처를 사용하지 말아라
- 왜냐하면 오버레이 평면은 싱글 버퍼이기 때문에 만약 씬이 너무 복잡하면 다시 그릴 때 깜빡거릴 수 있다
- 색상 맵을 로딩하는 걸 확실히 해라. 오버레이 평면에 대해 디폴트 색상 맵은 없다
- 오버레이 평면에 대한 색상 맵은 색들의 한계 수를 포함한다
- 색상 0 은 클리어이고 변할 수 없다
- 두 개의 비트 평면을 가지고, 색상을 위해 1부터 3까지 인덱스를 사용할 수 있다
SoRayPickAction은 View Volume 의 near 평면에서 점을 통해 카메라로부터 광선을 따라 물체를 찾는다
이 광선은 전형적으로 윈도우-공간 픽셀의 좌표를 줌으로써 구체화된다
SoRayPickAction은 액션을 적용한 신 그래프를 순환한다
그 후에 가장 가까운 거부터 가장 먼 거까지 정렬된, 찍은 광선을 따라 모든 도형에 대한 경로를 리턴한다
찍는 액션은 주로 지오메트리, 변형, 모양 노드에 관심있다
SoSelection 노드는 자동적으로 객체를 찍는다
* Picking Style
- 디폴트로 신 그래프에서 모든 물체는 찍음 가능하다
- 심지어 투명하거나 안 보이는 물체도 가능하다
- 찍음 액션에 보이지 않는 객체의 그룹 또는 물체를 만들기 위해
SoPickStyle 을 신 그래프에 삽입하고, style 필드를 UNPICKABLE로 설정
_ SHAPE, BOUNDING_BOX
- 액션의 인스턴스 생성
* SoRayPickAction 의 인스턴스 생성 예제
SbViewportRegion viewport;
SoRayPickAction pickAction(viewport);
뷰 포트 영역은 SoText2와 같은 스크린 정렬 물체에 대한 경계 박스를 계산하기 위해 사용
* 파라미터 설정
- 찍음 액션을 적용하기 전에 다음 파라미터를 설정할 수 있음
- 찍을 광선
- 오직 가까운 물체만 리턴할지 또는 광선에 따른 모든 물체를 리턴할지
- 찍음 광선은 두 방법 중에 하나로 구체화할 수 있다.
- 윈도우 점과 반경을 구체화 하든지
- 점과 세계 공간에 대한 방향을 구체화 하든지
- 첫 번째 방법이 상호 작용 프로그램에 대해 더 전형적이다
- 왜냐하면 일반적으로 커서 아래의 영역에 대부분 관심이 있기 때문
* 윈도우 점을 가진 찍음 광선 구체화
- setPoint(), setRadius() 함수를 찍음 광선을 설정하기 위해 사용
신 그래프에 어떤 액션을 수행하는 것은 일반적인 모델을 따른다
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() - 계산된 중심 반환
- 대부분 Volume 품질 설정은 SoVolumeRenderingQuality 노드의 부분
- 그러나 전체는 아님
- 예를 들면, 샘플의 수(the number of samples)와 관련된 설정은 SoVolumeRender 노드의 일부
* SoVolumeRenderingQuality
- lighting
- 슬라이스 렌더링과 비교하여, 직접적인 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)할 수 있음
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
- 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);
* 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의 값을 허락한다
- 관련있는 노드, 필드, 함수와 관련 있는 다양한 특징의 링크
* 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
* Volume 데이터를 로딩하는 가장 간단한 방법
- Volume은 디스크에 저장
- SoVolumeReader 클래스를 이용
- 응용 프로그램은 각자 자신의 Volume 리더 클래스를 생성할 수 있음
- 파일 확장자에 기초한 Volume 리더 클래스 선택
- ".ldm" 파일을 위해 SoVRLdmFileReader 클래스 사용
- SoVolumeData::filename 필드에 설정 예제
* 논의할 내용
- 파일 포맷
- 비표준 확장자를 가진 파일 로딩
- "raw" 데이터(no header) 로딩
- 이미지 스택 로딩
- RGBA 데이터
* 파일 포맷
- VolumeViz 파일 리더
- 파일 이름 확장자에 리더 클래스가 관련
File extension | Reader class | Description |
---|---|---|
.am | SoVRAmFileReader | Avizo Mesh file format |
.dc3, .dic, .dicom | SoVRDicomFileReader | DICOM file format |
.fld | SoVRAvsFileReader | AVS field file format |
.ldm | SoVRLdmFileReader | Large Data Management format |
.sgy or .segy | SoVRSegyFileReader | SEG Y revision 1 file format |
.vol | SoVRVolFileReader | Vol file format |
.vox | SoVRVoxFileReader | Vox file format |
.lst | SoVRRasterStackReader | 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은 무시한다
오른손 좌표계 사용
+z : 화면 밖으로 나오는 방향
모든 각은 radian으로 표시
객체는 자신의 로컬 좌표 공간에서 묘사(object coordinate space)
신 그래프에서 모든 변환이 객체에 적용된 후에 월드 좌표 공간으로 변환
월드 좌표 공간에서 카메라와 빛(light)을 포함