Commit cc0ed3fc authored by jcfr's avatar jcfr

ENH: Added OBJ file save option for model nodes

From: Andras Lasso <lasso@queensu.ca>

git-svn-id: http://svn.slicer.org/Slicer4/trunk@25421 3bd1e089-480b-0410-8dfb-8563597acbee
parent 8b8fe6da
......@@ -528,6 +528,7 @@ set(Slicer_VTK_COMPONENTS
vtkFiltersGeometry
vtkGUISupportQtOpenGL
vtkGUISupportQtSQL
vtkIOExport
vtkIOImage
vtkIOLegacy
vtkIOPLY
......
......@@ -160,7 +160,7 @@ simple_test( vtkMRMLLinearTransformNodeTest1 )
simple_test( vtkMRMLModelDisplayNodeTest1 )
simple_test( vtkMRMLModelHierarchyNodeTest1 )
simple_test( vtkMRMLModelNodeTest1 )
simple_test( vtkMRMLModelStorageNodeTest1 )
simple_test( vtkMRMLModelStorageNodeTest1 ${TEMP})
simple_test( vtkMRMLNodeTest1 )
simple_test( vtkMRMLLinearTransformNodeEventsTest )
simple_test( vtkMRMLNonlinearTransformNodeTest1 ${CMAKE_CURRENT_SOURCE_DIR}/NonLinearTransformScene.mrml)
......
......@@ -12,10 +12,90 @@
#include "vtkMRMLCoreTestingMacros.h"
#include "vtkMRMLModelStorageNode.h"
#include "vtkMRMLModelNode.h"
#include "vtkMRMLScene.h"
int vtkMRMLModelStorageNodeTest1(int , char * [] )
#include <vtkCleanPolyData.h>
#include <vtkCylinderSource.h>
#include <vtkNew.h>
#include <vtkTriangleFilter.h>
int TestReadWriteData(const char* tempDir);
int vtkMRMLModelStorageNodeTest1(int argc, char * argv[] )
{
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " /path/to/temp" << std::endl;
return EXIT_FAILURE;
}
vtkNew<vtkMRMLModelStorageNode> node1;
EXERCISE_ALL_BASIC_MRML_METHODS(node1.GetPointer());
const char* tempDir = argv[1];
CHECK_EXIT_SUCCESS(TestReadWriteData(tempDir));
return EXIT_SUCCESS;
}
int TestReadWriteData(const char* tempDir)
{
std::string sceneFileName = std::string(tempDir) + "/vtkMRMLModelStorageNodeTest1.mrml";
std::string modelFileNameBase = std::string(tempDir) + "/vtkMRMLModelNodeTest1";
std::vector< std::string > modelFileNameExtensions;
modelFileNameExtensions.push_back(".vtk");
modelFileNameExtensions.push_back(".vtp");
modelFileNameExtensions.push_back(".stl");
modelFileNameExtensions.push_back(".ply");
modelFileNameExtensions.push_back(".obj");
// Generate test polydata (triangle mesh without coincident points)
vtkNew<vtkCylinderSource> cylinderSource;
vtkNew<vtkTriangleFilter> triangulator;
triangulator->SetInputConnection(cylinderSource->GetOutputPort());
vtkNew<vtkCleanPolyData> cleaner;
cleaner->PointMergingOn();
cleaner->SetInputConnection(triangulator->GetOutputPort());
cleaner->Update();
// Validate test polydata
int numberOfPoints = cleaner->GetOutput()->GetNumberOfPoints();
int numberOfCells = cleaner->GetOutput()->GetNumberOfCells();
CHECK_BOOL(numberOfPoints > 0, true);
CHECK_BOOL(numberOfCells > 0, true);
// Create test scene
vtkNew<vtkMRMLScene> scene;
scene->SetRootDirectory(tempDir);
// Add model node
vtkNew<vtkMRMLModelNode> modelNode;
modelNode->SetPolyDataConnection(cleaner->GetOutputPort());
CHECK_NOT_NULL(scene->AddNode(modelNode.GetPointer()));
// Add storage node
modelNode->AddDefaultStorageNode();
vtkMRMLStorageNode* storageNode = modelNode->GetStorageNode();
CHECK_NOT_NULL(storageNode);
// Test writing and re-reading of test polydata
for (std::vector< std::string >::iterator modelFileNameExtensionIt = modelFileNameExtensions.begin();
modelFileNameExtensionIt != modelFileNameExtensions.end(); ++modelFileNameExtensionIt)
{
std::cout << "Testing " << (*modelFileNameExtensionIt) << "\n";
std::string fileName = modelFileNameBase + (*modelFileNameExtensionIt);
storageNode->SetFileName(fileName.c_str());
// Test writing
CHECK_BOOL(storageNode->WriteData(modelNode.GetPointer()), true);
// Clear data from model node
modelNode->SetAndObservePolyData(NULL);
// Test reading
CHECK_BOOL(storageNode->ReadData(modelNode.GetPointer()), true);
vtkNew<vtkCleanPolyData> cleaner2;
cleaner2->PointMergingOn();
cleaner2->SetInputConnection(modelNode->GetPolyDataConnection());
cleaner2->Update();
CHECK_INT(cleaner2->GetOutput()->GetNumberOfPoints(), numberOfPoints);
CHECK_INT(cleaner2->GetOutput()->GetNumberOfCells(), numberOfCells);
}
return EXIT_SUCCESS;
}
......@@ -18,16 +18,22 @@
#include "vtkMRMLScene.h"
// VTK includes
#include <vtkActor.h>
#include <vtkBYUReader.h>
#include <vtkCellArray.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkNew.h>
#include <vtkObjectFactory.h>
#include <vtkOBJReader.h>
#include <vtkOBJExporter.h>
#include <vtkPolyDataMapper.h>
#include <vtkPLYReader.h>
#include <vtkPLYWriter.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyDataWriter.h>
#include <vtkProperty.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkSTLReader.h>
#include <vtkSTLWriter.h>
#include <vtkStringArray.h>
......@@ -373,6 +379,42 @@ int vtkMRMLModelStorageNode::WriteDataInternal(vtkMRMLNode *refNode)
result = 0;
}
}
else if (extension == ".obj")
{
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(modelNode->GetPolyDataConnection());
vtkNew<vtkActor> actor;
actor->SetMapper(mapper.GetPointer());
vtkMRMLDisplayNode* displayNode = modelNode->GetDisplayNode();
if (displayNode)
{
actor->GetProperty()->SetColor(displayNode->GetColor());
actor->GetProperty()->SetOpacity(displayNode->GetOpacity());
}
vtkNew<vtkRenderer> renderer;
renderer->AddActor(actor.GetPointer());
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->AddRenderer(renderer.GetPointer());
vtkNew<vtkOBJExporter> exporter;
exporter->SetRenderWindow(renderWindow.GetPointer());
std::string fullNameWithoutExtension = fullName;
if (fullNameWithoutExtension.size() > 4)
{
fullNameWithoutExtension.erase(fullNameWithoutExtension.size() - 4);
}
exporter->SetFilePrefix(fullNameWithoutExtension.c_str());
try
{
exporter->Write();
this->ResetFileNameList();
std::string materialFileName = fullNameWithoutExtension + ".mtl";
this->AddFileName(materialFileName.c_str());
}
catch (...)
{
result = 0;
}
}
else
{
result = 0;
......@@ -402,9 +444,9 @@ void vtkMRMLModelStorageNode::InitializeSupportedWriteFileTypes()
// SupportedFileType() says they are supported
this->SupportedWriteFileTypes->InsertNextValue("Poly Data (.vtk)");
this->SupportedWriteFileTypes->InsertNextValue("XML Poly Data (.vtp)");
//
//this->SupportedWriteFileTypes->InsertNextValue("vtkXMLPolyDataReader (.g)");
//this->SupportedWriteFileTypes->InsertNextValue("vtkXMLPolyDataReader (.meta)");
this->SupportedWriteFileTypes->InsertNextValue("STL (.stl)");
this->SupportedWriteFileTypes->InsertNextValue("PLY (.ply)");
this->SupportedWriteFileTypes->InsertNextValue("Wavefront OBJ (.obj)");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment