Re: VisAD isosurfaces with mapped values

We might think of extending your DataRenderer class and
over-riding makeContour() to grab information about the
range of values of the RealType you are mapping to RGB,
but unfortunately those values are already converted to
byte RGB values before the calls to makeContour().

However, it wouldn't take much code to compute the range
directly from the float[] arrays of values mapped to
IsoContour and RGB. Here's a fragment of the needed code
(note you need to repeat the 3-nested loops three times
with small modifications to deal with grid edges parallel
to the three axes):

  int nr, nc, nl; // sizes of 3-D grid
  float v[nr * nc * nl]; // grid values for RealType mapped to IsoSurface
  float c[nr * nc * nl]; // grid values for RealType mapped to RGB
  float viso; // iso-value
  float cmin = Float.MAX_VALUE;
  float cmax = -Float.MAX_VALUE;
  // this set of 3 nested loops only does this for edges
  // parallel to "l" axis - need similar sets of nested
  // loops for edges parallel to "r" and "c" axes
  for (int ir=0; ir<nr; ir++) {
    for (int ic=0; ic<nc; ic++) {
      for (int il=0; il<nl-1; il++) {
        // you can easily find more efficient code for the
        // next two statements - this is just for clarity
        int ia = ir + nr * (ic + nc * il);
        int ib = ir + nr * (ic + nc * (il + 1));
        float va = v[ia];
        float vb = v[ib];
        // does iso-surface intersect grid edge?
        if ((va < viso && viso < vb) ||
            (vb < viso && viso < va)) {
          // may need some logic here in case va = vb = viso
          float ab = (viso - va) / (vb - va);
          // value of c at intersection
          float cab = c[ia] + ab * (c[ib] - c[ia]);
          if (cab > cmax) cmax = cab;
          if (cab < cmin) cmin = cab;
        }
      }
    }
  }
  // after you do this for grid edges parallel to the "r"
  // and "c" axes, (cmin, cmax) should give the range of
  // values

You'd put this code in your application and pass (cmin, cmax)
to setRange() for your ScalarMap to RGB.

Good luck,
Bill

> I have two linear (gridded) 3D data sets, which I am trying to visualize
> with VisAD.  I have succeeded in using VisAD to create an isosurface of the
> first data set, onto which I mapped values of the second data set using a
> ScalarMap with Display.RGB.
>
> Unfortunately, the ScalarMap is setting up the color map such that the
> minimum and maximum range values are given by the minimum and maximum values
> of the entire second data set, rather than then minimum and maximum values
> of the data set along the isosurface.  Since the variations of the property
> along the isosurface are small compared with the variations in the entire
> data set, the result is an isosurface that is all one color!
>
> Of course, I can alter this range with ScalarMap.setRange, but I need a way
> (programmatically) to determine the minimum and maximum values of the mapped
> property that lie ON THE ISOSURFACE.
>
> Does anyone know a simple way to accomplish this?  Alternatively, if I could
> access the VisAD generated isosurface somehow, I could simply determine the
> minimum and maximum values on the fly.  However, I do need a general
> solution (not just hard coding a maximum and minimum value), because this
> application will be used on many different data sets, with varying,
> user-selectable isosurface values.
>
> Thanks in advance for your help.
>
> J.R. Schmidt
> UW-Madison
>
>