Re: Voxel data handling

New Message Reply Date view Thread view Subject view Author view

From: Dave Akers (dla@engr.sgi.com)
Date: 12/04/2000 16:16:20


Hi Manfred,

> Does the bricks behaviour change with an external data array?
> I guess the external memory also has to be able to keep the
> volume data in external brick format, not only the pure
> voxel data. And in the same manner you will have to convert
> pure voxel data into the external format by
> voAppearanceActions::dataConvert?

There is no difference in the behavior of bricks, based on whether
dataAlloc() or setDataPtr() was called. You can think of dataAlloc() as a
simple convenience routine that allocates the correct amount of space
based on external format, data type, and texture dimensions.

You will need to keep your data in the external format of the texture.
This does get a little tricky when the external format isn't the same as
the disk data format. In certain machine configurations, Volumizer will
replicate INTENSITY data to LUMINANCE_ALPHA or RGBA data. (This
replication is the only thing that happens within the call to
dataConvert().) Note that dataConvert() assumes that the space has already
been allocated to the size of the external format!

> > Another complication comes up in texture interleaving. For better
> > download performance and texture memory usage, Volumizer will sometimes
> > interleave the data contained in pairs of bricks. This is done in the
> > voAppearanceActions::volumeOptimize() method, which _does_ affect the
> > brick data itself.
>
> How is this handled with external data. I guess for interleaved textures
> you will need an array of twice the size of the array for single brick.
> Does voAppearanceActions::volumeOptimize allocate a new array and copy
> the brick data into this array or would I have to consider the possibility
> of texture interleaving when allocating my external array? Is there
> a way to directly access the interleaved brick data array?

Interleaving is somewhat complicated. ;) By default, the API will simply
allocate a new array and copy the data, then free the previous two
pointers. However, if it sees that the two bricks being interleaved are
allocated from contiguous memory regions, it will attempt to perform
"in-place" interleaving. (The two pointers are concatenated together and
treated as one, minimizing fragmentation of memory.) Once the
volumeOptimize() method has interleaved the data, the data pointers for
both bricks are updated to point to the interleaved data. So it is indeed
possible to access the interleaved data directly.

> What about texuture objects. Consider the case of external brick data.
> What do I have to perform if I change some of the data values in order
> to get the generated texture objects updated?

If you change data by other means besides using
setVoxel()/setSubVolume()/initSubVolume(), you will need to mark the
affected brick(s) as dirty. Use the setDirtyFlag() method defined for
the voBrick, voBrickSet, and voBrickSetCollection classes.

> > If you're willing/able to keep two copies of your data in physical
> > memory - one for Volumizer and one for the rest of your app, then that
> > would be the best solution. Otherwise you can try to make things work by
> > bricking only in Z and making sure not to interleave the data.
>
> But that would mean one would have to copy the whole volume data
> or at least brick data whenever even a single voxel changes.
> That can't be really fast.

Why would you need to copy the whole volume data when a single voxel
changes? You would merely be allowing Volumizer to keep its own internal
representation of the data, separate from your application's data. Every
time you modify a voxel in your application, you would need to:

  a) update your own data structures
  b) update Volumizer's data structures. This is simple, since we have
provided a number of voxel modification convenience methods that correctly
handle interleaving and bricking.

The disadvantage, of course, is that you are consuming twice the memory -
and that you will have to make modifications to both representations every
time something changes. But it would allow you to take advantage of any
bricking strategy easily and to use texture interleaving to improve
performance.

Regarding the performance of getVoxelAddr(): It is a convenience routine
that determines the address of a voxel given its coordinates. It must
correctly take into account interleaving and bricking to make this
determination. For applications whose performance is gated by the speed of
many reads of voxel data, this is not as efficient as simply performing
pointer arithmetic on individual bricks.

Hope that helps. Good questions, by the way..

Dave


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Mon Dec 04 2000 - 17:25:59 PST