[vtkusers] Volume deformation bug: found.... and fixed! :)

AGPX agpxnet at yahoo.it
Thu Aug 12 09:30:44 EDT 2010


Hi,

good news guys'n'gals, I found and fix the last bug! :)

I said previously that the ray entry point calculation looks correct... and this 
is true. What is wrong is the computation of camera position in texture space! 
At least it's INCOMPATIBILE with the calculation of rays entry point. The two 
spaces are slightly different. So, the distorsion always occurs (it's not a 
problem related to near clipping plane) but it's more noticeable only when you 
look nearly the volume (and this is a very frequent case in a fly-through 
navigation). Basically, look at the routine that assign texture coordinate for 
each vertex of the volume box:

       if(this->CellFlag) // texcoords between 0 and 1. More complex
                          // depends on the loaded texture
       {
              tcoord[j] = spacingSign[j]*(vert[j] - loadedBounds[j*2]) /
                (loadedBounds[j*2+1] - loadedBounds[j*2]);
       }
       else // texcoords between 1/2N and 1-1/2N.
       {
              double tmp; // between 0 and 1
              tmp = spacingSign[j]*(vert[j] - loadedBounds[j*2]) /
                (loadedBounds[j*2+1] - loadedBounds[j*2]);
              double delta=static_cast<double>(
                loadedExtent[j*2+1]-loadedExtent[j*2]+1);
              tcoord[j]=(tmp*(delta-1)+0.5)/delta;
       }

We have 2 way of doing so: one when cellFlag is true and one when cellFlag is 
false. When you transform the camera position from world space to texture space 
you have to do the SAME job. And this is not the case! Look at the current code 
used for this:

cameraPosTexture[0] = (cameraPosDataset[0]-bounds[0])/dx;
cameraPosTexture[1] = (cameraPosDataset[1]-bounds[2])/dy;
cameraPosTexture[2] = (cameraPosDataset[2]-bounds[4])/dz;


This match the case when CellFlag is true!  (point coordinate minus bounds, 
divided by the bounds range). BUT, what happen (and this is my case) if CellFlag 
is false?  The formulas that map a vertex from world space to texture space are 
differents! The fix? Easy! Replace the previous three lines in the method 
vtkOpenGLGPUVolumeRayCastMapper::LoadProjectionParameters, with:

     // AGPX MODIFIED
    if (this->CellFlag)
    {
        cameraPosTexture[0] = (cameraPosDataset[0]-bounds[0])/dx;
        cameraPosTexture[1] = (cameraPosDataset[1]-bounds[2])/dy;
        cameraPosTexture[2] = (cameraPosDataset[2]-bounds[4])/dz;
    }
    else
    {
        double delta, tmp;
        delta = static_cast<double>(extents[1]-extents[0]+1);
        tmp = (cameraPosDataset[0]-bounds[0])/dx;
        cameraPosTexture[0] = (tmp * (delta - 1) + 0.5) / delta;

        delta = static_cast<double>(extents[3]-extents[2]+1);
        tmp = (cameraPosDataset[1]-bounds[2])/dy;
        cameraPosTexture[1] = (tmp * (delta - 1) + 0.5) / delta;

        delta = static_cast<double>(extents[5]-extents[4]+1);
        tmp = (cameraPosDataset[2]-bounds[4])/dz;
        cameraPosTexture[2] = (tmp * (delta - 1) + 0.5) / delta;
    }
    // AGPX MODIFIED

This resolve the problem. There still another difference: the term spacingSign 
is missing and surely must be introduced or it could produce wrong result when 
spacing is negative. I leave it for you as an exercise :)

That's all my friends! The malefic bug triad was defeat! :) Please update VTK!!! 
:)

Ok, thank you for your attentions and keep the very good works!

- Gianluca Arcidiacono (a.k.a. AGPX)



      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20100812/cf62cc0a/attachment.htm>


More information about the vtkusers mailing list