All of this has been logged as bug 5519, along with the diff patch.<br><br><a href="http://www.vtk.org/Bug/view.php?id=5519">http://www.vtk.org/Bug/view.php?id=5519</a><br clear="all"><br>-- <br>----------------------------------------
<br>Randall Hand <br>Visualization Scientist<br>ERDC MSRC-ITL
<br><br><div><span class="gmail_quote">On 8/16/07, <b class="gmail_sendername">Randall Hand</b> &lt;<a href="mailto:randall.hand@gmail.com">randall.hand@gmail.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
ok.. After several days of looking into this, I think I finally figured it out and came up with a fix that (in my tests) fixes the problem 100%.<br><br>The problem seems to be in the loss of accuracy involved with converting between Floating-Point and Fixed-Point.&nbsp; The loss of accuracy is a &quot;known issue&quot;, and typically not much of a problem, but the small numbers involved when the Direction approaches 0 yields some odd answers.&nbsp; This is further compounded by the way that the Endpoints of the Ray and the Direction of the ray are computed.&nbsp; Previously, the number of steps to take along the ray were computed on each axis independently, and then the smallest number was used.&nbsp;&nbsp;&nbsp; Presumably, this was because if anything bigger was used then the ray would leave the volume &amp; the array index routines ran the risk of overflowing (leading to Segfaults).&nbsp; But because of the accuracy of the arithmetic with very-small numbers, the answers are simply wrong sometimes.&nbsp; This leads to oddities where rayStart + Direction*NumSteps does not necessarily equal the end of the ray.
<br><br>So, I modified the code to take the Largest, rather than the smallest, of the 3 numbers calculated.&nbsp;&nbsp; Then, to prevent overflow, recompute the Fixed-Point ray direction to ensure that End = Start + Direction*numSteps.&nbsp; a Diff Patch to make these changes is shown below (and attached to this email).
<br><br>The time require to generate a volume rendering is effectively unchanged (144seconds before, 148 seconds now).<br><br><span style="font-family: courier new,monospace;">--- ../../backup/VTK/VolumeRendering/vtkFixedPointVolumeRayCastMapper.cxx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2006-12-02 11:10:
35.000000000 -0600</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+++ vtkFixedPointVolumeRayCastMapper.cxx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2007-08-16 09:51:07.070980624 -0500</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">@@ -1979,7 +1979,7 @@ float vtkFixedPointVolumeRayCastMapper::</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((rayDirection[0]&lt;0)?(-rayDirection[0]):(rayDirection[0])) );
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

-&nbsp;&nbsp;&nbsp; if ( diff[1] &gt;= diff[0] &amp;&amp; diff[1] &gt;= diff[2] &amp;&amp; rayDirection[2])</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp; if ( diff[1] &gt;= diff[0] &amp;&amp; diff[1] &gt;= diff[2] &amp;&amp; rayDirection[1])
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; steps = 1 + static_cast&lt;int&gt;( diff[1] /
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((rayDirection[1]&lt;0)?(-rayDirection[1]):(rayDirection[1])) );</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">@@ -2043,12 +2043,31 @@ float vtkFixedPointVolumeRayCastMapper::</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( !stepsValid || currSteps &lt; *numSteps )</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( !stepsValid || currSteps &gt; *numSteps )</span>

<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *numSteps = currSteps;
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stepsValid = 1;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( stepLoop = 0; stepLoop &lt; 3; stepLoop++ )</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int endVal = this-&gt;ToFixedPointPosition(rayEnd[stepLoop]);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dir[stepLoop]&amp;0x80000000)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (endVal &gt;= pos[stepLoop])</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir[stepLoop] =&nbsp; (endVal - pos[stepLoop]) / *numSteps;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir[stepLoop] = dir[stepLoop] | 0x80000000;
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (endVal &lt;= pos[stepLoop])</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">

+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir[stepLoop] =&nbsp; (pos[stepLoop] - endVal) / *numSteps;</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;">

<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;}</span><br><br clear="all"><br>-- <br>----------------------------------------
<br>Randall Hand <br>Visualization Scientist<br>ERDC MSRC-ITL
<br><br><div><span class="gmail_quote">On 8/15/07, <b class="gmail_sendername">Randall Hand</b> &lt;<a href="mailto:randall.hand@gmail.com" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">randall.hand@gmail.com
</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Anyone looking at this?<br><br>Also, I believe I found a typo bug in vtkFixedPointVolumeRayCastMapper.cxx.&nbsp; Line 1982 reads:<br><br>&nbsp;&nbsp;&nbsp; if ( diff[1] &gt;= diff[0] &amp;&amp; diff[1] &gt;= diff[2] &amp;&amp; rayDirection[2])
<br><br clear="all">But I&#39;m pretty sure it should be:<br><br>&nbsp;&nbsp;&nbsp; if ( diff[1] &gt;= diff[0] &amp;&amp; diff[1] &gt;= diff[2] &amp;&amp; rayDirection[1])<br><br>(Wrong rayDirection Index).<br><span><br>-- <br>
----------------------------------------
</span><span><br>Randall Hand <br>Visualization Scientist<br>ERDC MSRC-ITL
<br><br></span><div><span><div><span class="gmail_quote">On 8/13/07, <b class="gmail_sendername">Randall Hand</b> &lt;<a href="mailto:randall.hand@gmail.com" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">

randall.hand@gmail.com</a>&gt; wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I&#39;ve been looking into a problem in the vtkFixedPointVolumeRayCastMapper and I&#39;ve about exhausted my immediate expertise in the situation, so I present it here in hopes that someone else can chime in (Lisa, are you reading this?)
<br><br>I&#39;m rendering vtkImageData with the FixedPoint mapper, and seeing odd&nbsp; problems along the zero-crossings when the data is presented in a Perspective view direct-on to the user (or close to it).&nbsp; The problem doesn&#39;t manifest in Parallel/Orthographic views, and it&#39;s fairly difficult to see.&nbsp; The visual problem is black lines (black background in my case) presented in the center of the data on the X &amp; Y image axes, but not completely through the data.&nbsp; The part of the data closer to the viewer is rendered properly, but the distant part is not rendered at all.
<br><br>After alot of printfs, I&#39;ve started to narrow down the problem.&nbsp; In vtkFixedPointVolumeRayCastMapper.cxx&#39;s &quot;ComputeRayInfo&quot; function, the &quot;numSteps&quot; seems to be computed incorrectly.&nbsp; Currently, you compute the numSteps necessary along each of the 3 axis directions, and keep the smallest number.&nbsp; This works most of the time, except when the &quot;direction&quot; component is near-0.&nbsp; You have an &quot;if&quot; check for equal to zero, but when the alignment is such that the &quot;direction&quot; becomes 1 or -1 (which is infinitesimally close to zero once the Fixed-Point conversion is made), the math seems to come out wrong.&nbsp; In my dataset:
<br><br><div style="margin-left: 40px;">i=435, j=3, numSteps = 156<br>i=436, j=3, numSteps = 149<br>i=437, j=3, numSteps = 134<br>i=438, j=3, numSteps = 90<br>i=439, j=3, numSteps = 90<br>i=440, j=3, numSteps = 134<br>i=441, j=3, numSteps = 149
<br>i=442, j=3, numSteps = 156<br>i=443, j=3, numSteps = 160<br>i=444, j=3, numSteps = 163<br>i=445, j=3, numSteps = 165<br></div><br clear="all">(generated with printf&#39;s I added to the code).&nbsp; At the center of the image, when i=438 &amp; 439, you&#39;ll see the numSteps takes an unusual drop.&nbsp; The same happens when the j crosses the center of the image, because the Y component of the direction drops to near-0.&nbsp; The result is that the rays terminate early, without fully passing through the volume.&nbsp; 
<br><br>Now, I can &quot;alleviate&quot; this problem by changing:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( !(dir[stepLoop]&amp;0x7fffffff ))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>to <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( (dir[stepLoop]&amp;0x7fffffff ) &lt; 10)
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>But that doesn&#39;t really &quot;solve&quot; the problem.&nbsp; I think that perhaps the method used to compute &quot;currSteps&quot; needs to be changed, although I haven&#39;t been able to find a method that seems to work any better.
<br><br>Hopefully this can help someone find the cause of this problem.<br><span>-- <br>----------------------------------------<br>Randall Hand <br>Visualization Scientist<br>ERDC MSRC-ITL
</span></blockquote></div><br>
</span></div></blockquote></div><br>
<br clear="all"></blockquote></div><br>