//[-------------------------------------------------------] //[ Public RTTI methods ] //[-------------------------------------------------------] bool TransferFunctionLoaderTABLE::Load(TransferFunction &cTransferFunction, File &cFile) { // Get the image holding the transfer function Image &cImage = cTransferFunction.GetImage(); // A "table"-file (simple ASCII) looks like this /* 1 1 1 1 baseOpacity: 0.698039 NoTags 0 0 0 0 . . . . . . . . . . . . */ // Use the tokenizer in order to gather all required information, ignore the rest // Startup the tokenizer Tokenizer cTokenizer; cTokenizer.Start(cFile.GetContentAsString()); // Ignore the first line ("1 1 1 1") cTokenizer.GetNextToken(); cTokenizer.GetNextToken(); cTokenizer.GetNextToken(); cTokenizer.GetNextToken(); // Ignore base opacity ("baseOpacity: 0.698039") cTokenizer.GetNextToken(); cTokenizer.GetNextToken(); // Ignore tags to keep this loader simple ("NoTags") cTokenizer.GetNextToken(); // Create image buffer ImageBuffer *pImageBuffer = cImage.CreatePart()->CreateMipmap(); pImageBuffer->CreateImage(DataByte, ColorRGBA, Vector3i(256, 1, 1)); // Read in the palette uint8 *pImageData = pImageBuffer->GetData(); for (uint32 i=0; i<256; i++) { // Read RGBA entry *pImageData = cTokenizer.GetNextToken().GetUInt8(); pImageData++; *pImageData = cTokenizer.GetNextToken().GetUInt8(); pImageData++; *pImageData = cTokenizer.GetNextToken().GetUInt8(); pImageData++; *pImageData = cTokenizer.GetNextToken().GetUInt8(); pImageData++; } // Done return true; }
//[-------------------------------------------------------] //[ Public RTTI methods ] //[-------------------------------------------------------] bool VolumeLoaderDAT::Load(Volume &cVolume, File &cFile) { Url cObjectFilename; Vector3i vResolution; EDataFormat nFormat = DataByte; // Get the image holding the volumetric data Image &cImage = cVolume.GetVolumeImage(); { // Use the tokenizer in order to gather all required information, ignore the rest // A "dat"-file (simple ASCII) looks like this /* ObjectFileName: Teddybear.raw TaggedFileName: --- Resolution: 128 128 62 SliceThickness: 2.8 2.8 5 Format: UCHAR NbrTags: 0 ObjectType: TEXTURE_VOLUME_OBJECT ObjectModel: RGBA GridType: EQUIDISTANT */ // Startup the tokenizer Tokenizer cTokenizer; cTokenizer.Start(cFile.GetContentAsString()); // Loop through all tokens String sToken = cTokenizer.GetNextToken(); while (sToken.GetLength()) { // ObjectFileName if (sToken == "ObjectFileName:") { // The file format specification says: // "The object file name refers to the name of the data file, which contains the raw voxel data. // This can be either an absolute path or a relative path with respect to the storage position of the dat file." // Get the value cObjectFilename = cTokenizer.GetNextToken(); // Resolution } else if (sToken == "Resolution:") { // The file format specification says: // "The volume data set consists of a large array of voxel values. The resolution of the data set is given // by the number of voxels in x-, y- and z- direction." // Get the values vResolution.x = cTokenizer.GetNextToken().GetInt(); vResolution.y = cTokenizer.GetNextToken().GetInt(); vResolution.z = cTokenizer.GetNextToken().GetInt(); // SliceThickness } else if (sToken == "SliceThickness:") { // The file format specification says: // "The size of one voxel in x-, y- and z- direction (usually in millimeters)." // mm to cm cm to m static const float Scale = 0.1f * 0.01f; // Get the values Vector3 vSliceThickness; vSliceThickness.x = cTokenizer.GetNextToken().GetFloat()*Scale; vSliceThickness.y = cTokenizer.GetNextToken().GetFloat()*Scale; vSliceThickness.z = cTokenizer.GetNextToken().GetFloat()*Scale; // Set the size of one voxel (without metric, but usually one unit is equal to one meter) cVolume.SetVoxelSize(vSliceThickness); // Format } else if (sToken == "Format:") { // The file format specification says: // "The data format of one voxel. Can be either UCHAR (8 bit) or USHORT (16 bit)." // Get the value const String sFormat = cTokenizer.GetNextToken(); if (sFormat == "UCHAR") nFormat = DataByte; // Byte (8 bit) else if (sFormat == "USHORT") nFormat = DataWord; // Word (16 bit) } // Next token, please sToken = cTokenizer.GetNextToken(); } } // Valid settings? If so, open and read in the raw data... if (!cObjectFilename.IsEmpty() && vResolution.x > 0 && vResolution.y > 0 && vResolution.z > 0) { // The file format specification says: // "The data file simply contains the raw voxel data as a large binary array which is indexed as // voxel(x,y,z) = array[z * YDIM * XDIM + y * XDIM + x], // with XDIM, YDIM and ZDIM referring to the resolution of the data set, as specified in line 3 // of the header file. For 16 bit data, the data may be stored either in big endian or little endian format." // -> We expect "Little Endian First" // Get the filename of the raw file const String sRawFilename = cObjectFilename.IsAbsolute() ? cObjectFilename.GetUrl() : (cFile.GetUrl().CutFilename() + cObjectFilename.GetUrl()); // Open the raw file File cRawFile(sRawFilename); if (cRawFile.Open(File::FileRead)) { // Create image buffer ImageBuffer *pImageBuffer = cImage.CreatePart()->CreateMipmap(); pImageBuffer->CreateImage(nFormat, ColorGrayscale, vResolution); // Read the data cRawFile.Read(pImageBuffer->GetData(), 1, pImageBuffer->GetDataSize()); // Load the transfer function by using "<filename>.table", or at least try it cVolume.GetTransferFunction().LoadByFilename(cFile.GetUrl().CutExtension() + ".table"); // Done return true; } } // Error! return false; }