python实现obj文件的3d预览

使用python实现obj模型的两种模式预览(片面图与附加纹理的3d预览)

 numpy 处理顶点数据,并通过 matplotlib 的 3D 功能可视化模型,使用 Poly3DCollection 绘制三角面片。

首先,我们需要知道,obj文件中都有些什么信息

        这是我从网上找的一个关于椅子的3d.obj文件


model.obj就是我们主要的文件了

obj文件中,包括(顶点坐标,面,纹理的uv映射和法线向量)这些信息要素

v代表的就是模型的顶点坐标

f代表的就是模型的面

vt代表的是纹理的uv映射

vn代表法线向量

一:解析文件

  • #解析obj文件中的信息,提取点面信息
    vertices = []
        faces = []
        with open(file_path, 'r') as f:
            for line in f:
                if line.startswith('v '):
                    parts = line.strip().split()
                    vertex = list(map(float, parts[1:4]))
                    vertices.append(vertex)
                elif line.startswith('f '):
                    parts = line.strip().split()
                    face = []
                    for part in parts[1:]:
                        vertex_index = part.split('/')[0]
                        face.append(int(vertex_index) - 1)
                    faces.append(face)
        return np.array(vertices), faces

二:创建画布与坐标系

 #创建画布与坐标系
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

三:生成面片信息

#生成面片数据
    mesh = []
    for face in faces:
        polygon = vertices[face, :]
        mesh.append(polygon)

 四:绘制三维的面片

#绘制三维的面片
    ax.add_collection3d(Poly3DCollection(
        mesh,
        facecolors='cyan',  #面片颜色
        linewidths=0.5,     #边线宽度
        edgecolors='black', #边线颜色
        alpha=0.4           #透明度
    ))

 

下面是代码:#生成的是面片的模型图

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import os
import numpy as np

def parse_obj(file_path):

    if not os.path.exists(obj_path):
        print(f"错误:文件不存在 - {obj_path}")
        exit()
    else:
        print("文件存在,继续解析...")

    #解析obj文件中的信息,提取点面信息
    vertices = []
    faces = []
    with open(file_path, 'r') as f:
        for line in f:
            if line.startswith('v '):
                parts = line.strip().split()
                vertex = list(map(float, parts[1:4]))
                vertices.append(vertex)
            elif line.startswith('f '):
                parts = line.strip().split()
                face = []
                for part in parts[1:]:
                    vertex_index = part.split('/')[0]
                    face.append(int(vertex_index) - 1)
                faces.append(face)
    return np.array(vertices), faces

def show_obj(vertices, faces):

    #创建画布与坐标系
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    #生成面片数据
    mesh = []
    for face in faces:
        polygon = vertices[face, :]
        mesh.append(polygon)

    #绘制三维的面片
    ax.add_collection3d(Poly3DCollection(
        mesh,
        facecolors='cyan',  #面片颜色
        linewidths=0.5,     #边线宽度
        edgecolors='black', #边线颜色
        alpha=0.4           #透明度
    ))

    #设置坐标轴的范围
    min_vals = vertices.min(axis=0)
    max_vals = vertices.max(axis=0)
    ax.auto_scale_xyz([min_vals[0], max_vals[0]],
                      [min_vals[1], max_vals[1]],
                      [min_vals[2], max_vals[2]])
    #坐标标签
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.show()



if __name__ == "__main__":
    obj_path = r"model.obj"
    vertices, faces = parse_obj(obj_path)
    show_obj(vertices, faces)

下面是生成带纹理的模型

mport trimesh

def load_and_render_obj_with_texture(obj_path):

    #加载带纹理的OBJ模型并渲染

    # 加载模型(自动解析纹理和材质)
    mesh = trimesh.load(obj_path, force='mesh')

    # 检查是否成功加载纹理
    if mesh.visual.kind != 'texture':
        print("警告:未找到纹理信息,将使用默认颜色渲染")
    else:
        print("纹理信息已加载")

    # 打印模型基本信息
    print(f"顶点数: {len(mesh.vertices)}")
    print(f"面数: {len(mesh.faces)}")
    print(f"纹理坐标数: {len(mesh.visual.uv)}")
    mesh.show()

if __name__ == "__main__":
    obj_path = r"model.obj"
    load_and_render_obj_with_texture(obj_path)

纹理信息已加载
顶点数: 7304
面数: 4574
纹理坐标数: 7304

下面是完整代码:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import os
import trimesh
import numpy as np

def parse_obj(file_path):

    if not os.path.exists(obj_path):
        print(f"错误:文件不存在 - {obj_path}")
        exit()
    else:
        print("文件存在,继续解析...")

    #解析obj文件中的信息,提取店面信息
    vertices = []
    faces = []
    with open(file_path, 'r') as f:
        for line in f:
            if line.startswith('v '):
                parts = line.strip().split()
                vertex = list(map(float, parts[1:4]))
                vertices.append(vertex)
            elif line.startswith('f '):
                parts = line.strip().split()
                face = []
                for part in parts[1:]:
                    vertex_index = part.split('/')[0]
                    face.append(int(vertex_index) - 1)
                faces.append(face)
    return np.array(vertices), faces

def show_obj(vertices, faces):

    #创建画布与坐标系
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    #生成面片数据
    mesh = []
    for face in faces:
        polygon = vertices[face, :]
        mesh.append(polygon)

    #绘制三维的面片
    ax.add_collection3d(Poly3DCollection(
        mesh,
        facecolors='cyan',  #面片颜色
        linewidths=0.5,     #边线宽度
        edgecolors='black', #边线颜色
        alpha=0.4           #透明度
    ))

    #设置坐标轴的范围
    min_vals = vertices.min(axis=0)
    max_vals = vertices.max(axis=0)
    ax.auto_scale_xyz([min_vals[0], max_vals[0]],
                      [min_vals[1], max_vals[1]],
                      [min_vals[2], max_vals[2]])
    #坐标标签
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.show()


def load_and_render_obj_with_texture(obj_path):

    #加载带纹理的OBJ模型并渲染

    # 加载模型(自动解析纹理和材质)
    mesh = trimesh.load(obj_path, force='mesh')

    # 检查是否成功加载纹理
    if mesh.visual.kind != 'texture':
        print("警告:未找到纹理信息,将使用默认颜色渲染")
    else:
        print("纹理信息已加载")

    # 打印模型基本信息
    print(f"顶点数: {len(mesh.vertices)}")
    print(f"面数: {len(mesh.faces)}")
    print(f"纹理坐标数: {len(mesh.visual.uv)}")
    mesh.show()




if __name__ == "__main__":
    obj_path = r"model.obj"
    vertices, faces = parse_obj(obj_path)
    show_obj(vertices, faces)
    load_and_render_obj_with_texture(obj_path)


文件存在,继续解析...
纹理信息已加载
顶点数: 7304
面数: 4574
纹理坐标数: 7304

模型来源https://free3d.io/

ps:第一次发文章,不便之处多多包涵

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值