From e8df904cc50dccb2011532831e3b3877a3a7601a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 12 Apr 2022 22:28:07 +0200 Subject: [PATCH] [wip] Trade: delegation from single-mesh coooooooooooo TODO: finish commit message once i stop being tired TODO: it sucks, needs to be fixed, see prev commit TODOs --- src/Magnum/Trade/AbstractSceneConverter.cpp | 10 +- src/Magnum/Trade/AbstractSceneConverter.h | 18 +++- .../Trade/Test/AbstractSceneConverterTest.cpp | 100 ++++++++++++++++++ 3 files changed, 122 insertions(+), 6 deletions(-) diff --git a/src/Magnum/Trade/AbstractSceneConverter.cpp b/src/Magnum/Trade/AbstractSceneConverter.cpp index 87dd09ba2..0642adc89 100644 --- a/src/Magnum/Trade/AbstractSceneConverter.cpp +++ b/src/Magnum/Trade/AbstractSceneConverter.cpp @@ -240,7 +240,14 @@ AbstractSceneConverter::convertToData(const MeshData& mesh) { #endif } -Containers::Optional> AbstractSceneConverter::doConvertToData(const MeshData&) { +Containers::Optional> AbstractSceneConverter::doConvertToData(const MeshData& data) { + if(features() >= (SceneConverterFeature::ConvertMultipleToData|SceneConverterFeature::AddMeshes)) { + beginData(); + Containers::Optional> out; + if(add(data) && (out = endData())) return out; + return {}; + } + CORRADE_ASSERT_UNREACHABLE("Trade::AbstractSceneConverter::convertToData(): mesh conversion advertised but not implemented", {}); } @@ -258,6 +265,7 @@ bool AbstractSceneConverter::convertToFile(const std::string& filename, const Me #endif bool AbstractSceneConverter::doConvertToFile(const MeshData& mesh, const Containers::StringView filename) { + // TODO delegate to batch CORRADE_ASSERT(features() >= SceneConverterFeature::ConvertMeshToData, "Trade::AbstractSceneConverter::convertToFile(): mesh conversion advertised but not implemented", false); const Containers::Optional> data = doConvertToData(mesh); diff --git a/src/Magnum/Trade/AbstractSceneConverter.h b/src/Magnum/Trade/AbstractSceneConverter.h index 426dec4a3..7170ad2b8 100644 --- a/src/Magnum/Trade/AbstractSceneConverter.h +++ b/src/Magnum/Trade/AbstractSceneConverter.h @@ -59,26 +59,26 @@ enum class SceneConverterFeature: UnsignedInt { * Convert a single mesh instance with * @ref AbstractSceneConverter::convert(const MeshData&). */ - ConvertMesh = 1 << 0, + ConvertMesh = 1 << 0, // TODO mention behavior w/ begin /** * Convert a single mesh instance in-place with * @ref AbstractSceneConverter::convertInPlace(MeshData&). */ - ConvertMeshInPlace = 1 << 1, + ConvertMeshInPlace = 1u << 1, /** * Convert a single mesh instance to a file with * @ref AbstractSceneConverter::convertToFile(const MeshData&, Containers::StringView). */ - ConvertMeshToFile = 1 << 2, + ConvertMeshToFile = 1 << 2, // TODO mention behavior w/ beginFile /** * Convert a single mesh instance to raw data with * @ref AbstractSceneConverter::convertToData(const MeshData&). Implies * @ref SceneConverterFeature::ConvertMeshToFile. */ - ConvertMeshToData = ConvertMeshToFile|(1 << 3), + ConvertMeshToData = ConvertMeshToFile|(1 << 3), // TODO mention behavior w/ beginData /** * Convert multiple data with @@ -158,7 +158,7 @@ enum class SceneConverterFeature: UnsignedInt { * @m_since_latest * @see @ref SceneConverterFeature::MeshLevels */ - AddMeshes = 1 << 13, + AddMeshes = 1 << 13, // TODO mention behavior with convert() /** * Add material instances with @@ -712,6 +712,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract * @ref SceneConverterFeature::ConvertMultiple is supported. * @see @ref features(), @ref beginData(), @ref beginFile() */ + // TODO mention behavior with ConvertMesh void begin(); /** @@ -727,6 +728,8 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract * earlier. On failure prints a message to @relativeref{Magnum,Error} * and returns @cpp nullptr @ce. */ + // TODO mention behavior with ConvertMesh, especially with the importer + // behavior, also test that to be more graceful Containers::Pointer end(); /** @@ -739,6 +742,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract * @ref SceneConverterFeature::ConvertMultipleToData is supported. * @see @ref features(), @ref begin(), @ref beginFile() */ + // TODO mention behavior with ConvertMeshToData void beginData(); /** @@ -749,6 +753,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract * message to @relativeref{Magnum,Error} and returns * @ref Containers::NullOpt. */ + // TODO mention behavior with ConvertMeshToData Containers::Optional> endData(); /** @@ -761,6 +766,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract * @ref SceneConverterFeature::ConvertMultipleToFile is supported. * @see @ref features(), @ref begin(), @ref beginData() */ + // TODO mention behavior with ConvertMeshToFile void beginFile(Containers::StringView filename); /** @@ -770,6 +776,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract * Expects that @ref beginData() was called before. On failure prints a * message to @relativeref{Magnum,Error} and returns @cpp false @ce. */ + // TODO mention behavior with ConvertMeshToFile, especially about when the file gets saved bool endFile(); /** @@ -1083,6 +1090,7 @@ class MAGNUM_TRADE_EXPORT AbstractSceneConverter: public PluginManager::Abstract * @see @ref isConverting(), @ref features(), * @ref setMeshAttributeName() */ + // TODO mention behavior with ConvertMeshToFile, especially when the file gets saved #ifdef DOXYGEN_GENERATING_OUTPUT Containers::Optional add(const MeshData& mesh, Containers::StringView name = {}); #else diff --git a/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp b/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp index ac6420bd1..b65c6b467 100644 --- a/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp +++ b/src/Magnum/Trade/Test/AbstractSceneConverterTest.cpp @@ -84,6 +84,9 @@ struct AbstractSceneConverterTest: TestSuite::Tester { void convertMeshToData(); void convertMeshToDataFailed(); + void convertMeshToDataThroughBatch(); + void convertMeshToDataThroughBatchAddFailed(); + void convertMeshToDataThroughBatchEndFailed(); void convertMeshToDataNotImplemented(); void convertMeshToDataNonOwningDeleter(); void convertMeshToDataGrowableDeleter(); @@ -94,6 +97,9 @@ struct AbstractSceneConverterTest: TestSuite::Tester { void convertMeshToFileThroughData(); void convertMeshToFileThroughDataFailed(); void convertMeshToFileThroughDataNotWritable(); + void convertMeshToFileThroughBatch(); + void convertMeshToFileThroughBatchAddFailed(); + void convertMeshToFileThroughBatchEndFailed(); void convertMeshToFileNotImplemented(); void beginEnd(); @@ -288,6 +294,9 @@ AbstractSceneConverterTest::AbstractSceneConverterTest() { &AbstractSceneConverterTest::convertMeshToData, &AbstractSceneConverterTest::convertMeshToDataFailed, + &AbstractSceneConverterTest::convertMeshToDataThroughBatch, + &AbstractSceneConverterTest::convertMeshToDataThroughBatchAddFailed, + &AbstractSceneConverterTest::convertMeshToDataThroughBatchEndFailed, &AbstractSceneConverterTest::convertMeshToDataNotImplemented, &AbstractSceneConverterTest::convertMeshToDataNonOwningDeleter, &AbstractSceneConverterTest::convertMeshToDataGrowableDeleter, @@ -298,6 +307,9 @@ AbstractSceneConverterTest::AbstractSceneConverterTest() { &AbstractSceneConverterTest::convertMeshToFileThroughData, &AbstractSceneConverterTest::convertMeshToFileThroughDataFailed, &AbstractSceneConverterTest::convertMeshToFileThroughDataNotWritable, + &AbstractSceneConverterTest::convertMeshToFileThroughBatch, + &AbstractSceneConverterTest::convertMeshToFileThroughBatchAddFailed, + &AbstractSceneConverterTest::convertMeshToFileThroughBatchEndFailed, &AbstractSceneConverterTest::convertMeshToFileNotImplemented, &AbstractSceneConverterTest::beginEnd, @@ -934,6 +946,85 @@ void AbstractSceneConverterTest::convertMeshToDataFailed() { CORRADE_COMPARE(out.str(), ""); } +void AbstractSceneConverterTest::convertMeshToDataThroughBatch() { + struct: AbstractSceneConverter { + SceneConverterFeatures doFeatures() const override { + return SceneConverterFeature::ConvertMultiple| + SceneConverterFeature::AddMeshes; + } + + void doBeginData() override {} + + bool doAdd(UnsignedInt id, const MeshData& mesh, Containers::StringView) override { + CORRADE_COMPARE(id, 0); + CORRADE_COMPARE(mesh.primitive(), MeshPrimitive::Triangles); + _vertexCount = mesh.vertexCount(); + return true; + } + + Containers::Optional> doEndData() override { + return Containers::Array{nullptr, _vertexCount}; + } + + std::size_t _vertexCount = 0; + } converter; + + Containers::Optional> data = converter.convertToData(MeshData{MeshPrimitive::Triangles, 6}); + CORRADE_VERIFY(data); + CORRADE_COMPARE(data->size(), 6); +} + +void AbstractSceneConverterTest::convertMeshToDataThroughBatchAddFailed() { + struct: AbstractSceneConverter { + SceneConverterFeatures doFeatures() const override { + return SceneConverterFeature::ConvertMultiple| + SceneConverterFeature::AddMeshes; + } + + void doBeginData() override {} + + bool doAdd(UnsignedInt, const MeshData&, Containers::StringView) override { + return false; + } + + Containers::Optional> doEndData() override { + CORRADE_FAIL_IF(true, "doEndData() shouldn't be called"); + return {}; + } + } converter; + + /* The implementation is expected to print an error message on its own */ + std::ostringstream out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(MeshData{MeshPrimitive::Triangles, 6})); + CORRADE_COMPARE(out.str(), ""); +} + +void AbstractSceneConverterTest::convertMeshToDataThroughBatchEndFailed() { + struct: AbstractSceneConverter { + SceneConverterFeatures doFeatures() const override { + return SceneConverterFeature::ConvertMultiple| + SceneConverterFeature::AddMeshes; + } + + void doBeginData() override {} + + bool doAdd(UnsignedInt, const MeshData&, Containers::StringView) override { + return true; + } + + Containers::Optional> doEndData() override { + return {}; + } + } converter; + + /* The implementation is expected to print an error message on its own */ + std::ostringstream out; + Error redirectError{&out}; + CORRADE_VERIFY(!converter.convertToData(MeshData{MeshPrimitive::Triangles, 6})); + CORRADE_COMPARE(out.str(), ""); +} + void AbstractSceneConverterTest::convertMeshToDataNotImplemented() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); @@ -1106,6 +1197,15 @@ void AbstractSceneConverterTest::convertMeshToFileThroughDataNotWritable() { TestSuite::Compare::StringHasSuffix); } +void AbstractSceneConverterTest::convertMeshToFileThroughBatch() { +} + +void AbstractSceneConverterTest::convertMeshToFileThroughBatchAddFailed() { +} + +void AbstractSceneConverterTest::convertMeshToFileThroughBatchEndFailed() { +} + void AbstractSceneConverterTest::convertMeshToFileNotImplemented() { #ifdef CORRADE_NO_ASSERT CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");