Browse Source

sceneconverter: add a --bounds option.

pull/461/head
Vladimír Vondruš 6 years ago
parent
commit
cf4dc69f0d
  1. 5
      doc/changelog.dox
  2. 66
      src/Magnum/MeshTools/sceneconverter.cpp

5
doc/changelog.dox

@ -46,6 +46,11 @@ See also:
@subsection changelog-latest-changes Changes and improvements
@subsubsection changelog-latest-changes-meshtools MeshTools library
- Added a `--bounds` option to @ref magnum-sceneconverter "magnum-sceneconverter",
showing data ranges of known attributes
@subsubsection changelog-latest-changes-trade Trade library
- Recognizing TIFF file header magic in @ref Trade::AnyImageImporter "AnyImageImporter"

66
src/Magnum/MeshTools/sceneconverter.cpp

@ -26,6 +26,7 @@
#include <algorithm>
#include <chrono>
#include <set>
#include <sstream>
#include <Corrade/Containers/Optional.h>
#include <Corrade/Utility/Arguments.h>
#include <Corrade/Utility/DebugStl.h>
@ -34,6 +35,8 @@
#include <Corrade/Utility/String.h>
#include "Magnum/PixelFormat.h"
#include "Magnum/Math/Color.h"
#include "Magnum/Math/FunctionsBatch.h"
#include "Magnum/MeshTools/RemoveDuplicates.h"
#include "Magnum/Trade/AbstractImporter.h"
#include "Magnum/Trade/MeshData.h"
@ -72,7 +75,8 @@ magnum-sceneconverter [-h|--help] [--importer IMPORTER]
[--remove-duplicates-fuzzy EPSILON]
[-i|--importer-options key=val,key2=val2,]
[-c|--converter-options key=val,key2=val2,]... [--mesh MESH]
[--level LEVEL][--info] [-v|--verbose] [--profile] [--] input output
[--level LEVEL] [--info] [--bounds] [-v|--verbose] [--profile]
[--] input output
@endcode
Arguments:
@ -98,6 +102,7 @@ Arguments:
- `--mesh MESH` --- mesh to import (default: `0`)
- `--level LEVEL` --- mesh level to import (default: `0`)
- `--info` --- print info about the input file and exit
- `--bounds` --- show bounds of known attributes in `--info` output
- `-v`, `--verbose` --- verbose output from importer and converter plugins
- `--profile` --- measure import and conversion time
@ -168,6 +173,23 @@ struct Duration {
std::chrono::high_resolution_clock::time_point _t;
};
/** @todo const Array& doesn't work, minmax() would fail to match */
template<class T> std::string calculateBounds(Containers::Array<T>&& attribute) {
/** @todo clean up when Debug::toString() exists */
std::ostringstream out;
Debug{&out, Debug::Flag::NoNewlineAtTheEnd} << Math::minmax(attribute);
return out.str();
}
/* Named attribute index from a global index */
/** @todo some helper for this directly on the MeshData class? */
UnsignedInt namedAttributeId(const Trade::MeshData& mesh, UnsignedInt id) {
const Trade::MeshAttribute name = mesh.attributeName(id);
for(UnsignedInt i = 0; i != mesh.attributeCount(name); ++i)
if(mesh.attributeId(name, i) == id) return i;
CORRADE_INTERNAL_ASSERT_UNREACHABLE();
}
}
int main(int argc, char** argv) {
@ -185,6 +207,7 @@ int main(int argc, char** argv) {
.addOption("mesh", "0").setHelp("mesh", "mesh to import")
.addOption("level", "0").setHelp("level", "mesh level to import")
.addBooleanOption("info").setHelp("info", "print info about the input file and exit")
.addBooleanOption("bounds").setHelp("bounds", "show bounds of known attributes 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) {
@ -251,6 +274,7 @@ save its output; if no --converter is specified, AnySceneConverter is used.)")
Trade::MeshAttribute name;
std::string customName;
VertexFormat format;
std::string bounds;
};
struct MeshInfo {
@ -306,13 +330,49 @@ save its output; if no --converter is specified, AnySceneConverter is used.)")
}
for(UnsignedInt k = 0; k != mesh->attributeCount(); ++k) {
const Trade::MeshAttribute name = mesh->attributeName(k);
/* Calculate bounds, if requested and this is not an
implementation-specific format */
std::string bounds;
if(args.isSet("bounds") && !isVertexFormatImplementationSpecific(mesh->attributeFormat(k))) switch(name) {
case Trade::MeshAttribute::Position:
bounds = calculateBounds(mesh->positions3DAsArray(namedAttributeId(*mesh, k)));
break;
case Trade::MeshAttribute::Tangent:
bounds = calculateBounds(mesh->tangentsAsArray(namedAttributeId(*mesh, k)));
break;
case Trade::MeshAttribute::Bitangent:
bounds = calculateBounds(mesh->bitangentsAsArray(namedAttributeId(*mesh, k)));
break;
case Trade::MeshAttribute::Normal:
bounds = calculateBounds(mesh->normalsAsArray(namedAttributeId(*mesh, k)));
break;
case Trade::MeshAttribute::TextureCoordinates:
bounds = calculateBounds(mesh->textureCoordinates2DAsArray(namedAttributeId(*mesh, k)));
break;
case Trade::MeshAttribute::Color:
bounds = calculateBounds(mesh->colorsAsArray(namedAttributeId(*mesh, k)));
break;
case Trade::MeshAttribute::ObjectId:
Debug{} << mesh->objectIdsAsArray(namedAttributeId(*mesh, k));
bounds = calculateBounds(mesh->objectIdsAsArray(namedAttributeId(*mesh, k)));
break;
/* And also all other custom attribs. Not saying
default: here so we get notified when we forget to
handle newly added attribute names */
case Trade::MeshAttribute::Custom:
break;
}
arrayAppend(info.attributes, Containers::InPlaceInit,
mesh->attributeOffset(k),
mesh->attributeStride(k),
mesh->attributeArraySize(k),
name, Trade::isMeshAttributeCustom(name) ?
importer->meshAttributeName(name) : "",
mesh->attributeFormat(k));
mesh->attributeFormat(k),
bounds);
}
std::sort(info.attributes.begin(), info.attributes.end(),
@ -363,6 +423,8 @@ save its output; if no --converter is specified, AnySceneConverter is used.)")
}
d << "@" << attribute.format << Debug::nospace << ", stride"
<< attribute.stride;
if(!attribute.bounds.empty())
d << Debug::newline << " bounds:" << attribute.bounds;
}
}
for(const Trade::Implementation::ImageInfo& info: imageInfos) {

Loading…
Cancel
Save