[vtkusers] [Edit]: UGrid volume ray cast Bug?

Randall Hand randall.hand at gmail.com
Thu Apr 6 10:42:00 EDT 2006


Ok, I found the "bug".  It's not really a bug per-se, but it is something
that probably needs some tweaking, or at least some better documenting :)

The vtkUnstructuredGridHomogeneousRayIntegrator is responsible for
controlling the Ray Traversal in the RayCastMapper when you 1) Use
Independant Components, 2) Have only 1 component, and 3) Data is defined
per-cell.  When you turn off IndependantComponents (like for the 4-component
scalar), it instead uses one of the other Integrators.  Inside the
HomogeneousRayIntegrator's constructor, it defines
"TransferFunctionTableSize" = 1024, which is the maximum size of the
Transfer Function lookup table.  That's where the problem comes from, you
are effectively restricted to a colormap of TransferFunctionTableSize/3 (for
the 3 components), which by default means 1024/3 = 341 entries.

You can increase the size of the table with the
"SetTransferFunctionTableSize" function, but it's a bit tricker than that..
You have to do something like the following:

  vtkUnstructuredGridVolumeRayCastMapper *vrcm =
        vtkUnstructuredGridVolumeRayCastMapper::New();
//  vtkProjectedTetrahedraMapper *vrcm =
vtkProjectedTetrahedraMapper::New();
  vrcm->SetInput(filter->GetOutput());
  vtkUnstructuredGridHomogeneousRayIntegrator *integrator =
        vtkUnstructuredGridHomogeneousRayIntegrator::New();
  integrator->SetTransferFunctionTableSize(no_voxels*3);
  vrcm->SetRayIntegrator(integrator);

This is typically done for you, but you have to do it yourself to change
that.  Once I made this change, I was easily able to run it with a 20-cube
and it looks just fine.

Honestly, tho, for your situation... You're just better off building a
4-component data scalar with your R/G/B/A in it.. The colormap is just
adding extra overhead.


On 4/6/06, Juan José Aja Fernández <juan.aja at gmail.com> wrote:
>
>
> Yep, that did the trick.
> This deserves a bug report?
>
> Thanks a lot Randall, you've been most helpful.
>
>
> Juan
>
> On 4/6/06, Randall Hand <randall.hand at gmail.com> wrote:
> >
> > OK, I'm seeing the same glitch here on my end.. That is an odd one.. The
> > only thing I know to attribute it to is some type of interpolation within
> > the colormap.  If you switch from vtkUnstructuredGridVolumeRayCastMapper to
> > vtkProjectedTetrahedraMapper then it works perfectly.  Also, if you switch
> > from the colormap approach to the 4-component approach I mentioned last
> > night, then it works just fine.  At this point, it does seem to be some kind
> > of issue in the RayCastMapper.
> >
> > I'm gonna dig a little deeper, I'll let you know what I find, if
> > anything.  Also, just fyi, you don't need to declare the OpenGL objects
> > directly, the object factories know when to create the OpenGL ones vs the
> > Mesa ones just fine :)
> >
> > As promised, code for the 4-component scalar shown below:
> >
> > #include " vtkVoxel.h"
> > #include "vtkCellData.h"
> > #include " vtkRenderer.h"
> > #include "vtkPoints.h"
> > #include "vtkUnstructuredGrid.h"
> > #include "vtkRenderWindow.h"
> > #include "vtkRenderWindowInteractor.h"
> > #include "vtkColorTransferFunction.h "
> > #include "vtkPiecewiseFunction.h"
> > #include "vtkVolume.h"
> > #include "vtkVolumeProperty.h"
> > #include "vtkUnstructuredGridWriter.h"
> > #include "vtkDoubleArray.h "
> > #include "vtkDataSetTriangleFilter.h"
> > #include "vtkUnstructuredGridVolumeRayCastMapper.h"
> > #include "vtkUnstructuredGridVolumeRayCastFunction.h"
> > #include "vtkImageData.h"
> > #include "vtkDataSetToImageFilter.h"
> > #include "stdio.h"
> > #include "iostream.h"
> > #include "fstream.h"
> > #include "string.h"
> > #include "vtkOpenGLRenderer.h "
> > #include "vtkXOpenGLRenderWindow.h"
> > #include "vtkXRenderWindowInteractor.h"
> >
> >
> > int main(int argc, char *dim[])
> > {
> >
> >   int dim_x =  atoi(dim[1]);
> >   int dim_y =  atoi(dim[1]);
> >   int dim_z =  atoi(dim[1]);
> >   int i, j, k;
> >   int no_points = dim_x * dim_x * dim_x;
> >   int no_voxels = (dim_x-1) * (dim_x-1) * (dim_x-1);
> >
> >   vtkPoints *points = vtkPoints::New();
> >   points->SetNumberOfPoints(no_points);
> >   points->SetDataTypeToDouble();
> >
> >   for(k=0; k< dim_z; k++)
> >     for(j=0; j< dim_y; j++)
> >       for(i=0; i< dim_x; i++)
> >         points->InsertNextPoint(i, j, k);
> >
> >   vtkDoubleArray *pts = vtkDoubleArray::New();
> >   pts->SetNumberOfComponents(4);
> >   pts->SetName("pts");
> >
> >   for(i=0; i < no_voxels; i++) {
> >     if (i & 0x01)
> >         pts->InsertNextTuple4(1,0,0, 0.9);
> >     else
> >         pts->InsertNextTuple4(0,1,0, 0.9);
> >   }
> >
> >   vtkUnstructuredGrid *grid = vtkUnstructuredGrid::New();
> >
> >
> >   //To create the grid we need to know if we are in any of the
> >   //cube limits (height, width, depth), to prevent from adding
> >   //inexistant cells
> >   j=0;
> >   k=0;
> >   int w = 0;
> >   int count = 0;
> >   vtkVoxel *v = vtkVoxel::New();
> >
> >   for(i=0; i< (no_points - ((dim_x * dim_x) + (dim_x + 1))); i++) {
> >     if(j != dim_x - 1 && k!= dim_x - 1) {
> >       (v->GetPointIds())->SetId(0, i);
> >       (v->GetPointIds())->SetId(1, i+1);
> >       (v->GetPointIds())->SetId(2, i+dim_x);
> >       (v->GetPointIds())->SetId(3, i+dim_x+1);
> >       (v->GetPointIds())->SetId(4, i + (dim_x * dim_y));
> >       (v->GetPointIds())->SetId(5, i + (dim_x * dim_y) + 1);
> >       (v->GetPointIds())->SetId(6, i + (dim_x * dim_y) + dim_x);
> >       (v->GetPointIds())->SetId(7, i + (dim_x * dim_y) + dim_x + 1);
> >       grid->InsertNextCell(v->GetCellType(), v->GetPointIds());
> >
> >       j++;
> >       count++;
> >     }
> >     else {
> >       if(j == dim_x-1) {
> >         j=0;
> >         k++;
> >         if(k == dim_x-1) {
> >           j=0;
> >           k=0;
> >           i = i+dim_x;
> >           w++;
> >         }
> >       }
> >     }
> >   }
> >   grid->SetPoints(points);
> >
> >   vtkCellData *cd = grid->GetCellData();
> >   cd->SetNumberOfTuples(no_voxels);
> >   cd->SetScalars(pts);
> >
> >   vtkRenderer *renderer = vtkRenderer::New();
> >   vtkRenderWindow *renwin =  vtkRenderWindow::New();
> >   vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
> >
> >
> >   renwin->AddRenderer(renderer);
> >   iren->SetRenderWindow(renwin);
> >
> >   vtkVolumeProperty *vp = vtkVolumeProperty::New();
> >   // vp->SetColor(funtrans);
> >   // vp->SetScalarOpacity(funop);
> >   vp->IndependentComponentsOff();
> >
> >
> >   vtkUnstructuredGridVolumeRayCastMapper *vrcm =
> >             vtkUnstructuredGridVolumeRayCastMapper::New();
> >
> >   vtkDataSetTriangleFilter *filter = vtkDataSetTriangleFilter::New();
> >   filter->SetInput(grid);
> >
> >   vrcm->SetInput(filter->GetOutput());
> >
> >   vtkVolume *volume = vtkVolume::New();
> >   volume->SetMapper(vrcm);
> >   volume->SetProperty(vp);
> >
> >   renderer->AddActor(volume);
> >
> >   renwin->Render();
> >   iren->Start();
> > }
> >
> >
> >
> >
> > On 4/5/06, Randall Hand <randall.hand at gmail.com> wrote:
> > >
> > > If you look at the documentation for vtkVolumeProperty around the
> > > SetIndependantComponents stuff : http://www.vtk.org/doc/release/5.0/html/a02182.html#z4350_1
> > >
> > >
> > > I'll play around with it tomorrow morning.. if I can get a working
> > > version of your test driver, I'll send it to you for you to check out :)
> > >
> > >
> > > On 4/5/06, Juan José Aja Fernández <juan.aja at gmail.com> wrote:
> > > >
> > > > Hi, Randall:
> > > >
> > > > Thanks again for the swift response.
> > > >
> > > > I haven't tried using point data, first thing tomorrow I will
> > > > rewrite the code.
> > > >
> > > > Your second suggestion was exactly what I was looking for, until now
> > > > I didn't know if there was a way to color whithout using a transfer function
> > > > (that explains my horrible hack of using the voxel index as a "scalar"). I
> > > > skimmed through the docs trying to find something related, and I looked at
> > > > vtkScalarsToColors as a possible candidate, but I have my doubts: ¿How can I
> > > > create a RGBA scalar field and how can this be used as the color function in
> > > > the mapper?
> > > >
> > > >
> > > > Thanks a lot,
> > > >
> > > > Juan.
> > > >
> > > >
> > > >
> > > > On 4/5/06, Randall Hand <randall.hand at gmail.com> wrote:
> > > > >
> > > > > I'll try this out on my end tomorrow, since I'm already neck-deep
> > > > > in the Volume Rendering code anyway :)
> > > > >
> > > > > Just a thought tho, I believe most of the Volume Renderers expect
> > > > > Point Data, not Cell Data.. Have you tried using Per-point data?
> > > > >
> > > > > Also, if you really want to define colors per-point and not via a
> > > > > colormap, then if you use a 4-component scalar field you can have it
> > > > > directly contain R/G/B/A for volume rendering.
> > > > >
> > > > >  On 4/5/06, Juan José Aja Fernández <juan.aja at gmail.com> wrote:
> > > > >
> > > > > > (Sorry for the double post, The first url was broken)
> > > > >
> > > > > Hi, Everyone:
> > > > >
> > > > > This is the third time I'm posting about this issue, of the
> > > > > previous two one remained unanswered and the last one I've got a kind
> > > > > response by Randall Hand: http://public.kitware.com/pipermail/vtkusers/2006-February/083786.html
> > > > >
> > > > >
> > > > >  who pointed me in the direction of this fixed bug:
> > > > >
> > > > > http://www.vtk.org/Bug/bug.php?op=show&bugid=2546&pos=3 but the
> > > > > problem persists.
> > > > >
> > > > > I think the vtkUnstructuredGridVolumeRayCastMapper has some
> > > > > serious bug (look at the screenshots posted in the thread that Randall
> > > > > answered), and to prove It I think I need to post my entire example code:
> > > > >
> > > > > (Really, I think I'm on to something, specially If you consider
> > > > > that the mapper for unstructured grids is fairly new, but I didn't want to
> > > > > litter the bug report with false positives).
> > > > >
> > > > >
> > > > > #include "vtkVoxel.h"
> > > > > #include "vtkCellData.h"
> > > > > #include "vtkRenderer.h"
> > > > > #include "vtkPoints.h"
> > > > > #include "vtkUnstructuredGrid.h"
> > > > > #include "vtkRenderWindow.h"
> > > > > #include "vtkRenderWindowInteractor.h"
> > > > > #include "vtkColorTransferFunction.h"
> > > > > #include "vtkPiecewiseFunction.h"
> > > > > #include "vtkVolume.h"
> > > > > #include "vtkVolumeProperty.h"
> > > > > #include "vtkUnstructuredGridWriter.h"
> > > > > #include "vtkDoubleArray.h"
> > > > > #include "vtkDataSetTriangleFilter.h"
> > > > > #include "vtkUnstructuredGridVolumeRayCastMapper.h"
> > > > > #include "vtkUnstructuredGridVolumeRayCastFunction.h"
> > > > > #include "vtkImageData.h"
> > > > > #include "vtkDataSetToImageFilter.h"
> > > > > #include "stdio.h"
> > > > > #include "iostream.h"
> > > > > #include "fstream.h"
> > > > > #include "string.h"
> > > > > #include "vtkOpenGLRenderer.h"
> > > > > #include "vtkXOpenGLRenderWindow.h"
> > > > > #include "vtkXRenderWindowInteractor.h"
> > > > >
> > > > >
> > > > > int main(int argc, char *dim[])
> > > > > {
> > > > >
> > > > >   int dim_x =  atoi(dim[1]);
> > > > >   int dim_y =  atoi(dim[1]);
> > > > >   int dim_z =  atoi(dim[1]);
> > > > >   int i, j, k;
> > > > >   int no_points = dim_x * dim_x * dim_x;
> > > > >   int no_voxels = (dim_x-1) * (dim_x-1) * (dim_x-1);
> > > > >
> > > > >   vtkPoints *points = vtkPoints::New();
> > > > >   points->SetNumberOfPoints(no_points);
> > > > >   points->SetDataTypeToDouble();
> > > > >
> > > > >   for(k=0; k< dim_z; k++)
> > > > >     for(j=0; j< dim_y; j++)
> > > > >       for(i=0; i< dim_x; i++)
> > > > >         points->InsertNextPoint(i, j, k);
> > > > >
> > > > >   vtkDoubleArray *pts = vtkDoubleArray::New();
> > > > >   pts->SetName("pts");
> > > > >
> > > > >   for(i=0; i < no_voxels; i++)
> > > > >     pts->InsertNextValue(i);
> > > > >
> > > > >   vtkUnstructuredGrid *grid = vtkUnstructuredGrid::New();
> > > > >
> > > > >   vtkColorTransferFunction *funtrans =
> > > > > vtkColorTransferFunction::New();
> > > > >
> > > > >   //To create the grid we need to know if we are in any of the
> > > > >   //cube limits (height, width, depth), to prevent from adding
> > > > >   //inexistant cells
> > > > >   j=0;
> > > > >   k=0;
> > > > >   int w = 0;
> > > > >   int count = 0;
> > > > >   vtkVoxel *v = vtkVoxel::New();
> > > > >
> > > > >   for(i=0; i< (no_points - ((dim_x * dim_x) + (dim_x + 1))); i++)
> > > > > {
> > > > >     if(j != dim_x - 1 && k!= dim_x - 1) {
> > > > >       (v->GetPointIds())->SetId(0, i);
> > > > >       (v->GetPointIds())->SetId(1, i+1);
> > > > >       (v->GetPointIds())->SetId(2, i+dim_x);
> > > > >       (v->GetPointIds())->SetId(3, i+dim_x+1);
> > > > >       (v->GetPointIds())->SetId(4, i + (dim_x * dim_y));
> > > > >       (v->GetPointIds())->SetId(5, i + (dim_x * dim_y) + 1);
> > > > >       (v->GetPointIds())->SetId(6, i + (dim_x * dim_y) + dim_x);
> > > > >       (v->GetPointIds())->SetId(7, i + (dim_x * dim_y) + dim_x +
> > > > > 1);
> > > > >       grid->InsertNextCell(v->GetCellType(), v->GetPointIds());
> > > > >
> > > > >       j++;
> > > > >       count++;
> > > > >     }
> > > > >     else {
> > > > >       if(j == dim_x-1) {
> > > > >         j=0;
> > > > >         k++;
> > > > >         if(k == dim_x-1) {
> > > > >           j=0;
> > > > >           k=0;
> > > > >           i = i+dim_x;
> > > > >           w++;
> > > > >         }
> > > > >       }
> > > > >     }
> > > > >   }
> > > > >   grid->SetPoints(points);
> > > > >
> > > > >   vtkCellData *cd = grid->GetCellData();
> > > > >   cd->SetNumberOfTuples(no_voxels);
> > > > >   cd->SetScalars(pts);
> > > > >
> > > > >   int idx = 0;
> > > > >   while (idx < no_voxels) {
> > > > >     if (idx%2 == 0 )
> > > > >
> > > > >       funtrans->AddRGBPoint(pts->GetValue(idx), 1, 0, 0);
> > > > >     else funtrans->AddRGBPoint(pts->GetValue(idx), 0, 1,0);
> > > > >
> > > > >     idx++;
> > > > >   }
> > > > >   vtkOpenGLRenderer *renderer = vtkOpenGLRenderer::New();
> > > > >   vtkXOpenGLRenderWindow *renwin =  vtkXOpenGLRenderWindow::New();
> > > > >   vtkXRenderWindowInteractor *iren =
> > > > > vtkXRenderWindowInteractor::New();
> > > > >
> > > > >   renwin->AddRenderer(renderer);
> > > > >   iren->SetRenderWindow(renwin);
> > > > >
> > > > >   vtkPiecewiseFunction *funop = vtkPiecewiseFunction::New();
> > > > >   funop->AddPoint(0, 1);
> > > > >   funop->AddPoint(no_voxels, 1);
> > > > >
> > > > >   vtkVolumeProperty *vp = vtkVolumeProperty::New();
> > > > >   vp->SetColor(funtrans);
> > > > >   vp->SetScalarOpacity(funop);
> > > > >
> > > > >   vtkUnstructuredGridVolumeRayCastMapper *vrcm =
> > > > > vtkUnstructuredGridVolumeRayCastMapper::New();
> > > > >
> > > > >   vtkDataSetTriangleFilter *filter =
> > > > > vtkDataSetTriangleFilter::New();
> > > > >   filter->SetInput(grid);
> > > > >
> > > > >   vrcm->SetInput(filter->GetOutput());
> > > > >
> > > > >   vtkVolume *volume = vtkVolume::New();
> > > > >   volume->SetMapper(vrcm);
> > > > >   volume->SetProperty(vp);
> > > > >
> > > > >   renderer->AddActor(volume);
> > > > >
> > > > >   renwin->Render();
> > > > >   iren->Start();
> > > > > }
> > > > >
> > > > >
> > > > > This will attempt to create a cube with dimensions arg[1] coloring
> > > > > odd and even cells with green and red.
> > > > > Try it with argv[1] = 6, then argv[1] = 20, see the results.
> > > > >
> > > > > Is this a bug, or I'm doing things the wrong way?
> > > > >
> > > > >
> > > > > Thanks in advance,
> > > > >
> > > > > Juan.
> > > > >
> > > > >
> > > > > _______________________________________________
> > > > > This is the private VTK discussion list.
> > > > > Please keep messages on-topic. Check the FAQ at:
> > > > > http://www.vtk.org/Wiki/VTK_FAQ
> > > > > Follow this link to subscribe/unsubscribe:
> > > > > http://www.vtk.org/mailman/listinfo/vtkusers
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > --
> > > > > Randall Hand
> > > > > Visualization Scientist,
> > > > > ERDC-MSRC Vicksburg, MS
> > > > > Homepage: http://www.yeraze.com
> > > > >
> > > >
> > > >
> > >
> > >
> > > --
> > > Randall Hand
> > > Visualization Scientist,
> > > ERDC-MSRC Vicksburg, MS
> > > Homepage: http://www.yeraze.com
> > >
> >
> >
> >
> > --
> > Randall Hand
> > Visualization Scientist,
> > ERDC-MSRC Vicksburg, MS
> > Homepage: http://www.yeraze.com
> >
>
>


--
Randall Hand
Visualization Scientist,
ERDC-MSRC Vicksburg, MS
Homepage: http://www.yeraze.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20060406/785f454e/attachment.htm>


More information about the vtkusers mailing list