diff --git a/src/Magnum/Trade/AbstractImporter.cpp b/src/Magnum/Trade/AbstractImporter.cpp index 2146519d2..cda75437e 100644 --- a/src/Magnum/Trade/AbstractImporter.cpp +++ b/src/Magnum/Trade/AbstractImporter.cpp @@ -547,6 +547,17 @@ void AbstractImporter::populateCachedScenes() { newObjectOffset = Math::max(newObjectOffset, _cachedScenes->scenes[i]->objectCount()); } } + + /* If there are scenes but no objects (because for example all scenes + failed to import), use the dimension-less object count at least, and + assume the scene was 3D. Otherwise this may cause unexpected assertions + in code that expected proper object count to be reported even if a scene + contains errors. + + Not ideal, especially regarding the 3D assumption, but better than + nothing. */ + if(!_cachedScenes->scenes.empty() && !_cachedScenes->object2DCount && !_cachedScenes->object3DCount) + _cachedScenes->object3DCount = objectCount(); } UnsignedInt AbstractImporter::object2DCount() const { diff --git a/src/Magnum/Trade/Test/AbstractImporterTest.cpp b/src/Magnum/Trade/Test/AbstractImporterTest.cpp index d7d44c859..627ba15a9 100644 --- a/src/Magnum/Trade/Test/AbstractImporterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractImporterTest.cpp @@ -126,6 +126,8 @@ struct AbstractImporterTest: TestSuite::Tester { void sceneDeprecatedFallbackTransformless3D(); void sceneDeprecatedFallbackMultiFunctionObjects2D(); void sceneDeprecatedFallbackMultiFunctionObjects3D(); + void sceneDeprecatedFallbackObjectCountNoScenes(); + void sceneDeprecatedFallbackObjectCountAllSceneImportFailed(); #endif void sceneNameNotImplemented(); void objectNameNotImplemented(); @@ -410,6 +412,8 @@ AbstractImporterTest::AbstractImporterTest() { &AbstractImporterTest::sceneDeprecatedFallbackTransformless3D, &AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects2D, &AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects3D, + &AbstractImporterTest::sceneDeprecatedFallbackObjectCountNoScenes, + &AbstractImporterTest::sceneDeprecatedFallbackObjectCountAllSceneImportFailed, #endif &AbstractImporterTest::sceneForNameOutOfRange, &AbstractImporterTest::objectForNameOutOfRange, @@ -3219,6 +3223,45 @@ void AbstractImporterTest::sceneDeprecatedFallbackMultiFunctionObjects3D() { } CORRADE_IGNORE_DEPRECATED_POP } + +void AbstractImporterTest::sceneDeprecatedFallbackObjectCountNoScenes() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doSceneCount() const override { return 0; } + UnsignedLong doObjectCount() const override { return 27; } + } importer; + + /* There's no scenes to get data or hierarchy from, so there are no + 2D/3D objects reported even though objectCount() says 27 */ + CORRADE_IGNORE_DEPRECATED_PUSH + CORRADE_COMPARE(importer.object2DCount(), 0); + CORRADE_COMPARE(importer.object3DCount(), 0); + CORRADE_IGNORE_DEPRECATED_POP +} + +void AbstractImporterTest::sceneDeprecatedFallbackObjectCountAllSceneImportFailed() { + struct: AbstractImporter { + ImporterFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + UnsignedInt doSceneCount() const override { return 1; } + UnsignedLong doObjectCount() const override { return 27; } + Containers::Optional doScene(UnsignedInt) override { + return {}; + } + } importer; + + /* There's a scene but it failed to import, assume it was 3D and proxy the + objectCount() */ + CORRADE_IGNORE_DEPRECATED_PUSH + CORRADE_COMPARE(importer.object2DCount(), 0); + CORRADE_COMPARE(importer.object3DCount(), 27); + CORRADE_IGNORE_DEPRECATED_POP +} #endif void AbstractImporterTest::sceneNameNotImplemented() {