|
|
|
|
@ -29,6 +29,7 @@
|
|
|
|
|
#include <Corrade/TestSuite/Tester.h> |
|
|
|
|
#include <Corrade/TestSuite/Compare/Container.h> |
|
|
|
|
#include <Corrade/Utility/DebugStl.h> |
|
|
|
|
#include <Corrade/Utility/FormatStl.h> |
|
|
|
|
#include <Corrade/Utility/Path.h> |
|
|
|
|
|
|
|
|
|
#include "Magnum/Mesh.h" |
|
|
|
|
@ -43,55 +44,38 @@ namespace Magnum { namespace Trade { namespace Test { namespace {
|
|
|
|
|
struct ObjImporterTest: TestSuite::Tester { |
|
|
|
|
explicit ObjImporterTest(); |
|
|
|
|
|
|
|
|
|
void pointMesh(); |
|
|
|
|
void lineMesh(); |
|
|
|
|
void triangleMesh(); |
|
|
|
|
void mixedPrimitives(); |
|
|
|
|
void empty(); |
|
|
|
|
|
|
|
|
|
void positionsOnly(); |
|
|
|
|
void textureCoordinates(); |
|
|
|
|
void normals(); |
|
|
|
|
void textureCoordinatesNormals(); |
|
|
|
|
void meshPrimitivePoints(); |
|
|
|
|
void meshPrimitiveLines(); |
|
|
|
|
void meshPrimitiveTriangles(); |
|
|
|
|
|
|
|
|
|
/* Positions alone are tested above */ |
|
|
|
|
void meshPositionsOptionalCoordinate(); |
|
|
|
|
void meshTextureCoordinates(); |
|
|
|
|
void meshTextureCoordinatesOptionalCoordinate(); |
|
|
|
|
void meshNormals(); |
|
|
|
|
void meshTextureCoordinatesNormals(); |
|
|
|
|
|
|
|
|
|
void meshIgnoredKeyword(); |
|
|
|
|
|
|
|
|
|
void meshNamed(); |
|
|
|
|
void meshNamedFirstUnnamed(); |
|
|
|
|
|
|
|
|
|
void emptyFile(); |
|
|
|
|
void unnamedMesh(); |
|
|
|
|
void namedMesh(); |
|
|
|
|
void moreMeshes(); |
|
|
|
|
void unnamedFirstMesh(); |
|
|
|
|
|
|
|
|
|
void wrongFloat(); |
|
|
|
|
void wrongInteger(); |
|
|
|
|
void unmergedIndexOutOfRange(); |
|
|
|
|
void mergedIndexOutOfRange(); |
|
|
|
|
void zeroIndex(); |
|
|
|
|
|
|
|
|
|
void explicitOptionalPositionCoordinate(); |
|
|
|
|
void explicitOptionalTextureCoordinate(); |
|
|
|
|
void unsupportedOptionalPositionCoordinate(); |
|
|
|
|
void unsupportedOptionalTextureCoordinate(); |
|
|
|
|
|
|
|
|
|
void shortFloatData(); |
|
|
|
|
void longFloatData(); |
|
|
|
|
void longOptionalFloatData(); |
|
|
|
|
|
|
|
|
|
void longIndexData(); |
|
|
|
|
void wrongPointIndexData(); |
|
|
|
|
void wrongLineIndexData(); |
|
|
|
|
void wrongTriangleIndexData(); |
|
|
|
|
void polygonIndexData(); |
|
|
|
|
|
|
|
|
|
void missingPositionData(); |
|
|
|
|
void missingNormalData(); |
|
|
|
|
void missingTextureCoordinateData(); |
|
|
|
|
void missingPositionIndices(); |
|
|
|
|
void missingNormalIndices(); |
|
|
|
|
void missingTextureCoordinateIndices(); |
|
|
|
|
|
|
|
|
|
void wrongTextureCoordinateIndexCount(); |
|
|
|
|
void wrongNormalIndexCount(); |
|
|
|
|
|
|
|
|
|
void unsupportedKeyword(); |
|
|
|
|
void unknownKeyword(); |
|
|
|
|
|
|
|
|
|
/* Technically, all invalid cases could be put into a single file, but
|
|
|
|
|
because the indexing is global, it would get increasingly hard to |
|
|
|
|
maintain. So it's instead grouped into files by a common error scenario |
|
|
|
|
with each case testing one file and just the invalid() case testing |
|
|
|
|
separate files. */ |
|
|
|
|
void invalid(); |
|
|
|
|
void invalidMixedPrimitives(); |
|
|
|
|
void invalidNumbers(); |
|
|
|
|
void invalidNumberCount(); |
|
|
|
|
void invalidInconsistentIndexTuple(); |
|
|
|
|
void invalidIncompleteData(); |
|
|
|
|
void invalidOptionalCoordinate(); |
|
|
|
|
|
|
|
|
|
void openTwice(); |
|
|
|
|
void importTwice(); |
|
|
|
|
@ -100,58 +84,133 @@ struct ObjImporterTest: TestSuite::Tester {
|
|
|
|
|
PluginManager::Manager<AbstractImporter> _manager{"nonexistent"}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const struct { |
|
|
|
|
const char* name; |
|
|
|
|
const char* filename; |
|
|
|
|
} MeshNamedFirstUnnamedData[]{ |
|
|
|
|
{"", "mesh-named-first-unnamed.obj"}, |
|
|
|
|
{"index first", "mesh-named-first-unnamed-index-first.obj"}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const struct { |
|
|
|
|
const char* name; |
|
|
|
|
const char* filename; |
|
|
|
|
const char* message; |
|
|
|
|
} InvalidData[]{ |
|
|
|
|
{"unknown keyword", "invalid-keyword.obj", |
|
|
|
|
"unknown keyword bleh"} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const struct { |
|
|
|
|
const char* name; |
|
|
|
|
const char* message; |
|
|
|
|
} InvalidMixedPrimitivesData[]{ |
|
|
|
|
{"points after some other", |
|
|
|
|
"mixed primitive MeshPrimitive::Triangles and MeshPrimitive::Points"}, |
|
|
|
|
{"lines after some other", |
|
|
|
|
"mixed primitive MeshPrimitive::Points and MeshPrimitive::Lines"}, |
|
|
|
|
{"triangles after some other", |
|
|
|
|
"mixed primitive MeshPrimitive::Lines and MeshPrimitive::Triangles"}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const struct { |
|
|
|
|
const char* name; |
|
|
|
|
const char* message; |
|
|
|
|
} InvalidNumbersData[]{ |
|
|
|
|
{"invalid float literal", "error while converting numeric data"}, |
|
|
|
|
{"invalid integer literal", "error while converting numeric data"}, |
|
|
|
|
{"position index out of range", "index 1 out of range for 1 vertices"}, |
|
|
|
|
{"texture index out of range", "index 4 out of range for 3 vertices"}, |
|
|
|
|
{"normal index out of range", "index 3 out of range for 2 vertices"}, |
|
|
|
|
{"zero index", "index 0 out of range for 1 vertices"} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const struct { |
|
|
|
|
const char* name; |
|
|
|
|
const char* message; |
|
|
|
|
} InvalidNumberCountData[]{ |
|
|
|
|
{"two-component position", "invalid float array size"}, |
|
|
|
|
{"five-component position with optional fourth component", "invalid float array size"}, |
|
|
|
|
{"four-component normal", "invalid float array size"}, |
|
|
|
|
{"four-component index tuple", "invalid index data"}, |
|
|
|
|
{"point with two indices", "wrong index count for point"}, |
|
|
|
|
{"line with one index", "wrong index count for line"}, |
|
|
|
|
{"triangle with two indices", "wrong index count for triangle"}, |
|
|
|
|
{"quad", "polygons are not supported"} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const struct { |
|
|
|
|
const char* name; |
|
|
|
|
const char* message; |
|
|
|
|
} InvalidInconsistentIndexTupleData[]{ |
|
|
|
|
{"missing normal reference", "some normal indices are missing"}, |
|
|
|
|
{"missing texture reference", "some texture coordinate indices are missing"}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const struct { |
|
|
|
|
const char* name; |
|
|
|
|
const char* message; |
|
|
|
|
} InvalidIncompleteDataData[]{ |
|
|
|
|
{"missing position data", "incomplete position data"}, |
|
|
|
|
{"missing position indices", "incomplete position data"}, |
|
|
|
|
{"missing normal data", "incomplete normal data"}, |
|
|
|
|
{"missing normal indices", "incomplete normal data"}, |
|
|
|
|
{"missing texture coordinate data", "incomplete texture coordinate data"}, |
|
|
|
|
{"missing texture coordinate indices", "incomplete texture coordinate data"}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const struct { |
|
|
|
|
const char* name; |
|
|
|
|
const char* message; |
|
|
|
|
} InvalidOptionalCoordinateData[]{ |
|
|
|
|
{"position with optional fourth component not one", "homogeneous coordinates are not supported"}, |
|
|
|
|
{"texture with optional third component not zero", "3D texture coordinates are not supported"} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
ObjImporterTest::ObjImporterTest() { |
|
|
|
|
addTests({&ObjImporterTest::pointMesh, |
|
|
|
|
&ObjImporterTest::lineMesh, |
|
|
|
|
&ObjImporterTest::triangleMesh, |
|
|
|
|
&ObjImporterTest::mixedPrimitives, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::positionsOnly, |
|
|
|
|
&ObjImporterTest::textureCoordinates, |
|
|
|
|
&ObjImporterTest::normals, |
|
|
|
|
&ObjImporterTest::textureCoordinatesNormals, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::emptyFile, |
|
|
|
|
&ObjImporterTest::unnamedMesh, |
|
|
|
|
&ObjImporterTest::namedMesh, |
|
|
|
|
&ObjImporterTest::moreMeshes, |
|
|
|
|
&ObjImporterTest::unnamedFirstMesh, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::wrongFloat, |
|
|
|
|
&ObjImporterTest::wrongInteger, |
|
|
|
|
&ObjImporterTest::unmergedIndexOutOfRange, |
|
|
|
|
&ObjImporterTest::mergedIndexOutOfRange, |
|
|
|
|
&ObjImporterTest::zeroIndex, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::explicitOptionalPositionCoordinate, |
|
|
|
|
&ObjImporterTest::explicitOptionalTextureCoordinate, |
|
|
|
|
&ObjImporterTest::unsupportedOptionalPositionCoordinate, |
|
|
|
|
&ObjImporterTest::unsupportedOptionalTextureCoordinate, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::shortFloatData, |
|
|
|
|
&ObjImporterTest::longFloatData, |
|
|
|
|
&ObjImporterTest::longOptionalFloatData, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::longIndexData, |
|
|
|
|
&ObjImporterTest::wrongPointIndexData, |
|
|
|
|
&ObjImporterTest::wrongLineIndexData, |
|
|
|
|
&ObjImporterTest::wrongTriangleIndexData, |
|
|
|
|
&ObjImporterTest::polygonIndexData, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::missingPositionData, |
|
|
|
|
&ObjImporterTest::missingNormalData, |
|
|
|
|
&ObjImporterTest::missingTextureCoordinateData, |
|
|
|
|
&ObjImporterTest::missingPositionIndices, |
|
|
|
|
&ObjImporterTest::missingNormalIndices, |
|
|
|
|
&ObjImporterTest::missingTextureCoordinateIndices, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::wrongTextureCoordinateIndexCount, |
|
|
|
|
&ObjImporterTest::wrongNormalIndexCount, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::unsupportedKeyword, |
|
|
|
|
&ObjImporterTest::unknownKeyword, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::openTwice, |
|
|
|
|
addTests({&ObjImporterTest::empty, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::meshPrimitivePoints, |
|
|
|
|
&ObjImporterTest::meshPrimitiveLines, |
|
|
|
|
&ObjImporterTest::meshPrimitiveTriangles, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::meshPositionsOptionalCoordinate, |
|
|
|
|
&ObjImporterTest::meshTextureCoordinates, |
|
|
|
|
&ObjImporterTest::meshTextureCoordinatesOptionalCoordinate, |
|
|
|
|
&ObjImporterTest::meshNormals, |
|
|
|
|
&ObjImporterTest::meshTextureCoordinatesNormals, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::meshIgnoredKeyword, |
|
|
|
|
|
|
|
|
|
&ObjImporterTest::meshNamed}); |
|
|
|
|
|
|
|
|
|
addInstancedTests({&ObjImporterTest::meshNamedFirstUnnamed}, |
|
|
|
|
Containers::arraySize(MeshNamedFirstUnnamedData)); |
|
|
|
|
|
|
|
|
|
addTests({&ObjImporterTest::moreMeshes}); |
|
|
|
|
|
|
|
|
|
addInstancedTests({&ObjImporterTest::invalid}, |
|
|
|
|
Containers::arraySize(InvalidData)); |
|
|
|
|
|
|
|
|
|
addInstancedTests({&ObjImporterTest::invalidMixedPrimitives}, |
|
|
|
|
Containers::arraySize(InvalidMixedPrimitivesData)); |
|
|
|
|
|
|
|
|
|
addInstancedTests({&ObjImporterTest::invalidNumbers}, |
|
|
|
|
Containers::arraySize(InvalidNumbersData)); |
|
|
|
|
|
|
|
|
|
addInstancedTests({&ObjImporterTest::invalidNumberCount}, |
|
|
|
|
Containers::arraySize(InvalidNumberCountData)); |
|
|
|
|
|
|
|
|
|
addInstancedTests({&ObjImporterTest::invalidInconsistentIndexTuple}, |
|
|
|
|
Containers::arraySize(InvalidInconsistentIndexTupleData)); |
|
|
|
|
|
|
|
|
|
addInstancedTests({&ObjImporterTest::invalidIncompleteData}, |
|
|
|
|
Containers::arraySize(InvalidIncompleteDataData)); |
|
|
|
|
|
|
|
|
|
addInstancedTests({&ObjImporterTest::invalidOptionalCoordinate}, |
|
|
|
|
Containers::arraySize(InvalidOptionalCoordinateData)); |
|
|
|
|
|
|
|
|
|
addTests({&ObjImporterTest::openTwice, |
|
|
|
|
&ObjImporterTest::importTwice}); |
|
|
|
|
|
|
|
|
|
#ifdef OBJIMPORTER_PLUGIN_FILENAME |
|
|
|
|
@ -159,9 +218,25 @@ ObjImporterTest::ObjImporterTest() {
|
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::pointMesh() { |
|
|
|
|
void ObjImporterTest::empty() { |
|
|
|
|
/* Duplicates what's in invalidIncompleteData(MissingPositionData), but
|
|
|
|
|
it's good to have such case explicit. It also tests for empty naming. */ |
|
|
|
|
|
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "empty.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
CORRADE_COMPARE(importer->meshName(0), ""); |
|
|
|
|
CORRADE_COMPARE(importer->meshForName(""), -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(0)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete position data\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::meshPrimitivePoints() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "pointMesh.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-primitive-points.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
@ -183,9 +258,9 @@ void ObjImporterTest::pointMesh() {
|
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::lineMesh() { |
|
|
|
|
void ObjImporterTest::meshPrimitiveLines() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "lineMesh.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-primitive-lines.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
@ -205,9 +280,9 @@ void ObjImporterTest::lineMesh() {
|
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::triangleMesh() { |
|
|
|
|
void ObjImporterTest::meshPrimitiveTriangles() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "triangleMesh.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-primitive-triangles.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
@ -228,31 +303,23 @@ void ObjImporterTest::triangleMesh() {
|
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::mixedPrimitives() { |
|
|
|
|
void ObjImporterTest::meshPositionsOptionalCoordinate() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mixedPrimitives.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(0)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): mixed primitive MeshPrimitive::Points and MeshPrimitive::Lines\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::positionsOnly() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "triangleMesh.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-positions-optional-coordinate.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
CORRADE_VERIFY(data); |
|
|
|
|
CORRADE_COMPARE(data->attributeCount(), 1); |
|
|
|
|
CORRADE_VERIFY(data->hasAttribute(MeshAttribute::Position)); |
|
|
|
|
CORRADE_COMPARE_AS(data->attribute<Vector3>(MeshAttribute::Position), |
|
|
|
|
Containers::arrayView<Vector3>({ |
|
|
|
|
{1.5f, 2.0f, 3.0f} |
|
|
|
|
}), TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::textureCoordinates() { |
|
|
|
|
void ObjImporterTest::meshTextureCoordinates() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "textureCoordinates.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-texture-coordinates.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
@ -280,9 +347,23 @@ void ObjImporterTest::textureCoordinates() {
|
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::normals() { |
|
|
|
|
void ObjImporterTest::meshTextureCoordinatesOptionalCoordinate() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-texture-coordinates-optional-coordinate.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
CORRADE_VERIFY(data); |
|
|
|
|
CORRADE_COMPARE(data->attributeCount(MeshAttribute::TextureCoordinates), 1); |
|
|
|
|
CORRADE_COMPARE_AS(data->attribute<Vector2>(MeshAttribute::TextureCoordinates), |
|
|
|
|
Containers::arrayView<Vector2>({ |
|
|
|
|
{0.5f, 0.7f} |
|
|
|
|
}), TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::meshNormals() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "normals.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-normals.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
@ -310,9 +391,9 @@ void ObjImporterTest::normals() {
|
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::textureCoordinatesNormals() { |
|
|
|
|
void ObjImporterTest::meshTextureCoordinatesNormals() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "textureCoordinatesNormals.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-texture-coordinates-normals.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
@ -350,31 +431,53 @@ void ObjImporterTest::textureCoordinatesNormals() {
|
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::emptyFile() { |
|
|
|
|
void ObjImporterTest::meshIgnoredKeyword() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "emptyFile.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-ignored-keyword.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::unnamedMesh() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "emptyFile.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
CORRADE_COMPARE(importer->meshName(0), ""); |
|
|
|
|
CORRADE_COMPARE(importer->meshForName(""), -1); |
|
|
|
|
/* Everything should be parsed properly */ |
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(0); |
|
|
|
|
CORRADE_VERIFY(data); |
|
|
|
|
CORRADE_COMPARE(data->primitive(), MeshPrimitive::Points); |
|
|
|
|
CORRADE_COMPARE(data->attributeCount(), 1); |
|
|
|
|
CORRADE_COMPARE_AS(data->attribute<Vector3>(MeshAttribute::Position), |
|
|
|
|
Containers::arrayView<Vector3>({ |
|
|
|
|
{0.0f, 1.0f, 2.0f} |
|
|
|
|
}), TestSuite::Compare::Container); |
|
|
|
|
CORRADE_VERIFY(data->isIndexed()); |
|
|
|
|
CORRADE_COMPARE(data->indexType(), MeshIndexType::UnsignedInt); |
|
|
|
|
CORRADE_COMPARE_AS(data->indices<UnsignedInt>(), |
|
|
|
|
Containers::arrayView<UnsignedInt>({0}), |
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::namedMesh() { |
|
|
|
|
void ObjImporterTest::meshNamed() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "namedMesh.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-named.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
CORRADE_COMPARE(importer->meshName(0), "MyMesh"); |
|
|
|
|
CORRADE_COMPARE(importer->meshForName("MyMesh"), 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::meshNamedFirstUnnamed() { |
|
|
|
|
auto&& data = MeshNamedFirstUnnamedData[testCaseInstanceId()]; |
|
|
|
|
setTestCaseDescription(data.name); |
|
|
|
|
|
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, data.filename))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 2); |
|
|
|
|
|
|
|
|
|
CORRADE_COMPARE(importer->meshName(0), ""); |
|
|
|
|
CORRADE_COMPARE(importer->meshForName(""), -1); |
|
|
|
|
|
|
|
|
|
CORRADE_COMPARE(importer->meshName(1), "SecondMesh"); |
|
|
|
|
CORRADE_COMPARE(importer->meshForName("SecondMesh"), 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::moreMeshes() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "moreMeshes.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-multiple.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 3); |
|
|
|
|
|
|
|
|
|
CORRADE_COMPARE(importer->meshName(0), "PointMesh"); |
|
|
|
|
@ -452,370 +555,129 @@ void ObjImporterTest::moreMeshes() {
|
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::unnamedFirstMesh() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "unnamedFirstMesh.obj"))); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 2); |
|
|
|
|
|
|
|
|
|
CORRADE_COMPARE(importer->meshName(0), ""); |
|
|
|
|
CORRADE_COMPARE(importer->meshForName(""), -1); |
|
|
|
|
|
|
|
|
|
CORRADE_COMPARE(importer->meshName(1), "SecondMesh"); |
|
|
|
|
CORRADE_COMPARE(importer->meshForName("SecondMesh"), 1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::wrongFloat() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumbers.obj"))); |
|
|
|
|
const Int id = importer->meshForName("WrongFloat"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
void ObjImporterTest::invalid() { |
|
|
|
|
auto&& data = InvalidData[testCaseInstanceId()]; |
|
|
|
|
setTestCaseDescription(data.name); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): error while converting numeric data\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::wrongInteger() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumbers.obj"))); |
|
|
|
|
const Int id = importer->meshForName("WrongInteger"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, data.filename))); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): error while converting numeric data\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::unmergedIndexOutOfRange() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumbers.obj"))); |
|
|
|
|
const Int id = importer->meshForName("PositionIndexOutOfRange"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): index 1 out of range for 1 vertices\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::mergedIndexOutOfRange() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumbers.obj"))); |
|
|
|
|
const Int id = importer->meshForName("TextureIndexOutOfRange"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): index 2 out of range for 1 vertices\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::zeroIndex() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumbers.obj"))); |
|
|
|
|
const Int id = importer->meshForName("ZeroIndex"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), 1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): index 0 out of range for 1 vertices\n"); |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(0)); |
|
|
|
|
CORRADE_COMPARE(out.str(), Utility::formatString("Trade::ObjImporter::mesh(): {}\n", data.message)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::explicitOptionalPositionCoordinate() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "optionalCoordinates.obj"))); |
|
|
|
|
const Int id = importer->meshForName("SupportedPositionW"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(id); |
|
|
|
|
CORRADE_VERIFY(data); |
|
|
|
|
CORRADE_COMPARE(data->attributeCount(), 1); |
|
|
|
|
CORRADE_COMPARE_AS(data->attribute<Vector3>(MeshAttribute::Position), |
|
|
|
|
Containers::arrayView<Vector3>({ |
|
|
|
|
{1.5f, 2.0f, 3.0f} |
|
|
|
|
}), TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
void ObjImporterTest::invalidMixedPrimitives() { |
|
|
|
|
auto&& data = InvalidMixedPrimitivesData[testCaseInstanceId()]; |
|
|
|
|
setTestCaseDescription(data.name); |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::explicitOptionalTextureCoordinate() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "optionalCoordinates.obj"))); |
|
|
|
|
const Int id = importer->meshForName("SupportedTextureW"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(id); |
|
|
|
|
CORRADE_VERIFY(data); |
|
|
|
|
CORRADE_COMPARE(data->attributeCount(MeshAttribute::TextureCoordinates), 1); |
|
|
|
|
CORRADE_COMPARE_AS(data->attribute<Vector2>(MeshAttribute::TextureCoordinates), |
|
|
|
|
Containers::arrayView<Vector2>({ |
|
|
|
|
{0.5f, 0.7f} |
|
|
|
|
}), TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "invalid-mixed-primitives.obj"))); |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::unsupportedOptionalPositionCoordinate() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "optionalCoordinates.obj"))); |
|
|
|
|
const Int id = importer->meshForName("UnsupportedPositionW"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
/* Ensure we didn't forget to test any case */ |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), Containers::arraySize(InvalidMixedPrimitivesData)); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): homogeneous coordinates are not supported\n"); |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(data.name)); |
|
|
|
|
CORRADE_COMPARE(out.str(), Utility::formatString("Trade::ObjImporter::mesh(): {}\n", data.message)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::unsupportedOptionalTextureCoordinate() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "optionalCoordinates.obj"))); |
|
|
|
|
const Int id = importer->meshForName("UnsupportedTextureW"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): 3D texture coordinates are not supported\n"); |
|
|
|
|
} |
|
|
|
|
void ObjImporterTest::invalidNumbers() { |
|
|
|
|
auto&& data = InvalidNumbersData[testCaseInstanceId()]; |
|
|
|
|
setTestCaseDescription(data.name); |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::shortFloatData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumberCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("ShortFloat"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "invalid-numbers.obj"))); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): invalid float array size\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::longFloatData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumberCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("LongFloat"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
/* Ensure we didn't forget to test any case */ |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), Containers::arraySize(InvalidNumbersData)); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): invalid float array size\n"); |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(data.name)); |
|
|
|
|
CORRADE_COMPARE(out.str(), Utility::formatString("Trade::ObjImporter::mesh(): {}\n", data.message)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::longOptionalFloatData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumberCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("LongOptionalFloat"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): invalid float array size\n"); |
|
|
|
|
} |
|
|
|
|
void ObjImporterTest::invalidNumberCount() { |
|
|
|
|
auto&& data = InvalidNumberCountData[testCaseInstanceId()]; |
|
|
|
|
setTestCaseDescription(data.name); |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::longIndexData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumberCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("InvalidIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): invalid index data\n"); |
|
|
|
|
} |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "invalid-number-count.obj"))); |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::wrongPointIndexData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumberCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("WrongPointIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
/* Ensure we didn't forget to test any case */ |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), Containers::arraySize(InvalidNumberCountData)); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): wrong index count for point\n"); |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(data.name)); |
|
|
|
|
CORRADE_COMPARE(out.str(), Utility::formatString("Trade::ObjImporter::mesh(): {}\n", data.message)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::wrongLineIndexData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumberCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("WrongLineIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
void ObjImporterTest::invalidInconsistentIndexTuple() { |
|
|
|
|
auto&& data = InvalidInconsistentIndexTupleData[testCaseInstanceId()]; |
|
|
|
|
setTestCaseDescription(data.name); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): wrong index count for line\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::wrongTriangleIndexData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumberCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("WrongTriangleIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "invalid-inconsistent-index-tuple.obj"))); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): wrong index count for triangle\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::polygonIndexData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongNumberCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("PolygonIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
/* Ensure we didn't forget to test any case */ |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), Containers::arraySize(InvalidInconsistentIndexTupleData)); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): polygons are not supported\n"); |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(data.name)); |
|
|
|
|
CORRADE_COMPARE(out.str(), Utility::formatString("Trade::ObjImporter::mesh(): {}\n", data.message)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::missingPositionData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "missingData.obj"))); |
|
|
|
|
const Int id = importer->meshForName("MissingPositionData"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete position data\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::missingPositionIndices() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "missingData.obj"))); |
|
|
|
|
const Int id = importer->meshForName("MissingPositionIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete position data\n"); |
|
|
|
|
} |
|
|
|
|
void ObjImporterTest::invalidIncompleteData() { |
|
|
|
|
auto&& data = InvalidIncompleteDataData[testCaseInstanceId()]; |
|
|
|
|
setTestCaseDescription(data.name); |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::missingNormalData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "missingData.obj"))); |
|
|
|
|
const Int id = importer->meshForName("MissingNormalData"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "invalid-incomplete-data.obj"))); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete normal data\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::missingNormalIndices() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "missingData.obj"))); |
|
|
|
|
const Int id = importer->meshForName("MissingNormalIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
/* Ensure we didn't forget to test any case */ |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), Containers::arraySize(InvalidIncompleteDataData)); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete normal data\n"); |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(data.name)); |
|
|
|
|
CORRADE_COMPARE(out.str(), Utility::formatString("Trade::ObjImporter::mesh(): {}\n", data.message)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::missingTextureCoordinateData() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "missingData.obj"))); |
|
|
|
|
const Int id = importer->meshForName("MissingTextureData"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
void ObjImporterTest::invalidOptionalCoordinate() { |
|
|
|
|
auto&& data = InvalidOptionalCoordinateData[testCaseInstanceId()]; |
|
|
|
|
setTestCaseDescription(data.name); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete texture coordinate data\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::missingTextureCoordinateIndices() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "missingData.obj"))); |
|
|
|
|
const Int id = importer->meshForName("MissingTextureIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "invalid-optional-coordinate.obj"))); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete texture coordinate data\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::wrongNormalIndexCount() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongIndexCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("ShortNormalIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): some normal indices are missing\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::wrongTextureCoordinateIndexCount() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "wrongIndexCount.obj"))); |
|
|
|
|
const Int id = importer->meshForName("ShortTextureIndices"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): some texture coordinate indices are missing\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::unsupportedKeyword() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "keywords.obj"))); |
|
|
|
|
const Int id = importer->meshForName("UnsupportedKeyword"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
|
|
|
|
|
/* Everything should be parsed properly */ |
|
|
|
|
const Containers::Optional<MeshData> data = importer->mesh(id); |
|
|
|
|
CORRADE_VERIFY(data); |
|
|
|
|
CORRADE_COMPARE(data->primitive(), MeshPrimitive::Points); |
|
|
|
|
CORRADE_COMPARE(data->attributeCount(), 1); |
|
|
|
|
CORRADE_COMPARE_AS(data->attribute<Vector3>(MeshAttribute::Position), |
|
|
|
|
Containers::arrayView<Vector3>({ |
|
|
|
|
{0.0f, 1.0f, 2.0f} |
|
|
|
|
}), TestSuite::Compare::Container); |
|
|
|
|
CORRADE_VERIFY(data->isIndexed()); |
|
|
|
|
CORRADE_COMPARE(data->indexType(), MeshIndexType::UnsignedInt); |
|
|
|
|
CORRADE_COMPARE_AS(data->indices<UnsignedInt>(), |
|
|
|
|
Containers::arrayView<UnsignedInt>({0}), |
|
|
|
|
TestSuite::Compare::Container); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::unknownKeyword() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "keywords.obj"))); |
|
|
|
|
const Int id = importer->meshForName("UnknownKeyword"); |
|
|
|
|
CORRADE_VERIFY(id > -1); |
|
|
|
|
/* Ensure we didn't forget to test any case */ |
|
|
|
|
CORRADE_COMPARE(importer->meshCount(), Containers::arraySize(InvalidOptionalCoordinateData)); |
|
|
|
|
|
|
|
|
|
std::ostringstream out; |
|
|
|
|
Error redirectError{&out}; |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(id)); |
|
|
|
|
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): unknown keyword bleh\n"); |
|
|
|
|
CORRADE_VERIFY(!importer->mesh(data.name)); |
|
|
|
|
CORRADE_COMPARE(out.str(), Utility::formatString("Trade::ObjImporter::mesh(): {}\n", data.message)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::openTwice() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
|
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "pointMesh.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "pointMesh.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-primitive-points.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-primitive-points.obj"))); |
|
|
|
|
|
|
|
|
|
/* Shouldn't crash, leak or anything */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void ObjImporterTest::importTwice() { |
|
|
|
|
Containers::Pointer<AbstractImporter> importer = _manager.instantiate("ObjImporter"); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "pointMesh.obj"))); |
|
|
|
|
CORRADE_VERIFY(importer->openFile(Utility::Path::join(OBJIMPORTER_TEST_DIR, "mesh-primitive-points.obj"))); |
|
|
|
|
|
|
|
|
|
/* Verify that everything is working the same way on second use */ |
|
|
|
|
{ |
|
|
|
|
|