Skip to content

Mesh IO: OBJ and PLY read/write #14

@csparker247

Description

@csparker247

Track ID: mesh-io_20260323

Summary

Provide OBJ and PLY reader/writer functions for Mesh, supporting vertex normals, vertex colors, N-gon faces, and a single UV-mapped texture image per mesh. Readers/writers use if constexpr + C++17 detection idiom to silently skip attributes the target mesh type does not carry.

Dependencies

Acceptance Criteria

  • readOBJ / writeOBJ: positions, N-gon faces, per-wedge UVs (via UVMap), vertex normals (if WithNormal), vertex colors (if WithColor); MTL texture path returned from reader
  • readPLY / writePLY: positions, N-gon faces, vertex normals (if WithNormal), vertex colors (if WithColor); ASCII write, ASCII + binary-LE read
  • writePLY(path, mesh, uvmap) overload: seam-expansion adapter duplicates vertices at UV seam edges to produce per-vertex UVs; round-trip vertex count loss documented
  • All reader/writer functions are templates over MeshT; absent traits handled via if constexpr — no runtime branching
  • Round-trip tests for all attribute combinations (OBJ and PLY)
  • C++17 compatible; headers under io/

Implementation Plan

Phase 1: Trait Detection Infrastructure

  • Task 1.1: Tests for has_normal<V> / has_color<V> (compile-time static_assert)
  • Task 1.2: include/educelab/core/types/detail/MeshTraits.hpp with std::void_t detection helpers

Phase 2: OBJ IO

  • Task 2.1: Round-trip tests for all OBJ attribute combinations
  • Task 2.2: writeOBJ(path, mesh)
  • Task 2.3: writeOBJ(path, mesh, uvmap) overload
  • Task 2.4: readOBJ(path, mesh)
  • Task 2.5: readOBJ(path, mesh, uvmap) overload
  • Task 2.6: Register in CMakeLists

Phase 3: PLY IO

  • Task 3.1: Tests for expandAtSeams(mesh, uvmap)
  • Task 3.2: expandAtSeams in utils/MeshUtils.hpp
  • Task 3.3: Round-trip tests for all PLY attribute combinations
  • Task 3.4: writePLY(path, mesh)
  • Task 3.5: writePLY(path, mesh, uvmap) — calls expandAtSeams internally
  • Task 3.6: readPLY(path, mesh) — ASCII + binary-LE

Notes

  • expandAtSeams belongs in utils/MeshUtils.hpp (not the IO layer) — also useful for GPU vertex buffer upload
  • PLY UV round-trip loss: written mesh may have more vertices than the original due to seam expansion; geometry is lossless but seam topology is not recoverable
  • MTL parsing covers map_Kd only; full material support is out of scope
  • Multiple UV channels / texture images per mesh: future feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions