Browse Source

Trade: implement Importer interfaces for the new MeshData.

Deprecating of the old ones comes later.
pull/371/head
Vladimír Vondruš 6 years ago
parent
commit
fb1fdf6105
  1. 3
      doc/changelog.dox
  2. 54
      src/Magnum/Trade/AbstractImporter.cpp
  3. 117
      src/Magnum/Trade/AbstractImporter.h
  4. 23
      src/Magnum/Trade/MeshData.h
  5. 320
      src/Magnum/Trade/Test/AbstractImporterTest.cpp

3
doc/changelog.dox

@ -162,7 +162,8 @@ See also:
- A new, redesigned @ref Trade::MeshData class that allows much more flexible - A new, redesigned @ref Trade::MeshData class that allows much more flexible
access to vertex/index data without unnecessary allocations and data access to vertex/index data without unnecessary allocations and data
conversions or copies conversions or copies. Importers expose it through the new
@ref Trade::AbstractImporter::mesh() family of APIs.
- Ability to import image mip levels via an additional parameter in - Ability to import image mip levels via an additional parameter in
@ref Trade::AbstractImporter::image2D(), @ref Trade::AbstractImporter::image2D(),
@ref Trade::AbstractImporter::image2DLevelCount() and similar APIs for 1D @ref Trade::AbstractImporter::image2DLevelCount() and similar APIs for 1D

54
src/Magnum/Trade/AbstractImporter.cpp

@ -38,6 +38,7 @@
#include "Magnum/Trade/CameraData.h" #include "Magnum/Trade/CameraData.h"
#include "Magnum/Trade/ImageData.h" #include "Magnum/Trade/ImageData.h"
#include "Magnum/Trade/LightData.h" #include "Magnum/Trade/LightData.h"
#include "Magnum/Trade/MeshData.h"
#include "Magnum/Trade/MeshData2D.h" #include "Magnum/Trade/MeshData2D.h"
#include "Magnum/Trade/MeshData3D.h" #include "Magnum/Trade/MeshData3D.h"
#include "Magnum/Trade/ObjectData2D.h" #include "Magnum/Trade/ObjectData2D.h"
@ -403,6 +404,59 @@ Containers::Pointer<ObjectData3D> AbstractImporter::doObject3D(UnsignedInt) {
CORRADE_ASSERT(false, "Trade::AbstractImporter::object3D(): not implemented", {}); CORRADE_ASSERT(false, "Trade::AbstractImporter::object3D(): not implemented", {});
} }
UnsignedInt AbstractImporter::meshCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::meshCount(): no file opened", {});
return doMeshCount();
}
UnsignedInt AbstractImporter::doMeshCount() const { return 0; }
Int AbstractImporter::meshForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::meshForName(): no file opened", {});
return doMeshForName(name);
}
Int AbstractImporter::doMeshForName(const std::string&) { return -1; }
std::string AbstractImporter::meshName(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::meshName(): no file opened", {});
CORRADE_ASSERT(id < doMeshCount(), "Trade::AbstractImporter::meshName(): index" << id << "out of range for" << doMeshCount() << "entries", {});
return doMeshName(id);
}
std::string AbstractImporter::doMeshName(UnsignedInt) { return {}; }
Containers::Optional<MeshData> AbstractImporter::mesh(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh(): no file opened", {});
CORRADE_ASSERT(id < doMeshCount(), "Trade::AbstractImporter::mesh(): index" << id << "out of range for" << doMeshCount() << "entries", {});
Containers::Optional<MeshData> mesh = doMesh(id);
CORRADE_ASSERT(!mesh || (!mesh->_indexData.deleter() && !mesh->_vertexData.deleter() && !mesh->_attributes.deleter()), "Trade::AbstractImporter::mesh(): implementation is not allowed to use a custom Array deleter", {});
return mesh;
}
Containers::Optional<MeshData> AbstractImporter::doMesh(UnsignedInt) {
CORRADE_ASSERT(false, "Trade::AbstractImporter::mesh(): not implemented", {});
}
MeshAttribute AbstractImporter::meshAttributeForName(const std::string& name) {
const MeshAttribute out = doMeshAttributeForName(name);
CORRADE_ASSERT(out == MeshAttribute{} || isMeshAttributeCustom(out),
"Trade::AbstractImporter::meshAttributeForName(): implementation-returned" << out << "is neither custom nor invalid", {});
return out;
}
MeshAttribute AbstractImporter::doMeshAttributeForName(const std::string&) {
return {};
}
std::string AbstractImporter::meshAttributeName(MeshAttribute name) {
CORRADE_ASSERT(isMeshAttributeCustom(name),
"Trade::AbstractImporter::meshAttributeName():" << name << "is not custom", {});
return doMeshAttributeName(meshAttributeCustom(name));
}
std::string AbstractImporter::doMeshAttributeName(UnsignedShort) { return {}; }
UnsignedInt AbstractImporter::mesh2DCount() const { UnsignedInt AbstractImporter::mesh2DCount() const {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh2DCount(): no file opened", {}); CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::mesh2DCount(): no file opened", {});
return doMesh2DCount(); return doMesh2DCount();

117
src/Magnum/Trade/AbstractImporter.h

@ -159,8 +159,8 @@ expose internal state through various accessors:
imported by @ref image1D(), @ref image2D() or @ref image3D() imported by @ref image1D(), @ref image2D() or @ref image3D()
- @ref LightData::importerState() can expose importer state for a light - @ref LightData::importerState() can expose importer state for a light
imported by @ref light() imported by @ref light()
- @ref MeshData3D::importerState() can expose importer state for a mesh - @ref MeshData::importerState() can expose importer state for a mesh
imported by @ref mesh2D() or @ref mesh3D() imported by @ref mesh()
- @ref ObjectData3D::importerState() can expose importer state for an object - @ref ObjectData3D::importerState() can expose importer state for an object
imported by @ref object2D() or @ref object3D() imported by @ref object2D() or @ref object3D()
- @ref SceneData::importerState() can expose importer state for a scene - @ref SceneData::importerState() can expose importer state for a scene
@ -680,6 +680,72 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
*/ */
Containers::Pointer<ObjectData3D> object3D(UnsignedInt id); Containers::Pointer<ObjectData3D> object3D(UnsignedInt id);
/**
* @brief Mesh count
* @m_since_latest
*
* Expects that a file is opened.
*/
UnsignedInt meshCount() const;
/**
* @brief Mesh ID for given name
* @m_since_latest
*
* If no mesh for given name exists, returns @cpp -1 @ce. Expects that
* a file is opened.
* @see @ref meshName()
*/
Int meshForName(const std::string& name);
/**
* @brief Mesh name
* @param id Mesh ID, from range [0, @ref meshCount()).
* @m_since_latest
*
* Expects that a file is opened.
* @see @ref meshForName()
*/
std::string meshName(UnsignedInt id);
/**
* @brief Mesh
* @param id Mesh ID, from range [0, @ref meshCount()).
* @m_since_latest
*
* Returns given mesh or @ref Containers::NullOpt if importing failed.
* Expects that a file is opened.
*/
Containers::Optional<MeshData> mesh(UnsignedInt id);
/**
* @brief Mesh attribute for given name
* @m_since_latest
*
* If the name is not recognized, returns a zero (invalid)
* @ref MeshAttribute, otherwise returns a custom mesh attribute. Note
* that the value returned by this function may depend on whether a
* file is opened or not and also be different for different files ---
* see documentation of a particular importer for more information.
* @see @ref isMeshAttributeCustom()
*/
MeshAttribute meshAttributeForName(const std::string& name);
/**
* @brief String name for given custom mesh attribute
* @m_since_latest
*
* Given a custom @p name returned by @ref mesh() in a @ref MeshData,
* returns a string identifier. If a string representation is not
* available or @p name is not recognized, returns an empty string.
* Expects that @p name is custom. Note that the value returned by
* this function may depend on whether a file is opened or not and also
* be different for different files --- see documentation of a
* particular importer for more information.
* @see @ref isMeshAttributeCustom()
*/
std::string meshAttributeName(MeshAttribute name);
/** /**
* @brief Two-dimensional mesh count * @brief Two-dimensional mesh count
* *
@ -1164,6 +1230,53 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
/** @brief Implementation for @ref object3D() */ /** @brief Implementation for @ref object3D() */
virtual Containers::Pointer<ObjectData3D> doObject3D(UnsignedInt id); virtual Containers::Pointer<ObjectData3D> doObject3D(UnsignedInt id);
/**
* @brief Implementation for @ref meshCount()
* @m_since_latest
*
* Default implementation returns @cpp 0 @ce.
*/
virtual UnsignedInt doMeshCount() const;
/**
* @brief Implementation for @ref meshForName()
* @m_since_latest
*
* Default implementation returns @cpp -1 @ce.
*/
virtual Int doMeshForName(const std::string& name);
/**
* @brief Implementation for @ref meshName()
* @m_since_latest
*
* Default implementation returns an empty string.
*/
virtual std::string doMeshName(UnsignedInt id);
/**
* @brief Implementation for @ref mesh()
* @m_since_latest
*/
virtual Containers::Optional<MeshData> doMesh(UnsignedInt id);
/**
* @brief Implementation for @ref meshAttributeForName()
* @m_since_latest
*
* Default implementation returns an invalid (zero) value.
*/
virtual MeshAttribute doMeshAttributeForName(const std::string& name);
/**
* @brief Implementation for @ref meshAttributeName()
* @m_since_latest
*
* Receives the custom ID extracted via @ref meshAttributeCustom(MeshAttribute).
* Default implementation returns an empty string.
*/
virtual std::string doMeshAttributeName(UnsignedShort name);
/** /**
* @brief Implementation for @ref mesh2DCount() * @brief Implementation for @ref mesh2DCount()
* *

23
src/Magnum/Trade/MeshData.h

@ -44,11 +44,16 @@ namespace Magnum { namespace Trade {
@brief Mesh attribute name @brief Mesh attribute name
@m_since_latest @m_since_latest
@see @ref MeshData, @ref MeshAttributeData, @ref VertexFormat @see @ref MeshData, @ref MeshAttributeData, @ref VertexFormat,
@ref AbstractImporter::meshAttributeForName(),
@ref AbstractImporter::meshAttributeName()
*/ */
/* 16 bits because 8 bits is not enough to cover all potential per-edge, /* 16 bits because 8 bits is not enough to cover all potential per-edge,
per-face, per-instance and per-meshlet attributes */ per-face, per-instance and per-meshlet attributes */
enum class MeshAttribute: UnsignedShort { enum class MeshAttribute: UnsignedShort {
/* 0 reserved for an invalid value (returned from
AbstractImporter::meshAttributeForName()) */
/** /**
* Position. Type is usually @ref Magnum::Vector2 "Vector2" for 2D and * Position. Type is usually @ref Magnum::Vector2 "Vector2" for 2D and
* @ref Magnum::Vector3 "Vector3" for 3D. Corresponds to * @ref Magnum::Vector3 "Vector3" for 3D. Corresponds to
@ -57,7 +62,7 @@ enum class MeshAttribute: UnsignedShort {
* @ref MeshData::positions2DAsArray(), * @ref MeshData::positions2DAsArray(),
* @ref MeshData::positions3DAsArray() * @ref MeshData::positions3DAsArray()
*/ */
Position, Position = 1,
/** /**
* Normal. Type is usually @ref Magnum::Vector3 "Vector3". Corresponds to * Normal. Type is usually @ref Magnum::Vector3 "Vector3". Corresponds to
@ -243,7 +248,8 @@ class MAGNUM_TRADE_EXPORT MeshAttributeData {
@m_since_latest @m_since_latest
Provides access to mesh vertex and index data, together with additional Provides access to mesh vertex and index data, together with additional
information such as primitive type. information such as primitive type. Populated instances of this class are
returned from @ref AbstractImporter::mesh().
@section Trade-MeshData-usage Basic usage @section Trade-MeshData-usage Basic usage
@ -268,6 +274,8 @@ of data, which you can directly upload, and then use provided metadata to let
the GPU know of the format and layout: the GPU know of the format and layout:
@snippet MagnumTrade.cpp MeshData-usage-advanced @snippet MagnumTrade.cpp MeshData-usage-advanced
@see @ref AbstractImporter::mesh()
*/ */
class MAGNUM_TRADE_EXPORT MeshData { class MAGNUM_TRADE_EXPORT MeshData {
public: public:
@ -441,7 +449,9 @@ class MAGNUM_TRADE_EXPORT MeshData {
* @brief Attribute name * @brief Attribute name
* *
* The @p id is expected to be smaller than @ref attributeCount() const. * The @p id is expected to be smaller than @ref attributeCount() const.
* @see @ref attributeFormat(), @ref isMeshAttributeCustom() * @see @ref attributeFormat(), @ref isMeshAttributeCustom(),
* @ref AbstractImporter::meshAttributeForName(),
* @ref AbstractImporter::meshAttributeName()
*/ */
MeshAttribute attributeName(UnsignedInt id) const; MeshAttribute attributeName(UnsignedInt id) const;
@ -714,6 +724,11 @@ class MAGNUM_TRADE_EXPORT MeshData {
const void* importerState() const { return _importerState; } const void* importerState() const { return _importerState; }
private: private:
/* For custom deleter checks. Not done in the constructors here because
the restriction is pointless when used outside of plugin
implementations. */
friend AbstractImporter;
UnsignedInt attributeFor(MeshAttribute name, UnsignedInt id) const; UnsignedInt attributeFor(MeshAttribute name, UnsignedInt id) const;
UnsignedInt _vertexCount; UnsignedInt _vertexCount;

320
src/Magnum/Trade/Test/AbstractImporterTest.cpp

@ -37,6 +37,7 @@
#include "Magnum/Trade/CameraData.h" #include "Magnum/Trade/CameraData.h"
#include "Magnum/Trade/ImageData.h" #include "Magnum/Trade/ImageData.h"
#include "Magnum/Trade/LightData.h" #include "Magnum/Trade/LightData.h"
#include "Magnum/Trade/MeshData.h"
#include "Magnum/Trade/MeshData2D.h" #include "Magnum/Trade/MeshData2D.h"
#include "Magnum/Trade/MeshData3D.h" #include "Magnum/Trade/MeshData3D.h"
#include "Magnum/Trade/MeshObjectData2D.h" #include "Magnum/Trade/MeshObjectData2D.h"
@ -156,6 +157,25 @@ struct AbstractImporterTest: TestSuite::Tester {
void object3DNoFile(); void object3DNoFile();
void object3DOutOfRange(); void object3DOutOfRange();
void mesh();
void meshCountNotImplemented();
void meshCountNoFile();
void meshForNameNotImplemented();
void meshForNameNoFile();
void meshNameNotImplemented();
void meshNameNoFile();
void meshNameOutOfRange();
void meshNotImplemented();
void meshNoFile();
void meshOutOfRange();
void meshCustomIndexDataDeleter();
void meshCustomVertexDataDeleter();
void meshCustomAttributesDeleter();
void meshAttributeName();
void meshAttributeNameNotImplemented();
void meshAttributeNameNotCustom();
void mesh2D(); void mesh2D();
void mesh2DCountNotImplemented(); void mesh2DCountNotImplemented();
void mesh2DCountNoFile(); void mesh2DCountNoFile();
@ -371,6 +391,25 @@ AbstractImporterTest::AbstractImporterTest() {
&AbstractImporterTest::object3DNoFile, &AbstractImporterTest::object3DNoFile,
&AbstractImporterTest::object3DOutOfRange, &AbstractImporterTest::object3DOutOfRange,
&AbstractImporterTest::mesh,
&AbstractImporterTest::meshCountNotImplemented,
&AbstractImporterTest::meshCountNoFile,
&AbstractImporterTest::meshForNameNotImplemented,
&AbstractImporterTest::meshForNameNoFile,
&AbstractImporterTest::meshNameNotImplemented,
&AbstractImporterTest::meshNameNoFile,
&AbstractImporterTest::meshNameOutOfRange,
&AbstractImporterTest::meshNotImplemented,
&AbstractImporterTest::meshNoFile,
&AbstractImporterTest::meshOutOfRange,
&AbstractImporterTest::meshCustomIndexDataDeleter,
&AbstractImporterTest::meshCustomVertexDataDeleter,
&AbstractImporterTest::meshCustomAttributesDeleter,
&AbstractImporterTest::meshAttributeName,
&AbstractImporterTest::meshAttributeNameNotImplemented,
&AbstractImporterTest::meshAttributeNameNotCustom,
&AbstractImporterTest::mesh2D, &AbstractImporterTest::mesh2D,
&AbstractImporterTest::mesh2DCountNotImplemented, &AbstractImporterTest::mesh2DCountNotImplemented,
&AbstractImporterTest::mesh2DCountNoFile, &AbstractImporterTest::mesh2DCountNoFile,
@ -2031,6 +2070,287 @@ void AbstractImporterTest::object3DOutOfRange() {
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::object3D(): index 8 out of range for 8 entries\n"); CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::object3D(): index 8 out of range for 8 entries\n");
} }
void AbstractImporterTest::mesh() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doMeshCount() const override { return 8; }
Int doMeshForName(const std::string& name) override {
if(name == "eighth") return 7;
else return -1;
}
std::string doMeshName(UnsignedInt id) override {
if(id == 7) return "eighth";
else return {};
}
Containers::Optional<MeshData> doMesh(UnsignedInt id) override {
/* Verify that initializer list is converted to an array with
the default deleter and not something disallowed */
if(id == 7) return MeshData{MeshPrimitive::Points, nullptr, {MeshAttributeData{MeshAttribute::Position, VertexFormat::Vector3, nullptr}}, &state};
else return {};
}
} importer;
CORRADE_COMPARE(importer.meshCount(), 8);
CORRADE_COMPARE(importer.meshForName("eighth"), 7);
CORRADE_COMPARE(importer.meshName(7), "eighth");
auto data = importer.mesh(7);
CORRADE_VERIFY(data);
CORRADE_COMPARE(data->importerState(), &state);
}
void AbstractImporterTest::meshCountNotImplemented() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
} importer;
CORRADE_COMPARE(importer.meshCount(), 0);
}
void AbstractImporterTest::meshCountNoFile() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.meshCount();
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::meshCount(): no file opened\n");
}
void AbstractImporterTest::meshForNameNotImplemented() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
} importer;
CORRADE_COMPARE(importer.meshForName(""), -1);
}
void AbstractImporterTest::meshForNameNoFile() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.meshForName("");
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::meshForName(): no file opened\n");
}
void AbstractImporterTest::meshNameNotImplemented() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doMeshCount() const override { return 8; }
} importer;
CORRADE_COMPARE(importer.meshName(7), "");
}
void AbstractImporterTest::meshNameNoFile() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.meshName(42);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::meshName(): no file opened\n");
}
void AbstractImporterTest::meshNameOutOfRange() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doMeshCount() const override { return 8; }
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.meshName(8);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::meshName(): index 8 out of range for 8 entries\n");
}
void AbstractImporterTest::meshNotImplemented() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doMeshCount() const override { return 8; }
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.mesh(7);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::mesh(): not implemented\n");
}
void AbstractImporterTest::meshNoFile() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.mesh(42);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::mesh(): no file opened\n");
}
void AbstractImporterTest::meshOutOfRange() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doMeshCount() const override { return 8; }
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.mesh(8);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::mesh(): index 8 out of range for 8 entries\n");
}
void AbstractImporterTest::meshCustomIndexDataDeleter() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doMeshCount() const override { return 1; }
Containers::Optional<MeshData> doMesh(UnsignedInt) override {
return MeshData{MeshPrimitive::Triangles, Containers::Array<char>{data, 1, [](char*, std::size_t) {}}, MeshIndexData{MeshIndexType::UnsignedByte, data}};
}
char data[1];
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.mesh(0);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::mesh(): implementation is not allowed to use a custom Array deleter\n");
}
void AbstractImporterTest::meshCustomVertexDataDeleter() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doMeshCount() const override { return 1; }
Containers::Optional<MeshData> doMesh(UnsignedInt) override {
return MeshData{MeshPrimitive::Triangles, Containers::Array<char>{nullptr, 0, [](char*, std::size_t) {}}, {MeshAttributeData{MeshAttribute::Position, VertexFormat::Vector3, nullptr}}};
}
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.mesh(0);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::mesh(): implementation is not allowed to use a custom Array deleter\n");
}
void AbstractImporterTest::meshCustomAttributesDeleter() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
UnsignedInt doMeshCount() const override { return 1; }
Containers::Optional<MeshData> doMesh(UnsignedInt) override {
return MeshData{MeshPrimitive::Triangles, nullptr, Containers::Array<MeshAttributeData>{&positions, 1, [](MeshAttributeData*, std::size_t) {}}};
}
MeshAttributeData positions{MeshAttribute::Position, VertexFormat::Vector3, nullptr};
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.mesh(0);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::mesh(): implementation is not allowed to use a custom Array deleter\n");
}
void AbstractImporterTest::meshAttributeName() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
MeshAttribute doMeshAttributeForName(const std::string& name) override {
if(name == "SMOOTH_GROUP_ID") return meshAttributeCustom(37);
return MeshAttribute{};
}
std::string doMeshAttributeName(UnsignedShort id) override {
if(id == 37) return "SMOOTH_GROUP_ID";
return "";
}
} importer;
CORRADE_COMPARE(importer.meshAttributeForName("SMOOTH_GROUP_ID"), meshAttributeCustom(37));
CORRADE_COMPARE(importer.meshAttributeName(meshAttributeCustom(37)), "SMOOTH_GROUP_ID");
}
void AbstractImporterTest::meshAttributeNameNotImplemented() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
} importer;
CORRADE_COMPARE(importer.meshAttributeForName(""), MeshAttribute{});
CORRADE_COMPARE(importer.meshAttributeName(meshAttributeCustom(37)), "");
}
void AbstractImporterTest::meshAttributeNameNotCustom() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
MeshAttribute doMeshAttributeForName(const std::string&) override {
return MeshAttribute::Position;
}
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.meshAttributeForName("SMOOTH_GROUP_ID");
importer.meshAttributeName(MeshAttribute::Position);
CORRADE_COMPARE(out.str(),
"Trade::AbstractImporter::meshAttributeForName(): implementation-returned Trade::MeshAttribute::Position is neither custom nor invalid\n"
"Trade::AbstractImporter::meshAttributeName(): Trade::MeshAttribute::Position is not custom\n");
}
void AbstractImporterTest::mesh2D() { void AbstractImporterTest::mesh2D() {
struct: AbstractImporter { struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; } ImporterFeatures doFeatures() const override { return {}; }

Loading…
Cancel
Save