Stanford PLY importer plugin.
Supports Little- and Big-Endian binary formats with triangle and quad meshes. Imports vertex positions, normals, 2D texture coordinates, vertex colors, custom attributes and per-face data as well.
This plugin depends on the Trade library and is built if
WITH_STANFORDIMPORTER is enabled when building Magnum Plugins. To use as a dynamic plugin, load
"StanfordImporter" via Corrade::
Additionally, if you're using Magnum as a CMake subproject, bundle the magnum-plugins repository and do the following:
set(WITH_STANFORDIMPORTER ON CACHE BOOL "" FORCE) add_subdirectory(magnum-plugins EXCLUDE_FROM_ALL) # So the dynamically loaded plugin gets built implicitly add_dependencies(your-app MagnumPlugins::StanfordImporter)
To use as a static plugin or as a dependency of another plugin with CMake, put FindMagnumPlugins.cmake into your
modules/ directory, request the
StanfordImporter component of the
MagnumPlugins package and link to the
find_package(MagnumPlugins REQUIRED StanfordImporter) # ... target_link_libraries(your-app PRIVATE MagnumPlugins::StanfordImporter)
In order to optimize for fast import, the importer supports a restricted subset of PLY features, which however shouldn't affect any real-world models.
- Both Little- and Big-Endian binary files are supported, with bytes swapped to match platform endianness. ASCII files are not supported due to the storage size overhead and inherent inefficiency of float literal parsing.
- Position coordinates (
z) are expected to have the same type, be tightly packed in a XYZ order and be either 32-bit floats or (signed) bytes or shorts. Resulting position type is then VertexFormat::
Vector3, VertexFormat:: Vector3ub, VertexFormat:: Vector3b, VertexFormat:: Vector3us or VertexFormat:: Vector3s. 32-bit integer and double positions are not supported.
- Normal coordinates (
nz) are expected to have the same type, be tightly packed in a XYZ order and be either 32-bit floats or signed bytes or shorts. Resulting normal type is then VertexFormat::
Vector3, VertexFormat:: Vector3bNormalized or VertexFormat:: Vector3sNormalized. 32-bit integer, unsigned and double normals are not supported.
- Texture coordinates (
t) are expected to have the same type, be tightly packed in a XY order and be either 32-bit floats or unsigned bytes or shorts. Resulting texture coordinate type is then VertexFormat::
Vector2, VertexFormat:: Vector2ubNormalized or VertexFormat:: Vector2usNormalized. Double texture coordinates are not supported, signed and 32.bit integer coordinates don't have a well-defined mapping to the range and thus are not supported either.
- Color channels (
alpha) are expected to have the same type, be tightly packed in a RGB or RGBA order and be either 32-bit floats or unsigned bytes/shorts. Tesulting color type is then VertexFormat::
Vector3 / VertexFormat:: Vector4, VertexFormat:: Vector3ubNormalized / VertexFormat:: Vector4ubNormalized or VertexFormat:: Vector3usNormalized / VertexFormat:: Vector4usNormalized. Signed, 32-bit integer and double colors are not supported.
- Per-vertex object ID attribute is imported as either VertexFormat::
UnsignedInt, VertexFormat:: UnsignedShort or VertexFormat:: UnsignedByte. By default
object_idis the recognized name, use the
objectIdAttributeconfiguration option to change the identifier that's being looked for. Because there are real-world files with signed object IDs, signed types are allowed as well, but interpreted as unsigned.
- Indices are imported as either MeshIndexType::
UnsignedByte, MeshIndexType:: UnsignedShort or MeshIndexType:: UnsignedInt. Quads are triangulated, but higher-order polygons are not supported. Because there are real-world files with signed indices, signed types are allowed for indices as well, but interpreted as unsigned (because negative values wouldn't make sense anyway).
The mesh is always indexed; positions are always present, other attributes are optional.
The importer recognizes ImporterFlag::
By default, if the mesh contains per-face attributes apart from indices, these get converted to per-vertex during import. This is what the users usually want, however for large meshes this may have a performance impact due to calculating only unique per-vertex/per-face data combinations. If this conversion takes place, the resulting index type is always MeshIndexType::
Alternatively, if the
perFaceToPerVertex configuration option is disabled, the importer provides access to per-face attributes in a second mesh level — i.e., meshLevelCount() returns
2 in that case, and calling mesh() with
level set to
1 will return a MeshData instance with MeshPrimitive::
From the builtin attributes, colors, normals and object IDs can be either per-vertex or per-face, positions and texture coordinates are always per-vertex.
Custom and unrecognized vertex and face attributes of known types are present in the imported meshes as well. Their mapping to/from a string can be queried using meshAttributeName() and meshAttributeForName(). Attributes with unknown types cause the import to fail, as the format relies on knowing the type size.
It's possible to tune various import options through configuration(). See below for all options and their default values:
[configuration] # Turn per-face attributes into per-vertex. If enabled, all attributes from the # file (including custom ones) are present in the triangle mesh, with the # additional cost of merging unique per-face attributes into vertices. If # disabled, per-face attributes are available in a separate mesh level. perFaceToPerVertex=true # Use a fast index import path when the file looks like it has only triangle # faces. This is significantly faster for large files but omits all face size # checks and thus might cause broken files to not be detected correctly in rare # cases. triangleFastPath=true # The non-standard MeshAttribute::ObjectId is by default recognized under this # name. Change if your file uses a different identifier. objectIdAttribute=object_id
- class AbstractImporter
- Base for importer plugins.