Browse Source

ObjImporter: using a five-element std::tuple is just ... nope.

And then std::tie() into mutable variables that are easy to get out of
sync. Just don't. No.

Interesting is that STL vector's emplace_back() doesn't accept the
arguments directly. Not sure why, but I'm going to drop the std::vector
next anyway.
pull/674/head
Vladimír Vondruš 1 year ago
parent
commit
bd01cf69f0
  1. 44
      src/MagnumPlugins/ObjImporter/ObjImporter.cpp

44
src/MagnumPlugins/ObjImporter/ObjImporter.cpp

@ -46,10 +46,22 @@
namespace Magnum { namespace Trade { namespace Magnum { namespace Trade {
namespace {
struct Mesh {
std::streampos begin;
std::streampos end;
UnsignedInt positionIndexOffset;
UnsignedInt textureCoordinateIndexOffset;
UnsignedInt normalIndexOffset;
};
}
struct ObjImporter::File { struct ObjImporter::File {
std::unordered_map<std::string, UnsignedInt> meshesForName; std::unordered_map<std::string, UnsignedInt> meshesForName;
std::vector<std::string> meshNames; std::vector<std::string> meshNames;
std::vector<std::tuple<std::streampos, std::streampos, UnsignedInt, UnsignedInt, UnsignedInt>> meshes; std::vector<Mesh> meshes;
Containers::Pointer<std::istream> in; Containers::Pointer<std::istream> in;
}; };
@ -123,7 +135,7 @@ void ObjImporter::parseMeshNames() {
UnsignedInt positionIndexOffset = 1; UnsignedInt positionIndexOffset = 1;
UnsignedInt normalIndexOffset = 1; UnsignedInt normalIndexOffset = 1;
UnsignedInt textureCoordinateIndexOffset = 1; UnsignedInt textureCoordinateIndexOffset = 1;
_file->meshes.emplace_back(0, 0, positionIndexOffset, normalIndexOffset, textureCoordinateIndexOffset); _file->meshes.emplace_back(Mesh{0, 0, positionIndexOffset, normalIndexOffset, textureCoordinateIndexOffset});
/* The first mesh doesn't have name by default but we might find it later, /* The first mesh doesn't have name by default but we might find it later,
so we need to track whether there are any data before first name */ so we need to track whether there are any data before first name */
@ -160,19 +172,19 @@ void ObjImporter::parseMeshNames() {
_file->meshNames.back() = Utility::move(name); _file->meshNames.back() = Utility::move(name);
/* Update its begin offset to be more precise */ /* Update its begin offset to be more precise */
std::get<0>(_file->meshes.back()) = _file->in->tellg(); _file->meshes.back().begin = _file->in->tellg();
/* Otherwise this is a name of new mesh */ /* Otherwise this is a name of new mesh */
} else { } else {
/* Set end of the previous one */ /* Set end of the previous one */
std::get<1>(_file->meshes.back()) = end; _file->meshes.back().end = end;
/* Save name and offset of the new one. The end offset will be /* Save name and offset of the new one. The end offset will be
updated later. */ updated later. */
if(!name.empty()) if(!name.empty())
_file->meshesForName.emplace(name, _file->meshes.size()); _file->meshesForName.emplace(name, _file->meshes.size());
_file->meshNames.emplace_back(Utility::move(name)); _file->meshNames.emplace_back(Utility::move(name));
_file->meshes.emplace_back(_file->in->tellg(), 0, positionIndexOffset, textureCoordinateIndexOffset, normalIndexOffset); _file->meshes.emplace_back(Mesh{_file->in->tellg(), 0, positionIndexOffset, textureCoordinateIndexOffset, normalIndexOffset});
} }
continue; continue;
@ -207,7 +219,7 @@ void ObjImporter::parseMeshNames() {
/* Set end of the last object */ /* Set end of the last object */
_file->in->clear(); _file->in->clear();
_file->in->seekg(0, std::ios::end); _file->in->seekg(0, std::ios::end);
std::get<1>(_file->meshes.back()) = _file->in->tellg(); _file->meshes.back().end = _file->in->tellg();
} }
UnsignedInt ObjImporter::doMeshCount() const { return _file->meshes.size(); } UnsignedInt ObjImporter::doMeshCount() const { return _file->meshes.size(); }
@ -239,10 +251,8 @@ template<class T> bool checkAndDuplicateInto(const Containers::StridedArrayView1
Containers::Optional<MeshData> ObjImporter::doMesh(UnsignedInt id, UnsignedInt) { Containers::Optional<MeshData> ObjImporter::doMesh(UnsignedInt id, UnsignedInt) {
/* Seek the file, set mesh parsing parameters */ /* Seek the file, set mesh parsing parameters */
std::streampos begin, end; const Mesh& mesh = _file->meshes[id];
UnsignedInt positionIndexOffset, textureCoordinateIndexOffset, normalIndexOffset; _file->in->seekg(mesh.begin);
std::tie(begin, end, positionIndexOffset, textureCoordinateIndexOffset, normalIndexOffset) = _file->meshes[id];
_file->in->seekg(begin);
Containers::Optional<MeshPrimitive> primitive; Containers::Optional<MeshPrimitive> primitive;
Containers::Array<Vector3> positions; Containers::Array<Vector3> positions;
@ -253,7 +263,7 @@ Containers::Optional<MeshData> ObjImporter::doMesh(UnsignedInt id, UnsignedInt)
Containers::Array<Vector3ui> indices; Containers::Array<Vector3ui> indices;
std::size_t textureCoordinateIndexCount = 0, normalIndexCount = 0; std::size_t textureCoordinateIndexCount = 0, normalIndexCount = 0;
try { while(_file->in->good() && _file->in->tellg() < end) { try { while(_file->in->good() && _file->in->tellg() < mesh.end) {
/* Ignore comments */ /* Ignore comments */
if(_file->in->peek() == '#') { if(_file->in->peek() == '#') {
ignoreLine(*_file->in); ignoreLine(*_file->in);
@ -367,17 +377,17 @@ Containers::Optional<MeshData> ObjImporter::doMesh(UnsignedInt id, UnsignedInt)
Vector3ui index; Vector3ui index;
/* Position indices */ /* Position indices */
index[0] = std::stoul(indexStrings[0]) - positionIndexOffset; index[0] = std::stoul(indexStrings[0]) - mesh.positionIndexOffset;
/* Texture coordinates */ /* Texture coordinates */
if(indexStrings.size() == 2 || (indexStrings.size() == 3 && !indexStrings[1].empty())) { if(indexStrings.size() == 2 || (indexStrings.size() == 3 && !indexStrings[1].empty())) {
index[2] = std::stoul(indexStrings[1]) - textureCoordinateIndexOffset; index[2] = std::stoul(indexStrings[1]) - mesh.textureCoordinateIndexOffset;
++textureCoordinateIndexCount; ++textureCoordinateIndexCount;
} }
/* Normal indices */ /* Normal indices */
if(indexStrings.size() == 3) { if(indexStrings.size() == 3) {
index[1] = std::stoul(indexStrings[2]) - normalIndexOffset; index[1] = std::stoul(indexStrings[2]) - mesh.normalIndexOffset;
++normalIndexCount; ++normalIndexCount;
} }
@ -459,7 +469,7 @@ Containers::Optional<MeshData> ObjImporter::doMesh(UnsignedInt id, UnsignedInt)
{ {
Containers::StridedArrayView1D<Vector3> view{vertexData, Containers::StridedArrayView1D<Vector3> view{vertexData,
reinterpret_cast<Vector3*>(vertexData.data()), vertexCount, stride}; reinterpret_cast<Vector3*>(vertexData.data()), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[0].prefix(vertexCount), positions, view, positionIndexOffset)) if(!checkAndDuplicateInto(indicesPerAttribute[0].prefix(vertexCount), positions, view, mesh.positionIndexOffset))
return Containers::NullOpt; return Containers::NullOpt;
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Position, view}; attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Position, view};
offset += sizeof(Vector3); offset += sizeof(Vector3);
@ -467,7 +477,7 @@ Containers::Optional<MeshData> ObjImporter::doMesh(UnsignedInt id, UnsignedInt)
if(normalIndexCount) { if(normalIndexCount) {
Containers::StridedArrayView1D<Vector3> view{vertexData, Containers::StridedArrayView1D<Vector3> view{vertexData,
reinterpret_cast<Vector3*>(vertexData.data() + offset), vertexCount, stride}; reinterpret_cast<Vector3*>(vertexData.data() + offset), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[1].prefix(vertexCount), normals, view, normalIndexOffset)) if(!checkAndDuplicateInto(indicesPerAttribute[1].prefix(vertexCount), normals, view, mesh.normalIndexOffset))
return Containers::NullOpt; return Containers::NullOpt;
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Normal, view}; attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::Normal, view};
offset += sizeof(Vector3); offset += sizeof(Vector3);
@ -475,7 +485,7 @@ Containers::Optional<MeshData> ObjImporter::doMesh(UnsignedInt id, UnsignedInt)
if(textureCoordinateIndexCount) { if(textureCoordinateIndexCount) {
Containers::StridedArrayView1D<Vector2> view{vertexData, Containers::StridedArrayView1D<Vector2> view{vertexData,
reinterpret_cast<Vector2*>(vertexData.data() + offset), vertexCount, stride}; reinterpret_cast<Vector2*>(vertexData.data() + offset), vertexCount, stride};
if(!checkAndDuplicateInto(indicesPerAttribute[2].prefix(vertexCount), textureCoordinates, view, textureCoordinateIndexOffset)) if(!checkAndDuplicateInto(indicesPerAttribute[2].prefix(vertexCount), textureCoordinates, view, mesh.textureCoordinateIndexOffset))
return Containers::NullOpt; return Containers::NullOpt;
attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::TextureCoordinates, view}; attributeData[attributeIndex++] = MeshAttributeData{MeshAttribute::TextureCoordinates, view};
offset += sizeof(Vector2); offset += sizeof(Vector2);

Loading…
Cancel
Save