Real time volume rendering and editing

I’m working on a project that requires real time volume rendering and editing. Initially I was going to use CSG. But, as the project works with medical images (CT/MRI) I decided to make a simple ray caster to render the volume data form a 3D texture directly.

The rendering works fine and is nice and fast, about 20 times the system’s bottle neck. But I’m now a bit stuck with the editing side. Effectively I’m just trying to make a 3D version of MS Paint’s brush tool.

My first attempt took the position of a 3D curser (x, y, z) and called:

//Make a brush of all zeros
GLubyte *brush = new GLubyte[10*10*10]();

//Bind data texture
glBindTexture(GL_TEXTURE_3D, dataTBO);

//Replace section of data texture with brush
glTexSubImage3D(GL_TEXTURE_3D, 0, x, y, z, 10, 10, 10, GL_RED, GL_UNSIGNED_BYTE, brush);

The first problem with this is that I wanted to be able to customize the brush shape by setting elements in the brush array to on or off. However, as far as I can tell, the glTexSubImage function only overwrites the whole range. There’s no way to say something like, “If the new element is 0 leave the original element as it is.”

So for my next approach I kept a copy of the main data on main memory as well as on the GPU. Then to edit the data I made the brush array by copying the relevant section of the main data. I then put the brush into the brush array, by setting some values to 0. Then, as before, pass this to the GPU with glTexSubImage3D.

This is pretty wasteful of resources, as some of my data sets are over 1 GB.

The bigger problem with this and the previous method however is the lack of rotation. Ideally I’d like to be able to rotate the brush, relative to the data, so shapes like pyramids could be drawn at different angles.

So, I suppose I have two questions, firstly the vague one. Does anyone have any ideas how to make a volume painting system with rotatable and shapable brushes?

Secondly, is there away way of achieving the “If the new element is 0 leave the original element as it is.” functionality without a local data copy, or fetching the full data?

Thanks for any advice,