diff --git a/include/mitsuba/render/trimesh.h b/include/mitsuba/render/trimesh.h index d6b48917..b8cc9e7c 100644 --- a/include/mitsuba/render/trimesh.h +++ b/include/mitsuba/render/trimesh.h @@ -299,6 +299,10 @@ public: */ size_t getEffectivePrimitiveCount() const; + /// Import a shape from the Blender in-memory representation + static ref 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; diff --git a/src/converter/collada.cpp b/src/converter/collada.cpp index a330ed11..0e2fde21 100644 --- a/src/converter/collada.cpp +++ b/src/converter/collada.cpp @@ -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(); } diff --git a/src/converter/converter.cpp b/src/converter/converter.cpp index 89cd1a26..83d75fd6 100644 --- a/src/converter/converter.cpp +++ b/src/converter/converter.cpp @@ -297,7 +297,7 @@ void GeometryConverter::convert(const fs::path &inputFile, } if (m_geometryFile) { for (size_t i=0; iwriteSize(m_geometryDict[i]); + m_geometryFile->writeULong((uint64_t) m_geometryDict[i]); m_geometryFile->writeUInt((uint32_t) m_geometryDict.size()); m_geometryFile->close(); } diff --git a/src/converter/converter.h b/src/converter/converter.h index 74b0708e..b7db362c 100644 --- a/src/converter/converter.h +++ b/src/converter/converter.h @@ -63,6 +63,6 @@ public: std::string m_filmType; ref m_geometryFile; fs::path m_geometryFileName; - std::vector m_geometryDict; + std::vector m_geometryDict; bool m_packGeometry; }; diff --git a/src/converter/obj.cpp b/src/converter/obj.cpp index 89b014bc..d99f59b2 100644 --- a/src/converter/obj.cpp +++ b/src/converter/obj.cpp @@ -207,7 +207,7 @@ void GeometryConverter::convertOBJ(const fs::path &inputFile, stream->close(); os << "\t\t" << 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" << endl; diff --git a/src/libpython/SConscript b/src/libpython/SConscript index 90ac661b..82b062d9 100644 --- a/src/libpython/SConscript +++ b/src/libpython/SConscript @@ -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') diff --git a/src/libpython/render.cpp b/src/libpython/render.cpp index 78308eac..03c9f5a3 100644 --- a/src/libpython/render.cpp +++ b/src/libpython/render.cpp @@ -125,7 +125,6 @@ bp::list scene_getMedia(Scene *scene) { return list; } - typedef InternalArray InternalUInt32Array; typedef InternalArray InternalPoint3Array; typedef InternalArray InternalNormalArray; @@ -158,6 +157,13 @@ InternalTangentSpaceArray trimesh_getUVTangents(TriMesh *triMesh) { return InternalTangentSpaceArray(triMesh, triMesh->getUVTangents(), triMesh->getVertexCount()); } +ref 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(facePtr), vertexCount, + reinterpret_cast(vertexPtr), reinterpret_cast(uvPtr), + reinterpret_cast(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; diff --git a/src/librender/trimesh.cpp b/src/librender/trimesh.cpp index 79d660d4..d7a4724b 100644 --- a/src/librender/trimesh.cpp +++ b/src/librender/trimesh.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #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::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 vertexMap; + uint32_t triangleCtr = 0, vertexCtr = 0; + + for (int i=0; i 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::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;