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());
}
}
}
}

需要注意的就是两点:

  1. 传入draco::Decoder进行解压缩的需要二进制流,这个在从文件读取时一定要注意,很容易读成了文本流导致不能正常解压缩。
  2. 对draco::Mesh的解析。draco::Mesh的顶点属性中的buffer并不是顶点索引中存储的数据。这个时压缩算法决定的,解析Mesh时一定要按照实例中解析。直接解析顶点属性中的buffer会得不到正确的顶点顺序。

Draco使用笔记(1)——图形解压缩的更多相关文章

  1. ggplo2学习笔记——基本图形类型

    1.散点图:又称散点分布图,是以一个变量为恨坐标,另一个变量为纵坐标,利用散点(坐标点)的分布形态反映变量统计关系的一种图形.可以用来确认两个变量之间的关系.绘制自由曲线.矩阵关联分析等. 2.条形图 ...

  2. android学习笔记43——图形图像处理3——Path

    Path类 Path类可以预先在View上将N个点连成一条“路径”,然后调用Canavas的drawPath(path,paint)即可沿着路径绘制图形. android还为路径绘制提供了PathEf ...

  3. android学习笔记42——图形图像处理2——绘图

    绘图 android的绘图应该继承View组件,并重写onDraw(Canvas canvas)方法即可. 重写onDraw(Canvas canvas)方法时涉及一个绘图API:Canvas,Can ...

  4. R语言实战读书笔记(三)图形初阶

    这篇简直是白写了,写到后面发现ggplot明显更好用 3.1 使用图形 attach(mtcars)plot(wt, mpg) #x轴wt,y轴pgabline(lm(mpg ~ wt)) #画线拟合 ...

  5. Java学习笔记--Swing2D图形

    1.处理2D图形 要想使用java 2D库绘制图形,需要获得一个Graphics2D类对象.这个类是Graphics类的子类.paintComponent方法自动获得一个Graphics2D类对象,我 ...

  6. Java学习笔记--Java图形用户界面

    AWT:抽象窗口组件工具包 Abstract Windows Toolkit(AWT)是最原始的 Java GUI 工具包.AWT 的主要优点是,它在 Java 技术的每个版本上都成为了一种标准配置, ...

  7. [html] 学习笔记-Canvas图形绘制处理

    使用Canvas API 可以将一个图形重叠绘制在另外一个图形上,也可以给图形添加阴影效果. 1.Canvas 图形组合 通过 globalCompositeOperation = 属性 来指定重叠效 ...

  8. ggplot2学习笔记之图形排列

    转载:https://www.jianshu.com/p/d46cf6934a2f R语言基本绘图函数中可以利用par()以及layout()来进行图形排列,但是这两个函数对于ggplot图则不太适用 ...

  9. android学习笔记41——图形图像处理1

    图像图像处理 ImageView:用于显示普通静态图片: AnimationDrawable:用于开发逐帧动画: Animation:用于对普通图片使用补间动画: Bitmap.BitmapFacto ...

  10. Python学习笔记007_图形用户界面[EasyGui][Tkinter]

    EasyGui官网:http://easygui.sourceforge.net/ EasyGui最新版:easygui-0.97.rar 小甲鱼根据官网文档翻译之后的中文文档地址: http://b ...

随机推荐

  1. NW排错

    fist date VM备份失败时: NW server上(linux): > nsradmin >p type : nsr recover > cd /nsr/logs >n ...

  2. Fiddler安装,使用及汉化教程

    Fiddler安装及汉化教程 一.下载安装 1.下载 官网链接:https://www.telerik.com/download/fiddler 左侧填写用途,邮箱及城市,然后下载就可以 左侧下载即D ...

  3. 飞码LowCode前端技术系列(二):如何便捷配置出页面 | 京东云技术团队

    一.配置解法 飞码LowCode前端技术(一)中飞码提出了至少需要满足2个大能力点以及对应16个细化点.在业务复杂的场景下数据具有流转性质,事件的触发会改变数据.同时也会触发其他事件等情况.飞码使用数 ...

  4. AtCoder Beginner Contest 326 (ABC326)

    A. 2UP3DOWN 直接模拟即可. Code B. 326-like Numbers 枚举,每次拆除百.十.个位,再判断. Code C. Peak Description 数字线上放置了 \(N ...

  5. 快来让你的网页色彩绚丽--linear-gradient与radial-gradient

    作者:WangMin 格言:努力做好自己喜欢的每一件事 随着前端技术的发展,单一的背景色已经满足不了客户的需求了,所以在前端开发中我们常常会用到一些渐变色的效果,这样可以使前端页面更加美观.那么渐变色 ...

  6. 【PySide6】QChart笔记(一)—— 用QDateTimeAxis作为x轴绘制多条折线图

    一.QDateTimeAxis简介 1. 官方描述 https://doc.qt.io/qtforpython-6/PySide6/QtCharts/QDateTimeAxis.html QDateT ...

  7. 题解 CF637B

    题目大意: 维护个栈,去重保留最上层 题目分析: 啥也不是,数组模拟 \(\text{stack} + \text{unordered\_map}\) 直接秒掉. 复杂度 \(O(n)\) 代码实现: ...

  8. 理解Go中的零值

    在 Go 语言中,零值(Zero Value)是指在声明变量但没有显式赋值的情况下,变量会被自动赋予一个默认值.这个默认值取决于变量的类型,不同类型的变量会有不同的零值.零值是 Go 语言中的一个重要 ...

  9. 解密Prompt系列19. LLM Agent之数据分析领域的应用:Data-Copilot & InsightPilot

    在之前的 LLM Agent+DB 的章节我们已经谈论过如何使用大模型接入数据库并获取数据,这一章我们聊聊大模型代理在数据分析领域的应用.数据分析主要是指在获取数据之后的数据清洗,数据处理,数据建模, ...

  10. 手撕Vue-Router-初始化路由信息

    前言 经过上一节课的学习,我们已经完成了提取我们想要的路由信息数据格式,提取完毕了之后,接下来我们该干什么,接下来需要做的步骤就是监听路由的变化,保存当前的路由. 那么就会遇到几个问题,就是怎么监听, ...