STLExport/STLExporter.cpp

STLExport/STLExporter.cpp
//**************************************************************************/
// Copyright (c) 2009 Autodesk, Inc.
// All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk license
// agreement provided at the time of installation or download, or which
// otherwise accompanies this software in either electronic or hard copy form.
//
//**************************************************************************/
// DESCRIPTION: Sample stereolithography (STL) file exporter.
//
// Limitations
// - requires a single, closed mesh to work.
// - There will be no decimation done, so the mesh will be saved at full density,
// which might be too big for stereolithography shops.
// - Self-intersecting meshes
// are not corrected, which may cause problems with the resulting STL file.
//
// CREATED: February 2009
//**************************************************************************/
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <QtCore/QFile>
#if defined(JAMBUILD)
#include <Mudbox/mudbox.h>
#else
#include "../../include/Mudbox/mudbox.h"
#endif
#include "utility.hpp"
namespace mudbox
{
// Creates a record in the memory to describe the plugin to Mudbox
MB_PLUGIN( "STL Exporter", "STL file export plugin", "Autodesk", "http://www.mudbox3d.com", 0 );
// Main plug-in declaration
class STLExporter :
public BaseExporter,
public Singleton<STLExporter>
{
public:
// The following line is used to expose RTTI information to Mudbox
// Default constructor, does nothing.
STLExporter() {
}
// Return the supported file extension(s) by the plugin.
virtual QString Extension() const { return "stl"; };
virtual QString Description() const { return "Stereolithography File"; };
virtual QVector<FileExtension> SupportedExtensions( void ) const
{
ret.push_back(FileExtension("stl", "Stereolithography File"));
return ret;
}
void Export( const QString &sFileName, const QString &sFormat = QString() )
{
if (GetNumMeshes() == 0)
MB_ERROR("There are no meshes to export");
if (GetNumMeshes() > 1)
MB_ERROR("Multiple meshes can not be exported to this format");
const Mesh* m = GetMesh(0);
if (IsMeshOpen(m))
MB_ERROR("Only continuous meshes can be exported");
QFile ofile(sFileName);
const uint STL_HEADER_SIZE = 80;
char header[STL_HEADER_SIZE] = "";
std::fill(header, header + STL_HEADER_SIZE, 0);
ofile.write(header, STL_HEADER_SIZE);
// output the total number of faces
uint32 cnt = m->FaceCount();
if ( m->Type() == Mesh::typeQuadric )
cnt *= 2;
WriteUInt32(ofile, cnt);
// Write each triangle face to file
if ( m->Type() == Mesh::typeTriangular )
{
for ( uint i = 0; i < m->FaceCount(); ++i ) {
// Write the normal vector
const Vector& normal = m->FaceNormal(i);
WriteVectorFloat32(ofile, normal);
// three sets of three 32-bit floats specifying the position of each vertex
for (uint j = 0; j < 3; ++j) {
const Vector& v = m->TriangleVertexPosition( i, j );
WriteVectorFloat32(ofile, v);
}
// 2-byte padding
WriteUInt16(ofile, 0);
}
}
// Write each quadric face as two triangles
else if ( m->Type() == Mesh::typeQuadric )
{
for ( uint i = 0; i < m->FaceCount(); ++i ) {
// Write the normal vector
const Vector& normal = m->FaceNormal(i);
WriteVectorFloat32(ofile, normal);
// Get first sub-triangle using corners 0, 2, and 3 of quad
for (uint j = 0; j < 4; ++j) {
if (j != 1) {
const Vector& v = m->QuadVertexPosition( i, j );
WriteVectorFloat32(ofile, v);
}
}
// 2-byte padding
WriteUInt16(ofile, 0);
// Write the normal vector again (both triangles share the same normal)
WriteVectorFloat32(ofile, normal);
// Get second sub-triangle using corners 0, 1, and 2 of quad
for (uint j = 0; j < 4; ++j) {
if (j != 3) {
const Vector& v = m->QuadVertexPosition( i, j );
WriteVectorFloat32(ofile, v);
}
}
// 2-byte padding
WriteUInt16(ofile, 0);
}
}
ofile.close();
};
};
// RTTI information
IMPLEMENT_CLASS( STLExporter, Exporter, "STL Exporter" );
} // namespace mudbox