From 917db39bd1e9b06b8f7f0557a8c1ba7dde761377 Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Fri, 3 Jan 2025 00:46:11 +0100 Subject: [PATCH 01/13] implemented reader option --- application/F3DOptionsTools.cxx | 1 + application/F3DOptionsTools.h | 1 + doc/user/OPTIONS.md | 1 + library/options.json | 3 +++ library/private/factory.h | 13 +++++++++++++ library/src/factory.cxx.in | 24 +++++++++++++++++++++++- library/src/scene_impl.cxx | 12 +++++++++++- 7 files changed, 53 insertions(+), 2 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index e57c749bf4..fa9121d6a2 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -65,6 +65,7 @@ static inline const std::array CLIOptions = {{ { "no-background", "", "No background when render to file", "", "1" }, { "help", "h", "Print help", "", "" }, { "version", "", "Print version details", "", "" }, { "list-readers", "", "Print the list of readers", "", "" }, + {"reader", "", "Enforce specific reader", "", ""}, { "list-bindings", "", "Print the list of interaction bindings and exits, ignored with `--no-render`, only considers the first file group.", "", "" }, { "config", "", "Specify the configuration file to use. absolute/relative path or filename/filestem to search in configuration file locations", "", "" }, { "no-config", "", "Do not read the configuration file", "", "1" }, diff --git a/application/F3DOptionsTools.h b/application/F3DOptionsTools.h index dce906ad0a..9ff86cd88e 100644 --- a/application/F3DOptionsTools.h +++ b/application/F3DOptionsTools.h @@ -126,6 +126,7 @@ static inline const std::map LibOptionsNames { "anti-aliasing", "render.effect.anti_aliasing" }, { "tone-mapping", "render.effect.tone_mapping" }, { "final-shader", "render.effect.final_shader" }, + { "reader", "render.reader" }, }; /** diff --git a/doc/user/OPTIONS.md b/doc/user/OPTIONS.md index 26b36aadcb..203ee03465 100644 --- a/doc/user/OPTIONS.md +++ b/doc/user/OPTIONS.md @@ -14,6 +14,7 @@ Options|Type
Default|Description -h, \-\-help||Print *help* and exit. Ignore `--verbose`. \-\-version||Show *version* information and exit. Ignore `--verbose`. \-\-list-readers||List available *readers* and exit. Ignore `--verbose`. +\-\-reader=\|string
-|Enforce specific reader. \-\-list-bindings||List available *bindings* and exit. Ignore `--verbose`. \-\-list-rendering-backends||List available *rendering backends* and exit. Ignore `--verbose`. \-\-config=\|string
config|Specify the [configuration file](CONFIGURATION_FILE.md) to use. Supports absolute/relative path but also filename/filestem to search for in standard configuration file locations. diff --git a/library/options.json b/library/options.json index 31ece9b78f..95c8830711 100644 --- a/library/options.json +++ b/library/options.json @@ -28,6 +28,9 @@ } }, "render": { + "reader": { + "type": "string" + }, "show_edges": { "type": "bool" }, diff --git a/library/private/factory.h b/library/private/factory.h index c1edca7f1d..dfbc1e7466 100644 --- a/library/private/factory.h +++ b/library/private/factory.h @@ -17,6 +17,7 @@ #include "reader.h" #include +#include #include namespace f3d @@ -57,6 +58,16 @@ class factory */ plugin_initializer_t getStaticInitializer(const std::string& pluginName); + /** + * Set preferred reader + */ + bool setPreferredReader(const std::string& preferredReader); + + /** + * Get preferred reader + */ + std::optional getPreferredReader(); + protected: factory(); virtual ~factory() = default; @@ -66,6 +77,8 @@ class factory std::vector Plugins; std::map StaticPluginInitializers; + + std::optional Reader; }; } #endif diff --git a/library/src/factory.cxx.in b/library/src/factory.cxx.in index 97a58bffee..0ce373f3a1 100644 --- a/library/src/factory.cxx.in +++ b/library/src/factory.cxx.in @@ -49,7 +49,11 @@ reader* factory::getReader(const std::string& fileName) { for (auto r : p->getReaders()) { - if (r->getScore() > bestScore && r->canRead(fileName)) + if (this->Reader.has_value() && r->getName() == *(this->Reader)) + { + return r->canRead(fileName) ? r.get() : nullptr; + } + if (r->canRead(fileName) && r->getScore() > bestScore) { bestScore = r->getScore(); bestReader = r.get(); @@ -99,4 +103,22 @@ bool factory::registerOnce(plugin* plug) } return false; } + +//---------------------------------------------------------------------------- +bool factory::setPreferredReader(const std::string& preferredReader) { + if (preferredReader == "") + { + return false; + } + else + { + this->Reader = preferredReader; + return true; + } +} + +//---------------------------------------------------------------------------- +std::optional factory::getPreferredReader() { + return this->Reader; } +} \ No newline at end of file diff --git a/library/src/scene_impl.cxx b/library/src/scene_impl.cxx index 5303b23f1e..d2ee77fa72 100644 --- a/library/src/scene_impl.cxx +++ b/library/src/scene_impl.cxx @@ -11,6 +11,7 @@ #include "vtkF3DMemoryMesh.h" #include "vtkF3DMetaImporter.h" +#include #include #include #include @@ -231,8 +232,17 @@ scene& scene_impl::add(const std::vector& filePaths) throw scene::load_failure_exception(filePath.string() + " does not exists"); } + auto* factory = f3d::factory::instance(); + + if (const auto& opts = this->Internals->Options; + !factory->getPreferredReader().has_value() && opts.render.reader.has_value()) + { + const auto& reader = opts.render.reader; + factory->setPreferredReader(*reader); + } + // Recover the importer for the provided file path - f3d::reader* reader = f3d::factory::instance()->getReader(filePath.string()); + f3d::reader* reader = factory->getReader(filePath.string()); if (reader) { log::debug( From c85a20c59dd62a47906c63e6b441ceb32fe4a73d Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Fri, 3 Jan 2025 02:00:29 +0100 Subject: [PATCH 02/13] added test & bugfix --- library/public/engine.h | 5 +++ library/src/engine.cxx | 8 ++++ library/src/scene_impl.cxx | 5 +-- library/testing/CMakeLists.txt | 1 + library/testing/TestSDKReaderSelection.cxx | 46 ++++++++++++++++++++++ 5 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 library/testing/TestSDKReaderSelection.cxx diff --git a/library/public/engine.h b/library/public/engine.h index 32760408f9..7a052a4aea 100644 --- a/library/public/engine.h +++ b/library/public/engine.h @@ -234,6 +234,11 @@ class F3D_EXPORT engine */ [[nodiscard]] interactor& getInteractor(); + /** + * Get the enforced readers name + */ + [[nodiscard]] std::string_view getReader(); + /** * List rendering backends supported by libf3d. * All backends have an associated boolean flag indicating if it can be used. diff --git a/library/src/engine.cxx b/library/src/engine.cxx index 5d083d529f..d28c89430f 100644 --- a/library/src/engine.cxx +++ b/library/src/engine.cxx @@ -481,6 +481,14 @@ std::vector engine::getReadersInfo() return readersInfo; } +//---------------------------------------------------------------------------- +std::string_view engine::getReader() +{ + static const std::string empty_str = ""; // used to avoid dangling pointer; a bit strange way + auto prefReader = factory::instance()->getPreferredReader(); + return prefReader.has_value() ? *prefReader : empty_str; +} + //---------------------------------------------------------------------------- engine& engine::setCachePath(const fs::path& cachePath) { diff --git a/library/src/scene_impl.cxx b/library/src/scene_impl.cxx index d2ee77fa72..1ceae2b2ea 100644 --- a/library/src/scene_impl.cxx +++ b/library/src/scene_impl.cxx @@ -234,10 +234,9 @@ scene& scene_impl::add(const std::vector& filePaths) auto* factory = f3d::factory::instance(); - if (const auto& opts = this->Internals->Options; - !factory->getPreferredReader().has_value() && opts.render.reader.has_value()) + if (auto reader = this->Internals->Options.render.reader; reader.has_value()) { - const auto& reader = opts.render.reader; + log::debug("Current value of a reader:" + *reader + "\n"); factory->setPreferredReader(*reader); } diff --git a/library/testing/CMakeLists.txt b/library/testing/CMakeLists.txt index 9dfc7e9a33..483e4e9ca7 100644 --- a/library/testing/CMakeLists.txt +++ b/library/testing/CMakeLists.txt @@ -15,6 +15,7 @@ list(APPEND libf3dSDKTests_list TestSDKMultiColoring.cxx TestSDKOptions.cxx TestSDKOptionsIO.cxx + TestSDKReaderSelection.cxx TestSDKRenderFinalShader.cxx TestSDKUtils.cxx TestSDKWindowAuto.cxx diff --git a/library/testing/TestSDKReaderSelection.cxx b/library/testing/TestSDKReaderSelection.cxx new file mode 100644 index 0000000000..c67819d28c --- /dev/null +++ b/library/testing/TestSDKReaderSelection.cxx @@ -0,0 +1,46 @@ +#include "PseudoUnitTest.h" +#include "TestSDKHelpers.h" + +#include +#include +#include +#include + +namespace fs = std::filesystem; +int TestSDKReaderSelection(int argc, char* argv[]) +{ + PseudoUnitTest test; + + f3d::log::setVerboseLevel(f3d::log::VerboseLevel::DEBUG); + f3d::engine::autoloadPlugins(); + + // Test file path setup + std::string monkey = std::string(argv[1]) + "data/red_translucent_monkey.gltf"; + + // Test default reader (no preference) + { + f3d::engine engine = f3d::engine::create(true); + f3d::scene& scene = engine.getScene(); + test("add with a single path", [&]() { scene.add(fs::path(monkey)); }); + } + + // Test Draco reader + { + f3d::engine engine = f3d::engine::create(true); + engine.getOptions().render.reader = "GLTFDraco"; + f3d::scene& scene = engine.getScene(); + test("Draco reader works", [&]() { scene.add(fs::path(monkey)); }); + test("Reader is GLTFDraco", engine.getReader() == "GLTFDraco"); + } + + // Test GLTF reader + { + f3d::engine engine = f3d::engine::create(true); + engine.getOptions().render.reader = "GLTF"; + f3d::scene& scene = engine.getScene(); + test("GLTF reader works", [&]() { scene.add(fs::path(monkey)); }); + test("Reader is GLTF", engine.getReader() == "GLTF"); + } + + return test.result(); +} \ No newline at end of file From 45ba1a919759e276040d083c3194af28d333a074 Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Fri, 3 Jan 2025 02:17:52 +0100 Subject: [PATCH 03/13] spelling correction --- application/F3DOptionsTools.cxx | 2 +- doc/user/OPTIONS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index fa9121d6a2..0c3893869d 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -65,7 +65,7 @@ static inline const std::array CLIOptions = {{ { "no-background", "", "No background when render to file", "", "1" }, { "help", "h", "Print help", "", "" }, { "version", "", "Print version details", "", "" }, { "list-readers", "", "Print the list of readers", "", "" }, - {"reader", "", "Enforce specific reader", "", ""}, + {"reader", "", "Enforce a specific reader", "", ""}, { "list-bindings", "", "Print the list of interaction bindings and exits, ignored with `--no-render`, only considers the first file group.", "", "" }, { "config", "", "Specify the configuration file to use. absolute/relative path or filename/filestem to search in configuration file locations", "", "" }, { "no-config", "", "Do not read the configuration file", "", "1" }, diff --git a/doc/user/OPTIONS.md b/doc/user/OPTIONS.md index 203ee03465..b19c2fea59 100644 --- a/doc/user/OPTIONS.md +++ b/doc/user/OPTIONS.md @@ -14,7 +14,7 @@ Options|Type
Default|Description -h, \-\-help||Print *help* and exit. Ignore `--verbose`. \-\-version||Show *version* information and exit. Ignore `--verbose`. \-\-list-readers||List available *readers* and exit. Ignore `--verbose`. -\-\-reader=\|string
-|Enforce specific reader. +\-\-reader=\|string
-|Enforce a specific reader. \-\-list-bindings||List available *bindings* and exit. Ignore `--verbose`. \-\-list-rendering-backends||List available *rendering backends* and exit. Ignore `--verbose`. \-\-config=\|string
config|Specify the [configuration file](CONFIGURATION_FILE.md) to use. Supports absolute/relative path but also filename/filestem to search for in standard configuration file locations. From 5b00fcb954a7ec7c09774182222f5ec7910f3f8e Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Fri, 3 Jan 2025 02:25:52 +0100 Subject: [PATCH 04/13] reformat --- library/src/factory.cxx.in | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/library/src/factory.cxx.in b/library/src/factory.cxx.in index 0ce373f3a1..d7f2afac6d 100644 --- a/library/src/factory.cxx.in +++ b/library/src/factory.cxx.in @@ -52,7 +52,7 @@ reader* factory::getReader(const std::string& fileName) if (this->Reader.has_value() && r->getName() == *(this->Reader)) { return r->canRead(fileName) ? r.get() : nullptr; - } + } if (r->canRead(fileName) && r->getScore() > bestScore) { bestScore = r->getScore(); @@ -105,20 +105,22 @@ bool factory::registerOnce(plugin* plug) } //---------------------------------------------------------------------------- -bool factory::setPreferredReader(const std::string& preferredReader) { - if (preferredReader == "") +bool factory::setPreferredReader(const std::string& preferredReader) +{ + if (preferredReader == "") { return false; } - else - { + else + { this->Reader = preferredReader; return true; } } //---------------------------------------------------------------------------- -std::optional factory::getPreferredReader() { +std::optional factory::getPreferredReader() +{ return this->Reader; } } \ No newline at end of file From e916daff7e5bb733b6fe85562f6fe384ea68c773 Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:00:08 +0100 Subject: [PATCH 05/13] force-reader to scene & fixes --- application/F3DOptionsTools.cxx | 2 +- application/F3DOptionsTools.h | 3 ++- library/options.json | 6 +++--- library/private/factory.h | 15 ++------------ library/public/engine.h | 5 ----- library/src/engine.cxx | 8 -------- library/src/factory.cxx.in | 24 ++-------------------- library/src/scene_impl.cxx | 15 +++++--------- library/testing/TestSDKReaderSelection.cxx | 13 ++++++------ 9 files changed, 21 insertions(+), 70 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index 0c3893869d..db32571fc7 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -65,7 +65,7 @@ static inline const std::array CLIOptions = {{ { "no-background", "", "No background when render to file", "", "1" }, { "help", "h", "Print help", "", "" }, { "version", "", "Print version details", "", "" }, { "list-readers", "", "Print the list of readers", "", "" }, - {"reader", "", "Enforce a specific reader", "", ""}, + {"force-reader", "", "Enforce a specific reader", "", ""}, { "list-bindings", "", "Print the list of interaction bindings and exits, ignored with `--no-render`, only considers the first file group.", "", "" }, { "config", "", "Specify the configuration file to use. absolute/relative path or filename/filestem to search in configuration file locations", "", "" }, { "no-config", "", "Do not read the configuration file", "", "1" }, diff --git a/application/F3DOptionsTools.h b/application/F3DOptionsTools.h index 9ff86cd88e..7cde46da15 100644 --- a/application/F3DOptionsTools.h +++ b/application/F3DOptionsTools.h @@ -57,6 +57,7 @@ static inline const OptionsDict DefaultAppOptions = { { "interaction-test-play", "" }, { "command-script", "" }, { "frame-rate", "30.0" }, + { "force-reader", "" }, }; /** @@ -80,6 +81,7 @@ static inline const std::map LibOptionsNames { "animation-autoplay", "scene.animation.autoplay" }, { "animation-index", "scene.animation.index" }, { "animation-speed-factor", "scene.animation.speed_factor" }, + { "force-reader", "scene.force_reader" }, { "font-file", "ui.font_file" }, { "point-sprites", "model.point_sprites.enable" }, { "point-sprites-type", "model.point_sprites.type" }, @@ -126,7 +128,6 @@ static inline const std::map LibOptionsNames { "anti-aliasing", "render.effect.anti_aliasing" }, { "tone-mapping", "render.effect.tone_mapping" }, { "final-shader", "render.effect.final_shader" }, - { "reader", "render.reader" }, }; /** diff --git a/library/options.json b/library/options.json index 95c8830711..4abf643418 100644 --- a/library/options.json +++ b/library/options.json @@ -25,12 +25,12 @@ "orthographic": { "type": "bool" } + }, + "force_reader": { + "type": "string" } }, "render": { - "reader": { - "type": "string" - }, "show_edges": { "type": "bool" }, diff --git a/library/private/factory.h b/library/private/factory.h index dfbc1e7466..ddd883e99d 100644 --- a/library/private/factory.h +++ b/library/private/factory.h @@ -18,6 +18,7 @@ #include #include +#include #include namespace f3d @@ -45,7 +46,7 @@ class factory /** * Get the reader that can read the given file, nullptr if none */ - reader* getReader(const std::string& fileName); + reader* getReader(const std::string& fileName, std::optional forceReader); /** * Get the list of the registered plugins @@ -58,16 +59,6 @@ class factory */ plugin_initializer_t getStaticInitializer(const std::string& pluginName); - /** - * Set preferred reader - */ - bool setPreferredReader(const std::string& preferredReader); - - /** - * Get preferred reader - */ - std::optional getPreferredReader(); - protected: factory(); virtual ~factory() = default; @@ -77,8 +68,6 @@ class factory std::vector Plugins; std::map StaticPluginInitializers; - - std::optional Reader; }; } #endif diff --git a/library/public/engine.h b/library/public/engine.h index 7a052a4aea..32760408f9 100644 --- a/library/public/engine.h +++ b/library/public/engine.h @@ -234,11 +234,6 @@ class F3D_EXPORT engine */ [[nodiscard]] interactor& getInteractor(); - /** - * Get the enforced readers name - */ - [[nodiscard]] std::string_view getReader(); - /** * List rendering backends supported by libf3d. * All backends have an associated boolean flag indicating if it can be used. diff --git a/library/src/engine.cxx b/library/src/engine.cxx index 766b748d57..ada3e2e370 100644 --- a/library/src/engine.cxx +++ b/library/src/engine.cxx @@ -481,14 +481,6 @@ std::vector engine::getReadersInfo() return readersInfo; } -//---------------------------------------------------------------------------- -std::string_view engine::getReader() -{ - static const std::string empty_str = ""; // used to avoid dangling pointer; a bit strange way - auto prefReader = factory::instance()->getPreferredReader(); - return prefReader.has_value() ? *prefReader : empty_str; -} - //---------------------------------------------------------------------------- engine& engine::setCachePath(const fs::path& cachePath) { diff --git a/library/src/factory.cxx.in b/library/src/factory.cxx.in index d7f2afac6d..fcb56cadfe 100644 --- a/library/src/factory.cxx.in +++ b/library/src/factory.cxx.in @@ -40,7 +40,7 @@ factory::plugin_initializer_t factory::getStaticInitializer(const std::string& p } //---------------------------------------------------------------------------- -reader* factory::getReader(const std::string& fileName) +reader* factory::getReader(const std::string& fileName, std::optional forceReader) { int bestScore = -1; reader* bestReader = nullptr; @@ -49,7 +49,7 @@ reader* factory::getReader(const std::string& fileName) { for (auto r : p->getReaders()) { - if (this->Reader.has_value() && r->getName() == *(this->Reader)) + if (forceReader.has_value() && r->getName() == *forceReader) { return r->canRead(fileName) ? r.get() : nullptr; } @@ -103,24 +103,4 @@ bool factory::registerOnce(plugin* plug) } return false; } - -//---------------------------------------------------------------------------- -bool factory::setPreferredReader(const std::string& preferredReader) -{ - if (preferredReader == "") - { - return false; - } - else - { - this->Reader = preferredReader; - return true; - } -} - -//---------------------------------------------------------------------------- -std::optional factory::getPreferredReader() -{ - return this->Reader; -} } \ No newline at end of file diff --git a/library/src/scene_impl.cxx b/library/src/scene_impl.cxx index 1ceae2b2ea..2c52eed33c 100644 --- a/library/src/scene_impl.cxx +++ b/library/src/scene_impl.cxx @@ -4,6 +4,7 @@ #include "interactor_impl.h" #include "log.h" #include "options.h" +#include "scene.h" #include "window_impl.h" #include "factory.h" @@ -232,16 +233,9 @@ scene& scene_impl::add(const std::vector& filePaths) throw scene::load_failure_exception(filePath.string() + " does not exists"); } - auto* factory = f3d::factory::instance(); - - if (auto reader = this->Internals->Options.render.reader; reader.has_value()) - { - log::debug("Current value of a reader:" + *reader + "\n"); - factory->setPreferredReader(*reader); - } - // Recover the importer for the provided file path - f3d::reader* reader = factory->getReader(filePath.string()); + f3d::reader* reader = f3d::factory::instance()->getReader( + filePath.string(), this->Internals->Options.scene.force_reader); if (reader) { log::debug( @@ -323,7 +317,8 @@ scene& scene_impl::clear() //---------------------------------------------------------------------------- bool scene_impl::supports(const fs::path& filePath) { - return f3d::factory::instance()->getReader(filePath.string()) != nullptr; + return f3d::factory::instance()->getReader( + filePath.string(), this->Internals->Options.scene.force_reader) != nullptr; } //---------------------------------------------------------------------------- diff --git a/library/testing/TestSDKReaderSelection.cxx b/library/testing/TestSDKReaderSelection.cxx index c67819d28c..8e5427d7eb 100644 --- a/library/testing/TestSDKReaderSelection.cxx +++ b/library/testing/TestSDKReaderSelection.cxx @@ -24,23 +24,22 @@ int TestSDKReaderSelection(int argc, char* argv[]) test("add with a single path", [&]() { scene.add(fs::path(monkey)); }); } - // Test Draco reader + // Test Draco reader; GLTF is by-default { f3d::engine engine = f3d::engine::create(true); - engine.getOptions().render.reader = "GLTFDraco"; + engine.getOptions().scene.force_reader = "GLTFDraco"; f3d::scene& scene = engine.getScene(); test("Draco reader works", [&]() { scene.add(fs::path(monkey)); }); - test("Reader is GLTFDraco", engine.getReader() == "GLTFDraco"); + test("Reader is GLTFDraco", engine.getOptions().scene.force_reader == "GLTFDraco"); } - // Test GLTF reader + // Test GLTF reader; { f3d::engine engine = f3d::engine::create(true); - engine.getOptions().render.reader = "GLTF"; + engine.getOptions().scene.force_reader = "GLTF"; f3d::scene& scene = engine.getScene(); test("GLTF reader works", [&]() { scene.add(fs::path(monkey)); }); - test("Reader is GLTF", engine.getReader() == "GLTF"); + test("Reader is GLTF", engine.getOptions().scene.force_reader == "GLTF"); } - return test.result(); } \ No newline at end of file From 17c2dda210ad5701276f957b095a464efe633c38 Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:17:26 +0100 Subject: [PATCH 06/13] bugfix --- application/F3DOptionsTools.cxx | 2 +- application/F3DOptionsTools.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index db32571fc7..32948d8c68 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -65,7 +65,7 @@ static inline const std::array CLIOptions = {{ { "no-background", "", "No background when render to file", "", "1" }, { "help", "h", "Print help", "", "" }, { "version", "", "Print version details", "", "" }, { "list-readers", "", "Print the list of readers", "", "" }, - {"force-reader", "", "Enforce a specific reader", "", ""}, + {"force-reader", "", "Enforce a specific reader", "", "1"}, { "list-bindings", "", "Print the list of interaction bindings and exits, ignored with `--no-render`, only considers the first file group.", "", "" }, { "config", "", "Specify the configuration file to use. absolute/relative path or filename/filestem to search in configuration file locations", "", "" }, { "no-config", "", "Do not read the configuration file", "", "1" }, diff --git a/application/F3DOptionsTools.h b/application/F3DOptionsTools.h index 7cde46da15..2b6cd4bcc2 100644 --- a/application/F3DOptionsTools.h +++ b/application/F3DOptionsTools.h @@ -57,7 +57,6 @@ static inline const OptionsDict DefaultAppOptions = { { "interaction-test-play", "" }, { "command-script", "" }, { "frame-rate", "30.0" }, - { "force-reader", "" }, }; /** From bc268949e91e76cff8b08703c53bef69839cddd9 Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Tue, 14 Jan 2025 19:55:58 +0100 Subject: [PATCH 07/13] reader: Applied suggestions & refactor --- application/F3DOptionsTools.cxx | 2 +- doc/libf3d/OPTIONS.md | 1 + doc/user/OPTIONS.md | 2 +- library/plugin/plugin.h | 10 +++++----- library/src/factory.cxx.in | 16 ++++++++-------- library/testing/TestSDKReaderSelection.cxx | 2 +- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/application/F3DOptionsTools.cxx b/application/F3DOptionsTools.cxx index 3f499554d6..e4ef1e8855 100644 --- a/application/F3DOptionsTools.cxx +++ b/application/F3DOptionsTools.cxx @@ -65,7 +65,7 @@ static inline const std::array CLIOptions = {{ { "no-background", "", "No background when render to file", "", "1" }, { "help", "h", "Print help", "", "" }, { "version", "", "Print version details", "", "" }, { "list-readers", "", "Print the list of readers", "", "" }, - {"force-reader", "", "Enforce a specific reader", "", "1"}, + {"force-reader", "", "Force a specific reader to be used, disrigarding the file extension", "", "1"}, { "list-bindings", "", "Print the list of interaction bindings and exits, ignored with `--no-render`, only considers the first file group.", "", "" }, { "config", "", "Specify the configuration file to use. absolute/relative path or filename/filestem to search in configuration file locations", "", "" }, { "no-config", "", "Do not read the configuration file", "", "1" }, diff --git a/doc/libf3d/OPTIONS.md b/doc/libf3d/OPTIONS.md index deefb34459..2a5dd72379 100644 --- a/doc/libf3d/OPTIONS.md +++ b/doc/libf3d/OPTIONS.md @@ -27,6 +27,7 @@ scene.animation.index|int
0
load|Select the animation to load.
Any nega scene.animation.speed_factor|ratio
1
render|Set the animation speed factor to slow, speed up or even invert animation.|\-\-animation-speed-factor scene.animation.time|double
optional
load|Set the animation time to load.|\-\-animation-time scene.camera.index|int
optional
load|Select the scene camera to use when available in the file.
The default scene always uses automatic camera.|\-\-camera-index +scene.force_reader|string
optional
load|Force a specific reader to be used, disrigarding the file extension.|\-\-force-reader scene.up_direction|string
+Y
load|Define the Up direction. It impacts the grid, the axis, the HDRI and the camera.|\-\-up scene.camera.orthographic|bool
optional
load|Set to true to force orthographic projection. Model specified by default, which is false if not specified.|\-\-camera\-orthographic diff --git a/doc/user/OPTIONS.md b/doc/user/OPTIONS.md index 27fdd89fc6..8e1506b5f7 100644 --- a/doc/user/OPTIONS.md +++ b/doc/user/OPTIONS.md @@ -14,7 +14,7 @@ Options|Type
Default|Description -h, \-\-help||Print *help* and exit. Ignore `--verbose`. \-\-version||Show *version* information and exit. Ignore `--verbose`. \-\-list-readers||List available *readers* and exit. Ignore `--verbose`. -\-\-reader=\|string
-|Enforce a specific reader. +\-\-force-reader=\|string
-|Force a specific reader to be used, disrigarding the file extension. \-\-list-bindings||List available *bindings* and exit. Ignore `--verbose`. \-\-list-rendering-backends||List available *rendering backends* and exit. Ignore `--verbose`. \-\-config=\|string
config|Specify the [configuration file](CONFIGURATION_FILE.md) to use. Supports absolute/relative path but also filename/filestem to search for in standard configuration file locations. diff --git a/library/plugin/plugin.h b/library/plugin/plugin.h index 5a172b079b..14efac42ba 100644 --- a/library/plugin/plugin.h +++ b/library/plugin/plugin.h @@ -37,7 +37,7 @@ class plugin /** * Get the name of this plugin */ - const std::string& getName() + const std::string& getName() const { return this->Name; } @@ -45,7 +45,7 @@ class plugin /** * Get the description of this plugin */ - const std::string& getDescription() + const std::string& getDescription() const { return this->Description; } @@ -53,7 +53,7 @@ class plugin /** * Get the version of this plugin */ - const std::string& getVersion() + const std::string& getVersion() const { return this->Version; } @@ -61,7 +61,7 @@ class plugin /** * Get the list of readers created by this plugin */ - const std::vector>& getReaders() + const std::vector>& getReaders() const { return this->Readers; } @@ -71,7 +71,7 @@ class plugin * Set/Get the origin of this plugin, usually static, system or an actual path * Set by the engine. */ - const std::string& getOrigin() + const std::string& getOrigin() const { return this->Origin; } diff --git a/library/src/factory.cxx.in b/library/src/factory.cxx.in index fcb56cadfe..488d4488ab 100644 --- a/library/src/factory.cxx.in +++ b/library/src/factory.cxx.in @@ -45,18 +45,18 @@ reader* factory::getReader(const std::string& fileName, std::optionalPlugins) + for (const auto* plugin : this->Plugins) { - for (auto r : p->getReaders()) + for (const auto& reader : plugin->getReaders()) { - if (forceReader.has_value() && r->getName() == *forceReader) + if (forceReader.has_value() && reader->getName() == *forceReader) { - return r->canRead(fileName) ? r.get() : nullptr; + return reader.get(); } - if (r->canRead(fileName) && r->getScore() > bestScore) + if (reader->getScore() > bestScore && reader->canRead(fileName)) { - bestScore = r->getScore(); - bestReader = r.get(); + bestScore = reader->getScore(); + bestReader = reader.get(); } } } @@ -103,4 +103,4 @@ bool factory::registerOnce(plugin* plug) } return false; } -} \ No newline at end of file +} diff --git a/library/testing/TestSDKReaderSelection.cxx b/library/testing/TestSDKReaderSelection.cxx index 8e5427d7eb..70aaa09532 100644 --- a/library/testing/TestSDKReaderSelection.cxx +++ b/library/testing/TestSDKReaderSelection.cxx @@ -42,4 +42,4 @@ int TestSDKReaderSelection(int argc, char* argv[]) test("Reader is GLTF", engine.getOptions().scene.force_reader == "GLTF"); } return test.result(); -} \ No newline at end of file +} From d260c5567af7de50ad6ab34f9b487a169671ad7f Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Mon, 3 Mar 2025 20:29:35 +0100 Subject: [PATCH 08/13] apllication tests for force-reader --- application/testing/CMakeLists.txt | 10 ++++++++++ library/src/factory.cxx.in | 9 ++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index 73fcc24afc..04272c63c0 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -1121,6 +1121,16 @@ if(F3D_PLUGIN_BUILD_ALEMBIC AND F3D_PLUGIN_BUILD_ASSIMP) f3d_test(NAME TestReadersListMultiplePlugins ARGS --list-readers --load-plugins=assimp,alembic NO_BASELINE REGEXP_FAIL "Plugin failed to load") endif() +if(F3D_PLUGIN_BUILD_EXODUS) + f3d_test(NAME TestForceReaderExodusFail DATA BoxAnimated.gltf ARGS --force-reader=ExodusII NO_BASELINE REGEXP "failed to load scene") + f3d_test(NAME TestForceReaderExodusPass DATA disk_out_ref.ex2 ARGS --force-reader=ExodusII NO_BASELINE REGEXP_FAIL "failed to load scene") +endif() + +if(F3D_PLUGIN_BUILD_DRACO) + f3d_test(NAME TestForceReaderGLTFDraco DATA BoxAnimated.gltf ARGS --force-reader=GLTFDraco NO_BASELINE REGEXP_FAIL "failed to load scene") + f3d_test(NAME TestForceReaderGLTF DATA BoxAnimated.gltf ARGS --force-reader=GLTF NO_BASELINE REGEXP_FAIL "failed to load scene") +endif() + # Test bindings-list display f3d_test(NAME TestBindingsList ARGS --list-bindings REGEXP "Any.5 Toggle Orthographic Projection") diff --git a/library/src/factory.cxx.in b/library/src/factory.cxx.in index 488d4488ab..91c9994ecb 100644 --- a/library/src/factory.cxx.in +++ b/library/src/factory.cxx.in @@ -49,11 +49,14 @@ reader* factory::getReader(const std::string& fileName, std::optionalgetReaders()) { - if (forceReader.has_value() && reader->getName() == *forceReader) + if (forceReader.has_value()) { - return reader.get(); + if (reader->getName() == *forceReader) + { + return reader.get(); + } } - if (reader->getScore() > bestScore && reader->canRead(fileName)) + else if (reader->getScore() > bestScore && reader->canRead(fileName)) { bestScore = reader->getScore(); bestReader = reader.get(); From c93e9540acfad49e4ba0bb9781710e23c7e2d1f9 Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Mon, 3 Mar 2025 20:32:20 +0100 Subject: [PATCH 09/13] reformat --- library/options.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/options.json b/library/options.json index 3d8e8a50e3..dc92cafc1a 100644 --- a/library/options.json +++ b/library/options.json @@ -27,7 +27,7 @@ } }, "force_reader": { - "type": "string" + "type": "string" } }, "render": { From 63c0456decc255ab6a5b1a38a1b4a77c39997725 Mon Sep 17 00:00:00 2001 From: 0xfedcafe <17340030+0xfedcafe@users.noreply.github.com> Date: Wed, 12 Mar 2025 12:04:18 +0100 Subject: [PATCH 10/13] test fix --- application/testing/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index 04272c63c0..cd8dfde1d4 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -1122,13 +1122,13 @@ if(F3D_PLUGIN_BUILD_ALEMBIC AND F3D_PLUGIN_BUILD_ASSIMP) endif() if(F3D_PLUGIN_BUILD_EXODUS) - f3d_test(NAME TestForceReaderExodusFail DATA BoxAnimated.gltf ARGS --force-reader=ExodusII NO_BASELINE REGEXP "failed to load scene") - f3d_test(NAME TestForceReaderExodusPass DATA disk_out_ref.ex2 ARGS --force-reader=ExodusII NO_BASELINE REGEXP_FAIL "failed to load scene") + f3d_test(NAME TestForceReaderExodusFail DATA BoxAnimated.gltf ARGS --force-reader=ExodusII NO_BASELINE REGEXP "is not a file of a supported file format|failed to load scene") + f3d_test(NAME TestForceReaderExodusPass DATA disk_out_ref.ex2 ARGS --force-reader=ExodusII NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") endif() if(F3D_PLUGIN_BUILD_DRACO) - f3d_test(NAME TestForceReaderGLTFDraco DATA BoxAnimated.gltf ARGS --force-reader=GLTFDraco NO_BASELINE REGEXP_FAIL "failed to load scene") - f3d_test(NAME TestForceReaderGLTF DATA BoxAnimated.gltf ARGS --force-reader=GLTF NO_BASELINE REGEXP_FAIL "failed to load scene") + f3d_test(NAME TestForceReaderGLTFDraco DATA BoxAnimated.gltf ARGS --force-reader=GLTFDraco NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") + f3d_test(NAME TestForceReaderGLTF DATA BoxAnimated.gltf ARGS --force-reader=GLTF NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") endif() # Test bindings-list display From 9a5bca20ebd8e0c7da7a5b6956b6c3e44b22fa3a Mon Sep 17 00:00:00 2001 From: "Tim D. Vutor" <17340030+0xfedcafe@users.noreply.github.com> Date: Thu, 13 Mar 2025 18:31:44 +0100 Subject: [PATCH 11/13] Apply suggestions from code review fixes by mwestphal Co-authored-by: Mathieu Westphal --- application/testing/CMakeLists.txt | 8 ++++---- doc/libf3d/OPTIONS.md | 2 +- doc/user/OPTIONS.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application/testing/CMakeLists.txt b/application/testing/CMakeLists.txt index cd8dfde1d4..6e34811ebe 100644 --- a/application/testing/CMakeLists.txt +++ b/application/testing/CMakeLists.txt @@ -1122,13 +1122,13 @@ if(F3D_PLUGIN_BUILD_ALEMBIC AND F3D_PLUGIN_BUILD_ASSIMP) endif() if(F3D_PLUGIN_BUILD_EXODUS) - f3d_test(NAME TestForceReaderExodusFail DATA BoxAnimated.gltf ARGS --force-reader=ExodusII NO_BASELINE REGEXP "is not a file of a supported file format|failed to load scene") - f3d_test(NAME TestForceReaderExodusPass DATA disk_out_ref.ex2 ARGS --force-reader=ExodusII NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") + f3d_test(NAME TestForceReaderExodusFail DATA BoxAnimated.gltf ARGS --load-plugins=exodus --force-reader=ExodusII NO_BASELINE REGEXP "is not a file of a supported file format|failed to load scene") + f3d_test(NAME TestForceReaderExodusPass DATA disk_out_ref.ex2 ARGS --load-plugins=exodus --force-reader=ExodusII NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") endif() if(F3D_PLUGIN_BUILD_DRACO) - f3d_test(NAME TestForceReaderGLTFDraco DATA BoxAnimated.gltf ARGS --force-reader=GLTFDraco NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") - f3d_test(NAME TestForceReaderGLTF DATA BoxAnimated.gltf ARGS --force-reader=GLTF NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") + f3d_test(NAME TestForceReaderGLTFDraco DATA BoxAnimated.gltf ARGS --load-plugins=draco --force-reader=GLTFDraco NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") + f3d_test(NAME TestForceReaderGLTF DATA BoxAnimated.gltf ARGS --load-plugins=draco --force-reader=GLTF NO_BASELINE REGEXP_FAIL "is not a file of a supported file format|failed to load scene") endif() # Test bindings-list display diff --git a/doc/libf3d/OPTIONS.md b/doc/libf3d/OPTIONS.md index 8438e7b851..81e0265b50 100644 --- a/doc/libf3d/OPTIONS.md +++ b/doc/libf3d/OPTIONS.md @@ -28,7 +28,7 @@ See the [APIs](#APIs) details below for more info. | scene.animation.time | double
optional
load | Set the animation time to load. | \-\-animation-time | | scene.camera.index | int
optional
load | Select the scene camera to use when available in the file.
The default scene always uses automatic camera. | \-\-camera-index | | scene.up_direction | direction
+Y
load | Define the Up direction. It impacts the grid, the axis, the HDRI and the camera. | \-\-up | -| scene.force_reader | string
optional
load | Force a specific reader to be used, disrigarding the file extension. | \-\-force-reader | +| scene.force_reader | string
optional
load | Force a specific reader to be used, disregarding the file extension. | \-\-force-reader | | scene.camera.orthographic | bool
optional
load | Set to true to force orthographic projection. Model specified by default, which is false if not specified. | \-\-camera\-orthographic | ## Interactor Options diff --git a/doc/user/OPTIONS.md b/doc/user/OPTIONS.md index 81cab4ec8c..84b933678e 100644 --- a/doc/user/OPTIONS.md +++ b/doc/user/OPTIONS.md @@ -14,7 +14,7 @@ F3D behavior can be fully controlled from the command line using the following o | -h, \-\-help | | Print _help_ and exit. Ignore `--verbose`. | | \-\-version | | Show _version_ information and exit. Ignore `--verbose`. | | \-\-list-readers | | List available _readers_ and exit. Ignore `--verbose`. | -| \-\-force-reader=\ | string
- | Force a specific reader to be used, disrigarding the file extension. | +| \-\-force-reader=\ | string
- | Force a specific reader to be used, disregarding the file extension. | | \-\-list-bindings | | List available _bindings_ and exit. Ignore `--verbose`. | | \-\-list-rendering-backends | | List available _rendering backends_ and exit. Ignore `--verbose`. | | \-\-config=\ | string
config | Specify the [configuration file](CONFIGURATION_FILE.md) to use. Supports absolute/relative path but also filename/filestem to search for in standard configuration file locations. | From 2db35e20cfad740d8c066e1687eabfc4410f151f Mon Sep 17 00:00:00 2001 From: Artem Siryk Date: Tue, 25 Mar 2025 21:48:58 +0100 Subject: [PATCH 12/13] fix --- library/private/factory.h | 2 +- library/src/factory.cxx.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/private/factory.h b/library/private/factory.h index 2107763fe1..cab02934ce 100644 --- a/library/private/factory.h +++ b/library/private/factory.h @@ -46,7 +46,7 @@ class factory /** * Get the reader that can read the given file, nullptr if none */ - reader* getReader(const std::string& fileName, std::optional forceReader); + reader* getReader(const std::string& fileName, std::optional forceReader); /** * Get the list of the registered plugins diff --git a/library/src/factory.cxx.in b/library/src/factory.cxx.in index 487711156a..5079a025eb 100644 --- a/library/src/factory.cxx.in +++ b/library/src/factory.cxx.in @@ -40,7 +40,7 @@ factory::plugin_initializer_t factory::getStaticInitializer(const std::string& p } //---------------------------------------------------------------------------- -reader* factory::getReader(const std::string& fileName, std::optional forceReader) +reader* factory::getReader(const std::string& fileName, std::optional forceReader) { int bestScore = -1; reader* bestReader = nullptr; From dbaf7ba9514d8d68a2e8ec0370ea2086d82e95b7 Mon Sep 17 00:00:00 2001 From: Artem Siryk Date: Mon, 21 Apr 2025 20:23:53 +0200 Subject: [PATCH 13/13] Removed unnecessary test --- library/testing/CMakeLists.txt | 1 - library/testing/TestSDKReaderSelection.cxx | 45 ---------------------- 2 files changed, 46 deletions(-) delete mode 100644 library/testing/TestSDKReaderSelection.cxx diff --git a/library/testing/CMakeLists.txt b/library/testing/CMakeLists.txt index 9de7607f2c..44814b2e18 100644 --- a/library/testing/CMakeLists.txt +++ b/library/testing/CMakeLists.txt @@ -14,7 +14,6 @@ list(APPEND libf3dSDKTests_list TestSDKMultiColoring.cxx TestSDKOptions.cxx TestSDKOptionsIO.cxx - TestSDKReaderSelection.cxx TestSDKRenderFinalShader.cxx TestSDKUtils.cxx TestSDKWindowAuto.cxx diff --git a/library/testing/TestSDKReaderSelection.cxx b/library/testing/TestSDKReaderSelection.cxx deleted file mode 100644 index 70aaa09532..0000000000 --- a/library/testing/TestSDKReaderSelection.cxx +++ /dev/null @@ -1,45 +0,0 @@ -#include "PseudoUnitTest.h" -#include "TestSDKHelpers.h" - -#include -#include -#include -#include - -namespace fs = std::filesystem; -int TestSDKReaderSelection(int argc, char* argv[]) -{ - PseudoUnitTest test; - - f3d::log::setVerboseLevel(f3d::log::VerboseLevel::DEBUG); - f3d::engine::autoloadPlugins(); - - // Test file path setup - std::string monkey = std::string(argv[1]) + "data/red_translucent_monkey.gltf"; - - // Test default reader (no preference) - { - f3d::engine engine = f3d::engine::create(true); - f3d::scene& scene = engine.getScene(); - test("add with a single path", [&]() { scene.add(fs::path(monkey)); }); - } - - // Test Draco reader; GLTF is by-default - { - f3d::engine engine = f3d::engine::create(true); - engine.getOptions().scene.force_reader = "GLTFDraco"; - f3d::scene& scene = engine.getScene(); - test("Draco reader works", [&]() { scene.add(fs::path(monkey)); }); - test("Reader is GLTFDraco", engine.getOptions().scene.force_reader == "GLTFDraco"); - } - - // Test GLTF reader; - { - f3d::engine engine = f3d::engine::create(true); - engine.getOptions().scene.force_reader = "GLTF"; - f3d::scene& scene = engine.getScene(); - test("GLTF reader works", [&]() { scene.add(fs::path(monkey)); }); - test("Reader is GLTF", engine.getOptions().scene.force_reader == "GLTF"); - } - return test.result(); -}