Browse Source

ObjImporter: port away from MeshDataXD.

Not the tests yet -- those will get done in the next round.
pull/371/head
Vladimír Vondruš 6 years ago
parent
commit
4269c1303b
  1. 214
      src/MagnumPlugins/ObjImporter/ObjImporter.cpp
  2. 16
      src/MagnumPlugins/ObjImporter/ObjImporter.h
  3. 58
      src/MagnumPlugins/ObjImporter/Test/ObjImporterTest.cpp

214
src/MagnumPlugins/ObjImporter/ObjImporter.cpp

@ -29,16 +29,18 @@
#include <limits>
#include <sstream>
#include <unordered_map>
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/StridedArrayView.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/String.h>
#include "Magnum/Mesh.h"
#include "Magnum/MeshTools/CombineIndexedArrays.h"
#include "Magnum/MeshTools/CompressIndices.h"
#include "Magnum/MeshTools/RemoveDuplicates.h"
#include "Magnum/MeshTools/Duplicate.h"
#include "Magnum/Math/Color.h"
#include "Magnum/Trade/MeshData3D.h"
#include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace Trade {
@ -58,7 +60,7 @@ void ignoreLine(std::istream& in) {
template<std::size_t size> Math::Vector<size, Float> extractFloatData(const std::string& str, Float* extra = nullptr) {
std::vector<std::string> data = Utility::String::splitWithoutEmptyParts(str, ' ');
if(data.size() < size || data.size() > size + (extra ? 1 : 0)) {
Error() << "Trade::ObjImporter::mesh3D(): invalid float array size";
Error() << "Trade::ObjImporter::mesh(): invalid float array size";
throw 0;
}
@ -78,16 +80,6 @@ template<std::size_t size> Math::Vector<size, Float> extractFloatData(const std:
return output;
}
template<class T> void reindex(const std::vector<UnsignedInt>& indices, std::vector<T>& data) {
/* Check that indices are in range */
for(UnsignedInt i: indices) if(i >= data.size()) {
Error() << "Trade::ObjImporter::mesh3D(): index out of range";
throw 0;
}
data = MeshTools::duplicate(indices, data);
}
}
ObjImporter::ObjImporter() = default;
@ -214,18 +206,34 @@ void ObjImporter::parseMeshNames() {
std::get<1>(_file->meshes.back()) = _file->in->tellg();
}
UnsignedInt ObjImporter::doMesh3DCount() const { return _file->meshes.size(); }
UnsignedInt ObjImporter::doMeshCount() const { return _file->meshes.size(); }
Int ObjImporter::doMesh3DForName(const std::string& name) {
Int ObjImporter::doMeshForName(const std::string& name) {
const auto it = _file->meshesForName.find(name);
return it == _file->meshesForName.end() ? -1 : it->second;
}
std::string ObjImporter::doMesh3DName(UnsignedInt id) {
std::string ObjImporter::doMeshName(UnsignedInt id) {
return _file->meshNames[id];
}
Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
namespace {
template<class T> bool checkAndDuplicateInto(const Containers::StridedArrayView1D<const UnsignedInt>& indices, const Containers::Array<T>& data, const Containers::StridedArrayView1D<T>& out, UnsignedInt offset) {
/* Check that indices are in range. Add back the original index offset for
easier data debugging. */
for(UnsignedInt i: indices) if(i >= data.size()) {
Error{} << "Trade::ObjImporter::mesh(): index" << (i + offset) << "out of range for" << data.size() << "vertices";
return false;
}
MeshTools::duplicateInto(indices, stridedArrayView(data), out);
return true;
}
}
Containers::Optional<MeshData> ObjImporter::doMesh(UnsignedInt id, UnsignedInt) {
/* Seek the file, set mesh parsing parameters */
std::streampos begin, end;
UnsignedInt positionIndexOffset, textureCoordinateIndexOffset, normalIndexOffset;
@ -233,12 +241,13 @@ Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
_file->in->seekg(begin);
Containers::Optional<MeshPrimitive> primitive;
std::vector<Vector3> positions;
std::vector<std::vector<Vector2>> textureCoordinates;
std::vector<std::vector<Vector3>> normals;
std::vector<UnsignedInt> positionIndices;
std::vector<UnsignedInt> textureCoordinateIndices;
std::vector<UnsignedInt> normalIndices;
Containers::Array<Vector3> positions;
Containers::Array<Vector3> normals;
Containers::Array<Vector2> textureCoordinates;
/* Taking a shortcut as there's fortunately nothing else than just 3 types
of data. First positions, then normals, then texture coordinates. */
Containers::Array<Vector3ui> indices;
std::size_t textureCoordinateIndexCount = 0, normalIndexCount = 0;
try { while(_file->in->good() && _file->in->tellg() < end) {
/* Ignore comments */
@ -266,28 +275,26 @@ Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
Float extra{1.0f};
const Vector3 data = extractFloatData<3>(contents, &extra);
if(!Math::TypeTraits<Float>::equals(extra, 1.0f)) {
Error() << "Trade::ObjImporter::mesh3D(): homogeneous coordinates are not supported";
Error() << "Trade::ObjImporter::mesh(): homogeneous coordinates are not supported";
return Containers::NullOpt;
}
positions.push_back(data);
arrayAppend(positions, data);
/* Texture coordinate */
} else if(keyword == "vt") {
Float extra{0.0f};
const auto data = extractFloatData<2>(contents, &extra);
const Vector2 data = extractFloatData<2>(contents, &extra);
if(!Math::TypeTraits<Float>::equals(extra, 0.0f)) {
Error() << "Trade::ObjImporter::mesh3D(): 3D texture coordinates are not supported";
Error() << "Trade::ObjImporter::mesh(): 3D texture coordinates are not supported";
return Containers::NullOpt;
}
if(textureCoordinates.empty()) textureCoordinates.emplace_back();
textureCoordinates.front().emplace_back(data);
arrayAppend(textureCoordinates, data);
/* Normal */
} else if(keyword == "vn") {
if(normals.empty()) normals.emplace_back();
normals.front().emplace_back(extractFloatData<3>(contents));
arrayAppend(normals, Vector3{extractFloatData<3>(contents)});
/* Indices */
} else if(keyword == "p" || keyword == "l" || keyword == "f") {
@ -297,13 +304,13 @@ Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
if(keyword == "p") {
/* Check that we don't mix the primitives in one mesh */
if(primitive && primitive != MeshPrimitive::Points) {
Error() << "Trade::ObjImporter::mesh3D(): mixed primitive" << *primitive << "and" << MeshPrimitive::Points;
Error() << "Trade::ObjImporter::mesh(): mixed primitive" << *primitive << "and" << MeshPrimitive::Points;
return Containers::NullOpt;
}
/* Check vertex count per primitive */
if(indexTuples.size() != 1) {
Error() << "Trade::ObjImporter::mesh3D(): wrong index count for point";
Error() << "Trade::ObjImporter::mesh(): wrong index count for point";
return Containers::NullOpt;
}
@ -313,13 +320,13 @@ Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
} else if(keyword == "l") {
/* Check that we don't mix the primitives in one mesh */
if(primitive && primitive != MeshPrimitive::Lines) {
Error() << "Trade::ObjImporter::mesh3D(): mixed primitive" << *primitive << "and" << MeshPrimitive::Lines;
Error() << "Trade::ObjImporter::mesh(): mixed primitive" << *primitive << "and" << MeshPrimitive::Lines;
return Containers::NullOpt;
}
/* Check vertex count per primitive */
if(indexTuples.size() != 2) {
Error() << "Trade::ObjImporter::mesh3D(): wrong index count for line";
Error() << "Trade::ObjImporter::mesh(): wrong index count for line";
return Containers::NullOpt;
}
@ -329,16 +336,16 @@ Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
} else if(keyword == "f") {
/* Check that we don't mix the primitives in one mesh */
if(primitive && primitive != MeshPrimitive::Triangles) {
Error() << "Trade::ObjImporter::mesh3D(): mixed primitive" << *primitive << "and" << MeshPrimitive::Triangles;
Error() << "Trade::ObjImporter::mesh(): mixed primitive" << *primitive << "and" << MeshPrimitive::Triangles;
return Containers::NullOpt;
}
/* Check vertex count per primitive */
if(indexTuples.size() < 3) {
Error() << "Trade::ObjImporter::mesh3D(): wrong index count for triangle";
Error() << "Trade::ObjImporter::mesh(): wrong index count for triangle";
return Containers::NullOpt;
} else if(indexTuples.size() != 3) {
Error() << "Trade::ObjImporter::mesh3D(): polygons are not supported";
Error() << "Trade::ObjImporter::mesh(): polygons are not supported";
return Containers::NullOpt;
}
@ -347,22 +354,30 @@ Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
} else CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
for(const std::string& indexTuple: indexTuples) {
std::vector<std::string> indices = Utility::String::split(indexTuple, '/');
if(indices.size() > 3) {
Error() << "Trade::ObjImporter::mesh3D(): invalid index data";
std::vector<std::string> indexStrings = Utility::String::split(indexTuple, '/');
if(indexStrings.size() > 3) {
Error() << "Trade::ObjImporter::mesh(): invalid index data";
return Containers::NullOpt;
}
Vector3ui index;
/* Position indices */
positionIndices.push_back(std::stoul(indices[0]) - positionIndexOffset);
index[0] = std::stoul(indexStrings[0]) - positionIndexOffset;
/* Texture coordinates */
if(indices.size() == 2 || (indices.size() == 3 && !indices[1].empty()))
textureCoordinateIndices.push_back(std::stoul(indices[1]) - textureCoordinateIndexOffset);
if(indexStrings.size() == 2 || (indexStrings.size() == 3 && !indexStrings[1].empty())) {
index[2] = std::stoul(indexStrings[1]) - textureCoordinateIndexOffset;
++textureCoordinateIndexCount;
}
/* Normal indices */
if(indices.size() == 3)
normalIndices.push_back(std::stoul(indices[2]) - normalIndexOffset);
if(indexStrings.size() == 3) {
index[1] = std::stoul(indexStrings[2]) - normalIndexOffset;
++normalIndexCount;
}
arrayAppend(indices, index);
}
/* Ignore unsupported keywords, error out on unknown keywords */
@ -372,12 +387,12 @@ Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
if(keyword == expected) return true;
return false;
}()) {
Error() << "Trade::ObjImporter::mesh3D(): unknown keyword" << keyword;
Error() << "Trade::ObjImporter::mesh(): unknown keyword" << keyword;
return Containers::NullOpt;
}
}} catch(const std::exception&) {
Error() << "Trade::ObjImporter::mesh3D(): error while converting numeric data";
Error() << "Trade::ObjImporter::mesh(): error while converting numeric data";
return Containers::NullOpt;
} catch(...) {
/* Error message already printed */
@ -385,64 +400,87 @@ Containers::Optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
}
/* There should be at least indexed position data */
if(positions.empty() || positionIndices.empty()) {
Error() << "Trade::ObjImporter::mesh3D(): incomplete position data";
if(positions.empty() || indices.empty()) {
Error() << "Trade::ObjImporter::mesh(): incomplete position data";
return Containers::NullOpt;
}
/* If there are index data, there should be also vertex data (and also the other way) */
if(normals.empty() != normalIndices.empty()) {
Error() << "Trade::ObjImporter::mesh3D(): incomplete normal data";
if(normals.empty() != (normalIndexCount == 0)) {
Error() << "Trade::ObjImporter::mesh(): incomplete normal data";
return Containers::NullOpt;
}
if(textureCoordinates.empty() != textureCoordinateIndices.empty()) {
Error() << "Trade::ObjImporter::mesh3D(): incomplete texture coordinate data";
if(textureCoordinates.empty() != (textureCoordinateIndexCount == 0)) {
Error() << "Trade::ObjImporter::mesh(): incomplete texture coordinate data";
return Containers::NullOpt;
}
/* All index arrays should have the same length */
if(!normalIndices.empty() && normalIndices.size() != positionIndices.size()) {
CORRADE_INTERNAL_ASSERT(normalIndices.size() < positionIndices.size());
Error() << "Trade::ObjImporter::mesh3D(): some normal indices are missing";
if(normalIndexCount && normalIndexCount != indices.size()) {
CORRADE_INTERNAL_ASSERT(normalIndexCount < indices.size());
Error() << "Trade::ObjImporter::mesh(): some normal indices are missing";
return Containers::NullOpt;
}
if(!textureCoordinates.empty() && textureCoordinateIndices.size() != positionIndices.size()) {
CORRADE_INTERNAL_ASSERT(textureCoordinateIndices.size() < positionIndices.size());
Error() << "Trade::ObjImporter::mesh3D(): some texture coordinate indices are missing";
if(textureCoordinateIndexCount && textureCoordinateIndexCount != indices.size()) {
CORRADE_INTERNAL_ASSERT(textureCoordinateIndexCount < indices.size());
Error() << "Trade::ObjImporter::mesh(): some texture coordinate indices are missing";
return Containers::NullOpt;
}
/* Merge index arrays, if there aren't just the positions */
std::vector<UnsignedInt> indices;
if(!normalIndices.empty() || !textureCoordinateIndices.empty()) {
std::vector<std::reference_wrapper<std::vector<UnsignedInt>>> arrays;
arrays.reserve(3);
arrays.emplace_back(positionIndices);
if(!normalIndices.empty()) arrays.emplace_back(normalIndices);
if(!textureCoordinateIndices.empty()) arrays.emplace_back(textureCoordinateIndices);
indices = MeshTools::combineIndexArrays(arrays);
/* Reindex data arrays */
try {
reindex(positionIndices, positions);
if(!normalIndices.empty()) reindex(normalIndices, normals.front());
if(!textureCoordinateIndices.empty()) reindex(textureCoordinateIndices, textureCoordinates.front());
} catch(...) {
/* Error message already printed */
/* Merge index arrays. If any of the attributes was not there, the whole
index array has zeros, not affecting the uniqueness in any way. */
Containers::Array<char> indexData{Containers::NoInit, indices.size()*sizeof(UnsignedInt)};
const auto indexDataI = Containers::arrayCast<UnsignedInt>(indexData);
const std::size_t vertexCount = MeshTools::removeDuplicatesInPlaceInto(
Containers::arrayCast<2, char>(arrayView(indices)), indexDataI);
/* Allocate attribute and vertex data */
std::size_t attributeCount = 1;
UnsignedInt stride = sizeof(Vector3);
if(normalIndexCount) {
++attributeCount;
stride += sizeof(Vector3);
}
if(textureCoordinateIndexCount) {
++attributeCount;
stride += sizeof(Vector2);
}
Containers::Array<MeshAttributeData> attributeData{attributeCount};
Containers::Array<char> vertexData{Containers::NoInit, vertexCount*stride};
/* Duplicate the vertices into the output */
const auto indicesPerAttribute = Containers::arrayCast<2, const UnsignedInt>(stridedArrayView(indices)).transposed<0, 1>();
std::size_t attributeIndex = 0;
std::size_t offset = 0;
{
Containers::StridedArrayView1D<Vector3> view{vertexData,
reinterpret_cast<Vector3*>(vertexData.data()), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[0].prefix(vertexCount), positions, view, positionIndexOffset))
return Containers::NullOpt;
}
/* Otherwise just use the original position index array. Don't forget to
check range */
} else {
indices = std::move(positionIndices);
for(UnsignedInt i: indices) if(i >= positions.size()) {
Error() << "Trade::ObjImporter::mesh3D(): index out of range";
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Position, view};
offset += sizeof(Vector3);
}
if(normalIndexCount) {
Containers::StridedArrayView1D<Vector3> view{vertexData,
reinterpret_cast<Vector3*>(vertexData.data() + offset), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[1].prefix(vertexCount), normals, view, normalIndexOffset))
return Containers::NullOpt;
}
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Normal, view};
offset += sizeof(Vector3);
}
if(textureCoordinateIndexCount) {
Containers::StridedArrayView1D<Vector2> view{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + offset), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[2].prefix(vertexCount), textureCoordinates, view, textureCoordinateIndexOffset))
return Containers::NullOpt;
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::TextureCoordinates, view};
offset += sizeof(Vector2);
}
CORRADE_INTERNAL_ASSERT(offset == stride && attributeIndex == attributeCount);
return MeshData3D{*primitive, std::move(indices), {std::move(positions)}, std::move(normals), std::move(textureCoordinates), {}, nullptr};
return MeshData{*primitive,
std::move(indexData), Trade::MeshIndexData{indexDataI},
std::move(vertexData), std::move(attributeData)};
}
}}

16
src/MagnumPlugins/ObjImporter/ObjImporter.h

@ -91,8 +91,12 @@ See @ref building, @ref cmake and @ref plugins for more information.
@section Trade-ObjImporter-limitations Behavior and limitations
Polygons (quads etc.), automatic normal generation and material properties are
currently not supported.
Meshes are imported as @ref MeshPrimitive::Triangles with
@ref MeshIndexType::UnsignedInt indices, interleaved @ref VertexFormat::Vector3
positions with optional @ref VertexFormat::Vector3 normals and
@ref VertexFormat::Vector2 texture coordinates, if present in the source file.
Polygons (quads etc.) and material properties are currently not supported.
*/
class MAGNUM_OBJIMPORTER_EXPORT ObjImporter: public AbstractImporter {
public:
@ -114,10 +118,10 @@ class MAGNUM_OBJIMPORTER_EXPORT ObjImporter: public AbstractImporter {
MAGNUM_OBJIMPORTER_LOCAL void doOpenFile(const std::string& filename) override;
MAGNUM_OBJIMPORTER_LOCAL void doClose() override;
MAGNUM_OBJIMPORTER_LOCAL UnsignedInt doMesh3DCount() const override;
MAGNUM_OBJIMPORTER_LOCAL Int doMesh3DForName(const std::string& name) override;
MAGNUM_OBJIMPORTER_LOCAL std::string doMesh3DName(UnsignedInt id) override;
MAGNUM_OBJIMPORTER_LOCAL Containers::Optional<MeshData3D> doMesh3D(UnsignedInt id) override;
MAGNUM_OBJIMPORTER_LOCAL UnsignedInt doMeshCount() const override;
MAGNUM_OBJIMPORTER_LOCAL Int doMeshForName(const std::string& name) override;
MAGNUM_OBJIMPORTER_LOCAL std::string doMeshName(UnsignedInt id) override;
MAGNUM_OBJIMPORTER_LOCAL Containers::Optional<MeshData> doMesh(UnsignedInt id, UnsignedInt level) override;
MAGNUM_OBJIMPORTER_LOCAL void parseMeshNames();

58
src/MagnumPlugins/ObjImporter/Test/ObjImporterTest.cpp

@ -160,13 +160,15 @@ void ObjImporterTest::pointMesh() {
CORRADE_VERIFY(data);
CORRADE_COMPARE(data->primitive(), MeshPrimitive::Points);
CORRADE_COMPARE(data->positionArrayCount(), 1);
/* The points get reordered according to the index buffer. Might not be a
problem in general but it is when relying on the order */
CORRADE_COMPARE(data->positions(0), (std::vector<Vector3>{
{0.5f, 2.0f, 3.0f},
{0.0f, 1.5f, 1.0f},
{2.0f, 3.0f, 5.0f}
{2.0f, 3.0f, 5.0f},
{0.0f, 1.5f, 1.0f}
}));
CORRADE_COMPARE(data->indices(), (std::vector<UnsignedInt>{
0, 2, 1, 0
0, 1, 2, 0
}));
}
@ -217,7 +219,7 @@ void ObjImporterTest::mixedPrimitives() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(0));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): mixed primitive MeshPrimitive::Points and MeshPrimitive::Lines\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): mixed primitive MeshPrimitive::Points and MeshPrimitive::Lines\n");
}
void ObjImporterTest::positionsOnly() {
@ -417,7 +419,7 @@ void ObjImporterTest::wrongFloat() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): error while converting numeric data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): error while converting numeric data\n");
}
void ObjImporterTest::wrongInteger() {
@ -429,7 +431,7 @@ void ObjImporterTest::wrongInteger() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): error while converting numeric data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): error while converting numeric data\n");
}
void ObjImporterTest::unmergedIndexOutOfRange() {
@ -441,7 +443,7 @@ void ObjImporterTest::unmergedIndexOutOfRange() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): index out of range\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): index 1 out of range for 1 vertices\n");
}
void ObjImporterTest::mergedIndexOutOfRange() {
@ -453,7 +455,7 @@ void ObjImporterTest::mergedIndexOutOfRange() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): index out of range\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): index 2 out of range for 1 vertices\n");
}
void ObjImporterTest::zeroIndex() {
@ -465,7 +467,7 @@ void ObjImporterTest::zeroIndex() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): index out of range\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): index 0 out of range for 1 vertices\n");
}
void ObjImporterTest::explicitOptionalPositionCoordinate() {
@ -505,7 +507,7 @@ void ObjImporterTest::unsupportedOptionalPositionCoordinate() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): homogeneous coordinates are not supported\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): homogeneous coordinates are not supported\n");
}
void ObjImporterTest::unsupportedOptionalTextureCoordinate() {
@ -517,7 +519,7 @@ void ObjImporterTest::unsupportedOptionalTextureCoordinate() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): 3D texture coordinates are not supported\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): 3D texture coordinates are not supported\n");
}
void ObjImporterTest::shortFloatData() {
@ -529,7 +531,7 @@ void ObjImporterTest::shortFloatData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): invalid float array size\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): invalid float array size\n");
}
void ObjImporterTest::longFloatData() {
@ -541,7 +543,7 @@ void ObjImporterTest::longFloatData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): invalid float array size\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): invalid float array size\n");
}
void ObjImporterTest::longOptionalFloatData() {
@ -553,7 +555,7 @@ void ObjImporterTest::longOptionalFloatData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): invalid float array size\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): invalid float array size\n");
}
void ObjImporterTest::longIndexData() {
@ -565,7 +567,7 @@ void ObjImporterTest::longIndexData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): invalid index data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): invalid index data\n");
}
void ObjImporterTest::wrongPointIndexData() {
@ -577,7 +579,7 @@ void ObjImporterTest::wrongPointIndexData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): wrong index count for point\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): wrong index count for point\n");
}
void ObjImporterTest::wrongLineIndexData() {
@ -589,7 +591,7 @@ void ObjImporterTest::wrongLineIndexData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): wrong index count for line\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): wrong index count for line\n");
}
void ObjImporterTest::wrongTriangleIndexData() {
@ -601,7 +603,7 @@ void ObjImporterTest::wrongTriangleIndexData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): wrong index count for triangle\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): wrong index count for triangle\n");
}
void ObjImporterTest::polygonIndexData() {
@ -613,7 +615,7 @@ void ObjImporterTest::polygonIndexData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): polygons are not supported\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): polygons are not supported\n");
}
void ObjImporterTest::missingPositionData() {
@ -625,7 +627,7 @@ void ObjImporterTest::missingPositionData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): incomplete position data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete position data\n");
}
void ObjImporterTest::missingPositionIndices() {
@ -637,7 +639,7 @@ void ObjImporterTest::missingPositionIndices() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): incomplete position data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete position data\n");
}
void ObjImporterTest::missingNormalData() {
@ -649,7 +651,7 @@ void ObjImporterTest::missingNormalData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): incomplete normal data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete normal data\n");
}
void ObjImporterTest::missingNormalIndices() {
@ -661,7 +663,7 @@ void ObjImporterTest::missingNormalIndices() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): incomplete normal data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete normal data\n");
}
void ObjImporterTest::missingTextureCoordinateData() {
@ -673,7 +675,7 @@ void ObjImporterTest::missingTextureCoordinateData() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): incomplete texture coordinate data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete texture coordinate data\n");
}
void ObjImporterTest::missingTextureCoordinateIndices() {
@ -685,7 +687,7 @@ void ObjImporterTest::missingTextureCoordinateIndices() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): incomplete texture coordinate data\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): incomplete texture coordinate data\n");
}
void ObjImporterTest::wrongNormalIndexCount() {
@ -697,7 +699,7 @@ void ObjImporterTest::wrongNormalIndexCount() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): some normal indices are missing\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): some normal indices are missing\n");
}
void ObjImporterTest::wrongTextureCoordinateIndexCount() {
@ -709,7 +711,7 @@ void ObjImporterTest::wrongTextureCoordinateIndexCount() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): some texture coordinate indices are missing\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): some texture coordinate indices are missing\n");
}
void ObjImporterTest::unsupportedKeyword() {
@ -738,7 +740,7 @@ void ObjImporterTest::unknownKeyword() {
std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(id));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): unknown keyword bleh\n");
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh(): unknown keyword bleh\n");
}
}}}}

Loading…
Cancel
Save