From 8d00f0ab8f62e2a041bf63fd64607f19d0611f47 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 7 Apr 2017 15:59:01 -0700 Subject: [PATCH] allow obj reader to either combine meshes or keep parts separate --- libraries/fbx/src/OBJReader.cpp | 14 ++++++++++---- libraries/fbx/src/OBJReader.h | 11 +++++++---- .../src/model-networking/ModelCache.cpp | 3 ++- tools/vhacd-util/src/VHACDUtil.cpp | 3 ++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index c99b847722..7b46556530 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -302,7 +302,8 @@ QNetworkReply* OBJReader::request(QUrl& url, bool isTest) { } -bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, float& scaleGuess) { +bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, + float& scaleGuess, bool combineParts) { FaceGroup faces; FBXMesh& mesh = geometry.meshes[0]; mesh.parts.append(FBXMeshPart()); @@ -348,6 +349,9 @@ bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mappi } QByteArray groupName = tokenizer.getDatum(); currentGroup = groupName; + if (!combineParts) { + currentMaterialName = QString("part-") + QString::number(_partCounter++); + } } else if (token == "mtllib" && !_url.isEmpty()) { if (tokenizer.nextToken() != OBJTokenizer::DATUM_TOKEN) { break; @@ -361,7 +365,9 @@ bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mappi } QString nextName = tokenizer.getDatum(); if (nextName != currentMaterialName) { - currentMaterialName = nextName; + if (combineParts) { + currentMaterialName = nextName; + } #ifdef WANT_DEBUG qCDebug(modelformat) << "OBJ Reader new current material:" << currentMaterialName; #endif @@ -419,7 +425,7 @@ done: } -FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, const QUrl& url) { +FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url) { PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); QBuffer buffer { &model }; buffer.open(QIODevice::ReadOnly); @@ -438,7 +444,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, try { // call parseOBJGroup as long as it's returning true. Each successful call will // add a new meshPart to the geometry's single mesh. - while (parseOBJGroup(tokenizer, mapping, geometry, scaleGuess)) {} + while (parseOBJGroup(tokenizer, mapping, geometry, scaleGuess, combineParts)) {} FBXMesh& mesh = geometry.meshes[0]; mesh.meshIndex = 0; diff --git a/libraries/fbx/src/OBJReader.h b/libraries/fbx/src/OBJReader.h index b4a48c570e..4be5705f9a 100644 --- a/libraries/fbx/src/OBJReader.h +++ b/libraries/fbx/src/OBJReader.h @@ -22,7 +22,7 @@ public: glm::vec3 getVec3(); glm::vec2 getVec2(); float getFloat() { return std::stof((nextToken() != OBJTokenizer::DATUM_TOKEN) ? nullptr : getDatum().data()); } - + private: QIODevice* _device; QByteArray _datum; @@ -73,15 +73,18 @@ public: QHash materials; QNetworkReply* request(QUrl& url, bool isTest); - FBXGeometry* readOBJ(QByteArray& model, const QVariantHash& mapping, const QUrl& url = QUrl()); - + FBXGeometry* readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl()); + private: QUrl _url; QHash librariesSeen; - bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, float& scaleGuess); + bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, + float& scaleGuess, bool combineParts); void parseMaterialLibrary(QIODevice* device); bool isValidTexture(const QByteArray &filename); // true if the file exists. TODO?: check content-type header and that it is a supported format. + + int _partCounter { 0 }; }; // What are these utilities doing here? One is used by fbx loading code in VHACD Utils, and the other a general debugging utility. diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 142ea74af4..7e1de5055d 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -178,7 +178,8 @@ void GeometryReader::run() { throw QString("empty geometry, possibly due to an unsupported FBX version"); } } else if (_url.path().toLower().endsWith(".obj")) { - fbxGeometry.reset(OBJReader().readOBJ(_data, _mapping, _url)); + bool combineParts = false; + fbxGeometry.reset(OBJReader().readOBJ(_data, _mapping, combineParts, _url)); } else { throw QString("unsupported format"); } diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index 30d0b5e772..0b12cb64ed 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -43,7 +43,8 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) { QByteArray fbxContents = fbx.readAll(); FBXGeometry* geom; if (filename.toLower().endsWith(".obj")) { - geom = OBJReader().readOBJ(fbxContents, QVariantHash()); + bool combineParts = false; + geom = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts); } else if (filename.toLower().endsWith(".fbx")) { geom = readFBX(fbxContents, QVariantHash(), filename); } else {