Skip to content
Snippets Groups Projects
Commit e3be504b authored by Nicolas Vuaille's avatar Nicolas Vuaille
Browse files

Prevent memory leaks in vtkOBJExporter

Use vtkNew to prevent leaks in case of anticipated return.
parent 6163ddb0
No related branches found
No related tags found
No related merge requests found
......@@ -31,6 +31,7 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
${GL2PSTests} ${GL2PSTestsPDF}
TestRIBExporter.cxx,NO_VALID
UnitTestRIB.cxx,NO_DATA,NO_VALID
TestOBJExporter.cxx
)
vtk_test_cxx_executable(${vtk-module}CxxTests tests
RENDERING_FACTORY
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestOBJExporter.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkActor.h"
#include "vtkNew.h"
#include "vtkOBJExporter.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkSphereSource.h"
#include "vtkTestUtilities.h"
#include <cstdlib>
int fileSize(const std::string& filename);
int TestOBJExporter(int argc, char *argv[])
{
char *tempDir = vtkTestUtilities::GetArgOrEnvOrDefault(
"-T", argc, argv, "VTK_TEMP_DIR", "Testing/Temporary");
if (!tempDir)
{
std::cout << "Could not determine temporary directory.\n";
return EXIT_FAILURE;
}
std::string testDirectory = tempDir;
delete[] tempDir;
std::string filename = testDirectory
+ std::string("/") + std::string("Export");
vtkNew<vtkSphereSource> sphere;
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(sphere->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper.Get());
vtkNew<vtkRenderer> renderer;
renderer->AddActor(actor.Get());
vtkNew<vtkRenderWindow> window;
window->AddRenderer(renderer.Get());
vtkNew<vtkOBJExporter> exporter;
exporter->SetRenderWindow(window.Get());
exporter->SetFilePrefix(filename.c_str());
exporter->Write();
filename += ".obj";
size_t correctSize = fileSize(filename);
if (correctSize == 0)
{
return EXIT_FAILURE;
}
actor->VisibilityOff();
exporter->Write();
size_t noDataSize = fileSize(filename);
if (noDataSize == 0)
{
return EXIT_FAILURE;
}
if (noDataSize >= correctSize)
{
std::cerr << "Error: file should contain data for a visible actor"
"and not for a hidden one." << std::endl;
return EXIT_FAILURE;
}
actor->VisibilityOn();
actor->SetMapper(NULL);
exporter->Write();
size_t size = fileSize(filename);
if (size == 0)
{
return EXIT_FAILURE;
}
if (size > noDataSize)
{
std::cerr << "Error: file should not contain geometry"
" (actor has no mapper)" << std::endl;
return EXIT_FAILURE;
}
actor->SetMapper(mapper.Get());
mapper->RemoveAllInputConnections(0);
exporter->Write();
size = fileSize(filename);
if (size == 0)
{
return EXIT_FAILURE;
}
if (size > noDataSize)
{
std::cerr << "Error: file should not contain geometry"
" (mapper has no input)" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int fileSize(const std::string & filename)
{
size_t size = 0;
FILE* f = fopen(filename.c_str(), "r");
if (f)
{
fseek(f, 0, SEEK_END);
size = ftell(f);
}
else
{
std::cerr << "Error: cannot open file " << filename << std::endl;
}
fclose(f);
return size;
}
......@@ -22,6 +22,7 @@
#include "vtkFloatArray.h"
#include "vtkGeometryFilter.h"
#include "vtkMapper.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"
......@@ -124,17 +125,15 @@ void vtkOBJExporter::WriteAnActor(vtkActor *anActor, FILE *fpObj, FILE *fpMtl,
{
vtkDataSet *ds;
vtkPolyData *pd;
vtkGeometryFilter *gf = NULL;
vtkPointData *pntData;
vtkPoints *points;
vtkDataArray *normals = NULL;
vtkDataArray *tcoords;
int i, i1, i2, idNext;
vtkProperty *prop;
double *tempd;
double *p;
vtkCellArray *cells;
vtkTransform *trans = vtkTransform::New();
vtkNew<vtkTransform> trans;
vtkIdType npts = 0;
vtkIdType *indx = 0;
......@@ -173,7 +172,7 @@ void vtkOBJExporter::WriteAnActor(vtkActor *anActor, FILE *fpObj, FILE *fpMtl,
// we really want polydata
if ( ds->GetDataObjectType() != VTK_POLY_DATA )
{
gf = vtkGeometryFilter::New();
vtkNew<vtkGeometryFilter> gf;
gf->SetInputConnection(
anActor->GetMapper()->GetInputConnection(0, 0));
gf->Update();
......@@ -199,9 +198,9 @@ void vtkOBJExporter::WriteAnActor(vtkActor *anActor, FILE *fpObj, FILE *fpMtl,
pntData = pd->GetPointData();
if (pntData->GetNormals())
{
normals = vtkFloatArray::New();
vtkNew<vtkFloatArray> normals;
normals->SetNumberOfComponents(3);
trans->TransformNormals(pntData->GetNormals(),normals);
trans->TransformNormals(pntData->GetNormals(),normals.Get());
for (i = 0; i < normals->GetNumberOfTuples(); i++)
{
p = normals->GetTuple(i);
......@@ -276,7 +275,7 @@ void vtkOBJExporter::WriteAnActor(vtkActor *anActor, FILE *fpObj, FILE *fpMtl,
fprintf(fpObj,"f ");
for (i = 0; i < npts; i++)
{
if (normals)
if (pntData->GetNormals())
{
if (tcoords)
{
......@@ -329,7 +328,7 @@ void vtkOBJExporter::WriteAnActor(vtkActor *anActor, FILE *fpObj, FILE *fpMtl,
i1 = i - 1;
i2 = i - 2;
}
if (normals)
if (pntData->GetNormals())
{
if (tcoords)
{
......@@ -376,15 +375,6 @@ void vtkOBJExporter::WriteAnActor(vtkActor *anActor, FILE *fpObj, FILE *fpMtl,
}
idStart = idNext;
trans->Delete();
if (normals)
{
normals->Delete();
}
if (gf)
{
gf->Delete();
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment