1.10.5. Get line

This request returns all the voxels intersected by a line, optionally bounded by subvolume. In addition to the resolution and bufferObj parameters, this request takes an SbBox3i32( C++ | Java ) specifying the bounds of the subvolume in voxel (IJK) coordinates and an SbLine( C++ | Java ) specifying the line. Although an SbLine( C++ | Java ) is defined using floating point values, the line is specified in IJK (voxel) coordinates. The line can be specified using two points or using one point plus a direction vector (this is the internal definition of the line in either case). For example specifying a line using the point [0,63,0] and the direction [1,0,0] will return the same data as the “get trace” example (line 0, trace 63).

The request returns a DataInfoBox struct (defined in class SoLDMDataAccess( C++ | Java | .NET )) containing:

The data type is not returned in this struct, but can be queried from the volume data node as shown in a previous section.

DataInfoLine query

Figure 1.101. DataInfoLine query


The following example shows how to extract the voxels along a line. As usual the example code does not show error checking. In production code the application should check the errorFlag parameter in the returned DataInfoBox struct defined in class SoLDMDataAccess( C++ | Java | .NET ).


C++
// Get subvolume bounds equal to volume dimensions
const SbVec3i32& volDim = pVolData->data.getSize();
const SbBox3i32 subVol( 0,0,0, volDim[0]-1,volDim[1]-1,volDim[2]-1 );

// Line parallel to volume X axis, passing through voxel 0,63,0
SbVec3f pos(0,63,0);
SbVec3f dir(1,0,0);
SbLine line;
line.setPosDir( pos, dir );

// Call with null to get size of data
int res = 0;
SoLDMDataAccess& access = pVolData->getLdmDataAccess();
SoLDMDataAccess::DataInfoLine info;
info = access.getData( res, subVol, line );

// Create a buffer and set size large enough for returned data
SoRef<SoCpuBufferObject> pBuffer = new SoCpuBufferObject;
pBuffer->setSize( info.bufferSize );

// Call to get the actual data
info = access.getData( res, subVol, line, pBuffer.ptr() );

// Access the data then unmap the buffer
unsigned int* pData = (unsigned int*)pBuffer->map(SoBufferObject::READ_ONLY);
unsigned int value = pData[0];
 . . .
 pBuffer->unmap();

.NET
// Get subvolume bounds equal to volume dimensions
SbVec3i32 volDim = VolData.data.GetSize();
SbBox3i32 subVol = new SbBox3i32( 0,0,0, volDim[0]-1,volDim[1]-1,volDim[2]-1 );

// Line parallel to volume X axis, passing through voxel 0,63,0
SbVec3f pos = new SbVec3f(0,1,0);
SbVec3f dir = new SbVec3f(1,0,0);
SbLine line;
line.SetPosDir( pos, dir );

// Call with null to get size of data
int res = 0;
SoLDMDataAccess access = VolData.GetLdmDataAccess();
SoLDMDataAccess.DataInfoLine info;
info = access.GetData( res, subVol, line );

// Create a buffer and set size large enough for returned data
SoCpuBufferObject buffer = new SoCpuBufferObject();
buffer.SetSize((ulong)info.BufferSize);

// Call to get the actual data
info = access.GetData( res, subVol, line, buffer );

// Access the data then unmap the buffer
SbNativeArray<uint> data = (SbNativeArray<uint>)buffer.Map(SoBufferObject.AccessModes.READ_ONLY);
uint value = data[0];
. . .
buffer.Unmap();

Java
// Get subvolume bounds equal to volume dimensions
SbVec3i32 volDim = volData.data.getSize();
SbBox3i32 subVol = new SbBox3i32( 0,0,0, volDim.getX()-1,volDim.getY()-1,volDim.getZ()-1 );
  
// Line parallel to volume X axis, passing through voxel 0,63,0
SbVec3f pos = new SbVec3f(0,1,0);
SbVec3f dir = new SbVec3f(1,0,0);
SbLine line = new SbLine();
line.setPosDir( pos, dir );

// Call with null to get size of data
int res = 0;
SoLDMDataAccess access = volData.getLdmDataAccess();
SoLDMDataAccess.DataInfoLine info;
info = access.getData(res, subVol, line, null);
  
// Create a buffer and set size large enough for returned data
ByteBuffer buffer = ByteBuffer.allocateDirect( info.bufferSize );
buffer.order(ByteOrder.nativeOrder());

// Call to get the actual data
info = access.getData(res, subVol, line, buffer);
  
// Access the data
IntBuffer ibuffer = buffer.asIntBuffer();
int value = ibuffer.get(0);
. . .