Skip to content

Commit

Permalink
sceneconverter: print contents of the new SceneData.
Browse files Browse the repository at this point in the history
Was waiting for this to happen, as going through all the objects would
have been too messy. Plugins implemented using the legacy API will
now only show the parent field in SceneData, but since those eventually
get all ported, that's fine.
  • Loading branch information
mosra committed Oct 4, 2021
1 parent 2f2fcfe commit 21ef8f3
Showing 1 changed file with 89 additions and 22 deletions.
111 changes: 89 additions & 22 deletions src/Magnum/MeshTools/sceneconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <set>
#include <sstream>
#include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/Pair.h>
#include <Corrade/Utility/Arguments.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/Directory.h>
Expand All @@ -44,7 +45,7 @@
#include "Magnum/Trade/LightData.h"
#include "Magnum/Trade/MaterialData.h"
#include "Magnum/Trade/MeshData.h"
#include "Magnum/Trade/MeshObjectData3D.h"
#include "Magnum/Trade/SceneData.h"
#include "Magnum/Trade/SkinData.h"
#include "Magnum/Trade/TextureData.h"
#include "Magnum/Trade/AbstractSceneConverter.h"
Expand Down Expand Up @@ -338,30 +339,75 @@ used.)")
std::string name;
};

struct SceneFieldInfo {
Trade::SceneField name;
std::string customName;
Trade::SceneFieldType type;
UnsignedInt arraySize;
std::size_t size;
};

struct SceneInfo {
UnsignedInt scene;
Trade::SceneObjectType objectType;
UnsignedLong objectCount;
Containers::Array<SceneFieldInfo> fields;
std::size_t dataSize;
std::string name;
/** @todo object names? */
};

/* Parse everything first to avoid errors interleaved with output */

/* Scene properties. Currently just counting how much is each mesh /
light / material shared. Texture reference count is calculated when
parsing materials. */
/* Scene properties, together with counting how much is each mesh /
light / material / skin shared. Texture reference count is
calculated when parsing materials. */
Containers::Array<SceneInfo> sceneInfos;
Containers::Array<UnsignedInt> materialReferenceCount{importer->materialCount()};
Containers::Array<UnsignedInt> lightReferenceCount{importer->lightCount()};
Containers::Array<UnsignedInt> meshReferenceCount{importer->meshCount()};
Containers::Array<UnsignedInt> skinReferenceCount{importer->skin3DCount()};
for(UnsignedInt i = 0; i != importer->object3DCount(); ++i) {
Containers::Pointer<Trade::ObjectData3D> object = importer->object3D(i);
if(!object) continue;
if(object->instanceType() == Trade::ObjectInstanceType3D::Mesh) {
auto& meshObject = static_cast<Trade::MeshObjectData3D&>(*object);
if(std::size_t(meshObject.instance()) < meshReferenceCount.size())
++meshReferenceCount[meshObject.instance()];
if(std::size_t(meshObject.material()) < materialReferenceCount.size())
++materialReferenceCount[meshObject.material()];
if(std::size_t(meshObject.skin()) < skinReferenceCount.size())
++skinReferenceCount[meshObject.skin()];
} else if(object->instanceType() == Trade::ObjectInstanceType3D::Light) {
if(std::size_t(object->instance()) < lightReferenceCount.size())
++lightReferenceCount[object->instance()];
for(UnsignedInt i = 0; i != importer->sceneCount(); ++i) {
Containers::Optional<Trade::SceneData> scene = importer->scene(i);
if(!scene) continue;

SceneInfo info{};
info.scene = i;
info.objectType = scene->objectType();
info.objectCount = scene->objectCount();
info.dataSize = scene->data().size();
info.name = importer->sceneName(i);
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, Int>& meshMaterial: scene->meshesMaterialsAsArray()) {
if(meshMaterial.first() < meshReferenceCount.size())
++meshReferenceCount[meshMaterial.first()];
if(UnsignedInt(meshMaterial.second()) < materialReferenceCount.size())
++materialReferenceCount[meshMaterial.second()];
}

if(name == Trade::SceneField::Skin) for(const UnsignedInt skin: scene->skinsAsArray()) {
if(skin < skinReferenceCount.size())
++skinReferenceCount[skin];
/** @todo 2D/3D distinction */
}

if(name == Trade::SceneField::Light) for(const UnsignedInt light: scene->lightsAsArray()) {
if(light < lightReferenceCount.size())
++lightReferenceCount[light];
}

arrayAppend(info.fields, InPlaceInit,
name,
Trade::isSceneFieldCustom(name) ?
importer->sceneFieldName(name) : "",
scene->fieldType(j),
scene->fieldArraySize(j),
scene->fieldSize(j));
}

arrayAppend(sceneInfos, std::move(info));
}

/* Animation properties */
Expand Down Expand Up @@ -573,6 +619,27 @@ used.)")
Containers::Array<Trade::Implementation::ImageInfo> imageInfos =
Trade::Implementation::imageInfo(*importer, error, compactImages);

for(const SceneInfo& info: sceneInfos) {
Debug d;
d << "Scene" << info.scene << Debug::nospace << ":";
if(!info.name.empty()) d << info.name;
d << Debug::newline;
d << " " << info.objectCount << "objects," << info.objectType
<< "(" << Debug::nospace << Utility::formatString("{:.1f}", info.dataSize/1024.0f) << "kB)";

for(const SceneFieldInfo& field: info.fields) {
d << Debug::newline << " " << field.name;
if(Trade::isSceneFieldCustom(field.name)) {
d << "(" << Debug::nospace << field.customName
<< Debug::nospace << ")";
}
d << "@" << field.type;
if(field.arraySize)
d << Debug::nospace << Utility::formatString("[{}]", field.arraySize);
d << Debug::nospace << "," << field.size << "entries";
}
}

for(const AnimationInfo& info: animationInfos) {
Debug d;
d << "Animation" << info.animation << Debug::nospace << ":";
Expand Down Expand Up @@ -606,7 +673,7 @@ used.)")
d << "Skin" << info.skin;
/* Print reference count only if there actually is a scene,
otherwise this information is useless */
if(importer->object3DCount())
if(importer->objectCount())
d << Utility::formatString("(referenced by {} objects)", info.references);
d << Debug::nospace << ":";
if(!info.name.empty()) d << info.name;
Expand All @@ -619,7 +686,7 @@ used.)")
d << "Light" << info.light;
/* Print reference count only if there actually is a scene,
otherwise this information is useless */
if(importer->object3DCount())
if(importer->objectCount())
d << Utility::formatString("(referenced by {} objects)", info.references);
d << Debug::nospace << ":";
if(!info.name.empty()) d << info.name;
Expand All @@ -638,7 +705,7 @@ used.)")
d << "Material" << info.material;
/* Print reference count only if there actually is a scene,
otherwise this information is useless */
if(importer->object3DCount())
if(importer->objectCount())
d << Utility::formatString("(referenced by {} objects)", info.references);
d << Debug::nospace << ":";
if(!info.name.empty()) d << info.name;
Expand Down Expand Up @@ -721,7 +788,7 @@ used.)")
d << "Mesh" << info.mesh;
/* Print reference count only if there actually is a scene,
otherwise this information is useless */
if(importer->object3DCount())
if(importer->objectCount())
d << Utility::formatString("(referenced by {} objects)", info.references);
d << Debug::nospace << ":";
if(!info.name.empty()) d << info.name;
Expand Down

0 comments on commit 21ef8f3

Please sign in to comment.