TriMesh: binary PLY export feature
parent
beb85f9702
commit
70f08931b9
|
@ -304,9 +304,12 @@ public:
|
||||||
static ref<TriMesh> fromBlender(const std::string &name, size_t faceCount, void *facePtr,
|
static ref<TriMesh> fromBlender(const std::string &name, size_t faceCount, void *facePtr,
|
||||||
size_t vertexCount, void *vertexPtr, void *uvPtr, void *colPtr, short matNr);
|
size_t vertexCount, void *vertexPtr, void *uvPtr, void *colPtr, short matNr);
|
||||||
|
|
||||||
/// Export an Wavefront OBJ version of this file
|
/// Export a Wavefront OBJ version of this file
|
||||||
void writeOBJ(const fs::path &path) const;
|
void writeOBJ(const fs::path &path) const;
|
||||||
|
|
||||||
|
/// Export a Stanford PLY version of this file
|
||||||
|
void writePLY(const fs::path &path) const;
|
||||||
|
|
||||||
/// Return a string representation
|
/// Return a string representation
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
|
|
|
@ -565,6 +565,7 @@ void export_render() {
|
||||||
.def("serialize", triMesh_serialize1)
|
.def("serialize", triMesh_serialize1)
|
||||||
.def("serialize", triMesh_serialize2)
|
.def("serialize", triMesh_serialize2)
|
||||||
.def("writeOBJ", &TriMesh::writeOBJ)
|
.def("writeOBJ", &TriMesh::writeOBJ)
|
||||||
|
.def("writePLY", &TriMesh::writePLY)
|
||||||
.def("fromBlender", trimesh_fromBlender)
|
.def("fromBlender", trimesh_fromBlender)
|
||||||
.staticmethod("fromBlender");
|
.staticmethod("fromBlender");
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mitsuba/render/trimesh.h>
|
#include <mitsuba/render/trimesh.h>
|
||||||
|
#include <mitsuba/core/version.h>
|
||||||
#include <mitsuba/core/random.h>
|
#include <mitsuba/core/random.h>
|
||||||
#include <mitsuba/core/plugin.h>
|
#include <mitsuba/core/plugin.h>
|
||||||
#include <mitsuba/core/zstream.h>
|
#include <mitsuba/core/zstream.h>
|
||||||
|
@ -84,7 +85,6 @@ TriMesh::TriMesh(Stream *stream, int index)
|
||||||
loadCompressed(stream, index);
|
loadCompressed(stream, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Flags used to identify available data during serialization */
|
/* Flags used to identify available data during serialization */
|
||||||
enum ETriMeshFlags {
|
enum ETriMeshFlags {
|
||||||
EHasNormals = 0x0001,
|
EHasNormals = 0x0001,
|
||||||
|
@ -1057,6 +1057,81 @@ void TriMesh::writeOBJ(const fs::path &path) const {
|
||||||
os.close();
|
os.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TriMesh::writePLY(const fs::path &path) const {
|
||||||
|
fs::ofstream os(path, std::ios::out | std::ios::binary);
|
||||||
|
|
||||||
|
os << "ply\n";
|
||||||
|
if (Stream::getHostByteOrder() == Stream::ELittleEndian)
|
||||||
|
os << "format binary_little_endian 1.0\n";
|
||||||
|
else
|
||||||
|
os << "format binary_big_endian 1.0\n";
|
||||||
|
os << "comment generated by Mitsuba " << MTS_VERSION << "\n";
|
||||||
|
os << "element vertex " << getVertexCount() << "\n";
|
||||||
|
|
||||||
|
size_t storagePerVertex = 3 * sizeof(float);
|
||||||
|
os << "property float x\n";
|
||||||
|
os << "property float y\n";
|
||||||
|
os << "property float z\n";
|
||||||
|
|
||||||
|
if (m_normals) {
|
||||||
|
os << "property float nx\n";
|
||||||
|
os << "property float ny\n";
|
||||||
|
os << "property float nz\n";
|
||||||
|
storagePerVertex += 3 * sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_texcoords) {
|
||||||
|
os << "property float u\n";
|
||||||
|
os << "property float v\n";
|
||||||
|
storagePerVertex += 2 * sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_colors) {
|
||||||
|
os << "property uchar red\n";
|
||||||
|
os << "property uchar green\n";
|
||||||
|
os << "property uchar blue\n";
|
||||||
|
storagePerVertex += 3 * sizeof(uint8_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "element face " << m_triangleCount << "\n";
|
||||||
|
os << "property list uchar int vertex_indices\n";
|
||||||
|
os << "end_header\n";
|
||||||
|
|
||||||
|
size_t vertexStorageSize = storagePerVertex * (size_t) m_vertexCount;
|
||||||
|
uint8_t *vertexStorage = new uint8_t[vertexStorageSize], *ptr = vertexStorage;
|
||||||
|
|
||||||
|
for (size_t i=0; i< getVertexCount(); ++i) {
|
||||||
|
Vector3f p(m_positions[i]); memcpy(ptr, &p, sizeof(Vector3f)); ptr += sizeof(Vector3f);
|
||||||
|
if (m_normals) {
|
||||||
|
Vector3f n(m_normals[i]); memcpy(ptr, &n, sizeof(Vector3f)); ptr += sizeof(Vector3f);
|
||||||
|
}
|
||||||
|
if (m_texcoords) {
|
||||||
|
Vector2f uv(m_texcoords[i]); memcpy(ptr, &uv, sizeof(Vector2f)); ptr += sizeof(Vector2f);
|
||||||
|
}
|
||||||
|
if (m_colors) {
|
||||||
|
*ptr += (uint8_t) std::max(0.0f, std::min(255.0f, m_colors[i][0] * 255.0f + 0.5f));
|
||||||
|
*ptr += (uint8_t) std::max(0.0f, std::min(255.0f, m_colors[i][1] * 255.0f + 0.5f));
|
||||||
|
*ptr += (uint8_t) std::max(0.0f, std::min(255.0f, m_colors[i][2] * 255.0f + 0.5f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert(ptr-vertexStorage == vertexStorageSize);
|
||||||
|
os.write((const char *) vertexStorage, vertexStorageSize);
|
||||||
|
delete[] vertexStorage;
|
||||||
|
|
||||||
|
size_t faceStorageSize = (sizeof(Triangle) + 1) * (size_t) getTriangleCount();
|
||||||
|
uint8_t *faceStorage = new uint8_t[faceStorageSize];
|
||||||
|
ptr = faceStorage;
|
||||||
|
for (size_t i=0; i<getTriangleCount(); ++i) {
|
||||||
|
*ptr++ = (uint8_t) 0x03;
|
||||||
|
memcpy(ptr, &m_triangles[i], sizeof(Triangle));
|
||||||
|
ptr += sizeof(Triangle);
|
||||||
|
}
|
||||||
|
Assert(ptr-faceStorage == faceStorageSize);
|
||||||
|
os.write((const char *) faceStorage, faceStorageSize);
|
||||||
|
delete[] faceStorage;
|
||||||
|
|
||||||
|
os.close();
|
||||||
|
}
|
||||||
void TriMesh::serialize(Stream *_stream) const {
|
void TriMesh::serialize(Stream *_stream) const {
|
||||||
ref<Stream> stream = _stream;
|
ref<Stream> stream = _stream;
|
||||||
|
|
||||||
|
|
|
@ -273,7 +273,8 @@ public:
|
||||||
|
|
||||||
void face_vertex_indices_begin_uint8(ply::uint8 size) {
|
void face_vertex_indices_begin_uint8(ply::uint8 size) {
|
||||||
if (size != 3 && size != 4)
|
if (size != 3 && size != 4)
|
||||||
Log(EError, "Only triangle and quad-based PLY meshes are supported for now.");
|
Log(EError, "Encountered a face with %i vertices! "
|
||||||
|
"Only triangle and quad-based PLY meshes are supported for now.", size);
|
||||||
m_indexCtr = 0;
|
m_indexCtr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue