前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Draco使用笔记(1)——图形解压缩

Draco使用笔记(1)——图形解压缩

作者头像
charlee44
发布2022-05-19 12:51:31
6800
发布2022-05-19 12:51:31
举报
文章被收录于专栏:代码编写世界

目录

1. 概述

Draco是Google开发的图形压缩库,用于压缩和解压缩3D几何网格(geometric mesh)和点云(point cloud)。Draco还可以直接对obj或者ply格式的三维数据进行压缩和解压缩,甚至编译成wasm在浏览器端对glTF压缩和解压缩。

2. 详论

2.1. 工具

Draco编译完成后直接提供了压缩和解压缩的工具draco_decoder.exe和draco_encoder.exe。通过命令行,我们对某个已经压缩好的文件进行解压缩:

代码语言:javascript
复制
draco_decoder -i "D:/1.bin" -o "D:/1.ply"

2.2. 代码

如果需要用代码的方式实现,可以参考draco_decoder.exe中的源码,具体实现如下:

代码语言:javascript
复制
#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会得不到正确的顶点顺序。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 1. 概述
  • 2. 详论
    • 2.1. 工具
      • 2.2. 代码
      相关产品与服务
      文件存储
      文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档