/
WavefrontExporter.cpp
87 lines (68 loc) · 2.36 KB
/
WavefrontExporter.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "WavefrontExporter.h"
#include "itextstream.h"
#include "imodelsurface.h"
#include "imap.h"
#include <boost/algorithm/string/replace.hpp>
namespace model
{
WavefrontExporter::WavefrontExporter()
{}
IModelExporterPtr WavefrontExporter::clone()
{
return std::make_shared<WavefrontExporter>();
}
const std::string& WavefrontExporter::getDisplayName() const
{
static std::string _extension("Wavefront OBJ");
return _extension;
}
const std::string& WavefrontExporter::getExtension() const
{
static std::string _extension("OBJ");
return _extension;
}
void WavefrontExporter::exportToStream(std::ostream& stream)
{
// Count exported vertices. Exported indices are 1-based though.
std::size_t vertexCount = 0;
// Each surface is exported as group.
for (const Surfaces::value_type& pair : _surfaces)
{
const Surface& surface = pair.second;
// Base index for vertices, added to the surface indices
std::size_t vertBaseIndex = vertexCount;
// Since we don't write .mtl files store at least the material into the group name
stream << "g " << surface.materialName << std::endl;
stream << std::endl;
// Temporary buffers for vertices, texcoords and polys
std::stringstream vertexBuf;
std::stringstream texCoordBuf;
std::stringstream polyBuf;
for (const ArbitraryMeshVertex& meshVertex : surface.vertices)
{
// Write coordinates into the export buffers
const Vector3& vert = meshVertex.vertex;
const Vector2& uv = meshVertex.texcoord;
vertexBuf << "v " << vert.x() << " " << vert.y() << " " << vert.z() << "\n";
texCoordBuf << "vt " << uv.x() << " " << uv.y() << "\n";
vertexCount++;
}
// Every three indices form a triangle. Indices are 1-based so add +1 to each index
for (std::size_t i = 0; i + 2 < surface.indices.size(); i += 3)
{
std::size_t index1 = vertBaseIndex + static_cast<std::size_t>(surface.indices[i+0]) + 1;
std::size_t index2 = vertBaseIndex + static_cast<std::size_t>(surface.indices[i+1]) + 1;
std::size_t index3 = vertBaseIndex + static_cast<std::size_t>(surface.indices[i+2]) + 1;
// f 1/1 3/3 2/2
polyBuf << "f";
polyBuf << " " << index1 << "/" << index1;
polyBuf << " " << index2 << "/" << index2;
polyBuf << " " << index3 << "/" << index3;
polyBuf << "\n";
}
stream << vertexBuf.str() << std::endl;
stream << texCoordBuf.str() << std::endl;
stream << polyBuf.str() << std::endl;
}
}
}