Hello,<div><br></div><div>I have a voxel type terrain/height map updated at 1Hz. At first I tried using glyphs for the cells, which (un-surprisingly) turned out to be too slow. I re-wrote it today to use cells of triangle strips. I have been hitting my head on the wall with memory leaks, and after scouring the c++ examples I am almost to the point of scrapping everything and running back to direct openGL. </div>
<div><br></div><div>As the number of cells, points, etc are constant, I thought it would be possible to declare things as vtkSmartPointer&lt;&gt; kept as class members. This works for the points data (points,normals, colors), but if I try it with anything else (such as vtkcellarray, vtkPolyDataMapper, or vtkPolyData), i see huge memory leaks. the leak from polydata was really weird</div>
<div><br></div><div>Would someone please look at the code below and tell me what i&#39;m missing?  If i understand the book and tutorials, i should be able to just create everything once and then update the data arrays... is there some sort of a cleanup method I should be calling on each update? (also recommendations on how to use less memory would be appreciated)</div>
<div><br></div><div>for reference a &quot;MapHandle&quot; is a boost::shared_ptr&lt;Map&gt;, where Map is a vector of Cells. Map also has convenience methods to convert from iterators to/from x.y.z points.</div><div><br></div>
<div><div> class MapActor</div><div>            {</div><div>            public:</div><div><br></div><div>                MapActor();</div><div>                ~MapActor();</div><div><br></div><div>                void updateMap(MapHandle handle, ColorMap &amp;objectColors, bool heightColor = false);</div>
<div>                </div><div>                vtkActor * actorPointer() { return actor; };</div><div><br></div><div>            private:</div><div><br></div><div>                rframe::Timer updateTimer;</div><div>                </div>
<div>                vtkSmartPointer&lt;vtkPoints&gt; points;</div><div>                vtkSmartPointer&lt;vtkFloatArray&gt; normals;</div><div>                vtkSmartPointer&lt;vtkUnsignedCharArray&gt; colors;</div><div>
                vtkSmartPointer&lt;vtkPolyData&gt; polydata;</div><div>                vtkSmartPointer&lt;vtkCellArray&gt; celldata;</div><div>                vtkSmartPointer&lt;vtkPolyDataMapper&gt; mapper;</div><div>                vtkSmartPointer&lt;vtkActor&gt; actor;</div>
<div>                vtkSmartPointer&lt;vtkLookupTable&gt; heightLut;</div><div><br></div><div>                MapHandle mapHandle;</div><div>            };</div></div><div><br></div><div><br></div><div><div>MapActor::MapActor() </div>
<div>{</div><div>    polydata = vtkSmartPointer&lt;vtkPolyData&gt;::New();</div><div><br></div><div>    // create empty polydata for now</div><div>    polydata = vtkSmartPointer&lt;vtkPolyData&gt;::New();</div><div><br></div>
<div>    heightLut = vtkSmartPointer&lt;vtkLookupTable&gt;::New();</div><div>    heightLut-&gt;SetHueRange(0.6667,0.0);</div><div>    //   heightLut-&gt;SetTableRange(-3,10);</div><div>    heightLut-&gt;SetTableRange(-1,1);</div>
<div>    heightLut-&gt;Build();</div><div><br></div><div>    actor = vtkSmartPointer&lt;vtkActor&gt;::New();</div><div>}</div><div><br></div><div><br></div><div>MapActor::~MapActor() </div><div>{</div><div>}</div><div><br>
</div><div><br></div><div>void MapActor::updateMap(MapHandle handle, ColorMap &amp; objectColors, bool heightColor)</div><div>{</div><div>    updateTimer.start();</div><div><br></div><div>    mapHandle = handle;</div><div>
<br></div><div>    // Create points</div><div>    if (!points) </div><div>    {</div><div>        cout &lt;&lt; &quot;creating points&quot; &lt;&lt; endl;</div><div>        points = vtkSmartPointer&lt;vtkPoints&gt;::New();</div>
<div>        points-&gt;SetNumberOfPoints(mapHandle-&gt;size()*8);</div><div>    }</div><div>    </div><div>    if (!normals)</div><div>    {</div><div>        normals = vtkSmartPointer&lt;vtkFloatArray&gt;::New();</div><div>
        normals-&gt;SetNumberOfComponents(3);</div><div>        normals-&gt;SetName(&quot;normals&quot;);</div><div>        normals-&gt;SetNumberOfTuples(mapHandle-&gt;size());        </div><div>    }</div><div><br></div>
<div>    //    if (!celldata)</div><div>    {</div><div>        celldata = vtkSmartPointer&lt;vtkCellArray&gt;::New(); // we want to create a new cell data every time, for garbage collection</div><div>        // the docs say there is now way to pre-allocate celldata storage...</div>
<div>    }</div><div><br></div><div>    // add points for elevation cells</div><div>    Point p;</div><div>    float resolution = mapHandle-&gt;resolution();</div><div><br></div><div>    VirtualMap::MapType::iterator it, endIt;</div>
<div>    int cellCount = 0;</div><div>    int pointCount = 0;</div><div>    vtkIdType indicies[14];</div><div><br></div><div>    it = mapHandle-&gt;begin();</div><div>    endIt = mapHandle-&gt;end();</div><div><br></div><div>
    double minZ, maxZ;</div><div>    float normal[3];</div><div>    double dcolor[3];</div><div>    unsigned char color[3];</div><div><br></div><div>    minZ = 999999;</div><div>    maxZ = -999999;</div><div><br></div><div>
    if (!colors)</div><div>    {</div><div>        colors = vtkSmartPointer&lt;vtkUnsignedCharArray&gt;::New();</div><div>        colors-&gt;SetName(&quot;colors&quot;);</div><div>        colors-&gt;SetNumberOfComponents(3);</div>
<div>        colors-&gt;SetNumberOfTuples(mapHandle-&gt;size()*14);</div><div>    }</div><div><br></div><div>    while (it != endIt)</div><div>    {</div><div>        mapHandle-&gt;getPoint(p,it);</div><div><br></div><div>
        float height = -1*it-&gt;height();</div><div>        if (height &lt;= 0) height = 0.01;</div><div><br></div><div>        double z = -1*it-&gt;ground();</div><div><br></div><div>        if (heightColor == true)</div>
<div>        {</div><div>            // set color</div><div>            heightLut-&gt;GetColor(height,dcolor);</div><div>        }            </div><div>        else</div><div>        {</div><div>            dcolor[0] = objectColors[it-&gt;classType()].red();</div>
<div>            dcolor[1] = objectColors[it-&gt;classType()].green();</div><div>            dcolor[2] = objectColors[it-&gt;classType()].blue();</div><div>        }</div><div><br></div><div>        color[0] = static_cast&lt;unsigned char&gt;(255.0 * dcolor[0]);</div>
<div>        color[1] = static_cast&lt;unsigned char&gt;(255.0 * dcolor[1]);</div><div>        color[2] = static_cast&lt;unsigned char&gt;(255.0 * dcolor[2]);</div><div>        </div><div>        // bottom front left</div>
<div>        indicies[0] = pointCount;</div><div>        points-&gt;SetPoint(pointCount,p.x(),-p.y(),z);</div><div>        colors-&gt;InsertTupleValue(pointCount,color);</div><div>        normal[0] = -1;</div><div>        normal[1] = -1;</div>
<div>        normal[2] = -1;</div><div>        normals-&gt;InsertTupleValue(pointCount,normal);</div><div>        pointCount++;</div><div>        // top front left</div><div>        indicies[1] = pointCount;</div><div>        points-&gt;SetPoint(pointCount,p.x(),-p.y(),z+height);</div>
<div>        colors-&gt;InsertTupleValue(pointCount,color);</div><div>        normal[0] = -1;</div><div>        normal[1] = -1;</div><div>        normal[2] = 1;</div><div>        normals-&gt;InsertTupleValue(pointCount,normal);</div>
<div>        pointCount++;</div><div>        // bottom front right</div><div>        indicies[2] = pointCount;</div><div>        points-&gt;SetPoint(pointCount,p.x()+resolution,-p.y(),z);</div><div>        colors-&gt;InsertTupleValue(pointCount,color);</div>
<div>        normal[0] = 1;</div><div>        normal[1] = -1;</div><div>        normal[2] = -1;</div><div>        normals-&gt;InsertTupleValue(pointCount,normal);</div><div>        pointCount++;</div><div>        // top front right</div>
<div>        indicies[3] = pointCount;</div><div>        points-&gt;SetPoint(pointCount,p.x()+resolution,-p.y(),z+height);</div><div>        colors-&gt;InsertTupleValue(pointCount,color);</div><div>        normal[0] = 1;</div>
<div>        normal[1] = -1;</div><div>        normal[2] = 1;</div><div>        normals-&gt;InsertTupleValue(pointCount,normal);</div><div>        pointCount++;</div><div>        // bootom back right</div><div>        indicies[4] = pointCount;</div>
<div>        points-&gt;SetPoint(pointCount,p.x()+resolution,-p.y()-resolution,z);  // &lt;- should this be -resolution?</div><div>        colors-&gt;InsertTupleValue(pointCount,color);</div><div>        normal[0] = 1;</div>
<div>        normal[1] = 1;</div><div>        normal[2] = -1;</div><div>        normals-&gt;InsertTupleValue(pointCount,normal);</div><div>        pointCount++;</div><div>        // top back right</div><div>        indicies[5] = pointCount;</div>
<div>        points-&gt;SetPoint(pointCount,p.x()+resolution,-p.y()-resolution,z+height);</div><div>        colors-&gt;InsertTupleValue(pointCount,color);</div><div>        normal[0] = 1;</div><div>        normal[1] = 1;</div>
<div>        normal[2] = 1;</div><div>        normals-&gt;InsertTupleValue(pointCount,normal);</div><div>        pointCount++;</div><div>        // bottom back left</div><div>        indicies[6] = pointCount;</div><div>        points-&gt;SetPoint(pointCount,p.x(),-p.y()-resolution,z);</div>
<div>        colors-&gt;InsertTupleValue(pointCount,color);</div><div>        normal[0] = -1;</div><div>        normal[1] = 1;</div><div>        normal[2] = -1;</div><div>        normals-&gt;InsertTupleValue(pointCount,normal);</div>
<div>        pointCount++;</div><div>        // top back left</div><div>        indicies[7] = pointCount;</div><div>        points-&gt;SetPoint(pointCount,p.x(),-p.y()-resolution,z+height);</div><div>        colors-&gt;InsertTupleValue(pointCount,color);</div>
<div>        normal[0] = -1;</div><div>        normal[1] = 1;</div><div>        normal[2] = 1;</div><div>        normals-&gt;InsertTupleValue(pointCount,normal);</div><div>        pointCount++;</div><div><br></div><div>        // close box</div>
<div>        indicies[8] = indicies[0];</div><div>        indicies[9] = indicies[1];</div><div>        // add top</div><div>        // degenerate triangle</div><div>        indicies[10] = indicies[1];</div><div>        indicies[11] = indicies[7];</div>
<div>        indicies[12] = indicies[3];</div><div>        indicies[13] = indicies[5];</div><div><br></div><div>        // indicies[12] = ;</div><div>        </div><div>        //       celldata-&gt;InsertNextCell(triangleStrip);</div>
<div>        celldata-&gt;InsertNextCell(14,indicies);</div><div>   </div><div>        if (height &lt; minZ) minZ = height;</div><div>        if (height &gt; maxZ) maxZ = height;</div><div>        </div><div>        ++it;</div>
<div>        ++cellCount;</div><div>    }</div><div><br></div><div>    polydata = vtkSmartPointer&lt;vtkPolyData&gt;::New();</div><div><br></div><div>    polydata-&gt;SetPoints(points);</div><div>    polydata-&gt;GetPointData()-&gt;SetNormals(normals);</div>
<div>    polydata-&gt;SetStrips(celldata);</div><div><br></div><div>    //  polydata-&gt;Update();</div><div>    // polydata-&gt;GetCellData()-&gt;SetScalars(colors);  well this doesn&#39;t work right... </div><div>    polydata-&gt;GetPointData()-&gt;SetScalars(colors);</div>
<div>    polydata-&gt;Modified();</div><div><br></div><div>    // Create a mapper and actor</div><div>    //    if (!mapper)</div><div>    {</div><div>        mapper = vtkSmartPointer&lt;vtkPolyDataMapper&gt;::New();</div>
<div>    }</div><div><br></div><div>    //mapper-&gt;SetInputConnection(glyph3D-&gt;GetOutputPort());</div><div>    mapper-&gt;SetInput(polydata);</div><div><br></div><div>    actor-&gt;SetMapper(mapper);</div><div>    // actor-&gt;GetProperty()-&gt;BackfaceCullingOn();</div>
<div><br></div><div>    updateTimer.stop();</div><div><br></div><div>    cout &lt;&lt; &quot;map update took: &quot; &lt;&lt; updateTimer.elapsedDouble() &lt;&lt; &quot;, avg: &quot; &lt;&lt; updateTimer.averageElapsedDouble() &lt;&lt; endl;</div>
<div>}</div></div><div><br></div><div><br></div>