Browse Source

AnySceneImporter: test & document formats deliberately not handled.

pull/674/head
Vladimír Vondruš 1 year ago
parent
commit
3c27afae42
  1. 29
      src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp
  2. 12
      src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h
  3. 32
      src/MagnumPlugins/AnySceneImporter/Test/AnySceneImporterTest.cpp

29
src/MagnumPlugins/AnySceneImporter/AnySceneImporter.cpp

@ -81,6 +81,34 @@ void AnySceneImporter::doOpenFile(const Containers::StringView filename) {
extensions as well. But we can lowercase just the filename, at least. */ extensions as well. But we can lowercase just the filename, at least. */
const Containers::String normalized = Utility::String::lowercase(Utility::Path::filename(filename)); const Containers::String normalized = Utility::String::lowercase(Utility::Path::filename(filename));
/* Some extensions supported by AssimpImporter are deliberately not
recognized due to being overly generic, conflicting, or too obscure. In particular:
- `*.mdl`, used by both Quake I and "3D GameStudio (3DGS)"
- `*.md2`, `*.md3`, `*.pk3`, `*.md5*` used by Quake II and III and
Doom 3, not recognized because Quake I isn't recognized either
- `*.mesh`, which is OGRE, Meshwork and likely other formats too
http://justsolve.archiveteam.org/wiki/Meshwork_model
https://file.org/extension/mesh
- `*.nff`, which is both "Neutral File Format" and
"Sense8 WorldToolKit"
- `*.off`, which is "Object File Format", likely a variant of the
above, feels rather obscure
- `*.ndo`, which is "Izware Nendo", feels rather obscure
- `*.raw`, which can be PovRAY Raw, but also raw image data or just
anything. Especially problematic when e.g. magnum-player first
tries to open a file as a scene and if that fails, falls back to
opening an image.
- `*.xml`, which can be an OGRE XML mesh but also COLLADA. Ogre XML
is recognized as `*.mesh.xml` instead.
- `*.ter`, which is Terragen Terrain. I couldn't find any file that
would load with Assimp, the only `terrain.ter` I found is an
OBJ-like text file for which Assimp complains that "Magic string
'TERRAGEN' not found".
The conflicting extensions are explicitly tested in AnySceneImporterTest
to ensure they're not added by accident. */
/* Detect the plugin from extension */ /* Detect the plugin from extension */
Containers::StringView plugin; Containers::StringView plugin;
if(normalized.hasSuffix(".3ds"_s) || if(normalized.hasSuffix(".3ds"_s) ||
@ -135,6 +163,7 @@ void AnySceneImporter::doOpenFile(const Containers::StringView filename) {
else if(normalized.hasSuffix(".stl"_s)) else if(normalized.hasSuffix(".stl"_s))
plugin = "StlImporter"_s; plugin = "StlImporter"_s;
else if(normalized.hasSuffix(".cob"_s) || else if(normalized.hasSuffix(".cob"_s) ||
/** @todo isn't *.scn also too generic? */
normalized.hasSuffix(".scn"_s)) normalized.hasSuffix(".scn"_s))
plugin = "TrueSpaceImporter"_s; plugin = "TrueSpaceImporter"_s;
else if(normalized.hasSuffix(".3d"_s)) else if(normalized.hasSuffix(".3d"_s))

12
src/MagnumPlugins/AnySceneImporter/AnySceneImporter.h

@ -85,7 +85,9 @@ tries to open the file with it. Supported formats:
- Wavefront OBJ (`*.obj`), loaded with @ref ObjImporter or any other plugin - Wavefront OBJ (`*.obj`), loaded with @ref ObjImporter or any other plugin
that provides it that provides it
- OGRE XML (`*.mesh.xml`), loaded with any plugin that provides - OGRE XML (`*.mesh.xml`), loaded with any plugin that provides
`OgreImporter` `OgreImporter`. The `*.mesh` extension isn't recognized because it's used
by [Meshwork](http://justsolve.archiveteam.org/wiki/Meshwork_model) as
well.
- OpenGEX (`*.ogex`), loaded with @ref OpenGexImporter or any other plugin - OpenGEX (`*.ogex`), loaded with @ref OpenGexImporter or any other plugin
that provides it that provides it
- Stanford (`*.ply`), loaded with @ref StanfordImporter or any other plugin - Stanford (`*.ply`), loaded with @ref StanfordImporter or any other plugin
@ -99,6 +101,14 @@ tries to open the file with it. Supported formats:
`ValveImporter` `ValveImporter`
- XGL (`*.xgl`, `*.zgl`), loaded with any plugin that provides `XglImporter` - XGL (`*.xgl`, `*.zgl`), loaded with any plugin that provides `XglImporter`
@note
Note that this list is not exhaustive, in particular the
@ref AssimpImporter lists many more file extensions. Not all can be
supported by this plugin because they're either very generic or used by
multiple different formats, such as `*.mdl` used for both Quake I and 3D
GameStudio. If file opening fails with this plugin, you can try directly
with a concrete plugin such as the @ref AssimpImporter as a fallback.
Only loading from files is supported as the filename is used to detect the Only loading from files is supported as the filename is used to detect the
format, however @ref ImporterFeature::FileCallback is supported as well. format, however @ref ImporterFeature::FileCallback is supported as well.

32
src/MagnumPlugins/AnySceneImporter/Test/AnySceneImporterTest.cpp

@ -65,6 +65,7 @@ struct AnySceneImporterTest: TestSuite::Tester {
void load(); void load();
void detect(); void detect();
void reject();
void unknown(); void unknown();
@ -159,6 +160,22 @@ const struct {
{"XGL compressed", "thingy.zgl", "XglImporter"}, {"XGL compressed", "thingy.zgl", "XglImporter"},
}; };
const struct {
const char* name;
const char* filename;
} RejectData[]{
/* This lists pairs of filenames where, just based on extension, any
detection cannot be done */
{"COLLADA with a *.xml extension", "collada.xml"},
{"OGRE XML with just a *.xml extension", "mesh.xml"},
{"OGRE *.mesh", "ogre.mesh"},
{"Meshwork *.mesh", "foo.mesh"},
{"OBJ-like *.ter file", "terrain.ter"},
{"Terragen *.ter", "terragen.ter"},
{"Quake 1 *.mdl", "quake.mdl"},
{"3D Game Studio (3DGS) *.mdl", "3dgs.mdl"},
};
const struct { const struct {
const char* name; const char* name;
ImporterFlags flags; ImporterFlags flags;
@ -175,6 +192,9 @@ AnySceneImporterTest::AnySceneImporterTest() {
addInstancedTests({&AnySceneImporterTest::detect}, addInstancedTests({&AnySceneImporterTest::detect},
Containers::arraySize(DetectData)); Containers::arraySize(DetectData));
addInstancedTests({&AnySceneImporterTest::reject},
Containers::arraySize(RejectData));
addTests({&AnySceneImporterTest::unknown, addTests({&AnySceneImporterTest::unknown,
&AnySceneImporterTest::propagateFlags, &AnySceneImporterTest::propagateFlags,
@ -270,6 +290,18 @@ void AnySceneImporterTest::detect() {
#endif #endif
} }
void AnySceneImporterTest::reject() {
auto&& data = RejectData[testCaseInstanceId()];
setTestCaseDescription(data.name);
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("AnySceneImporter");
Containers::String out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->openFile(data.filename));
CORRADE_COMPARE(out, Utility::format("Trade::AnySceneImporter::openFile(): cannot determine the format of {}\n", data.filename));
}
void AnySceneImporterTest::unknown() { void AnySceneImporterTest::unknown() {
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("AnySceneImporter"); Containers::Pointer<AbstractImporter> importer = _manager.instantiate("AnySceneImporter");

Loading…
Cancel
Save