diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp index 26b927452e..035903c6cb 100644 --- a/libraries/baking/src/FBXBaker.cpp +++ b/libraries/baking/src/FBXBaker.cpp @@ -223,11 +223,13 @@ void FBXBaker::rewriteAndBakeSceneModels() { auto extractedMesh = FBXReader::extractMesh(objectChild, meshIndex, false); // Callback to get MaterialID - getMaterialIDCallback materialIDcallback = [=](int partIndex) {return extractedMesh.partMaterialTextures[partIndex].first;}; + GetMaterialIDCallback materialIDcallback = [&extractedMesh](int partIndex) { + return extractedMesh.partMaterialTextures[partIndex].first; + }; // Compress mesh information and store in dracoMeshNode FBXNode dracoMeshNode; - bool success = this->compressMesh(extractedMesh.mesh, hasDeformers, dracoMeshNode, materialIDcallback); + bool success = compressMesh(extractedMesh.mesh, hasDeformers, dracoMeshNode, materialIDcallback); // if bake fails - return, if there were errors and continue, if there were warnings. if (!success) { @@ -314,23 +316,20 @@ void FBXBaker::rewriteAndBakeSceneTextures() { for (FBXNode& textureChild : object->children) { if (textureChild.name == "RelativeFilename") { - QString fbxTextureFileName { textureChild.properties.at(0).toByteArray() }; + QString fbxTextureFileName { textureChild.properties.at(0).toString() }; // Callback to get texture type - getTextureTypeCallback textureTypeCallback = [=]() { - // grab the ID for this texture so we can figure out the - // texture type from the loaded materials - auto textureID{ object->properties[0].toByteArray() }; - auto textureType = textureTypes[textureID]; - return textureType; - }; + // grab the ID for this texture so we can figure out the + // texture type from the loaded materials + auto textureID { object->properties[0].toString() }; + auto textureType = textureTypes[textureID]; // Compress the texture information and return the new filename to be added into the FBX scene - QByteArray* bakedTextureFile = this->compressTexture(fbxTextureFileName, textureTypeCallback); + auto bakedTextureFile = compressTexture(fbxTextureFileName, textureType); // If no errors or warnings have occurred during texture compression add the filename to the FBX scene - if (bakedTextureFile) { - textureChild.properties[0] = *bakedTextureFile; + if (!bakedTextureFile.isNull()) { + textureChild.properties[0] = bakedTextureFile; } else { // if bake fails - return, if there were errors and continue, if there were warnings. if (hasErrors()) { diff --git a/libraries/baking/src/FBXBaker.h b/libraries/baking/src/FBXBaker.h index 0a3b80fde9..2888a60f73 100644 --- a/libraries/baking/src/FBXBaker.h +++ b/libraries/baking/src/FBXBaker.h @@ -35,9 +35,6 @@ class FBXBaker : public ModelBaker { public: using ModelBaker::ModelBaker; - QUrl getFBXUrl() const { return _modelURL; } - QString getBakedFBXFilePath() const { return _bakedModelFilePath; } - public slots: virtual void bake() override; diff --git a/libraries/baking/src/ModelBaker.cpp b/libraries/baking/src/ModelBaker.cpp index 1c3040dd24..5d04c17688 100644 --- a/libraries/baking/src/ModelBaker.cpp +++ b/libraries/baking/src/ModelBaker.cpp @@ -71,7 +71,7 @@ void ModelBaker::abort() { } } -bool ModelBaker::compressMesh(FBXMesh& mesh, bool hasDeformers,FBXNode& dracoMeshNode, getMaterialIDCallback materialIDCallback) { +bool ModelBaker::compressMesh(FBXMesh& mesh, bool hasDeformers, FBXNode& dracoMeshNode, GetMaterialIDCallback materialIDCallback) { if (mesh.wasCompressed) { handleError("Cannot re-bake a file that contains compressed mesh"); return false; @@ -106,12 +106,12 @@ bool ModelBaker::compressMesh(FBXMesh& mesh, bool hasDeformers,FBXNode& dracoMes bool hasPerFaceMaterials = (materialIDCallback) ? (mesh.parts.size() > 1 || materialIDCallback(0) != 0 ) : true; bool needsOriginalIndices{ hasDeformers }; - int normalsAttributeID{ -1 }; - int colorsAttributeID{ -1 }; - int texCoordsAttributeID{ -1 }; - int texCoords1AttributeID{ -1 }; - int faceMaterialAttributeID{ -1 }; - int originalIndexAttributeID{ -1 }; + int normalsAttributeID { -1 }; + int colorsAttributeID { -1 }; + int texCoordsAttributeID { -1 }; + int texCoords1AttributeID { -1 }; + int faceMaterialAttributeID { -1 }; + int originalIndexAttributeID { -1 }; const int positionAttributeID = meshBuilder.AddAttribute(draco::GeometryAttribute::POSITION, 3, draco::DT_FLOAT32); @@ -244,14 +244,7 @@ bool ModelBaker::compressMesh(FBXMesh& mesh, bool hasDeformers,FBXNode& dracoMes return true; } -QByteArray* ModelBaker::compressTexture(QString modelTextureFileName, getTextureTypeCallback textureTypeCallback) { - static QByteArray textureChild; - QByteArray textureContent = ""; - image::TextureUsage::Type textureType = image::TextureUsage::Type::DEFAULT_TEXTURE; - - if (textureTypeCallback) { - textureType = textureTypeCallback(); - } +QString ModelBaker::compressTexture(QString modelTextureFileName, image::TextureUsage::Type textureType) { QFileInfo modelTextureFileInfo{ modelTextureFileName.replace("\\", "/") }; @@ -259,18 +252,20 @@ QByteArray* ModelBaker::compressTexture(QString modelTextureFileName, getTexture // re-baking a model that already references baked textures // this is an error - return from here handleError("Cannot re-bake a file that already references compressed textures"); - return nullptr; + return QString::null; } if (!TextureBaker::getSupportedFormats().contains(modelTextureFileInfo.suffix())) { // this is a texture format we don't bake, skip it handleWarning(modelTextureFileName + " is not a bakeable texture format"); - return nullptr; + return QString::null; } // make sure this texture points to something and isn't one we've already re-mapped + QString textureChild { QString::null }; if (!modelTextureFileInfo.filePath().isEmpty()) { // check if this was an embedded texture that we already have in-memory content for + QByteArray textureContent; // figure out the URL to this texture, embedded or external if (!modelTextureFileInfo.filePath().isEmpty()) { @@ -296,7 +291,7 @@ QByteArray* ModelBaker::compressTexture(QString modelTextureFileName, getTexture _bakedOutputDir + "/" + bakedTextureFileName }; - textureChild = bakedTextureFileName.toLocal8Bit(); + textureChild = bakedTextureFileName; if (!_bakingTextures.contains(urlToTexture)) { _outputFiles.push_back(bakedTextureFilePath); @@ -306,11 +301,11 @@ QByteArray* ModelBaker::compressTexture(QString modelTextureFileName, getTexture } } - return &textureChild; + return textureChild; } void ModelBaker::bakeTexture(const QUrl& textureURL, image::TextureUsage::Type textureType, - const QDir& outputDir, const QString& bakedFilename, const QByteArray& textureContent) { + const QDir& outputDir, const QString& bakedFilename, const QByteArray& textureContent) { // start a bake for this texture and add it to our list to keep track of QSharedPointer bakingTexture{ diff --git a/libraries/baking/src/ModelBaker.h b/libraries/baking/src/ModelBaker.h index 5949e12774..944b9b8f2a 100644 --- a/libraries/baking/src/ModelBaker.h +++ b/libraries/baking/src/ModelBaker.h @@ -27,8 +27,7 @@ #include using TextureBakerThreadGetter = std::function; -using getMaterialIDCallback = std::function ; -using getTextureTypeCallback = std::function; +using GetMaterialIDCallback = std::function ; class ModelBaker : public Baker { Q_OBJECT @@ -37,10 +36,13 @@ public: ModelBaker(const QUrl& inputModelURL, TextureBakerThreadGetter inputTextureThreadGetter, const QString& bakedOutputDirectory, const QString& originalOutputDirectory = ""); virtual ~ModelBaker(); - bool compressMesh(FBXMesh& mesh, bool hasDeformers, FBXNode& dracoMeshNode, getMaterialIDCallback materialIDCallback = NULL); - QByteArray* compressTexture(QString textureFileName, getTextureTypeCallback textureTypeCallback = NULL); + bool compressMesh(FBXMesh& mesh, bool hasDeformers, FBXNode& dracoMeshNode, GetMaterialIDCallback materialIDCallback = nullptr); + QString compressTexture(QString textureFileName, image::TextureUsage::Type = image::TextureUsage::Type::DEFAULT_TEXTURE); virtual void setWasAborted(bool wasAborted) override; + QUrl getModelURL() const { return _modelURL; } + QString getBakedModelFilePath() const { return _bakedModelFilePath; } + public slots: virtual void abort() override; diff --git a/libraries/baking/src/OBJBaker.cpp b/libraries/baking/src/OBJBaker.cpp index f84e2abd29..c4ca3485de 100644 --- a/libraries/baking/src/OBJBaker.cpp +++ b/libraries/baking/src/OBJBaker.cpp @@ -134,7 +134,7 @@ void OBJBaker::bakeOBJ() { bool combineParts = true; // set true so that OBJReader reads material info from material library OBJReader reader; - FBXGeometry* geometry = reader.readOBJ(objData, QVariantHash(), combineParts, _modelURL); + auto geometry = reader.readOBJ(objData, QVariantHash(), combineParts, _modelURL); // Write OBJ Data as FBX tree nodes FBXNode rootNode; @@ -211,7 +211,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { // Compress the mesh information and store in dracoNode bool hasDeformers = false; // No concept of deformers for an OBJ FBXNode dracoNode; - this->compressMesh(geometry.meshes[0], hasDeformers, dracoNode); + compressMesh(geometry.meshes[0], hasDeformers, dracoNode); geometryNode.children.append(dracoNode); // Generating Object node's child - Model node @@ -219,11 +219,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { modelNode.name = MODEL_NODE_NAME; { _modelID = _nodeID++; - modelNode.properties = { - _nodeID, - MODEL_NODE_NAME, - MESH - }; + modelNode.properties = { _nodeID, MODEL_NODE_NAME, MESH }; } _objectNode.children = { geometryNode, modelNode }; @@ -253,7 +249,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { FBXMaterial currentMaterial = geometry.materials[material]; if (!currentMaterial.albedoTexture.filename.isEmpty() || !currentMaterial.specularTexture.filename.isEmpty()) { _textureID = _nodeID; - _mapTextureMaterial.push_back(QPair(_textureID, i)); + _mapTextureMaterial.emplace_back(_textureID, i); FBXNode textureNode; { @@ -277,18 +273,15 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { QByteArray textureFileName = (!currentMaterial.albedoTexture.filename.isEmpty()) ? currentMaterial.albedoTexture.filename : currentMaterial.specularTexture.filename; - // Callback to get Texture content and type - getTextureTypeCallback textureContentTypeCallback = [=]() { - return (!currentMaterial.albedoTexture.filename.isEmpty()) ? image::TextureUsage::Type::ALBEDO_TEXTURE : image::TextureUsage::Type::SPECULAR_TEXTURE; - }; + auto textureType = (!currentMaterial.albedoTexture.filename.isEmpty()) ? image::TextureUsage::Type::ALBEDO_TEXTURE : image::TextureUsage::Type::SPECULAR_TEXTURE; // Compress the texture using ModelBaker::compressTexture() and store compressed file's name in the node - QByteArray* textureFile = this->compressTexture(textureFileName, textureContentTypeCallback); - if (!textureFile) { + auto textureFile = compressTexture(textureFileName, textureType); + if (textureFile.isNull()) { // Baking failed return return; } - relativeFilenameNode.properties = { *textureFile }; + relativeFilenameNode.properties = { textureFile }; textureNode.children = { textureNameNode, relativeFilenameNode }; @@ -303,27 +296,19 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { // connect Geometry to Model FBXNode cNode; cNode.name = C_NODE_NAME; - cNode.properties = { - CONNECTIONS_NODE_PROPERTY, - _geometryID, - _modelID - }; + cNode.properties = { CONNECTIONS_NODE_PROPERTY, _geometryID, _modelID }; connectionsNode.children = { cNode }; // connect all materials to model for (auto& materialID : _materialIDs) { FBXNode cNode; cNode.name = C_NODE_NAME; - cNode.properties = { - CONNECTIONS_NODE_PROPERTY, - materialID, - _modelID - }; + cNode.properties = { CONNECTIONS_NODE_PROPERTY, materialID, _modelID }; connectionsNode.children.append(cNode); } // Connect textures to materials - for (auto& texMat : _mapTextureMaterial) { + for (const auto& texMat : _mapTextureMaterial) { FBXNode cAmbientNode; cAmbientNode.name = C_NODE_NAME; cAmbientNode.properties = { @@ -353,11 +338,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { void OBJBaker::setMaterialNodeProperties(FBXNode& materialNode, QString material, FBXGeometry& geometry) { auto materialID = _nodeID++; _materialIDs.push_back(materialID); - materialNode.properties = { - materialID, - material, - MESH - }; + materialNode.properties = { materialID, material, MESH }; FBXMaterial currentMaterial = geometry.materials[material]; diff --git a/libraries/baking/src/OBJBaker.h b/libraries/baking/src/OBJBaker.h index 4c41fb5db4..2e0d76e954 100644 --- a/libraries/baking/src/OBJBaker.h +++ b/libraries/baking/src/OBJBaker.h @@ -20,6 +20,9 @@ using TextureBakerThreadGetter = std::function; +using TextureID = int64_t; +using MaterialID = int64_t; + class OBJBaker : public ModelBaker { Q_OBJECT public: @@ -43,9 +46,9 @@ private: qlonglong _nodeID = 0; qlonglong _geometryID; qlonglong _modelID; - std::vector _materialIDs; + std::vector _materialIDs; qlonglong _textureID; - std::vector> _mapTextureMaterial; + std::vector> _mapTextureMaterial; FBXNode _objectNode; }; #endif // hifi_OBJBaker_h diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index e0c2efd72e..7fd2d39931 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -490,13 +490,13 @@ done: } -FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url) { +FBXGeometry::Pointer 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); - FBXGeometry* geometryPtr = new FBXGeometry(); - FBXGeometry& geometry = *geometryPtr; + auto geometryPtr { std::make_shared() }; + FBXGeometry& geometry { *geometryPtr }; OBJTokenizer tokenizer { &buffer }; float scaleGuess = 1.0f; diff --git a/libraries/fbx/src/OBJReader.h b/libraries/fbx/src/OBJReader.h index fb250833cf..7fe71892f6 100644 --- a/libraries/fbx/src/OBJReader.h +++ b/libraries/fbx/src/OBJReader.h @@ -75,7 +75,7 @@ public: QString currentMaterialName; QHash materials; - FBXGeometry* readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl()); + FBXGeometry::Pointer readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl()); private: QUrl _url; diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index b62ad7b366..2ed301b192 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -186,11 +186,11 @@ 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, _combineParts, _url)); + fbxGeometry = OBJReader().readOBJ(_data, _mapping, _combineParts, _url); } else if (_url.path().toLower().endsWith(".obj.gz")) { QByteArray uncompressedData; if (gunzip(_data, uncompressedData)){ - fbxGeometry.reset(OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url)); + fbxGeometry = OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url); } else { throw QString("failed to decompress .obj.gz" ); } diff --git a/tools/oven/src/DomainBaker.cpp b/tools/oven/src/DomainBaker.cpp index 535d9a49a9..c5573f8074 100644 --- a/tools/oven/src/DomainBaker.cpp +++ b/tools/oven/src/DomainBaker.cpp @@ -304,11 +304,11 @@ void DomainBaker::handleFinishedModelBaker() { if (baker) { if (!baker->hasErrors()) { // this FBXBaker is done and everything went according to plan - qDebug() << "Re-writing entity references to" << baker->getFBXUrl(); + qDebug() << "Re-writing entity references to" << baker->getModelURL(); // enumerate the QJsonRef values for the URL of this FBX from our multi hash of // entity objects needing a URL re-write - for (QJsonValueRef entityValue : _entitiesNeedingRewrite.values(baker->getFBXUrl())) { + for (QJsonValueRef entityValue : _entitiesNeedingRewrite.values(baker->getModelURL())) { // convert the entity QJsonValueRef to a QJsonObject so we can modify its URL auto entity = entityValue.toObject(); @@ -317,7 +317,7 @@ void DomainBaker::handleFinishedModelBaker() { QUrl oldModelURL { entity[ENTITY_MODEL_URL_KEY].toString() }; // setup a new URL using the prefix we were passed - auto relativeFBXFilePath = baker->getBakedFBXFilePath().remove(_contentOutputPath); + auto relativeFBXFilePath = baker->getBakedModelFilePath().remove(_contentOutputPath); if (relativeFBXFilePath.startsWith("/")) { relativeFBXFilePath = relativeFBXFilePath.right(relativeFBXFilePath.length() - 1); } @@ -370,10 +370,10 @@ void DomainBaker::handleFinishedModelBaker() { } // remove the baked URL from the multi hash of entities needing a re-write - _entitiesNeedingRewrite.remove(baker->getFBXUrl()); + _entitiesNeedingRewrite.remove(baker->getModelURL()); // drop our shared pointer to this baker so that it gets cleaned up - _modelBakers.remove(baker->getFBXUrl()); + _modelBakers.remove(baker->getModelURL()); // emit progress to tell listeners how many models we have baked emit bakeProgress(++_completedSubBakes, _totalNumberOfSubBakes); diff --git a/tools/oven/src/ui/BakeWidget.cpp b/tools/oven/src/ui/BakeWidget.cpp index 9fb8f2f880..fba9a46d9d 100644 --- a/tools/oven/src/ui/BakeWidget.cpp +++ b/tools/oven/src/ui/BakeWidget.cpp @@ -42,5 +42,5 @@ void BakeWidget::cancelButtonClicked() { auto stackedWidget = qobject_cast(parentWidget()); stackedWidget->removeWidget(this); - this->deleteLater(); + deleteLater(); } diff --git a/tools/oven/src/ui/ModelBakeWidget.cpp b/tools/oven/src/ui/ModelBakeWidget.cpp index 0bef9f9414..c4c6dc1297 100644 --- a/tools/oven/src/ui/ModelBakeWidget.cpp +++ b/tools/oven/src/ui/ModelBakeWidget.cpp @@ -204,31 +204,30 @@ void ModelBakeWidget::bakeButtonClicked() { bakedOutputDirectory.mkdir("."); originalOutputDirectory.mkdir("."); + std::unique_ptr baker; + auto getWorkerThreadCallback = []() -> QThread* { + return qApp->getNextWorkerThread(); + }; // everything seems to be in place, kick off a bake for this model now if (modelToBakeURL.fileName().endsWith(".fbx")) { - _baker = std::unique_ptr{ - new FBXBaker(modelToBakeURL, []() -> QThread* { - return qApp->getNextWorkerThread(); - }, bakedOutputDirectory.absolutePath(), originalOutputDirectory.absolutePath()) - }; - _isFBX = true; + baker.reset(new FBXBaker(modelToBakeURL, getWorkerThreadCallback, bakedOutputDirectory.absolutePath(), + originalOutputDirectory.absolutePath())); } else if (modelToBakeURL.fileName().endsWith(".obj")) { - _baker = std::unique_ptr{ - new OBJBaker(modelToBakeURL, []() -> QThread* { - return qApp->getNextWorkerThread(); - }, bakedOutputDirectory.absolutePath(), originalOutputDirectory.absolutePath()) - }; - _isOBJ = true; + baker.reset(new OBJBaker(modelToBakeURL, getWorkerThreadCallback, bakedOutputDirectory.absolutePath(), + originalOutputDirectory.absolutePath())); + } else { + qWarning() << "Unknown model type: " << modelToBakeURL.fileName()); + continue; } // move the baker to the FBX/OBJ baker thread - _baker->moveToThread(qApp->getNextWorkerThread()); + baker->moveToThread(qApp->getNextWorkerThread()); // invoke the bake method on the baker thread - QMetaObject::invokeMethod(_baker.get(), "bake"); + QMetaObject::invokeMethod(baker.get(), "bake"); // make sure we hear about the results of this baker when it is done - connect(_baker.get(), &Baker::finished, this, &ModelBakeWidget::handleFinishedBaker); + connect(baker.get(), &Baker::finished, this, &ModelBakeWidget::handleFinishedBaker); // add a pending row to the results window to show that this bake is in process auto resultsWindow = qApp->getMainWindow()->showResultsWindow(); @@ -236,16 +235,15 @@ void ModelBakeWidget::bakeButtonClicked() { // keep a unique_ptr to this baker // and remember the row that represents it in the results table - _bakers.emplace_back(std::move(_baker), resultsRow); + _bakers.emplace_back(std::move(baker), resultsRow); } } void ModelBakeWidget::handleFinishedBaker() { - Baker* baker; - if (_isFBX) { - baker = qobject_cast(sender()); - } else if (_isOBJ) { - baker = qobject_cast(sender()); + Baker* baker = dynamic_cast(sender()); + if (!baker) { + qWarning() << "Received signal from unexpected sender"; + return; } // add the results of this bake to the results window diff --git a/tools/oven/src/ui/ModelBakeWidget.h b/tools/oven/src/ui/ModelBakeWidget.h index 02e7dde660..73527fbcc9 100644 --- a/tools/oven/src/ui/ModelBakeWidget.h +++ b/tools/oven/src/ui/ModelBakeWidget.h @@ -49,9 +49,6 @@ private: Setting::Handle _modelStartDirectory; std::unique_ptr _baker; - - bool _isOBJ = false; - bool _isFBX = false; }; #endif // hifi_ModelBakeWidget_h diff --git a/tools/oven/src/ui/OvenMainWindow.cpp b/tools/oven/src/ui/OvenMainWindow.cpp index dd40fb1f8f..bebc2fa7dc 100644 --- a/tools/oven/src/ui/OvenMainWindow.cpp +++ b/tools/oven/src/ui/OvenMainWindow.cpp @@ -46,7 +46,7 @@ ResultsWindow* OvenMainWindow::showResultsWindow(bool shouldRaise) { _resultsWindow->show(); // place the results window initially below our window - _resultsWindow->move(_resultsWindow->x(), this->frameGeometry().bottom()); + _resultsWindow->move(_resultsWindow->x(), frameGeometry().bottom()); } // show the results window and make sure it is in front diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index 0b12cb64ed..a52e948f01 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -41,18 +41,17 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) { } try { QByteArray fbxContents = fbx.readAll(); - FBXGeometry* geom; + FBXGeometry::Pointer geom; if (filename.toLower().endsWith(".obj")) { bool combineParts = false; geom = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts); } else if (filename.toLower().endsWith(".fbx")) { - geom = readFBX(fbxContents, QVariantHash(), filename); + geom.reset(readFBX(fbxContents, QVariantHash(), filename)); } else { qWarning() << "file has unknown extension" << filename; return false; } result = *geom; - delete geom; reSortFBXGeometryMeshes(result); } catch (const QString& error) {