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:
errorFlag – Set to CORRECT if the request succeeded.
bufferSize – Set to the required buffer size (int) in bytes.
bufferDimension – Set to the number of voxels (int) in the buffer.
lineCoord[2] – Set to the begin and end IJK coordinates (SbVec3i32( C++ | Java )) of the line segment (intersection of the line with the specified subvolume).
The data type is not returned in this struct, but can be queried from the volume data node as shown in a previous section.
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 ).
// 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();
// 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();
// 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); . . .