Raytrix Light Field SDK  4.0
Logo
Using CluViz

Contents


What is CluViz?

CluViz is a visualization tool which can be used with the Raytrix runtime. The CluViz-Engine loads various scripts that implement the drawing functionalities. The underlying CluViz-Scripts are delivered by Raytrix and cannot be customized or exchanged. You can use CluViz to display images, textures or graphical objects like circles, lines, points or even text. Raytrix offers a View Image Tool class that wraps all the mentioned functionalities. This page should give an understanding of Raytrix's View Image Tool and how you can utilize CluViz.

The following image demonstrates the general concept of working with the View Image Tool.

CluVizGeneral.png
CluViz general concept

The figure above shows the three basic steps to utilize the View Image Tool.

  1. Set up the View Image Tool (It is essential to initialize CluViz before selecting a cuda device during the Raytrix API initialization. The main reason for that is that the rendering context must be declarated as shared beforehand.)
  2. Assign an image (The image assignment can be done in two different ways. To use the image information hold on the cuda device the texture id must be assigned to the View Image Tool. Using an actual image, the information must be copied into the host device memory.)
  3. Draw objects to scenes (Finally the figure shows that it is possible to draw other graphical objects into the CluViz scene.)

Set up the View Image Tool

To initialize the View Image Tool you must follow a specific order of a function call hierarchy. The

CLUViz::Net::ViewImageTool::ViewImageTool

class offers two different constructors. If you have chosen the constructor without a parameter you have to call

eventually. The second constructor does this implicitly.

Either way you must create a

The View-Control is a graphical user interface control that draws the context. The View-Control must be initialized differently depending on how many View-Controls are demanded in the application (see Multiple CluViz View-Controls). After initializing the View-Control, it can be added to the GUI. The best way to accomplish this task is to place a Windows Forms Panel into the GUI where the View-Control should be placed. It can be declared as it's parent later programmatically.

Furthermore you need to create a global instance of the CluViz engine to start and end it properly. Lastly you must create an instance of the View Image Tool.

Attention
Before you can select a cuda device for the Raytrix api you must declarate the rendering context shared beforehand.
private void FormMain_Shown(object sender, EventArgs e)
{
try
{
// The CLUViz Engine instance
// Global to end the engine on form closing
m_xCluEngine = new CLUViz.Net.EngineCtrl();
m_xCluEngine.Start();
// Now create the CLU control and embed it into the "panelClu" control.
// Changes in size and position of panelClu are automatically applied
// to the CLU control.
// Since the CLU control display runs in a separate thread, we must
// create an OpenGL rendering context for the CUDA thread (this thread)
// that shares its texture memory with the OpenGL rendering context in
// the CLU control thread. This is done automatically by setting the second
// parameter to "true".
CLUViz.Net.ViewCtrl xCluView = new CLUViz.Net.ViewCtrl(false, true, 0);
panelClu.Controls.Add(xCluView);
xCluView.Dock = DockStyle.Fill;
// The View Image Tool can be constructed with help of the view control
m_xViewImageTool = new CLUViz.Net.ViewImageTool(xCluView);
// Make the current context shared
m_xViewImageTool.ViewControl.MakeCurrentSharedRC();
// Initialize the Lightfield Runtime. This always has to be called first.
Rx.Net.ApiLF.RxInit();
// Automatically select an appropriate CUDA device, that can
// directly communicate with an OpenGL rendering context.
// This allows us to directly copy images from CUDA memory to
// OpenGL texture memory, which is much faster, than first copying
// the image back to the host memory and then again to the
// OpenGl card.
Rx.Net.ApiLF.RxCudaSelectDevice(-1, true);
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}

Multiple CluViz View-Controls

In general when only one View-Control is needed you can initialize the View-Control as described above using the following parameter settings:

When you need to use more than one View-Control and the both controls need to share a context you must proceed as follows:

  1. Initialize the first View-Control as if you would only have one (see above).
  2. Get the handle to the newly created shared rendering context from the first View-Control.
  3. Initialize the second View-Control without creating a shared rendering context but with the handle to the shared context as third parameter.

The following code example shows how two View-Controls, that share a rendering context, are initialized:

private void FormMain_Shown(object sender, EventArgs e)
{
try
{
// The CLUViz Engine instance
m_xCluEngine = new CLUViz.Net.EngineCtrl();
m_xCluEngine.Start();
// Now create the CLU control and embed it into the "panelClu" control.
// Changes in size and position of panelClu are automatically applied
// to the CLU control.
// Since the CLU control display runs in a separate thread, we must
// create an OpenGL rendering context for the CUDA thread (this thread)
// that shares its texture memory with the OpenGL rendering context in
// the CLU control thread. This is done automatically by setting the second
// parameter to "true".
CLUViz.Net.ViewCtrl xCluView1 = new CLUViz.Net.ViewCtrl(false, true, 0);
// Get the handle to the shared rendering context
Int64 iSharedContext = xCluView1.SharedGLRC;
// Now create the second CLU control that shares the OpenGL rendering
// context with the first CLU control and CUDA.
CLUViz.Net.ViewCtrl xCluView2 = new CLUViz.Net.ViewCtrl(false, false, iSharedContext);
// Make the current context shared
xCluView1.MakeCurrentSharedRC();
// Initialize the Lightfield Runtime. This always has to be called first.
Rx.Net.ApiLF.RxInit();
// Automatically select an appropriate CUDA device, that can
// directly communicate with an OpenGL rendering context.
// This allows us to directly copy images from CUDA memory to
// OpenGL texture memory, which is much faster, than first copying
// the image back to the host memory and then again to the
// OpenGl card.
Rx.Net.ApiLF.RxCudaSelectDevice(-1, true);
// .
// .
// .
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}

Assign an image

There are two ways to display the images of the Raytrix light field runtime:

Copy the image to the host memory

The advantage of copying the image onto the host device, is that you have the possibility to process the image yourself afterwards.

The disadvantage of copying the image is that the runtime time is increased significantly.

The following code example shows how you assign images to the View Image Tool:

private void NewImage()
{
try
{
//.
//.
//.
// Compute the total focus image with the Raytrix API
// Copy the image into the host memory
Rx.Net.Image xImage;
Rx.Net.ApiLF.RxGetImage(Rx.Net.ApiLF.EImgID.TotalFocus_ViewCamera, out xImage);
// Set the image to the view
m_xViewImageTool.SetImage(xImage, false);
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}

The function:

CLUViz::Net::ViewImageTool::SetImage

has two parameter. The first parameter is the image and the second parameter is an update flag.

Attention
If the image is set for the first time it is essential to set the update flag to false. Else the view image tool is not prepared properly regarding the image format.

Share the rendering context

The great advantage of using the shared rendering context is the runtime speed. The image information does not have to be copied from the cuda device.

The disadvantage is that you do not have the possibility to process the image yourself.

The following code example shows how you assign texture ids to the View Image Tool:

private void NewImage()
{
try
{
// Get the context
Rx.Net.ApiLF.RxGlGetContext();
//.
//.
//.
// Compute the total focus image with the Raytrix API
// Lock the visualization to ensure mutual access
m_xViewImageTool.ViewControl.LockVis(true);
// Create a new texture with a texture id
Rx.Net.ApiLF.RxGlUpdateTex((uint)Rx.Net.ApiLF.EImgID.TotalFocus_ViewCamera);
// Unlock the visualization
m_xViewImageTool.ViewControl.LockVis(false);
// Get the newly created texture id
uint uiTexID = Rx.Net.ApiLF.RxGlGetTextureID(Rx.Net.ApiLF.EImgID.TotalFocus_ViewCamera);
// Set the id to the view
m_xViewImageTool.SetTextureID((uint)uiTexID, m_xImgFormat, true);
// Release the shared context
Rx.Net.ApiLF.RxGlReleaseContext();
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}
Attention
When you are working with a shared context you must ensure that all participants use the shared context mutually exclusive.

The Raytrix API offers functions to get and relase a context:

  • Rx::Net::ApiLF::RxGlGetContext
  • Rx::Net::ApiLF::RxGlReleaseContext
Attention
When you are updating the texture you should always lock the visualization to ensure a safe texture manipulation.

Lastly it is important that you always set the image format when you are setting the texture. This ensures that the View Image Tool is set to the right image dimensions.

Draw objects to scenes

Drawing objects and text into the View-Control can help visualizing and highlighting computational results. The View Image Tool offers four different types of objects.

  1. Text
  2. Circles
  3. Lines
  4. Points

All drawing functions exist with multiple signatures. Hence they can be easily interchanged, one signature type will be focused here. Usually all objects are drawn into the same main scene. Nevertheless you have the possibility to make a specific scenes current for all following drawing operations.

CLUViz::Net::ViewImageTool::DrawToScene
Attention
The programmer is responsible for clearing a scene. This can be done with:
CLUViz::Net::ViewImageTool::ClearObjectsAndText
or by using the 'Update-flag' provided by the most drawing functions.

Text

Drawing text into a scene can be very useful to demonstrate a resultant image. The following code example shows how simple text can be drawn into a scene:

private void NewImage()
{
try
{
// .
// .
// .
Rx.Net.Text2D xText;
xText.Align = new Rx.Net.Vector2D(0.5, 0.5);
xText.Col = new Rx.Net.Vector4D(0f, 1f, 0f, 0.5f);
xText.MagStep = 12;
xText.Pnt = new Rx.Net.Vector2D((m_xImgFormat.Width / 2), 50);
xText.Text = "CluViz Demonstration";
m_xViewImageTool.AddText("caption", xText);
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}

Circles

Drawing circles into a scene can be very useful to highlight important regions in an image. The following code example shows how circles can be drawn into a scene:

private void NewImage()
{
try
{
// .
// .
// .
// Create a circle list
Rx.Net.ColorCircle2D[] aCircles = new Rx.Net.ColorCircle2D[10];
// Position the circles in the image
int iToggle = -1;
for (int i = 0; i < aCircles.Length; i++)
{
aCircles[i].Center = new Rx.Net.Vector2D((m_xImgFormat.Width / 2) + ((i * 30) * iToggle), (m_xImgFormat.Height / 2) + ((i * 30) * iToggle));
aCircles[i].Col = new Rx.Net.Vector4D(1f, 0f, 0f, 0.5f);
aCircles[i].Radius = 10;
iToggle *= -1;
}
// Create circle view parameters and set the line width to 0.002 pixel
xCirclePars.fLineWidth = 0.002f;
// Set the circle list to the view image tool
m_xViewImageTool.AddCircleList("circles", aCircles, xCirclePars, false);
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}

Lines

Lines are a useful tool to highlight regions in images. The following code example shows how lines can be drawn into a scene:

private void NewImage()
{
try
{
// .
// .
// .
// Create a line strip list
Rx.Net.LineStrip2D[] aLines = new Rx.Net.LineStrip2D[3];
// Position the lines in the image
for (int i = 0; i < aLines.Length; i++)
{
aLines[i] = new Rx.Net.LineStrip2D();
aLines[i].PntList = new Rx.Net.Vector2D[2];
aLines[i].PntList[0] = new Rx.Net.Vector2D((m_xImgFormat.Width / 2) - 500, 80 + (i * 50));
aLines[i].PntList[1] = new Rx.Net.Vector2D((m_xImgFormat.Width / 2) + 500, 80 + (i * 50));
aLines[i].Col = new Rx.Net.Vector4D(0f, 0f, 1f, 0.5f);
}
// Create line view parameters
xLineStripPars.colPicked = System.Drawing.Color.Red;
xLineStripPars.colSelected = System.Drawing.Color.Orange;
xLineStripPars.colPickSel = System.Drawing.Color.OrangeRed;
xLineStripPars.fLineWidth = 5;
// Set the line list to the view image tool
m_xViewImageTool.AddLineStripList("lines", aLines, xLineStripPars, false);
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}

Points

Points are useful to mark interesting regions in images. The following code example shows how points can be drawn into a scene:

private void NewImage()
{
try
{
// .
// .
// .
// Create a point list
Rx.Net.ColorPoint2D[] aPoints = new Rx.Net.ColorPoint2D[20];
// Position the points in the image
iToggle = -1;
for (int i = 0; i < aPoints.Length; i++)
{
aPoints[i].Pnt = new Rx.Net.Vector2D((m_xImgFormat.Width / 2) + (300 * iToggle), 200 + (i * 50));
aPoints[i].Col = new Rx.Net.Vector4D(1f, 0f, 1f, 0.5f);
iToggle *= -1;
}
// Create point view parameters
// Set the point list to the view image tool
m_xViewImageTool.AddPointList("points", aPoints, xPointPars, false);
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}

Listen to the mouse event handler

The mouse event handler allows you to get the mouse position. This can be very useful to display mouse position related information. For example a common usecase is to display the depth information related to the image pixel under the mouse cursor. The mouse event is raised in GUI thread.

Attention
It is important that you do not call any functions of the CluViz engine! The CluViz engine does not allow any script executions within an handler. The handler must return so that CluViz functions can be called again. Therefore you must invoke so that this handler can return.
private void FormMain_Shown(object sender, EventArgs e)
{
try
{
// .
// .
// .
// Enable Mouse event callback
xCluView.ViewMouseEvent += new CLUViz.Net.ViewMouseEventHandler(OnCluViewMouseEvent);
xCluView.EnableViewMouseEvents(true);
// .
// .
// .
}
catch (Rx.Net.RxException xEx)
{
MessageBox.Show(xEx.ToString());
}
}
public void OnCluViewMouseEvent(CLUViz.Net.SMouseEventData xMouseEventData)
{
// !!!!!! IMPORTANT !!!!!!
// It is important that you do not call any functions of the CluViz engine here!
if (xMouseEventData.bIsLeftButtonDown && xMouseEventData.bIsCtrlDown)
{
BeginInvoke(new ShowPositionHandler(OnShowImagePosition), xMouseEventData.vMouseDragLocal);
}
}
unsafe void OnShowImagePosition(Rx.Net.Vector3D vPos)
{
// .
// .
// .
}

Clean up CluViz

To make sure that the View Image Tool is stopped properly the engine must be stopped.

CLUViz::Net::Engine::End