<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Hej,
<p>I made a object factory to combine vtk and qt. Now we got a problem
under NT4.0.
<br>My object factory replaces vtkRenderWindow, vtkRenderWindowInteractor,
etc....
<br>and VTK (3.2) is build as one vtkdll.dll (no changes)
<p>The problem:
<br>We create a vtkRenderWindow and add vtkCubeSource.
<br>If we try to pick the cube (pressing 'p') we got a memory heap error.
<br>The same programm on an SGI works fine and the same programm under
NT without my objectfactory
<br>works fine, too.
<p>The reason is, we can't execute <tt>renderer->GetZ(150, 400);</tt> under
NT.
<p>Here is the code from vtkRenderer:
<blockquote><tt>float vtkRenderer::GetZ (int x, int y)</tt>
<br><tt>{</tt>
<br><tt>&nbsp; float *zPtr;</tt>
<br><tt>&nbsp; float z;</tt>
<p><tt>&nbsp; zPtr = this->RenderWindow->GetZbufferData (x, y, x, y);</tt>
<br><tt>&nbsp; if (zPtr)</tt>
<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; z = *zPtr;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; delete [] zPtr;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp; else</tt>
<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; z = 1.0;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp; return z;</tt>
<br><tt>}</tt></blockquote>
and the corresponding method of my QGLWindow (its a one to one copy from
vtkopenglrenderwindow resp. vtkwin32renderwindow):
<blockquote><tt>float *vtkQGLRenderWindow::GetZbufferData( int x1, int
y1, int x2, int y2&nbsp; )</tt>
<br><tt>{</tt>
<br><tt>&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
y_low, y_hi;</tt>
<br><tt>&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
x_low, x_hi;</tt>
<br><tt>&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
width, height;</tt>
<br><tt>&nbsp; float&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
*z_data = NULL;</tt>
<p><tt>&nbsp; // set the current window</tt>
<br><tt>&nbsp; this->MakeCurrent();</tt>
<p><tt>&nbsp; if (y1 &lt; y2)</tt>
<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; y_low = y1;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; y_hi&nbsp; = y2;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp; else</tt>
<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; y_low = y2;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; y_hi&nbsp; = y1;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<p><tt>&nbsp; if (x1 &lt; x2)</tt>
<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; x_low = x1;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; x_hi&nbsp; = x2;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp; else</tt>
<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
<br><tt>&nbsp;&nbsp;&nbsp; x_low = x2;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; x_hi&nbsp; = x1;</tt>
<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
<p><tt>&nbsp; width =&nbsp; abs(x2 - x1)+1;</tt>
<br><tt>&nbsp; height = abs(y2 - y1)+1;</tt>
<p><tt>&nbsp; z_data = new float[width*height];</tt>
<p><tt>&nbsp; // Turn of texturing in case it is on - some drivers have
a problem</tt>
<br><tt>&nbsp; // getting / setting pixels with texturing enabled.</tt>
<br><tt>&nbsp; glDisable( GL_TEXTURE_2D );</tt>
<p><tt>&nbsp; glPixelStorei( GL_PACK_ALIGNMENT, 1 );</tt>
<br><tt>&nbsp; glReadPixels( x_low, y_low,</tt>
<br><tt>&nbsp; width, height,</tt>
<br><tt>&nbsp; GL_DEPTH_COMPONENT, GL_FLOAT,</tt>
<br><tt>&nbsp; z_data );</tt>
<p><tt>&nbsp; return z_data;</tt>
<br><tt>}</tt></blockquote>
Why can't we execute "<tt>renderer->GetZ (150, 400);"?</tt>
<p>The renderwindow was created in the application and the renderer is
created in the vtkdll.dll.
<br>The renderwindow allocates memory "<tt>z_data = new float[width*height]"</tt>
but the renderer
<br>isn't allowed to free the memory "<tt>delete [] zPtr;"</tt>. My solution
was that I add a method NewMemory
<br>in the vtkObjectFactory which allocates memory on the heap of the dll
and recompile vtkdll.dll.
<blockquote><tt>char *vtkObjectFactory::NewMemory(int size)</tt>
<br><tt>{</tt>
<br><tt>&nbsp; return new char[size];</tt>
<br><tt>}</tt></blockquote>
I had to remove all memory allocations by:
<blockquote><tt>#ifdef _WIN32</tt>
<br><tt>&nbsp; z_data = (float*)vtkObjectFactory::NewMemory(sizeof(float)*width*height);</tt>
<br><tt>#else</tt>
<br><tt>&nbsp; z_data = new float[width*height];</tt>
<br><tt>#endif</tt></blockquote>
Now all works fine, but I had to create my own VTKdll.dll...
<br>&nbsp;
<p>My questions:
<ul>
<li>
Is there a way to allocate memory which can be freed from an other dll?</li>

<li>
Is there a similar problem with shared libraries on SGIs?</li>

<li>
Is there a solution without changing code from vtk3.2?</li>
</ul>

<p><br>Carsten</html>