Browse Source

sceneconverter: add --object-hierarchy.

Useful for quickly visualizing how the objects are parented to each
other, discovering groupings, overly deep hierarchies and such.
pull/620/head
Vladimír Vondruš 3 years ago
parent
commit
39054f1b64
  1. 2
      doc/changelog.dox
  2. 143
      src/Magnum/SceneTools/Implementation/sceneConverterUtilities.h
  3. 4
      src/Magnum/SceneTools/Test/CMakeLists.txt
  4. 79
      src/Magnum/SceneTools/Test/SceneConverterImplementationTest.cpp
  5. 14
      src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-object-hierarchy-no-parents.txt
  6. 7
      src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-object-hierarchy-only-objects-no-parents.txt
  7. 14
      src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-object-hierarchy-only-objects.txt
  8. 28
      src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-object-hierarchy.txt
  9. 7
      src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes-no-default.txt
  10. 19
      src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes-objects.txt
  11. 7
      src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes.txt
  12. 4
      src/Magnum/SceneTools/sceneconverter.cpp

2
doc/changelog.dox

@ -667,6 +667,8 @@ See also:
`--info-materials`, `--info-meshes`, `--info-skins` and `--info-textures`
for printing information just about particular data type, with `--info`
being a shortcut for all specified together
- Added a `--object-hierarchy` option to @ref magnum-sceneconverter "magnum-sceneconverter"
that visualizes scene hierarchy in each scene by indenting object info
- Added a `--prefer` option to @ref magnum-sceneconverter "magnum-sceneconverter",
allowing to specify what plugins should be preferred for particular import
and conversion plugin aliases

143
src/Magnum/SceneTools/Implementation/sceneConverterUtilities.h

@ -33,6 +33,7 @@
#include <Corrade/Utility/Arguments.h>
#include "Magnum/Math/FunctionsBatch.h"
#include "Magnum/SceneTools/Hierarchy.h"
#include "Magnum/Trade/AbstractSceneConverter.h"
#include "Magnum/Trade/AnimationData.h"
#include "Magnum/Trade/CameraData.h"
@ -157,6 +158,8 @@ bool printInfo(const Debug::Flags useColor, const bool useColor24, const Utility
std::size_t dataSize;
Trade::DataFlags dataFlags;
Containers::String name;
/* Populated only if --object-hierarchy is set */
Containers::Array<Containers::Pair<UnsignedInt, UnsignedInt>> childrenDepthFirst;
};
struct ObjectInfo {
@ -198,13 +201,15 @@ bool printInfo(const Debug::Flags useColor, const bool useColor24, const Utility
Containers::Array<UnsignedInt> meshReferenceCount;
Containers::Array<UnsignedInt> skin2DReferenceCount;
Containers::Array<UnsignedInt> skin3DReferenceCount;
if((args.isSet("info") || args.isSet("info-scenes")) && importer.sceneCount()) {
materialReferenceCount = Containers::Array<UnsignedInt>{importer.materialCount()};
lightReferenceCount = Containers::Array<UnsignedInt>{importer.lightCount()};
cameraReferenceCount = Containers::Array<UnsignedInt>{importer.cameraCount()};
meshReferenceCount = Containers::Array<UnsignedInt>{importer.meshCount()};
skin2DReferenceCount = Containers::Array<UnsignedInt>{importer.skin2DCount()};
skin3DReferenceCount = Containers::Array<UnsignedInt>{importer.skin3DCount()};
if((args.isSet("info") || args.isSet("info-scenes") || args.isSet("object-hierarchy")) && importer.sceneCount()) {
if(args.isSet("info") || args.isSet("info-scenes")) {
materialReferenceCount = Containers::Array<UnsignedInt>{importer.materialCount()};
lightReferenceCount = Containers::Array<UnsignedInt>{importer.lightCount()};
cameraReferenceCount = Containers::Array<UnsignedInt>{importer.cameraCount()};
meshReferenceCount = Containers::Array<UnsignedInt>{importer.meshCount()};
skin2DReferenceCount = Containers::Array<UnsignedInt>{importer.skin2DCount()};
skin3DReferenceCount = Containers::Array<UnsignedInt>{importer.skin3DCount()};
}
for(UnsignedInt i = 0; i != importer.sceneCount(); ++i) {
Containers::Optional<Trade::SceneData> scene = importer.scene(i);
@ -221,7 +226,7 @@ bool printInfo(const Debug::Flags useColor, const bool useColor24, const Utility
info.dataSize = scene->data().size();
info.dataFlags = scene->dataFlags();
info.name = importer.sceneName(i);
for(UnsignedInt j = 0; j != scene->fieldCount(); ++j) {
if(args.isSet("info") || args.isSet("info-scenes")) for(UnsignedInt j = 0; j != scene->fieldCount(); ++j) {
const Trade::SceneField name = scene->fieldName(j);
if(name == Trade::SceneField::Mesh) for(const Containers::Pair<UnsignedInt, Containers::Pair<UnsignedInt, Int>>& meshMaterial: scene->meshesMaterialsAsArray()) {
@ -279,6 +284,9 @@ bool printInfo(const Debug::Flags useColor, const bool useColor24, const Utility
}
}
if(args.isSet("object-hierarchy") && scene->hasField(Trade::SceneField::Parent))
info.childrenDepthFirst = SceneTools::childrenDepthFirst(*scene);
arrayAppend(sceneInfos, std::move(info));
}
}
@ -603,6 +611,26 @@ bool printInfo(const Debug::Flags useColor, const bool useColor24, const Utility
if((args.isSet("info") || args.isSet("info-scenes")) && importer.defaultScene() != -1)
Debug{useColor} << Debug::boldColor(Debug::Color::Default) << "Default scene:" << Debug::resetColor << importer.defaultScene();
const auto printObjectFieldInfo = [&sceneFieldNames](Debug& d, const ObjectInfo& info) {
for(std::size_t i = 0; i != info.fields.size(); ++i) {
if(i) d << Debug::nospace << ",";
const Containers::Pair<Trade::SceneField, UnsignedInt> nameCount = info.fields[i];
d << Debug::color(Debug::Color::Cyan);
if(Trade::isSceneFieldCustom(nameCount.first())) {
d << "Custom(" << Debug::nospace
<< Trade::sceneFieldCustom(nameCount.first())
<< Debug::nospace << ":" << Debug::nospace
<< Debug::color(Debug::Color::Yellow)
<< sceneFieldNames[sceneFieldCustom(nameCount.first())]
<< Debug::nospace
<< Debug::color(Debug::Color::Cyan) << ")";
} else d << Debug::packed << nameCount.first();
if(nameCount.second() != 1)
d << Debug::nospace << Utility::format("[{}]", nameCount.second());
d << Debug::resetColor;
}
};
std::size_t totalSceneDataSize = 0;
for(const SceneInfo& info: sceneInfos) {
Debug d{useColor};
@ -620,28 +648,62 @@ bool printInfo(const Debug::Flags useColor, const bool useColor24, const Utility
<< Debug::resetColor;
d << Debug::nospace << ")";
d << Debug::newline << " Fields:";
for(const SceneFieldInfo& field: info.fields) {
d << Debug::newline << " "
<< Debug::boldColor(Debug::Color::Default);
if(Trade::isSceneFieldCustom(field.name)) {
d << "Custom(" << Debug::nospace
<< Trade::sceneFieldCustom(field.name)
<< Debug::nospace << ":" << Debug::nospace
<< Debug::color(Debug::Color::Yellow)
<< sceneFieldNames[sceneFieldCustom(field.name)]
<< Debug::nospace
<< Debug::boldColor(Debug::Color::Default) << ")";
} else d << Debug::packed << field.name;
if(info.fields) {
d << Debug::newline << " Fields:";
for(const SceneFieldInfo& field: info.fields) {
d << Debug::newline << " "
<< Debug::boldColor(Debug::Color::Default);
if(Trade::isSceneFieldCustom(field.name)) {
d << "Custom(" << Debug::nospace
<< Trade::sceneFieldCustom(field.name)
<< Debug::nospace << ":" << Debug::nospace
<< Debug::color(Debug::Color::Yellow)
<< sceneFieldNames[sceneFieldCustom(field.name)]
<< Debug::nospace
<< Debug::boldColor(Debug::Color::Default) << ")";
} else d << Debug::packed << field.name;
d << Debug::color(Debug::Color::Blue) << "@" << Debug::packed << Debug::color(Debug::Color::Cyan) << field.type;
if(field.arraySize)
d << Debug::nospace << Utility::format("[{}]", field.arraySize);
d << Debug::resetColor;
if(field.flags) d << Debug::nospace << ","
<< Debug::packed << Debug::color(Debug::Color::Green)
<< field.flags << Debug::resetColor;
d << Debug::nospace << "," << field.size << "entries";
d << Debug::color(Debug::Color::Blue) << "@" << Debug::packed << Debug::color(Debug::Color::Cyan) << field.type;
if(field.arraySize)
d << Debug::nospace << Utility::format("[{}]", field.arraySize);
d << Debug::resetColor;
if(field.flags) d << Debug::nospace << ","
<< Debug::packed << Debug::color(Debug::Color::Green)
<< field.flags << Debug::resetColor;
d << Debug::nospace << "," << field.size << "entries";
}
}
if(args.isSet("object-hierarchy") && objectInfos) {
d << Debug::newline << " Object hierarchy:";
Containers::Array<std::size_t> childRangeEnds;
arrayAppend(childRangeEnds, info.childrenDepthFirst.size());
for(std::size_t i = 0; i != info.childrenDepthFirst.size(); ++i) {
while(childRangeEnds.back() == i)
arrayRemoveSuffix(childRangeEnds, 1);
const UnsignedInt object = info.childrenDepthFirst[i].first();
const UnsignedInt childCount = info.childrenDepthFirst[i].second();
const ObjectInfo& objectInfo = objectInfos[object];
const Containers::String indent = " "_s*(childRangeEnds.size());
d << Debug::newline << indent << Debug::nospace << Debug::boldColor(Debug::Color::Default) << " Object"
<< object << Debug::nospace << ":" << Debug::resetColor;
if(objectInfo.name) d << Debug::boldColor(Debug::Color::Yellow)
<< objectInfo.name << Debug::resetColor;
if(objectInfo.fields) {
d << Debug::newline << indent << Debug::nospace << " Fields:";
printObjectFieldInfo(d, objectInfo);
}
if(childCount) {
CORRADE_INTERNAL_ASSERT(childRangeEnds.back() > i + 1);
arrayAppend(childRangeEnds, i + childCount + 1);
}
}
}
totalSceneDataSize += info.dataSize;
@ -649,7 +711,9 @@ bool printInfo(const Debug::Flags useColor, const bool useColor24, const Utility
if(!sceneInfos.isEmpty())
Debug{} << "Total scene data size:" << Utility::format("{:.1f}", totalSceneDataSize/1024.0f) << "kB";
for(const ObjectInfo& info: objectInfos) {
/* If --object-hierarchy was specified, the object list was printed as part
of the scene already */
if(!args.isSet("object-hierarchy")) for(const ObjectInfo& info: objectInfos) {
/* Objects without a name and not referenced by any scenes are useless,
ignore */
if(!info.name && !info.scenes) continue;
@ -670,24 +734,7 @@ bool printInfo(const Debug::Flags useColor, const bool useColor24, const Utility
<< info.name << Debug::resetColor;
if(info.scenes) {
d << Debug::newline << " Fields:";
for(std::size_t i = 0; i != info.fields.size(); ++i) {
if(i) d << Debug::nospace << ",";
const Containers::Pair<Trade::SceneField, UnsignedInt> nameCount = info.fields[i];
d << Debug::color(Debug::Color::Cyan);
if(Trade::isSceneFieldCustom(nameCount.first())) {
d << "Custom(" << Debug::nospace
<< Trade::sceneFieldCustom(nameCount.first())
<< Debug::nospace << ":" << Debug::nospace
<< Debug::color(Debug::Color::Yellow)
<< sceneFieldNames[sceneFieldCustom(nameCount.first())]
<< Debug::nospace
<< Debug::color(Debug::Color::Cyan) << ")";
} else d << Debug::packed << nameCount.first();
if(nameCount.second() != 1)
d << Debug::nospace << Utility::format("[{}]", nameCount.second());
d << Debug::resetColor;
}
printObjectFieldInfo(d, info);
}
}

4
src/Magnum/SceneTools/Test/CMakeLists.txt

@ -67,6 +67,10 @@ corrade_add_test(SceneToolsSceneConverterImple___Test SceneConverterImplementati
SceneConverterImplementationTestFiles/info-meshes-bounds.txt
SceneConverterImplementationTestFiles/info-meshes.txt
SceneConverterImplementationTestFiles/info-objects.txt
SceneConverterImplementationTestFiles/info-object-hierarchy.txt
SceneConverterImplementationTestFiles/info-object-hierarchy-no-parents.txt
SceneConverterImplementationTestFiles/info-object-hierarchy-only-objects.txt
SceneConverterImplementationTestFiles/info-object-hierarchy-only-objects-no-parents.txt
SceneConverterImplementationTestFiles/info-references.txt
SceneConverterImplementationTestFiles/info-scenes.txt
SceneConverterImplementationTestFiles/info-scenes-no-default.txt

79
src/Magnum/SceneTools/Test/SceneConverterImplementationTest.cpp

@ -76,15 +76,47 @@ using namespace Math::Literals;
const struct {
const char* name;
const char* arg;
Containers::Array<const char*> args;
const char* expected;
Int defaultScene;
bool printVisualCheck;
bool omitParent;
} InfoScenesObjectsData[]{
{"", "--info", "info-scenes-objects.txt", 1, true},
{"only scenes", "--info-scenes", "info-scenes.txt", 0, false},
{"only scenes, no default scene", "--info-scenes", "info-scenes-no-default.txt", -1, false},
{"only objects", "--info-objects", "info-objects.txt", 1, false}
{"all", {InPlaceInit, {
"", "--info"
}}, "info-scenes-objects.txt", 1, true, false},
{"both", {InPlaceInit, {
"", "--info-objects", "--info-scenes"
}}, "info-scenes-objects.txt", 1, false, false},
{"only scenes", {InPlaceInit, {
"", "--info-scenes"
}}, "info-scenes.txt", 0, false, false},
{"only scenes, no default scene", {InPlaceInit, {
"", "--info-scenes"
}}, "info-scenes-no-default.txt", -1, false, false},
{"only objects", {InPlaceInit, {
"", "--info-objects"
}}, "info-objects.txt", 1, false, false},
{"object hierarchy, all", {InPlaceInit, {
"", "--info", "--object-hierarchy"
}}, "info-object-hierarchy.txt", -1, true, false},
{"object hierarchy, both", {InPlaceInit, {
"", "--info-objects", "--info-scenes", "--object-hierarchy"
}}, "info-object-hierarchy.txt", -1, false, false},
{"object hierarchy, no parents", {InPlaceInit, {
"", "--info", "--object-hierarchy"
}}, "info-object-hierarchy-no-parents.txt", -1, false, true},
{"object hierarchy, only scenes", {InPlaceInit, {
/* --object-hierarchy is only used if --info-objects is present
so this is the same as just --info-scenes alone */
"", "--info-scenes", "--object-hierarchy"
}}, "info-scenes-no-default.txt", -1, false, false},
{"object hierarchy, only objects", {InPlaceInit, {
"", "--info-objects", "--object-hierarchy"
}}, "info-object-hierarchy-only-objects.txt", -1, true, false},
{"object hierarchy, only objects, no parents", {InPlaceInit, {
"", "--info-objects", "--object-hierarchy"
}}, "info-object-hierarchy-only-objects-no-parents.txt", -1, false, true},
};
const struct {
@ -133,7 +165,8 @@ SceneConverterImplementationTest::SceneConverterImplementationTest() {
.addBooleanOption("info-meshes")
.addBooleanOption("info-textures")
.addBooleanOption("info-images")
.addBooleanOption("bounds");
.addBooleanOption("bounds")
.addBooleanOption("object-hierarchy");
/* Load the plugin directly from the build tree. Otherwise it's static and
already loaded. */
@ -200,7 +233,7 @@ void SceneConverterImplementationTest::infoScenesObjects() {
setTestCaseDescription(data.name);
struct Importer: Trade::AbstractImporter {
explicit Importer(Int defaultScene): _defaultScene{defaultScene} {}
explicit Importer(Int defaultScene, bool omitParent): _defaultScene{defaultScene}, _omitParent{omitParent} {}
Trade::ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
@ -236,24 +269,27 @@ void SceneConverterImplementationTest::infoScenesObjects() {
Containers::ArrayView<UnsignedInt> meshMapping;
Containers::ArrayView<UnsignedInt> meshes;
Containers::ArrayTuple data{
{NoInit, 3, parentMapping},
{ValueInit, 3, parents},
{NoInit, 5, parentMapping},
{NoInit, 5, parents},
{NoInit, 4, meshMapping},
{ValueInit, 4, meshes},
};
Utility::copy({1, 3, 2}, parentMapping);
Utility::copy({1, 2, 5, 4, 0}, parentMapping);
Utility::copy({2, -1, 1, 2, 5}, parents);
Utility::copy({2, 0, 2, 1}, meshMapping);
/* No need to fill the data, zero-init is fine */
return Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 4, std::move(data), {
Trade::SceneFieldData{Trade::SceneField::Parent, parentMapping, parents},
/* No need to fill the other data, zero-init is fine */
return Trade::SceneData{Trade::SceneMappingType::UnsignedInt, 6, std::move(data), {
Trade::SceneFieldData{_omitParent ? Trade::sceneFieldCustom(0) : Trade::SceneField::Parent, parentMapping, parents},
Trade::SceneFieldData{Trade::SceneField::Mesh, meshMapping, meshes, Trade::SceneFieldFlag::OrderedMapping},
}};
}
/* Two custom fields, one array. Stored as an external memory. */
/* Two custom fields, one array, parent. Stored as an external
memory. */
if(id == 1) {
return Trade::SceneData{Trade::SceneMappingType::UnsignedByte, 8, Trade::DataFlag::ExternallyOwned|Trade::DataFlag::Mutable, scene2Data, {
Trade::SceneFieldData{Trade::sceneFieldCustom(42), Containers::arrayView(scene2Data->customMapping), Containers::arrayView(scene2Data->custom)},
Trade::SceneFieldData{_omitParent ? Trade::sceneFieldCustom(0) : Trade::SceneField::Parent, Containers::arrayView(scene2Data->parentCustomMapping), Containers::arrayView(scene2Data->parent)},
Trade::SceneFieldData{Trade::sceneFieldCustom(42), Containers::arrayView(scene2Data->parentCustomMapping), Containers::arrayView(scene2Data->custom)},
Trade::SceneFieldData{Trade::sceneFieldCustom(1337), Trade::SceneMappingType::UnsignedByte, scene2Data->customArrayMapping, Trade::SceneFieldType::Short, scene2Data->customArray, 3},
}};
}
@ -262,20 +298,21 @@ void SceneConverterImplementationTest::infoScenesObjects() {
}
struct {
UnsignedByte customMapping[2];
UnsignedByte parentCustomMapping[2];
Int parent[2];
Double custom[2];
UnsignedByte customArrayMapping[3];
Vector3s customArray[3];
} scene2Data[1]{{
/* No need to fill the data, zero-init is fine */
{7, 3}, {}, {2, 4, 4}, {}
/* No need to fill data other than parents, zero-init is fine */
{7, 3}, {3, -1}, {}, {2, 4, 4}, {}
}};
Int _defaultScene;
} importer{data.defaultScene};
bool _omitParent;
} importer{data.defaultScene, data.omitParent};
const char* argv[]{"", data.arg};
CORRADE_VERIFY(_infoArgs.tryParse(Containers::arraySize(argv), argv));
CORRADE_VERIFY(_infoArgs.tryParse(data.args.size(), data.args));
std::chrono::high_resolution_clock::duration time;

14
src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-object-hierarchy-no-parents.txt

@ -0,0 +1,14 @@
Scene 0: A simple scene
Bound: 6 objects @ UnsignedInt (0.1 kB)
Fields:
Custom(0:) @ Int, 5 entries
Mesh @ UnsignedInt, OrderedMapping, 4 entries
Object hierarchy:
Scene 1:
Bound: 8 objects @ UnsignedByte (0.1 kB, ExternallyOwned|Mutable)
Fields:
Custom(0:) @ Int, 2 entries
Custom(42:) @ Double, 2 entries
Custom(1337:directionVector) @ Short[3], 3 entries
Object hierarchy:
Total scene data size: 0.1 kB

7
src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-object-hierarchy-only-objects-no-parents.txt

@ -0,0 +1,7 @@
Scene 0: A simple scene
Bound: 6 objects @ UnsignedInt (0.1 kB)
Object hierarchy:
Scene 1:
Bound: 8 objects @ UnsignedByte (0.1 kB, ExternallyOwned|Mutable)
Object hierarchy:
Total scene data size: 0.1 kB

14
src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-object-hierarchy-only-objects.txt

@ -0,0 +1,14 @@
Scene 0: A simple scene
Bound: 6 objects @ UnsignedInt (0.1 kB)
Object hierarchy:
Object 2: Two meshes, shared among two scenes
Object 1:
Object 5:
Object 0: Parent-less mesh
Object 4: Two custom arrays
Scene 1:
Bound: 8 objects @ UnsignedByte (0.1 kB, ExternallyOwned|Mutable)
Object hierarchy:
Object 3:
Object 7:
Total scene data size: 0.1 kB

28
src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-object-hierarchy.txt

@ -0,0 +1,28 @@
Scene 0: A simple scene
Bound: 6 objects @ UnsignedInt (0.1 kB)
Fields:
Parent @ Int, 5 entries
Mesh @ UnsignedInt, OrderedMapping, 4 entries
Object hierarchy:
Object 2: Two meshes, shared among two scenes
Fields: Parent, Mesh[2], Custom(1337:directionVector)
Object 1:
Fields: Parent, Mesh
Object 5:
Fields: Parent
Object 0: Parent-less mesh
Fields: Parent, Mesh
Object 4: Two custom arrays
Fields: Parent, Custom(1337:directionVector)[2]
Scene 1:
Bound: 8 objects @ UnsignedByte (0.1 kB, ExternallyOwned|Mutable)
Fields:
Parent @ Int, 2 entries
Custom(42:) @ Double, 2 entries
Custom(1337:directionVector) @ Short[3], 3 entries
Object hierarchy:
Object 3:
Fields: Parent, Custom(42:)
Object 7:
Fields: Parent, Custom(42:)
Total scene data size: 0.1 kB

7
src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes-no-default.txt

@ -1,11 +1,12 @@
Scene 0: A simple scene
Bound: 4 objects @ UnsignedInt (0.1 kB)
Bound: 6 objects @ UnsignedInt (0.1 kB)
Fields:
Parent @ Int, 3 entries
Parent @ Int, 5 entries
Mesh @ UnsignedInt, OrderedMapping, 4 entries
Scene 1:
Bound: 8 objects @ UnsignedByte (0.0 kB, ExternallyOwned|Mutable)
Bound: 8 objects @ UnsignedByte (0.1 kB, ExternallyOwned|Mutable)
Fields:
Parent @ Int, 2 entries
Custom(42:) @ Double, 2 entries
Custom(1337:directionVector) @ Short[3], 3 entries
Total scene data size: 0.1 kB

19
src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes-objects.txt

@ -1,26 +1,29 @@
Default scene: 1
Scene 0: A simple scene
Bound: 4 objects @ UnsignedInt (0.1 kB)
Bound: 6 objects @ UnsignedInt (0.1 kB)
Fields:
Parent @ Int, 3 entries
Parent @ Int, 5 entries
Mesh @ UnsignedInt, OrderedMapping, 4 entries
Scene 1:
Bound: 8 objects @ UnsignedByte (0.0 kB, ExternallyOwned|Mutable)
Bound: 8 objects @ UnsignedByte (0.1 kB, ExternallyOwned|Mutable)
Fields:
Parent @ Int, 2 entries
Custom(42:) @ Double, 2 entries
Custom(1337:directionVector) @ Short[3], 3 entries
Total scene data size: 0.1 kB
Object 0 (referenced by 1 scenes): Parent-less mesh
Fields: Mesh
Fields: Parent, Mesh
Object 1 (referenced by 1 scenes):
Fields: Parent, Mesh
Object 2 (referenced by 2 scenes): Two meshes, shared among two scenes
Fields: Parent, Mesh[2], Custom(1337:directionVector)
Object 3 (referenced by 2 scenes):
Object 3 (referenced by 1 scenes):
Fields: Parent, Custom(42:)
Object 4 (referenced by 1 scenes): Two custom arrays
Fields: Custom(1337:directionVector)[2]
Object 4 (referenced by 2 scenes): Two custom arrays
Fields: Parent, Custom(1337:directionVector)[2]
Object 5 (referenced by 1 scenes):
Fields: Parent
Object 6 (referenced by 0 scenes): Only in the second scene, but no fields, thus same as unreferenced
Object 7 (referenced by 1 scenes):
Fields: Custom(42:)
Fields: Parent, Custom(42:)
Object 8 (referenced by 0 scenes): Not in any scene

7
src/Magnum/SceneTools/Test/SceneConverterImplementationTestFiles/info-scenes.txt

@ -1,12 +1,13 @@
Default scene: 0
Scene 0: A simple scene
Bound: 4 objects @ UnsignedInt (0.1 kB)
Bound: 6 objects @ UnsignedInt (0.1 kB)
Fields:
Parent @ Int, 3 entries
Parent @ Int, 5 entries
Mesh @ UnsignedInt, OrderedMapping, 4 entries
Scene 1:
Bound: 8 objects @ UnsignedByte (0.0 kB, ExternallyOwned|Mutable)
Bound: 8 objects @ UnsignedByte (0.1 kB, ExternallyOwned|Mutable)
Fields:
Parent @ Int, 2 entries
Custom(42:) @ Double, 2 entries
Custom(1337:directionVector) @ Short[3], 3 entries
Total scene data size: 0.1 kB

4
src/Magnum/SceneTools/sceneconverter.cpp

@ -194,7 +194,7 @@ magnum-sceneconverter [-h|--help] [-I|--importer PLUGIN]
[--info-images] [--info-lights] [--info-cameras] [--info-materials]
[--info-meshes] [--info-objects] [--info-scenes] [--info-skins]
[--info-textures] [--info] [--color on|4bit|off|auto] [--bounds]
[-v|--verbose] [--profile] [--] input output
[--object-hierarchy] [-v|--verbose] [--profile] [--] input output
@endcode
Arguments:
@ -263,6 +263,7 @@ Arguments:
as specifying all other data-related `--info-*` options together
- `--color` --- colored output for `--info` (default: `auto`)
- `--bounds` --- show bounds of known attributes in `--info` output
- `--object-hierarchy` --- visualize object hierarchy in `--info` output
- `-v`, `--verbose` --- verbose output from importer and converter plugins
- `--profile` --- measure import and conversion time
@ -451,6 +452,7 @@ int main(int argc, char** argv) {
.addBooleanOption("info").setHelp("info", "print info about everything in the input file and exit, same as specifying all other data-related --info-* options together")
.addOption("color", "auto").setHelp("color", "colored output for --info", "on|4bit|off|auto")
.addBooleanOption("bounds").setHelp("bounds", "show bounds of known attributes in --info output")
.addBooleanOption("object-hierarchy").setHelp("object-hierarchy", "visualize object hierarchy in --info output")
.addBooleanOption('v', "verbose").setHelp("verbose", "verbose output from importer and converter plugins")
.addBooleanOption("profile").setHelp("profile", "measure import and conversion time")
.setParseErrorCallback([](const Utility::Arguments& args, Utility::Arguments::ParseError error, const std::string& key) {

Loading…
Cancel
Save