Re: collaboration graph for isosurface generation

Hi Bob,

> . . .
> And now we're scratching our heads on how we're going to add our stuff to
> yours.  You pointed out a key point in that the
> Gridded3DSet.makeIsoSurface() method takes a set of floats.  This is
> something we're going to have to think about.

Your description of the process for creating your data is
good news.  Your adaptive resolution (AR) data only has a
single value at any location, so it corresponds to a VisAD
FlatField whose domain Set has different grid resolutions
at different locations, depending on the variability of
density values.  The simplest way to bring this data into
VisAD would be to construct a DelaunayCustom for your octree
topology and pass it as the Delaunay argument to construct
an Irregular3DSet, using these constructors:

  public DelaunayCustom(float[][] samples, int[][] tri)
         throws VisADException;

  public Irregular3DSet(MathType type, float[][] samples,
                      CoordinateSystem coord_sys, Unit[] units,
                      ErrorEstimate[] errors, Delaunay delan)
         throws VisADException;

You need to interpret your octree as a set of sample locations
and organizations of these into tetrahedra.  In the
DelaunayCustom constructor, samples is organized as
float[3][number_of_samples] where the location of the i-th
sample is (samples[0][i], samples[1][i], samples[2][i]).
The tri array is organized int[4][number_of_tetrahedra]
where its values are indices into the samples array, and the
vertices of the j-th tetraheron are the sample locations
indexed by tri[0][j], tri[1][j], tri[2][j] and tri[3][j].

In the Irregular3DSet constructor, just pass null for the
coord_sys, units and errors arguments.  Pass the same samples
array, and a MathType like the one you used to construct an
Integer3DSet in an earlier message.

Then construct a FlatField for your density values using this
Irregular3DSet.  The values passed to FlatField.setSamples()
are the density values at the locations in the samples array
passed to the Irregular3DSet and DelaunayCustom constructors.

Irregular3DSet.makeIsoSurface() is implemented using marching
tetrahedra.  You also have the option to define a new
extension of Set (probably better to extend Irregular3DSet
rather than Gridded3DSet, since your AR is not gridded the
way Gridded3DSet expects) for the topology of your adaptive
resolution grid.  You'd implement makeIsoSurface() and
makeSpatial() as we discussed earlier.

> At this stage, we're still
> trying to figure out how your application works.  I'm trying to update the
> collaboration graph
> (http://www.cs.unh.edu/~rlaramee/pictures/collaborationGraph.jpg) but it's
> still fuzzy.  One area that is still fuzzy is the call to
> ShadowFunctionOrSetType3D.doTransform().  Where is this method called
> from?

This is pretty complex.  visad.ShadowFunctionOrSetType.doTransform()
is called by visad.java3d.ShadowFunctionOrSetTypeJ3D.doTransform() or
visad.java2d.ShadowFunctionOrSetTypeJ2D.doTransform() (or some other
ShadowType extension for a new graphhics API or for new rendering
behavior).  These are in turn called by one of:

  visad.java3d.DefaultRendererJ3D.doTransform() (or some other DataRenderer)
  visad.java2d.DefaultRendererJ2D.doTransform() (or some other DataRenderer)
  visad.java3d.ShadowTupleTypeJ3D.recurseComponent()
  visad.java3d.ShadowFunctionOrSetTypeJ3D.recurseRange()
  visad.java2d.ShadowTupleTypeJ2D.recurseComponent()
  visad.java2d.ShadowFunctionOrSetTypeJ2D.recurseRange()

The last four are used when the FlatField is part of some larger
Tuple of FieldImpl.

Until you want to implement a new graphics API (i.e., rather
than Java3D or Java2D) or some novel rendering behavior, you
probably don't need to think about this.  I do intend to
document all this, one of these days.

> Also the link between the ContourWidget and the Cell computation is
> still unclear to me.  Does anyone know which class relates those?  Thank
> you for you time.

When a ScalarMap to Display.IsoContour is passed to
DisplayImpl.addMap() a ContourControl is constructed
(and will be returned by the getControl() method of the
ScalarMap).  This allows applications to control
parameters of contour rendering.  If the application wants
to pass control to the user, it may construct a ContourWidget
(which takes the ScalarMap rather than the ContourControl as
an argument, but essentially links to the ContourControl).
The ContourWidget extends JPanel and may be inserted in a
GUI.

There is a bunch of Event logic behind the scenes with
Controls, ScalarMaps and Widgets, but applications can
often ignore this.  There is no general link between
ContourWidget and CellImpl (the local implementation of
Cell), although a CellImpl might invoke the methods of
ContourControl if an application wanted contour parameters
to vary depending on some computation.

> The Gridded3DSet.makeIsoSurface() method returns a
> VisADTriangleStripArray.  When looking at the code here, it's not obvious
> how the array is populated.  The MC algorithm generates triangles (only).
> It would be great to add these triangles, perhaps 1 or more at a time, to
> a VisADTriangleStripArray.  However, it's not clear how this is done.
> Should I be focusing on the merge() method?  Perhaps creating many
> VisADTriangleStripArrays and merging them together?

Near the end of Gridded3DSet.makeIsoSurface() you should see
where the code constructs either a VisADIndexedTriangleStripArray
or a VisADTriangleStripArray, depending on the value of 'indexed'
(the indexed version is more memory efficient, but Java3D just
unrolls it into the non-indexed version).  Basically, the code
takes the various arrays full of vertices, normals and colors
and constructs the appropriate VisADTriangleStripArray.  If you
write a new implementation of makeIsoSurface, just compute your
geometry and use it to construct a VisADTriangleStripArray.  Don't
worry about merge.

> I'm also concerned about a few of the other methods that may be involved.
> For example, the ShadowFunctionOrSetType.doTransform() and
> ShadowType.assembleSpatial() methods are 2,146 lines and 495 lines (of
> code) long respectively.  Will I have to modify these?

You should not need to change either of these.  These implement
the most general case and are pretty complex.  With the general
case covered, the future action in DataREnderers is for special
cases which are simpler.  There are already a few in the
visad.bom package.

Cheers,
Bill
----------------------------------------------------------
Bill Hibbard, SSEC, 1225 W. Dayton St., Madison, WI  53706
hibbard@xxxxxxxxxxxxxxxxx  608-263-4427  fax: 608-263-6738
http://www.ssec.wisc.edu/~billh/vis.html