4D Datasets

<< Click to Display Table of Contents >>

Navigation:  XStream® HDVR® SDK > Advanced Functionality >

4D Datasets

Previous pageReturn to chapter overviewNext page

C++ C++ Java Java .NET .NET

Summary

 

The XStream® HDVR® SDK supports animated rendering of 4D real-time datasets. These datasets contain multiple scans of a structure over time. To render in 4D, the render engine must be initialized with an array of datasets. Each dataset represents a single step in the time series. The resulting volume rendered 4D dataset can be visualized as an animation that consists of different datasets, each of which is dependent on the time index.

 

To be compatible with the XStream HDVR SDK 4D feature, each dataset that makes up a step in the time series must have exactly the same dimensions, pixel spacing, and orientation.

 

Note that the built-in DICOM loader supplied with the HDVR SDK supports only DICOM files that contain a single image per file. DICOM files with multiple images per file are not supported by the built-in DICOM loader. The XStream HDVR SDK does allow developers to supply their own DICOM loader. See the Custom Loading Function section for more information on this feature. For more information on using the built-in dataset loading method see the Data Loading Fundamentals chapter.

 

 

4DMovie

A 4D dataset

 

Rendering in 4D

 

To render in 4D a render engine, either IRenderEngineContext or IRenderQueue must be initialized with either the IRenderEngineContext::SetVolumeData4D() or IRenderQueue::Init4D() methods, depending on whether an IRenderEngineContex or IRenderQueue class is being used.

 

The IRenderEngineContext::SetVolumeData4D() method takes three parameters. The first parameter is an array of pointers to IVolumeDataContext objects. Each of the IVolumeDataContext objects represents a 'frame' in a 4D dataset. The second parameter is an array of pointers to IOctreeContext objects. Each IOctreeContext object in the array corresponds to a specific IVolumeDataContext object from the first parameter, in the same order. The third parameter is an integer that designates the number of entries in the IVolumeDataContext and IOctreeContext arrays.

 

The IRenderQueue::Init4D() method takes four parameters. The first parameter is a pointer to the IServerContext object for the rendering server. The second parameter is an array of pointers to IVolumeDataContext objects. Each of the IVolumeDataContext objects represents a 'frame' in a 4D dataset. The third parameter is an array of pointers to IOctreeContext objects. Each IOctreeContext object in the array has a one-to-one correspondence to an IVolumeDataContext object from the first parameter, in the same order. The fourth parameter is an integer designating the number of entries in the IVolumeDataContext and IOctreeContext arrays.

 

Once the render engine has been initialized with a 4D dataset, the rendering server will automatically return images from each volume sequentially. For example, if an IRenderEngineContext object is initialized with an array of five IVolumeDataContext objects, a call to IRenderEngineContext::Render() will return an image from each of the five volumes in sequence.

 

The IRenderEngineContext::SetFramesPerPhase() method is used to set the number of frames that will be returned by the rendering server for each IVolumeDataContext object comprising the 4D time series. For example, if frame per phase is set to six, the rendering server will return six frames for each dataset in the time series before moving on to the next one. The playback speed of the series can be controlled in this way. To effectively pause the playback on a specific frame, and set the 4D playback to a specific step in the series, the IRenderEngineContext::SetPhase() method will set the server to use only the set IVolumeDataContext for rendering.

 

If an IRenderQueue object is being used for rendering, the IRenderEngineContext::SetFramesPerPhase() and IRenderEngineContext::SetPhase() methods can be accessed through the IRenderQueue::GetRenderEngineContext() method.

 

// Load three separate datasets making up a 4D time series.

// Each dataset must have the same dimensions, pixel spacing, and orientation.

IVolumeDataContext *pVolumeDataContext[3];

pServerContext->LoadDicomDirectory(&pVolumeDataContext[0], "C:/Datasets/DICOM0");

pServerContext->LoadDicomDirectory(&pVolumeDataContext[1], "C:/Datasets/DICOM1");

pServerContext->LoadDicomDirectory(&pVolumeDataContext[2], "C:/Datasets/DICOM2");

 

// Create octree structures for each IVolumeDataContext object.

IOctreeContext *pOctreeContext[3];

pServerContext->CreateOctree(&pOctreeContext[0], pVolumeDataContext[0]);

pServerContext->CreateOctree(&pOctreeContext[1], pVolumeDataContext[1]);

pServerContext->CreateOctree(&pOctreeContext[2], pVolumeDataContext[2]);

 

// Create an IRenderEngineContext object for parallel rendering

IRenderEngineContext *pRenderEngine;

pServerContext->CreateRenderEngine(&pRenderEngine, RECID_PAR);

 

// Apply the 4D volume and octree data to the render engine.

pRenderEngine->SetVolumeData4D(pVolumeDataContext, pOctreeContext, 3);

 

// Set playback speed to one frames per dataset

pRenderEngine->SetFramePerPhase(1);

 

VOLVISIMAGE imgReq;

VOLVISIMAGE imgRes;

BCOM_ZEROMEMORY(imgReq);

BCOM_ZEROMEMORY(imgRes);

 

// Request interactive quality image.

imgReq.Stage = RENDER_STAGE_PROGR0;

 

// Returns an image from pVolumeDataContext[0].

pRenderEngine->Render(&imgReq, &imgRes);

 

// Returns an image from pVolumeDataContext[1].

pRenderEngine->Render(&imgReq, &imgRes);

 

// Returns an image from pVolumeDataContext[2].

pRenderEngine->Render(&imgReq, &imgRes);

 

// Returns an image from pVolumeDataContext[0].

pRenderEngine->Render(&imgReq, &imgRes);

 

To render in 4D a render engine, either hdrcRenderEngineContext or hdrcRenderQueue, must be initialized with either the hdrcRenderEngineContext::setVolumeData4D() or hdrcRenderQueue::init4D() methods, depending on which engine type is being used.

 

The hdrcRenderEngineContext::setVolumeData4D() method takes three parameters. The first parameter is an array of hdrcVolumeDataContext objects. Each of the hdrcVolumeDataContext objects represents a 'frame' in a 4D dataset. The second parameter is an array of hdrcOctreeContext objects. Each hdrcOctreeContext object in the array has a one-to-one correspondence to an hdrcVolumeDataContext object from the first parameter, in the same order. The third parameter is an integer that designates the number of entries in the hdrcVolumeDataContext and hdrcOctreeContext arrays.

 

The hdrcRenderQueue::init4D() method takes three parameters. The first parameter is a hdrcServerContext object for the rendering server. The second parameter is an array of hdrcVolumeDataContext objects. Each of the hdrcVolumeDataContext objects represents a 'frame' in a 4D dataset. The third parameter is an array of hdrcOctreeContext objects. Each hdrcOctreeContext object in the array corresponds to each of the hdrcVolumeDataContext objects from the first parameter, in the same order.

 

Once the render engine has been initialized with a 4D dataset, the rendering server will automatically return images from each volume sequentially. For example, if an IRenderEngineContext object is initialized with an array of five hdrcVolumeDataContext objects, a call to hdrcRenderEngineContext::render() will return an image from each of the five volumes in sequence.

 

The hdrcRenderEngineContext::setFramesPerPhase() method is used to set the number of frames that will be returned by the rendering server for each IVolumeDataContext object comprising the 4D time series. For example, if frame per phase is set to six, the rendering server will return six frames for each dataset in the time series before moving on to the next one. The playback speed of the series can be controlled in this way. To effectively pause the playback on a specific frame, and set the 4D playback to a specific step in the series, the hdrcRenderEngineContext::setPhase() method will set the server to use only the set IVolumeDataContext for rendering.

 

If an hdrcRenderQueue object is being used for rendering, the hdrcRenderEngineContext::setFramesPerPhase() and hdrcRenderEngineContext::setPhase() methods can be accessed through the hdrcRenderQueue::getRenderEngineContext() method.

 

 

// Load three separate datasets making up a 4D time series.

// Each dataset must have the same dimensions, pixel spacing, and orientation.

hdrcVolumeDataContext[] volumeDataContext = new hdrcVolumeDataContext[3];

 

volumeDataContext[0] = serverContext.loadDicomDirectory("C:/Datasets/DICOM0");

volumeDataContext[1] = serverContext.loadDicomDirectory("C:/Datasets/DICOM1");

volumeDataContext[2] = serverContext.loadDicomDirectory("C:/Datasets/DICOM2");

 

// Create octree structures for each hdrcVolumeDataContext object.

hdrcOctreeContext[] octreeContext = new hdrcOctreeContext[3];

octreeContext[0] = serverContext.createOctree(volumeDataContext[0].getId());

octreeContext[1] = serverContext.createOctree(volumeDataContext[1].getId());

octreeContext[2] = serverContext.createOctree(volumeDataContext[2].getId());

 

// Create an hdrcRenderEngineContext object for parallel rendering

hdrcRenderEngineContext renderEngine;

renderEngine = serverContext.createRenderEngine(hdrcDefines.RENDER_ENGINE_ID_PAR);

 

// Apply the 4D volume and octree data to the render engine.

renderEngine.setVolumeData4D(volumeDataContext, octreeContext, 3);

 

// Set playback speed to one frames per dataset

renderEngine.setFramePerPhase(1);

 

VOLVISIMAGE imgReq = new VOLVISIMAGE();

VOLVISIMAGE imgReq = new VOLVISIMAGE();

 

// Request interactive quality image.

imgReq.Stage = hdrcDefines.RENDER_STAGE_PROGR0;

 

// Returns an image from volumeDataContext[0].

pRenderEngine.render(imgReq, imgRes);

 

// Returns an image from pVolumeDataContext[1].

pRenderEngine.render(imgReq, imgRes);

 

// Returns an image from pVolumeDataContext[2].

pRenderEngine.render(imgReq, imgRes);

 

// Returns an image from pVolumeDataContext[0].

pRenderEngine.render(imgReq, imgRes);

 

// Load three separate datasets making up a 4D time series.

// Each dataset must have the same dimensions, pixel spacing, and orientation.

hdrcVolumeDataContext[] volumeDataContext = new hdrcVolumeDataContext[3];

 

volumeDataContext[0] = serverContext.loadDicomDirectory("C:/Datasets/DICOM0");

volumeDataContext[1] = serverContext.loadDicomDirectory("C:/Datasets/DICOM1");

volumeDataContext[2] = serverContext.loadDicomDirectory("C:/Datasets/DICOM2");

 

// Create octree structures for each hdrcVolumeDataContext object.

hdrcOctreeContext[] octreeContext = new hdrcOctreeContext[3];

octreeContext[0] = serverContext.createOctree(volumeDataContext[0].getId());

octreeContext[1] = serverContext.createOctree(volumeDataContext[1].getId());

octreeContext[2] = serverContext.createOctree(volumeDataContext[2].getId());

 

// Create an hdrcRenderEngineContext object for parallel rendering

hdrcRenderEngineContext renderEngine;

renderEngine = serverContext.createRenderEngine(hdrcDefines.__Fields.RENDER_ENGINE_ID_PAR);

 

// Apply the 4D volume and octree data to the render engine.

renderEngine.setVolumeData4D(volumeDataContext, octreeContext, 3);

 

// Set playback speed to one frames per dataset

renderEngine.setFramePerPhase(1);

 

VOLVISIMAGE imgReq = new VOLVISIMAGE();

VOLVISIMAGE imgReq = new VOLVISIMAGE();

 

// Request interactive quality image.

imgReq.Stage = hdrcDefines.RENDER_STAGE_PROGR0;

 

// Returns an image from volumeDataContext[0].

pRenderEngine.render(imgReq, imgRes);

 

// Returns an image from pVolumeDataContext[1].

pRenderEngine.render(imgReq, imgRes);

 

// Returns an image from pVolumeDataContext[2].

pRenderEngine.render(imgReq, imgRes);

 

// Returns an image from pVolumeDataContext[0].

pRenderEngine.render(imgReq, imgRes);