Files
ViewDesignEngine/include/vde/foundation/io_obj.h
T
茂之钳 4c9ee4f760
CI / Build & Test (push) Failing after 29s
CI / Release Build (push) Failing after 38s
docs: doxygen annotations for curves + mesh + sketch
2026-07-24 11:04:04 +00:00

111 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <string>
#include <vector>
#include "vde/foundation/math_types.h"
namespace vde::foundation {
/**
* @brief OBJ 文件解析结果数据结构
*
* 存储从 Wavefront OBJ 文件读取的完整几何数据,
* 包括顶点位置、纹理坐标、法线、面信息和材质分组。
*
* 内部索引均为 0-based,与文件中的 1-based 索引不同。
*
* @ingroup foundation
*/
struct ObjMeshData {
/// 顶点位置数组
std::vector<Point3D> vertices;
/// 纹理坐标数组(可能为空)
std::vector<Point2D> texcoords;
/// 顶点法线数组(可能为空)
std::vector<Vector3D> normals;
/**
* @brief 每个面的顶点索引列表(0-based)
*
* 无论文件中面的格式如何(纯顶点、"v/vt"、"v/vt/vn"),
* 此字段始终被填充。faces[i] 存储第 i 个面的所有顶点索引。
*/
std::vector<std::vector<int>> faces;
/**
* @brief 每个面的纹理坐标索引列表(0-based)
*
* 与 faces 数组长度相同;若无纹理数据则为空。
*/
std::vector<std::vector<int>> face_texcoords;
/**
* @brief 每个面的法线索引列表(0-based)
*
* 与 faces 数组长度相同;若无法线数据则为空。
*/
std::vector<std::vector<int>> face_normals;
/**
* @brief 每个面对应的材质名称
*
* face_materials[i] 给出第 i 个面使用的材质名。
* 材质名来源于 usemtl 指令,在定义后所有后续面使用该材质。
*/
std::vector<std::string> face_materials;
/// 是否有纹理坐标数据
[[nodiscard]] bool has_texcoords() const { return !texcoords.empty(); }
};
/**
* @brief 读取 Wavefront OBJ 文件
*
* 解析 ASCII OBJ 文件,支持以下 OBJ 特性:
* - v(顶点)、vt(纹理坐标)、vn(法线)
* - f(面):支持三角面和任意多边形面
* - usemtl(材质名称)、g(组名)、o(对象名)
* - # 注释行
*
* @param filepath OBJ 文件路径
* @return 解析后的 ObjMeshData
*
* @throws std::runtime_error 若文件无法打开或格式错误
*
* @note 不解析 MTL 材质文件,仅记录 usemtl 指令中的材质名称
* @note 面索引在内部转换为 0-based;若文件中使用相对索引(负值),自动转换为正向
*
* @code{.cpp}
* auto data = read_obj("model.obj");
* std::cout << "Vertices: " << data.vertices.size() << "\n";
* std::cout << "Faces: " << data.faces.size() << "\n";
* @endcode
*
* @see write_obj, ObjMeshData
* @ingroup foundation
*/
ObjMeshData read_obj(const std::string& filepath);
/**
* @brief 写入 Wavefront OBJ 文件
*
* 将 ObjMeshData 以 ASCII OBJ 格式写出,包含顶点、纹理坐标、
* 法线和面信息。材质名称通过注释嵌入。
*
* @param filepath 输出文件路径
* @param data 要写出的网格数据
*
* @note 输出的面索引为 1-basedOBJ 标准)
*
* @code{.cpp}
* ObjMeshData data;
* // ... 填充 data ...
* write_obj("output.obj", data);
* @endcode
*
* @see read_obj
* @ingroup foundation
*/
void write_obj(const std::string& filepath, const ObjMeshData& data);
} // namespace vde::foundation