深入了解.obj文件

一、.obj文件简介

OBJ文件是一种包含三维几何体信息的文件格式,它包括物体的位置、法线、纹理坐标和面信息。该格式最初是由AutoCAD创建的,现在被广泛用于3D图形应用程序中

OBJ文件是一种包含模型和材质数据的文本文件,其结构非常简单:文件头信息、顶点和法线、纹理坐标、面等。在OBJ文件中,每行都表示一个参数,用空格或者制表符分隔。这使得它成为一种简单、通用的格式,因为几乎任何3D图形软件都能读取和写入OBJ格式。因此,OBJ文件成为了3D图形软件间通用的桥梁。

二、.obj文件的结构

OBJ文件的结构由一系列的组成部分组成:

1.文件头

OBJ文件格式的第一行通常是格式说明。在这一行中,#代表注释(注释应该位于该行的开头),后面可以跟着一些数字或字母代表该文件的格式版本、作者等信息。

# This is a Wavefront OBJ file
# File created by Blender

2.顶点和法线

OBJ文件保存的每个物体顶点都以”v”开头的一行开始,后面跟着xyz三个浮点数表示三维位置坐标。此外,以”vn”开头的行代表了每个顶点的法向量。

# Vertex coordinates
v 0.0 0.0 0.0
v 1.0 0.0 0.0
v 0.0 1.0 0.0
vn 0.0 0.0 1.0
vn 0.0 0.0 1.0
vn 0.0 0.0 1.0

3.纹理坐标

使用”vt”开头的行表示每个顶点的纹理坐标。纹理坐标通常是二维的,以u,v两个浮点数表示。

# Texture coordinates
vt 0.0 0.0
vt 1.0 0.0
vt 0.0 1.0

4.面

面的定义以”f”开头的一行开始,后跟一系列整数表示该面顶点的索引号。索引号指向前面定义的顶点列表和纹理坐标列表。面的定义可以使用两种不同的格式表示:单个面和多重面。单个面只包含三个顶点,多重面可以包含任意数量的顶点。

# Face definitions
f 1/1/1 2/2/2 3/3/3
f 1/1/1 3/3/3 4/4/4

5.材质和组

OBJ文件格式还支持材质和组。使用”mtllib”定义材质库,使用”usemtl”定义使用材质,使用”g”定义物体组。

# Material definitions
mtllib example.mtl
usemtl red
usemtl green

# Object groups
g object1
g object2

三、示例代码

下面是一个读取并打印OBJ文件的C++函数示例:

#include 
#include 
#include 
#include 
#include 

struct Vec3 {
    float x, y, z;
};

struct Vec2 {
    float u, v;
};

struct TriangleIndex {
    int vertexIdx[3];
    int normalIdx[3];
    int texIdx[3];
};

std::vector vertices;
std::vector normals;
std::vector texCoords;
std::vector indices;

void loadObj(const std::string& filename) {
    std::ifstream file(filename);

    std::string line;

    while (std::getline(file, line)) {
        std::istringstream iss(line);

        char c;
        if (!(iss >> c))
            continue;

        switch (c) {
            case 'v':
                if (iss.peek() == 'n') {
                    Vec3 normal;
                    iss >> c;
                    iss >> normal.x;
                    iss >> normal.y;
                    iss >> normal.z;
                    normals.push_back(normal);
                } else if (iss.peek() == 't') {
                    Vec2 texCoord;
                    iss >> c;
                    iss >> texCoord.u;
                    iss >> texCoord.v;
                    texCoords.push_back(texCoord);
                } else {
                    Vec3 vertex;
                    iss >> vertex.x;
                    iss >> vertex.y;
                    iss >> vertex.z;
                    vertices.push_back(vertex);
                }
                break;

            case 'f': {
                TriangleIndex index;

                for (int i = 0; i > index.vertexIdx[i];
                    if (iss.peek() == '/') {
                        iss.ignore();
                        if (iss.peek() != '/') {
                            iss >> index.texIdx[i];
                        }
                        if (iss.peek() == '/') {
                            iss.ignore();
                            iss >> index.normalIdx[i];
                        }
                    }
                }

                indices.push_back(index);

                break;
            }
        }
    }
}

int main() {
    std::string filename = "example.obj";

    loadObj(filename);

    printf("Vertices:\n");
    for (const auto& v : vertices) {
        printf("%f %f %f\n", v.x, v.y, v.z);
    }

    printf("Normals:\n");
    for (const auto& n : normals) {
        printf("%f %f %f\n", n.x, n.y, n.z);
    }

    printf("Texture coordinates:\n");
    for (const auto& t : texCoords) {
        printf("%f %f\n", t.u, t.v);
    }

    printf("Faces:\n");
    for (const auto& i : indices) {
        printf("%d/%d/%d %d/%d/%d %d/%d/%d\n", i.vertexIdx[0], i.texIdx[0], i.normalIdx[0],
            i.vertexIdx[1], i.texIdx[1], i.normalIdx[1],
            i.vertexIdx[2], i.texIdx[2], i.normalIdx[2]);
    }

    return 0;
}

原创文章,作者:EAVKW,如若转载,请注明出处:https://www.506064.com/n/371105.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
EAVKWEAVKW
上一篇 2025-04-23 00:48
下一篇 2025-04-23 00:48

相关推荐

  • vue下载无后缀名的文件被加上后缀.txt,有后缀名的文件下载正常问题的解决

    本文旨在解决vue下载无后缀名的文件被加上后缀.txt,有后缀名的文件下载正常的问题,提供完整的代码示例供参考。 一、分析问题 首先,需了解vue中下载文件的情况。一般情况下,我们…

    编程 2025-04-29
  • 如何在Java中拼接OBJ格式的文件并生成完整的图像

    OBJ格式是一种用于表示3D对象的标准格式,通常由一组顶点、面和纹理映射坐标组成。在本文中,我们将讨论如何将多个OBJ文件拼接在一起,生成一个完整的3D模型。 一、读取OBJ文件 …

    编程 2025-04-29
  • Python程序文件的拓展

    Python是一门功能丰富、易于学习、可读性高的编程语言。Python程序文件通常以.py为文件拓展名,被广泛应用于各种领域,包括Web开发、机器学习、科学计算等。为了更好地发挥P…

    编程 2025-04-29
  • Python中读入csv文件数据的方法用法介绍

    csv是一种常见的数据格式,通常用于存储小型数据集。Python作为一种广泛流行的编程语言,内置了许多操作csv文件的库。本文将从多个方面详细介绍Python读入csv文件的方法。…

    编程 2025-04-29
  • 为什么用cmd运行Java时需要在文件内打开cmd为中心

    在Java开发中,我们经常会使用cmd在命令行窗口运行程序。然而,有时候我们会发现,在运行Java程序时,需要在文件内打开cmd为中心,这让很多开发者感到疑惑,那么,为什么会出现这…

    编程 2025-04-29
  • Python zipfile解压文件乱码处理

    本文主要介绍如何在Python中使用zipfile进行文件解压的处理,同时详细讨论在解压文件时可能出现的乱码问题的各种解决办法。 一、zipfile解压文件乱码问题的根本原因 在P…

    编程 2025-04-29
  • Python将矩阵存为CSV文件

    CSV文件是一种通用的文件格式,在统计学和计算机科学中非常常见,一些数据分析工具如Microsoft Excel,Google Sheets等都支持读取CSV文件。Python内置…

    编程 2025-04-29
  • Python如何导入py文件

    Python是一种开源的高级编程语言,因其易学易用和强大的生态系统而备受青睐。Python的import语句可以帮助用户将一个模块中的代码导入到另一个模块中,从而实现代码的重用。本…

    编程 2025-04-29
  • Python合并多个相同表头文件

    对于需要合并多个相同表头文件的情况,我们可以使用Python来实现快速的合并。 一、读取CSV文件 使用Python中的csv库读取CSV文件。 import csv with o…

    编程 2025-04-29
  • Python写文件a

    Python语言是一种功能强大、易于学习、通用并且高级编程语言,它具有许多优点,其中之一就是能够轻松地进行文件操作。文件操作在各种编程中都占有重要的位置,Python作为开发人员常…

    编程 2025-04-29

发表回复

登录后才能评论