Assignment Goals

The primary goals of this assignment are:

  1. Create a UE Plugin from scratch.
  2. Create a UE object importer.
  3. Get experience looking through other plugin code and engine source as a strategy for working with a large codebase.

For this assignment, you'll be creating an importer plugin to load a UVolumeTexture object from a file. The importer will load files in a subset of the MetaIO MHA/MHD format, created for and used by the ITK image processing toolkit. This is a simple uncompressed format supporting both image and volume files. It consists of an ASCII text header describing the file contents, coupled with an uncompressed binary array of data, either embedded in the same file (typically given the mha extension) or in a separate file in the same directory (typically given the mhd extension). Though there is a convention that detached header files use .mhd, the format does not distinguish between the two extensions. Similarly, there is a convention to use .raw or .dat for the binary data, but it can legally use any extension or none at all.

Volume Texture Pane for bucky.mhd

Details

This is the contents of the bucky.mhd file, with an explanation of each one.

ObjectType = Image Always the first line, identifies this as a valid image file
NDims = 3 3 for volume textures, 2 for images
DimSize = 32 32 32 Size in each dimension (read this from the file, do not hard code)
ElementNumberOfChannels = 1 Number of color channels, up to 4 = RGBA
ElementType = MET_UCHAR Data type for each color element, in this case, unsigned byte
ElementDataFile = bucky.raw Must be last: file name in the same directory to find the data

You are writing your own mha/mhd importer code for this assignment, not linking to the ITK library. Your importer only needs to support one color-channel volumes with unsigned byte components and the data in a separate file (like this one). You should ignore header lines that your importer does not support, but report errors for header lines you do support (so if Dims is anything but 3, or if any of the dimensions are zero or negative). Report errors using UE_LOG with a new log category (not just LogTemp) so they will show up in the editor Output window.

This assignment provides only rough pointers to where to find examples and class declarations you will need. Part of the assignment is for you to get more comfortable searching through the source to find things like this.

I have pushed a data directory to your github repository with the bucky ball files to use for testing. You can find more files in the Open Scientific Visualization Datasets. To use these files, you will need to download the raw file and create your own mhd header to go with it.

Create a project

  1. Create a Blank C++ project with no starter content called assn5.
    • As usual, put the project at the top level of your git repository

Create the plugin

  1. This time you will start from a Blank code plugin.
  2. Add an asset load class derived from UFactory to your plugin.
    • Add this in a new header and C++, not in the same files as the ModuleInterface file
    • Run GenerateProjectFiles and restart Visual Studio after adding the new files
    • Don't forget to add the PLUGINNAME_API macro in the class definition so it will be exported from your plugin module's dll
  3. Make your asset loader
    • To load from a file, you should override the UFactory::FactoryCreateFile function. Find examples in the engine and engine plugins.
    • To avoid undefined symbol errors, add the module for UFactory to your plugin's Build.cs. Follow the directory tree from the UFactory file to find its Build.cs file and find the module name.
    • Use Formats.Add in your class constructor to tell UE that you handle files with the mhd and mha file extensions. Note that the code that implements Formats.Add cannot handle extra spaces before the extension, or before or after the ";" that separates the extension from description.
    • At this point, if your importer creates and returns an empty UVolumeTexture object, you should be able to drag an mhd file into the Content window and get an empty volume texture object to confirm that your format registration code is correct.
    • Delete the old imported asset before trying to import again. Assuming you have not actually used it for anything (added it to any materials or as a property on another object), it is safe to "Force Delete" when removing the object.
  4. Load and parse the mhd header file
    • Look at FFileHelper for file loading functions.
    • Look at FString and FCString for simple string matching and string-to-integer conversion functions.
    • I recommend reading the file by lines. A few options for parsing the lines: you could split the line into key and value at the "=", split into tokens on whitespace, or even just use sscanf
    • If things go wrong, use UE_LOG to send a message to the Editor Output window and return nullptr.
  5. Load the data
    • FPaths has some helpful functions for splitting a file name into the path, base, and extension. Since the data file resides in the same directory as the header, you will need to combine the path for the nhdr file with the data file name to get the full file path to open to read the data.
    • Load the data into the UVolumeTexture
      • Set UTexture::SRGB to 0, since this is not color data
      • Set UTexture::MipGenSettings to TextureMipGenSettings::TMGS_NoMipmaps to avoid generating multiple resolution versions of the volume data (which may fail if the dimension are not a power of two).
      • Texture.Source.Init will initialize the size, format, and data
      • Call UTexture::UpdateResource to update the UVolumeTexture object with the loaded data

Grad Students

Support at least two additional MHA/MHD features:

Create test files for any features you add. If they are small (under 100 MB) you can commit them directly to your repository. Any larger sample files should be stored on google drive (or similar) with a link included in your assn5.txt file. The easiest way to create test files this is to write a simple standalone program to write them. You do not need to submit any data generation programs, just the resulting test data files.

Extra Credit

For up to 5 points each, add one or more of the grad features, up to a maximum of three (for up to 15 points of extra credit). Grad students must have at least two, but can get extra credit by doing more than two.

Submission

As always, for full credit, you must commit multiple times during your development.

Add an assn5.txt. Tell us what works and what doesn't, and anything else you think we should know for grading. For grad students, tell us what extensions you did. If you did any extensions for extra credit, tell us which ones. Tell us where to find the test files for any extensions.

For the base assignment, include two screen shots of the UE editor pane for your VolumeTexture object. One should be in "Depth Slices" view mode, and the other in "Trace Into Volume" view mode.

If you did the FScopedSlowTask progress meter extension, record video of you importing your file(s) so we can see the progress meter in action. Upload the video to google drive, youtube, or similar, and include a link to it in your assn5.txt file.

Push to your repository, and tag your final commit with an assn5 tag. Make sure the images and video links are included in the commit that you tag for us to grade.