Support for quickly importing geometry directly from Blender-internal memory
parent
fdcaaaf841
commit
d0dc0d9f36
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue