PLY模型格式详解【3D】
本文介绍PLY 多边形文件格式,这是一种用于存储被描述为多边形集合的图形对象。 PLY文件格式的目标是提供一种简单且易于实现但通用的格式足以适用于各种模型。 PLY有两种子格式:易于入门的 ASCII 表示形式和用于紧凑存储和快速保存和加载的二进制格式。 我们希望这种格式将促进程序之间以及人群之间的图形对象的交换。
如果需要将gltf、fbx、obj、dae等格式的3D模型转换到PLY格式,可以使用这个在线的 3D模型格式转换 工具。
1、PLY格式概述
任何在计算机图形领域工作过一段时间的人时间知道图形存储格式的令人眼花缭乱的阵列对象。 似乎每个程序员、每个新的编程项目都创建一种新的文件格式。
走出这个泥沼的出路是创建一个足够灵活的单一文件格式预测未来的需求,这很简单,以免被赶走潜在用户。 一旦定义了这样的格式,就会出现一套实用程序可以围绕这个格式编写。 添加到套件中的每个新实用程序都可以利用其他人的成果。
PLY 格式将对象描述为顶点、面和其他元素,以及颜色和法线方向等可以附加到这些元素上的属性。PLY 文件包含恰好是一个对象的以下描述。
此类对象的来源包括:手工数字化对象,来自建模程序的多边形对象、范围数据、行进立方体三角化(体积数据的等值面)、地形数据、光能传递模型等。
可能与对象一起存储的属性包括:颜色、表面法线、纹理坐标、透明度、范围数据置信度,以及多边形正面和背面的不同属性。
PLY 格式并非旨在作为一般场景描述语言、着色语言或包罗万象的建模格式。 这意味着它不包括变换矩阵、对象实例化、建模层次结构或对象子部分。
典型的 PLY 对象定义只是 (x,y,z) 三元组的顶点列表和面列表,由列表中的索引描述顶点。 大多数 PLY 文件都包含此核心信息。 顶点和面是“元素”的两个示例,PLY 文件的大部分内容是其列表元素。 给定文件中的每个元素都有固定数量的“属性”
为每个元素指定。
PLY 文件中的典型信息只包含两个元素,顶点的 (x,y,z) 三元组和每个面的顶点索引。 应用程序可以创建附加到对象元素的新属性。 例如,红色、绿色和蓝色的属性通常与顶点元素相关。 添加新的属性时,旧程序不应被中断,解释不了的可以被丢弃。
此外,还可以创建一个新元素类型并定义与该元素关联的属性。 新元素的例子是边、单元(指向面的指针列表)和材质(环境、漫反射和镜面反射颜色和系数)。 新元素还可以被不理解它们的程序携带或丢弃。
2、PLY文件结构
这是典型 PLY 文件的结构:
- 标头
- 顶点列表
- 面列表
- 其他元素的列表
标头是一系列以回车符结尾的文本行,描述文件的其余部分。 标头包含每个的描述
元素类型,包括元素的名称(例如 edge),有多少个这样的元素位于对象中,以及关联的各种属性的列表与元素。 标头还表明该文件是二进制文件还是 ASCII 文件。标头后面是每种元素类型的元素列表,按照表头中描述的顺序出现。
以下是一个立方体模型的完整 ASCII 描述。 同一对象的二进制文件的标头
仅仅是用 binary_little_endian或 binary_big_endian 代表单词 ascii。 这
括号中的注释不是文件的一部分,它们是对此示例的注释。 文件中的注释是普通的关键字标识行,以 comment 开头。
ply
format ascii 1.0 { ascii/binary, format version number }
comment made by anonymous { comments keyword specified, like all lines }
comment this file is a cube
element vertex 8 { define "vertex" element, 8 of them in file }
property float32 x { vertex contains float "x" coordinate }
property float32 y { y coordinate is also a vertex property }
property float32 z { z coordinate, too }
element face 6 { there are 6 "face" elements in the file }
property list uint8 int32 vertex_index { "vertex_indices" is a list of ints }
end_header { delimits the end of the header }
0 0 0 { start of vertex list }
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
4 0 1 2 3 { start of face list }
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
这个示例演示了标头的基本组成部分。 各部分标头是一个以关键词开头、以回车符结尾的 ASCII 字符串,甚至标题的开始和结束( ply和 end_header)也采用这种形式。
字符 ply必须是文件的前四个字符,因为它们是文件的魔力数字。 标题开头之后是关键字 format和ASCII 或二进制格式的规范,后跟版本数字。 接下来是多边形中各个元素的描述,并且在每个元素描述中是规范特性。 通用元素描述具有以下形式:
element <element-name> <number-in-file>
property <data-type> <property-name-1>
property <data-type> <property-name-2>
property <data-type> <property-name-3>
...
element行后面列出的属性定义了属性的数据类型以及该属性在每个元素中出现的顺序。属性可能具有三种数据类型:标量、字符串和列表。 以下是属性可能具有的标量数据类型的列表:
name | type | number of bytes |
---|---|---|
int8 | character | 1 |
uint8 | unsigned character | 1 |
int16 | short integer | 2 |
uint16 | unsigned short integer | 2 |
int32 | integer | 4 |
uint32 | unsigned integer | 4 |
float32 | single-precision float | 4 |
float64 | double-precision float | 8 |
这些字节数很重要,并且在不同的实现中不得有所不同以保证这些文件可移植。 有一种特殊形式的属性定义使用列表数据类型:
property list <numerical-type> <numerical-type> <property-name>
上面的立方体数据集文件中的一个示例:
property list uint8 int32 vertex_index
这意味着属性 vertex_index 首先包含一个无符号字符标识属性包含多少个索引,后跟一个包含的证书列表。 这个可变长度列表中的每个整数都是一个顶点的索引。
3、PLY文件的另一个例子
这是另一个立方体定义:
ply
format ascii 1.0
comment author: anonymous
comment object: another cube
element vertex 8
property float32 x
property float32 y
property float32 z
property red uint8 { start of vertex color }
property green uint8
property blue uint8
element face 7
property list uint8 int32 vertex_index { number of vertices for each face }
element edge 5 { five edges in object }
property int32 vertex1 { index to first vertex of edge }
property int32 vertex2 { index to second vertex }
property uint8 red { start of edge color }
property uint8 green
property uint8 blue
end_header
0 0 0 255 0 0 { start of vertex list }
0 0 1 255 0 0
0 1 1 255 0 0
0 1 0 255 0 0
1 0 0 0 0 255
1 0 1 0 0 255
1 1 1 0 0 255
1 1 0 0 0 255
3 0 1 2 { start of face list, begin with a triangle }
3 0 2 3 { another triangle }
4 7 6 5 4 { now some quadrilaterals }
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0
0 1 255 255 255 { start of edge list, begin with white edge }
1 2 255 255 255
2 3 255 255 255
3 0 255 255 255
2 0 0 0 0 { end with a single black line }
该文件为每个顶点指定红色、绿色和蓝色值。 为说明 vertex_index 的可变长度性质,对象的前两个面是三角形而不是正方形。 这意味着对象的面数为 7。
该对象还包含一个边的列表。 每条边都包含两个指向边的顶点的指针。 每个边也有一种颜色。 上面定义的五个边突出显示文件中的两个三角形。 前4条边是白色的,它们围绕着两个三角形。 最终的边是黑色,它是分隔三角形的边。
4、PLY自定义元素
上面的例子展示了三个元素的使用:顶点、面和边。 PLY 格式还允许用户定义自己的元素。
定义新元素的格式与定义顶点、边和面完全相同。 这是定义材质属性的标头:
element material 6
property ambient_red uint8 { ambient color }
property ambient_green uint8
property ambient_blue uint8
property ambient_coeff float32
property diffuse_red uint8 { diffuse color }
property diffuse_green uint8
property diffuse_blue uint8
property diffuse_coeff float32
property specular_red uint8 { specular color }
property specular_green uint8
property specular_blue uint8
property specular_coeff float32
property specular_power float32 { Phong power }
这些行将直接出现在标题中的顶点、面和边的规范之后。 如果我们希望每个顶点都有一个材质,我们可以将此行添加到顶点属性的末尾:
property material_index int32
这个整数是文件中包含的材质列表的索引。对于一个新应用程序的作者来说,发明几个要存储在 PLY 文件中的元素可能很吸引人。这种做法应该保持克制。 更好的方法是尝试调整常见元素(顶点、面、边、材质)到新用途,以便其他理解这些的程序elements 可能有助于操作这些元素。
例如,一个将分子描述为球体和柱体集合的应用程序, 为PLY增加包含分子的 球体和圆柱体元素的定义是很诱人的。 但是,如果我们使用顶点和边为此目的的元素(为每个元素添加半径属性),我们可以继续这些旧的程序。 显然不应为三角形和四边形创建特殊元素,而是使用face 元素。
原文链接:原文链接 — BimAnt
相关文章:

PLY模型格式详解【3D】
本文介绍PLY 多边形文件格式,这是一种用于存储被描述为多边形集合的图形对象。 PLY文件格式的目标是提供一种简单且易于实现但通用的格式足以适用于各种模型。 PLY有两种子格式:易于入门的 ASCII 表示形式和用于紧凑存储和快速保存和加载的二进制格式。 …...

Java的反射机制、Lambda表达式和枚举
Java的反射机制、Lambda表达式和枚举 文章目录 Java的反射机制、Lambda表达式和枚举1.反射机制反射的概念、用途、优缺点反射相关的类及使用(重要!!)相关类Class类:代表类实体,表示类和接口Field类…...

数据结构:堆的实现
1.堆的概念 如果有一个关键码的集合 K { k1 ,k2 ,k3 ,…,kn },把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并且 k(i) < k(i*21) 和 k(i) < k(i*22), i 0 ÿ…...
zabbix-6.4 监控 MySQL
目录 1、rpm安装zabbix_agentd服务 2、编写zabbix_agentd.conf文件 3、编写模板文件 4、创建mysql用户并赋权限 5、创建.my.cnf文件 6、将规则添加到SELinux策略中 注意: 若模板无法读取.my.cnf 信息,从而导致监控报错,可以尝试修改模…...

深入探索:解读创意的力量——idea的下载、初步使用
目录 编辑 1.IDEA的简介 2.IDEA的下载 2.1下载路径https://www.jetbrains.com/zh-cn/idea/download/?sectionwindows编辑 2.2下载的步骤 3 idea的初步使用 3.1新建一个简单的Java项目 3.1.1首先需要创建一个新的工程 3.1.2创建一个新的项目(模块&am…...

Redis详解
Redis 简介 Redis(Remote Dictionary Server)是一个开源的高性能键值对存储数据库,最初由 Salvatore Sanfilippo 开发,它在内存中存储数据,并提供了持久化功能,可以将数据保存到磁盘中,是一种N…...

【Linux】高级IO
目录 IO的基本概念 钓鱼五人组 五种IO模型 高级IO重要概念 同步通信 VS 异步通信 阻塞 VS 非阻塞 其他高级IO 阻塞IO 非阻塞IO IO的基本概念 什么是IO? I/O(input/output)也就是输入和输出,在著名的冯诺依曼体系结构当中…...
动态HTTP代理与竞争情报收集的关联
Hey,各位爬友们!作为一名专业的爬虫HTTP代理提供者,今天我要和大家聊一聊动态HTTP代理与竞争情报收集之间的关联。在这篇文章中,我将向大家解释怎么使用动态HTTP代理完成在竞争中的情报收集,并分享一些实用的技巧。 首…...

kafka基本概念及操作
kafka介绍 Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的 (replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各…...

分享个试卷去笔迹什么软件,几个步骤轻松擦除
试卷擦去笔迹是一项非常关键的技能,它可以帮助你更好地管理你的笔记和文件。不管是小伙伴们想重新测试试卷或者是将试卷输出为电子版,都可以实现的。在这篇文章中,我将分享一些方法和软件,帮助你更好地进行试卷擦除。有需要的小伙…...

ClickHouse(十八):Clickhouse Integration系列表引擎
进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容! 🏡个人主页:含各种IT体系技术,IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证-CSDN博客 &…...

日常BUG——代码提交到了本地但是没有push,删除了本地分支如何恢复
😜作 者:是江迪呀✒️本文关键词:日常BUG、BUG、问题分析☀️每日 一言 :存在错误说明你在进步! 一、问题描述 代码在本地提交了,但是没有push到远程,然后删除了本地的分支。想要恢…...

Markdown语法
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Markdown语法目录 前言1.标题2.文本样式3.列表四.图片5.链接6.目录7.代码片7.表格8.注脚9.注释10.自定义列表11.LaTeX数学公式12.插入甘特图13.插入UML图14.插入Merimaid流程…...
vue3表格,编辑案例
index.vue <script setup> import { onMounted, ref } from "vue"; import Edit from "./components/Edit.vue"; import axios from "axios";// TODO: 列表渲染 const list ref([]); const getList async () > {const res await ax…...

SQL Server Reporting Services 报错:报表服务器无法访问服务帐户的私钥
解决这个问题,有小伙伴提到可以使用命令 exec DeleteEncryptedContent 但这对这边的环境时行不通的,我在【服务账户】的配置和【数据库】的配置中到使用了域账户,试了几次都不行。改成使用内置账户就好了。具体原因还没扒拉(欢迎…...

QT报表Limereport v1.5.35编译及使用
1、编译说明 下载后QT CREATER中打开limereport.pro然后直接编译就可以了。编译后结果如下图: 一次编译可以得到库文件和DEMO执行程序。 2、使用说明 拷贝如下图编译后的lib目录到自己的工程目录中。 release版本的重新命名为librelease. PRO文件中配置 QT …...

互联网发展历程:从中继器口不够到集线器的引入
互联网的发展,就像一场不断演进的技术盛宴,每一步的变革都在推动着我们的世界向前。然而,在网络的早期,一项重要的技术问题曾困扰着人们:当中继器的接口数量不足时,如何连接更多的设备?这时&…...

vue+flask基于知识图谱的抑郁症问答系统
vueflask基于知识图谱的抑郁症问答系统 抑郁症已经成为当今社会刻不容缓需要解决的问题,抑郁症的危害主要有以下几种:1.可导致病人情绪低落:抑郁症的病人长期处于悲观的状态中,感觉不到快乐,总是高兴不起来。2.可导致工…...
操作格子---算法集
问题描述 有 n 个格子,从左到右放成一排,编号为 1-n。 共有 m 次操作,有 3 种操作类型: 1.修改一个格子的权值。 2.求连续一段格子权值和。 3.求连续一段格子的最大值。 对于每个 2、3 操作输出你所求出的结果。 输入格式 第一行 …...

科研绘图chapter1:绘图原则与配色基础
本系列会持续更新,主要参考datawhale的开源课程。详见: https://github.com/datawhalechina/paper-chart-tutorial 文章目录 1.1 科研论文配图的绘制基础1.2 科研论文配图的配色基础1.2.1 配色模式1.2.2 色环配色原则1.3 配色工具/网站 1.1 科研论文配图…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...

如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...
深度解析:etcd 在 Milvus 向量数据库中的关键作用
目录 🚀 深度解析:etcd 在 Milvus 向量数据库中的关键作用 💡 什么是 etcd? 🧠 Milvus 架构简介 📦 etcd 在 Milvus 中的核心作用 🔧 实际工作流程示意 ⚠️ 如果 etcd 出现问题会怎样&am…...
计算机系统结构复习-名词解释2
1.定向:在某条指令产生计算结果之前,其他指令并不真正立即需要该计算结果,如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方,那么就可以避免停顿。 2.多级存储层次:由若干个采用不同实现技术的存储…...