Draco使用笔记(1)——图形解压缩
1. 概述
Draco是Google开发的图形压缩库,用于压缩和解压缩3D几何网格(geometric mesh)和点云(point cloud)。Draco还可以直接对obj或者ply格式的三维数据进行压缩和解压缩,甚至编译成wasm在浏览器端对glTF压缩和解压缩。
2. 详论
2.1. 工具
Draco编译完成后直接提供了压缩和解压缩的工具draco_decoder.exe和draco_encoder.exe。通过命令行,我们对某个已经压缩好的文件进行解压缩:
draco_decoder -i "D:/1.bin" -o "D:/1.ply"
2.2. 代码
如果需要用代码的方式实现,可以参考draco_decoder.exe中的源码,具体实现如下:
#include <core/decoder_buffer.h>
#include <io/mesh_io.h>
#include <fstream>
#include <iostream>
using namespace draco;
using namespace std;
int main() {
string filePath = "D:/1.bin";
ifstream infile(filePath, ios::binary);
infile.seekg(0, std::ios::end);
size_t data_size = infile.tellg();
infile.seekg(0, std::ios::beg);
vector<char> data(data_size, 0);
infile.read(data.data(), data_size);
DecoderBuffer buffer;
buffer.Init(data.data(), data_size);
//解压缩
std::unique_ptr<draco::PointCloud> pc;
auto type_statusor = draco::Decoder::GetEncodedGeometryType(&buffer);
if (!type_statusor.ok()) {
return 1;
}
//解析数据
const draco::EncodedGeometryType geom_type = type_statusor.value();
if (geom_type == draco::TRIANGULAR_MESH) {
draco::Decoder decoder;
auto statusor = decoder.DecodeMeshFromBuffer(&buffer);
if (!statusor.ok()) {
return 1;
}
std::unique_ptr<draco::Mesh> mesh = std::move(statusor).value();
if (mesh) {
const int pos_att_id =
mesh->GetNamedAttributeId(GeometryAttribute::POSITION);
//解析顶点属性
for (PointIndex v(0); v < mesh->num_points(); ++v) {
const auto *const pos_att = mesh->attribute(pos_att_id);
const uint8_t *pos = pos_att->GetAddress(pos_att->mapped_index(v));
int64_t length = pos_att->byte_stride();
float temp[3];
memcpy(temp, pos, length);
printf("%f,%f,%f\t", temp[0], temp[1], temp[2]);
}
//解析顶点索引
for (FaceIndex f(0); f < mesh->num_faces(); ++f) {
printf("%d,%d,%d\t", mesh->face(f)[0].value(), mesh->face(f)[1].value(),
mesh->face(f)[2].value());
}
}
}
}
需要注意的就是两点:
- 传入draco::Decoder进行解压缩的需要二进制流,这个在从文件读取时一定要注意,很容易读成了文本流导致不能正常解压缩。
- 对draco::Mesh的解析。draco::Mesh的顶点属性中的buffer并不是顶点索引中存储的数据。这个时压缩算法决定的,解析Mesh时一定要按照实例中解析。直接解析顶点属性中的buffer会得不到正确的顶点顺序。
Draco使用笔记(1)——图形解压缩的更多相关文章
- ggplo2学习笔记——基本图形类型
1.散点图:又称散点分布图,是以一个变量为恨坐标,另一个变量为纵坐标,利用散点(坐标点)的分布形态反映变量统计关系的一种图形.可以用来确认两个变量之间的关系.绘制自由曲线.矩阵关联分析等. 2.条形图 ...
- android学习笔记43——图形图像处理3——Path
Path类 Path类可以预先在View上将N个点连成一条“路径”,然后调用Canavas的drawPath(path,paint)即可沿着路径绘制图形. android还为路径绘制提供了PathEf ...
- android学习笔记42——图形图像处理2——绘图
绘图 android的绘图应该继承View组件,并重写onDraw(Canvas canvas)方法即可. 重写onDraw(Canvas canvas)方法时涉及一个绘图API:Canvas,Can ...
- R语言实战读书笔记(三)图形初阶
这篇简直是白写了,写到后面发现ggplot明显更好用 3.1 使用图形 attach(mtcars)plot(wt, mpg) #x轴wt,y轴pgabline(lm(mpg ~ wt)) #画线拟合 ...
- Java学习笔记--Swing2D图形
1.处理2D图形 要想使用java 2D库绘制图形,需要获得一个Graphics2D类对象.这个类是Graphics类的子类.paintComponent方法自动获得一个Graphics2D类对象,我 ...
- Java学习笔记--Java图形用户界面
AWT:抽象窗口组件工具包 Abstract Windows Toolkit(AWT)是最原始的 Java GUI 工具包.AWT 的主要优点是,它在 Java 技术的每个版本上都成为了一种标准配置, ...
- [html] 学习笔记-Canvas图形绘制处理
使用Canvas API 可以将一个图形重叠绘制在另外一个图形上,也可以给图形添加阴影效果. 1.Canvas 图形组合 通过 globalCompositeOperation = 属性 来指定重叠效 ...
- ggplot2学习笔记之图形排列
转载:https://www.jianshu.com/p/d46cf6934a2f R语言基本绘图函数中可以利用par()以及layout()来进行图形排列,但是这两个函数对于ggplot图则不太适用 ...
- android学习笔记41——图形图像处理1
图像图像处理 ImageView:用于显示普通静态图片: AnimationDrawable:用于开发逐帧动画: Animation:用于对普通图片使用补间动画: Bitmap.BitmapFacto ...
- Python学习笔记007_图形用户界面[EasyGui][Tkinter]
EasyGui官网:http://easygui.sourceforge.net/ EasyGui最新版:easygui-0.97.rar 小甲鱼根据官网文档翻译之后的中文文档地址: http://b ...
随机推荐
- Oracle:字符串的拼接、截取、查找、替换
一.拼接:1.使用"||"来拼接字符串: select '拼接'||'字符串' as Str from dual; 2.使用concat(param1,param2)函数实现: s ...
- 手把手教你写一个JSON在线解析的前端网站1
前言 作为一名Android开发,经常要跟后端同事联调接口,那么总避免不了要格式化接口返回值,将其转换为清晰直观高亮的UI样式以及折叠部分内容,方便我们查看定位关键的信息. 一直以来都是打开Googl ...
- 快速掌握keepalived
转载请注明出处: Keepalived是一个基于VRRP(虚拟路由冗余协议)的开源软件,用于在Linux系统上实现高可用性和负载均衡.它的主要功能是通过多台服务器之间的协作,确保在其中一台服务器发生故 ...
- C++ STL标准容器的特点和典型的使用场景
概念和作用 C++标准模板库(Standard Template Library,STL)提供了一组通用的模板类和函数,用于处理常见的数据结构和算法.STL中的标准容器是其中的重要组成部分,它们提供了 ...
- umicv cv-summary1-全连接神经网络模块化实现
全连接神经网络模块化实现 Linear与Relu单层实现 LossLayer实现 多层神经网络 不同梯度下降方法 Dropout层 今天这篇博文针对Assignment3的全连接网络作业,对前面学习的 ...
- C++常见算法&数据结构模版
各种常见算法 & 数据结构模板 1. 最长不下降子序列(LIS) 1.1 \(O(n^2)\) 做法 点击查看代码 for (int i = 1;i <= n;i++) { cin &g ...
- 手撕Vuex-实现actions方法
经过上一篇章介绍,完成了实现 mutations 的功能,那么接下来本篇将会实现 actions 的功能. 本篇我先介绍一下 actions 的作用,然后再介绍一下实现的思路,最后再实现代码. act ...
- JAVA异常的不正确处理方式
最近收到一个求助信息,异常堆栈如下: ``` java.lang.RuntimeException: FF1C1005 at test_ssh.sftp.Pool.get(Pool.java:25) ...
- Java系列:Java8 新特性:强大的 Stream API(创建 Stream、中间操作、终止操作)
Java8中有两大最为重要的改变.第一个是 Lambda 表达式:另外一个则是 Stream API. Stream API ( java.util.stream) 把真正的函数式编程风格引入到Jav ...
- NLP文本生成全解析:从传统方法到预训练完整介绍
本文深入探讨了文本生成的多种方法,从传统的基于统计和模板的技术到现代的神经网络模型,尤其是LSTM和Transformer架构.文章还详细介绍了大型预训练模型如GPT在文本生成中的应用,并提供了Pyt ...