draco版本是Version 1.3.6
地址:
https://github.com/google/draco
压缩点信息,包括点的位置position、法线normal、颜色color和点云中的一个噪声noise
示例使用c++完成。
具体步骤
1、初始化变量和数据。
声明位置position、法线normal、颜色color和点云中的噪声noise的变量
std::vector<std::array<float, 3>> normals;//顶点
std::vector<std::array<float, 3>> positions;//法线
std::vector<std::array<unsigned char, 3>> colors;//颜色
std::vector<int> noises;//噪声
初始化数据,循环生成位置position、法线normal、颜色color和噪声noise
float x;
x = 0;
// create 30 points and normals
for (int i = 0; i < 30; i++) {
x = x + 0.01 * i;
x = x + 0.01 * i;
x = x + 0.01 * i;
positions.push_back({x, x, x});
normals.push_back({0, 1, 0});
colors.push_back({220, 132, 220});
noises.push_back(i);//噪声
}
2、将数据初始化到draco中
创建draco对象
std::unique_ptr<draco::PointCloud> dracoPointCloud(new draco::PointCloud());
dracoPointCloud->set_num_points(30);//设置要压缩的点个数
压缩顶点
int j;
int vertexCount = 30; // num
int componentCount = 3;
int byte_stride = sizeof(float) * componentCount;
draco::GeometryAttribute::Type att_type = draco::GeometryAttribute::POSITION;//设置压缩类型
draco::PointAttribute att;//创建压缩属性
att.Init(att_type, componentCount, draco::DT_FLOAT32, false, byte_stride);//初始化对象
int att_id = dracoPointCloud->AddAttribute(att, true, vertexCount);//添加到dracoPointCloud中
draco::PointAttribute *att_ptr = dracoPointCloud->attribute(att_id);//获取添加的对象
draco::PointIndex pointIndex(0);//一个计数
//将顶点数据添加到压缩属性att中
for (j = 0; j < 30; j++) {
std::array<float, 3> vIndex = positions[j];//顶点
std::vector<float> vertex_data(componentCount);
memcpy(&vertex_data[0], &(vIndex[0]), sizeof(float) * componentCount);//将顶点xyz保存到vertex_data中
att_ptr->SetAttributeValue(att_ptr->mapped_index(pointIndex), &vertex_data[0]);//顶点数据添加到压缩属性att中
pointIndex++;
}
添加法线数据
// NORMAL
vertexCount = 30; // num
componentCount = 3;
byte_stride = sizeof(float) * componentCount;
draco::GeometryAttribute::Type att_normal_type =
draco::GeometryAttribute::NORMAL;
draco::PointAttribute attNormal;
attNormal.Init(att_normal_type, componentCount, draco::DT_FLOAT32, false, byte_stride);
int att_normal_id =
dracoPointCloud->AddAttribute(attNormal, true, vertexCount);
draco::PointAttribute *att_normal_ptr =
dracoPointCloud->attribute(att_normal_id);
draco::PointIndex pointNormal(0);
for (j = 0; j < 30; j++) {
std::array<float, 3> vIndex = normals[j];
std::vector<float> vertex_data(componentCount);
memcpy(&vertex_data[0], &(vIndex[0]), sizeof(float) * componentCount);
att_normal_ptr->SetAttributeValue(att_normal_ptr->mapped_index(pointNormal),
&vertex_data[0]);
pointNormal++;
}
添加颜色数据
// color
vertexCount = 30; // num
componentCount = 3;
byte_stride = sizeof(unsigned char) * componentCount;
draco::GeometryAttribute::Type att_color_type =
draco::GeometryAttribute::COLOR;
draco::PointAttribute attColor;
attColor.Init(att_color_type, componentCount, draco::DT_INT8, false, byte_stride);
int att_color_id = dracoPointCloud->AddAttribute(attColor, true, vertexCount);
draco::PointAttribute *att_color_ptr = dracoPointCloud->attribute(att_color_id);
draco::PointIndex pointColor(0);
for (j = 0; j < 30; j++) {
std::array<unsigned char, 3> vIndex = colors[j];
std::vector<unsigned char> vertex_data(componentCount);
memcpy(&vertex_data[0], &(vIndex[0]), sizeof(unsigned char) * componentCount);
att_color_ptr->SetAttributeValue(att_color_ptr->mapped_index(pointColor),
&vertex_data[0]);
pointColor++;
}
添加噪声
// noises
vertexCount = 30; // num
componentCount = 1;
byte_stride = sizeof(int) * componentCount;
draco::GeometryAttribute::Type att_noise_type =
draco::GeometryAttribute::GENERIC;
draco::PointAttribute attNoise;
attNoise.Init(att_noise_type, componentCount, draco::DT_INT32, false, byte_stride);
int att_noise_id = dracoPointCloud->AddAttribute(attNoise, true, vertexCount);
draco::PointAttribute *att_noise_ptr = dracoPointCloud->attribute(att_noise_id);
draco::PointIndex noiseColor(0);
for (j = 0; j < 30; j++) {
int vIndex = noises[j];
std::vector<int> vertex_data;
vertex_data.push_back(vIndex);
att_noise_ptr->SetAttributeValue(att_noise_ptr->mapped_index(noiseColor),
&vertex_data[0]);
noiseColor++;
}
3、创建draco压缩对象
//设置压缩参数
const int dracoCompressionSpeed = 7;
const int dracoPositionBits = 14;
const int dracoNormalBits = 8;
const int dracoColorBits = 8;
const int dracoGenericBits = 12;
draco::EncoderBuffer dracoBuffer;//压缩后的数据存储到draco的缓冲区中
draco::Encoder encoder;//压缩对象
//设置压缩参数
encoder.SetSpeedOptions(dracoCompressionSpeed, dracoCompressionSpeed);
encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION,
dracoPositionBits);
encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL,
dracoNormalBits);
encoder.SetAttributeQuantization(draco::GeometryAttribute::COLOR,
dracoColorBits);
encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC,
dracoGenericBits);
//设置压缩方法
encoder.SetEncodingMethod(draco::PointCloudEncodingMethod::POINT_CLOUD_KD_TREE_ENCODING);
// draco::EncoderBuffer dracoBuffer1;
//压缩点、法线、颜色、噪声
const draco::Status status = encoder.EncodePointCloudToBuffer(*dracoPointCloud, &dracoBuffer);
4、获取压缩的数据
// dracoBuffer
if (!status.ok()) {
std::cout << "Error: Encode mesh.\n";
}
std::cout << "success\n";
std::cout << dracoBuffer.size() << std::endl;//压缩后的数据大小
std::cout << dracoBuffer.data() << std::endl;//压缩后的数据
//输出到文件中
if (!draco::WriteBufferToFile(dracoBuffer.data(), dracoBuffer.size(), "1.drc")) {
printf("Failed to write the output file.\n");
system("pause");
return -1;
}
运行结果如图
完整的代码:
//
// Created by asus on 2020/4/28.
//
#include <iostream>
#include <draco/core/status.h>
#include <draco/unity/draco_unity_plugin.h>
#include <draco/compression/encode.h>
#include <draco/io/file_utils.h>
#include <vector>
int main(int argc, char **argv) {
std::cout << "Hello, World!" << std::endl;
std::vector<std::array<float, 3>> normals;//顶点
std::vector<std::array<float, 3>> positions;//法线
std::vector<std::array<unsigned char, 3>> colors;//颜色
std::vector<int> noises;//噪声
float x;
x = 0;
// create 30 points and normals
for (int i = 0; i < 30; i++) {
x = x + 0.01 * i;
x = x + 0.01 * i;
x = x + 0.01 * i;
positions.push_back({x, x, x});
normals.push_back({0, 1, 0});
colors.push_back({220, 132, 220});
noises.push_back(i);//噪声
}
std::unique_ptr<draco::PointCloud> dracoPointCloud(new draco::PointCloud());
dracoPointCloud->set_num_points(30);//设置要压缩的点个数
// POSITION
int j;
int vertexCount = 30; // num
int componentCount = 3;
int byte_stride = sizeof(float) * componentCount;//每个顶点的步长,xyz坐标和数据大小,3*4 xyz是3每个是浮点型
draco::GeometryAttribute::Type att_type = draco::GeometryAttribute::POSITION;//设置压缩类型
draco::PointAttribute att;//创建压缩属性
att.Init(att_type, componentCount, draco::DT_FLOAT32, false, byte_stride);//初始化对象
int att_id = dracoPointCloud->AddAttribute(att, true, vertexCount);//添加到dracoPointCloud中
draco::PointAttribute *att_ptr = dracoPointCloud->attribute(att_id);//获取添加的对象
draco::PointIndex pointIndex(0);//一个计数
//将顶点数据添加到压缩属性att中
for (j = 0; j < 30; j++) {
std::array<float, 3> vIndex = positions[j];//顶点
std::vector<float> vertex_data(componentCount);
memcpy(&vertex_data[0], &(vIndex[0]), sizeof(float) * componentCount);//将顶点xyz保存到vertex_data中
att_ptr->SetAttributeValue(att_ptr->mapped_index(pointIndex), &vertex_data[0]);//顶点数据添加到压缩属性att中
pointIndex++;
}
// NORMAL
vertexCount = 30; // num
componentCount = 3;
byte_stride = sizeof(float) * componentCount;
draco::GeometryAttribute::Type att_normal_type =
draco::GeometryAttribute::NORMAL;
draco::PointAttribute attNormal;
attNormal.Init(att_normal_type, componentCount, draco::DT_FLOAT32, false, byte_stride);
int att_normal_id =
dracoPointCloud->AddAttribute(attNormal, true, vertexCount);
draco::PointAttribute *att_normal_ptr =
dracoPointCloud->attribute(att_normal_id);
draco::PointIndex pointNormal(0);
for (j = 0; j < 30; j++) {
std::array<float, 3> vIndex = normals[j];
std::vector<float> vertex_data(componentCount);
memcpy(&vertex_data[0], &(vIndex[0]), sizeof(float) * componentCount);
att_normal_ptr->SetAttributeValue(att_normal_ptr->mapped_index(pointNormal),
&vertex_data[0]);
pointNormal++;
}
// color
vertexCount = 30; // num
componentCount = 3;
byte_stride = sizeof(unsigned char) * componentCount;
draco::GeometryAttribute::Type att_color_type =
draco::GeometryAttribute::COLOR;
draco::PointAttribute attColor;
attColor.Init(att_color_type, componentCount, draco::DT_INT8, false, byte_stride);
int att_color_id = dracoPointCloud->AddAttribute(attColor, true, vertexCount);
draco::PointAttribute *att_color_ptr = dracoPointCloud->attribute(att_color_id);
draco::PointIndex pointColor(0);
for (j = 0; j < 30; j++) {
std::array<unsigned char, 3> vIndex = colors[j];
std::vector<unsigned char> vertex_data(componentCount);
memcpy(&vertex_data[0], &(vIndex[0]), sizeof(unsigned char) * componentCount);
att_color_ptr->SetAttributeValue(att_color_ptr->mapped_index(pointColor),
&vertex_data[0]);
pointColor++;
}
// noises
vertexCount = 30; // num
componentCount = 1;
byte_stride = sizeof(int) * componentCount;
draco::GeometryAttribute::Type att_noise_type =
draco::GeometryAttribute::GENERIC;
draco::PointAttribute attNoise;
attNoise.Init(att_noise_type, componentCount, draco::DT_INT32, false, byte_stride);
int att_noise_id = dracoPointCloud->AddAttribute(attNoise, true, vertexCount);
draco::PointAttribute *att_noise_ptr = dracoPointCloud->attribute(att_noise_id);
draco::PointIndex noiseColor(0);
for (j = 0; j < 30; j++) {
int vIndex = noises[j];
std::vector<int> vertex_data;
vertex_data.push_back(vIndex);
att_noise_ptr->SetAttributeValue(att_noise_ptr->mapped_index(noiseColor),
&vertex_data[0]);
noiseColor++;
}
//设置压缩参数
const int dracoCompressionSpeed = 7;
const int dracoPositionBits = 14;
const int dracoNormalBits = 8;
const int dracoColorBits = 8;
const int dracoGenericBits = 12;
draco::EncoderBuffer dracoBuffer;//压缩后的数据存储到draco的缓存区中
draco::Encoder encoder;//压缩对象
//设置压缩参数
encoder.SetSpeedOptions(dracoCompressionSpeed, dracoCompressionSpeed);
encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION,
dracoPositionBits);
encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL,
dracoNormalBits);
encoder.SetAttributeQuantization(draco::GeometryAttribute::COLOR,
dracoColorBits);
encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC,
dracoGenericBits);
//设置压缩方法
encoder.SetEncodingMethod(draco::PointCloudEncodingMethod::POINT_CLOUD_KD_TREE_ENCODING);
// draco::EncoderBuffer dracoBuffer1;
//压缩点法线颜色噪声
const draco::Status status = encoder.EncodePointCloudToBuffer(*dracoPointCloud, &dracoBuffer);
// dracoBuffer
if (!status.ok()) {
std::cout << "Error: Encode mesh.\n";
}
std::cout << "success\n";
std::cout << dracoBuffer.size() << std::endl;//压缩后的数据大小
std::cout << dracoBuffer.data() << std::endl;//压缩后的数据
//输出到文件中
if (!draco::WriteBufferToFile(dracoBuffer.data(), dracoBuffer.size(), "1.drc")) {
printf("Failed to write the output file.\n");
system("pause");
return -1;
}
system("pause");
return 0;
}
版权声明:本文为u014572215原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。