Support for quickly importing geometry directly from Blender-internal memory

metadata
Wenzel Jakob 2013-11-19 22:45:22 +01:00
parent fdcaaaf841
commit d0dc0d9f36
8 changed files with 122 additions and 7 deletions

View File

@ -299,6 +299,10 @@ public:
*/
size_t getEffectivePrimitiveCount() const;
/// Import a shape from the Blender in-memory representation
static ref<TriMesh> fromBlender(const std::string &name, size_t faceCount, void *facePtr,
size_t vertexCount, void *vertexPtr, void *uvPtr, void *colPtr, short matNr);
/// Export an Wavefront OBJ version of this file
void writeOBJ(const fs::path &path) const;

View File

@ -485,7 +485,7 @@ void writeGeometry(ColladaContext &ctx, const std::string &prefixName, std::stri
stream->close();
filename = "meshes/" + filename;
} else {
ctx.cvt->m_geometryDict.push_back((uint32_t) ctx.cvt->m_geometryFile->getPos());
ctx.cvt->m_geometryDict.push_back((uint64_t) ctx.cvt->m_geometryFile->getPos());
mesh->serialize(ctx.cvt->m_geometryFile);
filename = ctx.cvt->m_geometryFileName.filename().string();
}

View File

@ -297,7 +297,7 @@ void GeometryConverter::convert(const fs::path &inputFile,
}
if (m_geometryFile) {
for (size_t i=0; i<m_geometryDict.size(); ++i)
m_geometryFile->writeSize(m_geometryDict[i]);
m_geometryFile->writeULong((uint64_t) m_geometryDict[i]);
m_geometryFile->writeUInt((uint32_t) m_geometryDict.size());
m_geometryFile->close();
}

View File

@ -63,6 +63,6 @@ public:
std::string m_filmType;
ref<FileStream> m_geometryFile;
fs::path m_geometryFileName;
std::vector<uint32_t> m_geometryDict;
std::vector<size_t> m_geometryDict;
bool m_packGeometry;
};

View File

@ -207,7 +207,7 @@ void GeometryConverter::convertOBJ(const fs::path &inputFile,
stream->close();
os << "\t\t<string name=\"filename\" value=\"meshes/" << filename.c_str() << "\"/>" << endl;
} else {
m_geometryDict.push_back((uint32_t) m_geometryFile->getPos());
m_geometryDict.push_back((uint64_t) m_geometryFile->getPos());
SLog(EInfo, "Saving mesh \"%s\" ..", mesh->getName().c_str());
mesh->serialize(m_geometryFile);
os << "\t\t<string name=\"filename\" value=\"" << m_geometryFileName.filename().string() << "\"/>" << endl;

View File

@ -31,7 +31,7 @@ for ver in hasPython:
pythonEnv.Append(CPPFLAGS = ['/bigobj'])
if sys.platform == 'darwin':
pythonEnv.Append(LINKFLAGS=['-Xlinker', '-rpath', '-Xlinker', '@loader_path/../../Contents/Frameworks'])
pythonEnv.Append(LINKFLAGS=['-Xlinker', '-rpath', '-Xlinker', '@loader_path/../../Contents/Frameworks', '-undefined', 'dynamic_lookup'])
if hasPython:
libcore_obj = pythonEnv.SharedObject('core_'+ver, 'core.cpp')

View File

@ -125,7 +125,6 @@ bp::list scene_getMedia(Scene *scene) {
return list;
}
typedef InternalArray<uint32_t> InternalUInt32Array;
typedef InternalArray<Point3> InternalPoint3Array;
typedef InternalArray<Normal> InternalNormalArray;
@ -158,6 +157,13 @@ InternalTangentSpaceArray trimesh_getUVTangents(TriMesh *triMesh) {
return InternalTangentSpaceArray(triMesh, triMesh->getUVTangents(), triMesh->getVertexCount());
}
ref<TriMesh> trimesh_fromBlender(const std::string &name,
size_t faceCount, size_t facePtr, size_t vertexCount, size_t vertexPtr, size_t uvPtr, size_t colPtr, short matID) {
return TriMesh::fromBlender(name, faceCount, reinterpret_cast<void *>(facePtr), vertexCount,
reinterpret_cast<void *>(vertexPtr), reinterpret_cast<void *>(uvPtr),
reinterpret_cast<void *>(colPtr), matID);
}
void export_render() {
bp::object renderModule(
bp::handle<>(bp::borrowed(PyImport_AddModule("mitsuba.render"))));
@ -412,7 +418,9 @@ void export_render() {
.def("rebuildTopology", &TriMesh::rebuildTopology)
.def("serialize", triMesh_serialize1)
.def("serialize", triMesh_serialize2)
.def("writeOBJ", &TriMesh::writeOBJ);
.def("writeOBJ", &TriMesh::writeOBJ)
.def("fromBlender", trimesh_fromBlender)
.staticmethod("fromBlender");
Shape *(AbstractEmitter::*abstractemitter_getShape)(void) = &AbstractEmitter::getShape;
Medium *(AbstractEmitter::*abstractemitter_getMedium)(void) = &AbstractEmitter::getMedium;

View File

@ -28,6 +28,7 @@
#include <mitsuba/render/bsdf.h>
#include <mitsuba/render/emitter.h>
#include <boost/filesystem/fstream.hpp>
#include <boost/unordered_map.hpp>
#define MTS_FILEFORMAT_HEADER 0x041C
#define MTS_FILEFORMAT_VERSION_V3 0x0003
@ -848,6 +849,108 @@ void TriMesh::serialize(Stream *stream, InstanceManager *manager) const {
m_triangleCount * sizeof(Triangle)/sizeof(uint32_t));
}
ref<TriMesh> TriMesh::fromBlender(const std::string &name,
size_t faceCount, void *_facePtr, size_t vertexCount, void *_vertexPtr, void *_uvPtr, void *_colPtr, short mat_nr) {
struct MFace {
uint32_t v[4];
int16_t mat_nr;
uint8_t edcode, flag;
};
struct MVert {
float co[3];
int16_t no[3];
uint8_t flag, bweight;
};
struct MCol {
uint8_t a, r, g, b;
};
struct MLoopUV {
float uv[2];
int32_t flag;
};
MFace *facePtr = (MFace *) _facePtr;
MVert *vertexPtr = (MVert *) _vertexPtr;
MCol *colPtr = (MCol *) _colPtr;
MLoopUV *uvPtr = (MLoopUV *) _uvPtr;
boost::unordered_map<uint32_t, uint32_t> vertexMap;
uint32_t triangleCtr = 0, vertexCtr = 0;
for (int i=0; i<faceCount; ++i) {
const MFace &face = facePtr[i];
if (face.mat_nr == mat_nr) {
bool triangle = face.v[3] == 0;
for (int j=0; j<(triangle ? 3 : 4); ++j) {
if (vertexMap.find(face.v[j]) == vertexMap.end())
vertexMap[face.v[j]] = vertexCtr++;
}
triangleCtr += triangle ? 1 : 2;
}
}
ref<TriMesh> triMesh = new TriMesh(name, triangleCtr, vertexCtr, true,
uvPtr != NULL, colPtr != NULL);
uint32_t *triangles = (uint32_t *) triMesh->getTriangles();
Point *vertexPositions = (Point *) triMesh->getVertexPositions();
Normal *vertexNormals = (Normal *) triMesh->getVertexNormals();
Color3 *vertexColors = (Color3 *) triMesh->getVertexColors();
Point2 *vertexTexcoords = (Point2 *) triMesh->getVertexTexcoords();
for (int i=0; i<faceCount; ++i) {
const MFace &face = facePtr[i];
if (face.mat_nr == mat_nr) {
*triangles++ = vertexMap[face.v[0]];
*triangles++ = vertexMap[face.v[1]];
*triangles++ = vertexMap[face.v[2]];
if (face.v[3] != 0) {
*triangles++ = vertexMap[face.v[0]];
*triangles++ = vertexMap[face.v[2]];
*triangles++ = vertexMap[face.v[3]];
}
}
}
const float normalScale = 1.0f / 32767.0f;
const float rgbScale = 1.0f / 255.0f;
for (boost::unordered_map<uint32_t, uint32_t>::iterator it = vertexMap.begin();
it != vertexMap.end(); ++it) {
const MVert &vertex = vertexPtr[it->first];
uint32_t idx = it->second;
vertexPositions[idx] = Point3(vertex.co[0], vertex.co[1], vertex.co[2]);
vertexNormals[idx] = normalize(Normal(
vertex.no[0] * normalScale,
vertex.no[1] * normalScale,
vertex.no[2] * normalScale
));
if (uvPtr) {
const MLoopUV &uv = uvPtr[it->first];
vertexTexcoords[idx] = Point2(uv.uv[0], uv.uv[1]);
}
if (colPtr) {
const MCol &col = colPtr[it->first];
vertexColors[idx] = Color3(
col.r * rgbScale,
col.g * rgbScale,
col.b * rgbScale
);
}
}
return triMesh;
}
void TriMesh::writeOBJ(const fs::path &path) const {
fs::ofstream os(path);
os << "o " << m_name << endl;