SLPK bin 文件与draco 解压缩
SLPK bin 文件与draco 解压缩
- SLPK bin 文件与draco 解压缩
- 0.bin
- 1.bin
- draco 解压示例
- draco 压缩示例
- 参考
SLPK bin 文件与draco 解压缩
0.bin
SLPK 二进制0.bin 早前使用的几何文件存储格式,没有进行draco压缩处理。
- 4个字节 表示顶点的数量
- 顶点数据
- 法线数据
- 纹理数据
- 颜色数据
- FeatureId
- FaceRange

解析代码:
ifstream fin;fin.open("0.bin", ios::binary);if (!fin){cout << "open error!" << endl;return;}int vertexCount[1 * 1];fin.read((char*)vertexCount, sizeof(int) * (1 * 1));//从bin中读取顶点索引数量for (int i = 0; i < vertexCount[0]; i++){float Position[1 * 3];fin.read((char*)Position, sizeof(float) * (1 * 3));}for (int i = 0; i < vertexCount[0]; i++){float_t Normal[1 * 3];fin.read((char*)Normal, sizeof(float_t) * (1 * 3));}for (int i = 0; i < vertexCount[0]; i++){float_t Uv0[1 * 2];fin.read((char*)Uv0, sizeof(float_t) * (1 * 2));}for (size_t i = 0; i < vertexCount[0]; i++){uint8_t Color_x[1 * 4];fin.read((char*)Color_x, sizeof(uint8_t) * (1 * 4));}uint64_t FeatureId[1 * 1];fin.read((char*)FeatureId, sizeof(uint64_t) * (1 * 1));uint32_t FaceRange_start[1 * 1];fin.read((char*)FaceRange_start, sizeof(uint32_t) * (1 * 1));uint32_t FaceRange_end[1 * 1];fin.read((char*)FaceRange_end, sizeof(uint32_t) * (1 * 1));fin.close();
示例:

1.bin
SLPK 二进制1.bin 目前使用的几何文件存储格式,使用draco压缩处理。
直接使用drao库解压即可。
draco 解压示例
char* decodeBuffer(char* indata, int insize, int* outsize) {if (indata == nullptr || insize <= 0) {*outsize = 0;return nullptr;}std::string dracoGeometry(indata, insize);draco::DecoderBuffer buffer;buffer.Init(dracoGeometry.data(), dracoGeometry.size());std::unique_ptr<draco::PointCloud> pc;draco::Mesh* mesh;auto type_statusor = draco::Decoder::GetEncodedGeometryType(&buffer);if (!type_statusor.ok()) {*outsize = 0;return nullptr;}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()) {*outsize = 0;return nullptr;}std::unique_ptr<draco::Mesh> in_mesh = std::move(statusor).value();if (in_mesh) {mesh = in_mesh.get();pc = std::move(in_mesh);}}int realPointNum = mesh->num_points();int realFaceNum = mesh->num_faces();std::vector< int32_t> fids;//std::cout << "Point Num:" << realPointNum << std::endl;//std::cout << "Face Num:" << realFaceNum << std::endl;bool use_normal = false, use_uv = false, use_color = false, use_feature_id = false, use_uvregion = false;std::ostringstream outStr;outStr.write(reinterpret_cast<char*>(&realPointNum), sizeof(realPointNum));outStr.write(reinterpret_cast<char*>(&realFaceNum), sizeof(realFaceNum));const draco::PointAttribute* position_att =mesh->GetNamedAttribute(draco::GeometryAttribute::POSITION);const draco::PointAttribute* normal_att =mesh->GetNamedAttribute(draco::GeometryAttribute::NORMAL);if (normal_att != nullptr) {use_normal = true;}outStr.write(reinterpret_cast<char*>(&use_normal), sizeof(use_normal));//UVconst draco::PointAttribute* uv_att =mesh->GetNamedAttribute(draco::GeometryAttribute::TEX_COORD);if (uv_att != nullptr) {use_uv = true;}outStr.write(reinterpret_cast<char*>(&use_uv), sizeof(use_uv));//Colorconst draco::PointAttribute* clr_att =mesh->GetNamedAttribute(draco::GeometryAttribute::COLOR);if (clr_att != nullptr) {use_color = true;}outStr.write(reinterpret_cast<char*>(&use_color), sizeof(use_color));int fid_id = mesh->GetAttributeIdByMetadataEntry("i3s-attribute-type", "feature-index");const draco::PointAttribute* generic_att = mesh->GetAttributeByUniqueId(fid_id);if (generic_att && (generic_att->num_components() != 1 || generic_att->attribute_type() != draco::GeometryAttribute::Type::GENERIC)){generic_att = nullptr;}if (generic_att != nullptr) {use_feature_id = true;}outStr.write(reinterpret_cast<char*>(&use_feature_id), sizeof(use_feature_id));int region_id = mesh->GetAttributeIdByMetadataEntry("i3s-attribute-type", "uv-region");const draco::PointAttribute* region_att = mesh->GetAttributeByUniqueId(region_id);if (region_att && (region_att->num_components() != 4 || region_att->attribute_type() != draco::GeometryAttribute::Type::GENERIC)){region_att = nullptr;}if (region_att != nullptr) {use_uvregion = true;}outStr.write(reinterpret_cast<char*>(&use_uvregion), sizeof(use_uvregion));double i3sScaleX = 1.0, i3sScaleY = 1.0;if (position_att != nullptr) {//std::cout << "vertex count:" << realPointNum << std::endlauto pos_att = mesh->GetAttributeMetadataByAttributeId(mesh->GetNamedAttributeId(draco::GeometryAttribute::POSITION));if (pos_att){pos_att->GetEntryDouble("i3s-scale_x", &i3sScaleX);pos_att->GetEntryDouble("i3s-scale_y", &i3sScaleY);}std::array<float, 3>value;float x, y, z;for (draco::PointIndex i = draco::PointIndex(0); i < draco::PointIndex(realPointNum); ++i) {bool ret = position_att->ConvertValue(position_att->mapped_index(i), 3, &value[0]);if (!ret) {*outsize = 0;return nullptr;}else {x = value[0]*i3sScaleX;y = value[1]*i3sScaleY;z = value[2];outStr.write(reinterpret_cast<char*>(&x), sizeof(float));outStr.write(reinterpret_cast<char*>(&y), sizeof(float));outStr.write(reinterpret_cast<char*>(&z), sizeof(float));//std::cout << i << ":" <}}}else {*outsize = 0;return nullptr;}if (use_normal) {std::array<float, 3> value;for (draco::PointIndex i = draco::PointIndex(0); i < draco::PointIndex(realPointNum); ++i){bool ret = normal_att->ConvertValue(normal_att->mapped_index(i), 3, &value[0]);if (!ret) {value = { 0 };outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(float));outStr.write(reinterpret_cast<char*>(&value[1]), sizeof(float));outStr.write(reinterpret_cast<char*>(&value[2]), sizeof(float));}else {outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(float));outStr.write(reinterpret_cast<char*>(&value[1]), sizeof(float));outStr.write(reinterpret_cast<char*>(&value[2]), sizeof(float));}}}if (use_uv) {std::array<float, 2> value;for (draco::PointIndex i = draco::PointIndex(0); i < draco::PointIndex(realPointNum); ++i){bool ret = uv_att->ConvertValue(uv_att->mapped_index(i), 2, &value[0]);if (!ret) {value = { 0 };outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(float));outStr.write(reinterpret_cast<char*>(&value[1]), sizeof(float));}else {outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(float));outStr.write(reinterpret_cast<char*>(&value[1]), sizeof(float));}}}if (use_color) {std::array<uint8_t, 4>value;for (draco::PointIndex i = draco::PointIndex(0); i < draco::PointIndex(realPointNum); ++i){bool ret = clr_att->ConvertValue(clr_att->mapped_index(i), 4, &value[0]);if (!ret) {value = { 0 };outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(uint8_t));outStr.write(reinterpret_cast<char*>(&value[1]), sizeof(uint8_t));outStr.write(reinterpret_cast<char*>(&value[2]), sizeof(uint8_t));outStr.write(reinterpret_cast<char*>(&value[3]), sizeof(uint8_t));}else {outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(uint8_t));outStr.write(reinterpret_cast<char*>(&value[1]), sizeof(uint8_t));outStr.write(reinterpret_cast<char*>(&value[2]), sizeof(uint8_t));outStr.write(reinterpret_cast<char*>(&value[3]), sizeof(uint8_t));}}}//fidif (use_feature_id) {auto att_dmeta = mesh->GetMetadata()->GetAttributeMetadataByUniqueId(generic_att->unique_id());if (!generic_att || !att_dmeta->GetEntryIntArray("i3s-feature-ids", &fids)){}std::array<uint64_t, 1>value;for (draco::PointIndex i = draco::PointIndex(0); i < draco::PointIndex(realPointNum); ++i){bool ret = generic_att->ConvertValue(generic_att->mapped_index(i), 1, &value[0]);if (!ret) {value = { 0 };outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(uint64_t));}else {outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(uint64_t));//std::cout << i << ":" << value[0] << std::endl;}}}//UVRegionif (use_uvregion) {std::array<uint16_t, 4> value;for (draco::PointIndex i = draco::PointIndex(0); i < draco::PointIndex(realPointNum); ++i){bool ret = region_att->ConvertValue(region_att->mapped_index(i), 4, &value[0]);if (!ret) {value = { 0 };outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(uint16_t));outStr.write(reinterpret_cast<char*>(&value[1]), sizeof(uint16_t));outStr.write(reinterpret_cast<char*>(&value[2]), sizeof(uint16_t));outStr.write(reinterpret_cast<char*>(&value[3]), sizeof(uint16_t));}else {outStr.write(reinterpret_cast<char*>(&value[0]), sizeof(uint16_t));outStr.write(reinterpret_cast<char*>(&value[1]), sizeof(uint16_t));outStr.write(reinterpret_cast<char*>(&value[2]), sizeof(uint16_t));outStr.write(reinterpret_cast<char*>(&value[3]), sizeof(uint16_t));}}}//indexuint32_t numFaces = mesh->num_faces();uint32_t numIndices = numFaces * 3;std::vector<int64_t> my_Indicese;my_Indicese.resize(numIndices);for (draco::FaceIndex i(0); i < numFaces; ++i) {const draco::Mesh::Face& face = mesh->face(i);int64_t indexV = i.value();my_Indicese[indexV * 3] = face[0].value();my_Indicese[indexV * 3 + 1] = face[1].value();my_Indicese[indexV * 3 + 2] = face[2].value();}for (uint32_t i = 0; i < numIndices; ++i) {outStr.write(reinterpret_cast<char*>(&my_Indicese[i]), sizeof(uint32_t));}if (use_feature_id) {int32_t fc = fids.size();outStr.write(reinterpret_cast<char*>(&fc), sizeof(int32_t));for (size_t i = 0; i<fids.size(); i++) {outStr.write(reinterpret_cast<char*>(&fids[i]), sizeof(int32_t));}}outStr.write(reinterpret_cast<char*>(&i3sScaleX), sizeof(double));outStr.write(reinterpret_cast<char*>(&i3sScaleY), sizeof(double));*outsize = outStr.str().size();char* outdata = new char[*outsize];memcpy(outdata, outStr.str().data(), *outsize);return outdata;}
draco 压缩示例
将三维几何数据进行draco压缩。
char* encodeBuffer(char* indata, int insize, int* outsize,bool isGeo, bool hasregion) {std::string GeometryStr(indata,insize);std::istringstream inStr(GeometryStr,std::ios::binary);int realPointNum = 0;int realFaceNum = 0;inStr.read(reinterpret_cast<char*>(&realPointNum), sizeof(realPointNum));inStr.read(reinterpret_cast<char*>(&realFaceNum), sizeof(realFaceNum));bool use_normal = false, use_uv = false, use_color = false, use_feature_id = false, use_uvregion = false;inStr.read(reinterpret_cast<char*>(&use_normal), sizeof(use_normal));inStr.read(reinterpret_cast<char*>(&use_uv), sizeof(use_uv));inStr.read(reinterpret_cast<char*>(&use_color), sizeof(use_color));inStr.read(reinterpret_cast<char*>(&use_feature_id), sizeof(use_feature_id));inStr.read(reinterpret_cast<char*>(&use_uvregion), sizeof(use_uvregion));std::vector<Point>Points;Points.resize(realPointNum,{0.0f});for (int i = 0; i < realPointNum; i++) {inStr.read(reinterpret_cast<char*>(&Points[i][0]), sizeof(float));inStr.read(reinterpret_cast<char*>(&Points[i][1]), sizeof(float));inStr.read(reinterpret_cast<char*>(&Points[i][2]), sizeof(float));}std::vector<Normal>Normals;if (use_normal) {Normals.resize(realPointNum, { 0.0f });for (int i = 0; i < realPointNum; ++i) {//normalinStr.read(reinterpret_cast<char*>(&Normals[i][0]), sizeof(float));inStr.read(reinterpret_cast<char*>(&Normals[i][1]), sizeof(float));inStr.read(reinterpret_cast<char*>(&Normals[i][2]), sizeof(float));}}std::vector<UV0>UV0s;if (use_uv) {UV0s.resize(realPointNum, { 0.0f });for (int i = 0; i < realPointNum; ++i) {//uv0inStr.read(reinterpret_cast<char*>(&UV0s[i][0]), sizeof(float));inStr.read(reinterpret_cast<char*>(&UV0s[i][1]), sizeof(float));}}std::vector<Color>Colors;if (use_color) {Colors.resize(realPointNum, { 0 });for (int i = 0; i < realPointNum; ++i) {//colorsinStr.read(reinterpret_cast<char*>(&Colors[i][0]), sizeof(uint8_t));inStr.read(reinterpret_cast<char*>(&Colors[i][1]), sizeof(uint8_t));inStr.read(reinterpret_cast<char*>(&Colors[i][2]), sizeof(uint8_t));inStr.read(reinterpret_cast<char*>(&Colors[i][3]), sizeof(uint8_t));}}std::vector<FeatureId>FeatureIds;if (use_feature_id) {FeatureIds.resize(realPointNum, { 0 });for (int i = 0; i < realPointNum; ++i) {inStr.read(reinterpret_cast<char*>(&FeatureIds[i][0]), sizeof(uint64_t));//std::cout << i << ":" << FeatureIds[i][0] << std::endl;}}std::vector<UVRegion>UVRegions;if (use_uvregion) {UVRegions.resize(realPointNum, { 0 });for (int i = 0; i < realPointNum; ++i) {inStr.read(reinterpret_cast<char*>(&UVRegions[i][0]), sizeof(uint16_t));inStr.read(reinterpret_cast<char*>(&UVRegions[i][1]), sizeof(uint16_t));inStr.read(reinterpret_cast<char*>(&UVRegions[i][2]), sizeof(uint16_t));inStr.read(reinterpret_cast<char*>(&UVRegions[i][3]), sizeof(uint16_t));}}std::vector<Index>Indices;Indices.resize(realFaceNum * 3, { 0 });for (uint32_t i = 0; i < realFaceNum * 3; ++i) {inStr.read(reinterpret_cast<char*>(&Indices[i][0]), sizeof(uint32_t));}std::vector< int32_t> fids;if (use_feature_id) {int32_t fc = 0;inStr.read(reinterpret_cast<char*>(&fc), sizeof(int32_t));fids.resize(fc);for (int32_t i = 0; i < fc; i++) {inStr.read(reinterpret_cast<char*>(&fids[i]), sizeof(int32_t));}}double i3sScaleX = 1.0, i3sScaleY = 1.0;inStr.read(reinterpret_cast<char*>(&i3sScaleX), sizeof(double));inStr.read(reinterpret_cast<char*>(&i3sScaleY), sizeof(double));//draco encoder//std::unique_ptr pMesh(new draco::Mesh()); std::unique_ptr<draco::Mesh> pMesh_osg(new draco::Mesh());draco::Mesh* pMesh = pMesh_osg.get();uint64_t lVertNum = realPointNum;if (lVertNum == 0) {*outsize = 0;return nullptr;}pMesh->set_num_points(lVertNum);//positiondraco::GeometryAttribute pos_att;pos_att.Init(draco::GeometryAttribute::POSITION, nullptr, 3, draco::DT_FLOAT32, false,sizeof(float) * 3, 0);draco::PointAttribute pPointAttribute(pos_att);pPointAttribute.SetIdentityMapping();pPointAttribute.Reset(lVertNum);//normaldraco::GeometryAttribute norm_att;norm_att.Init(draco::GeometryAttribute::NORMAL, nullptr, 3, draco::DT_FLOAT32,false, sizeof(float) * 3, 0);draco::PointAttribute pNormalAttribute(norm_att);pNormalAttribute.SetIdentityMapping();pNormalAttribute.Reset(lVertNum);//uvdraco::GeometryAttribute tex_coord_att;tex_coord_att.Init(draco::GeometryAttribute::TEX_COORD, nullptr, 2, draco::DT_FLOAT32,false, sizeof(float) * 2, 0);draco::PointAttribute pTexCoordAtt(tex_coord_att);pTexCoordAtt.SetIdentityMapping();pTexCoordAtt.Reset(lVertNum);//colordraco::GeometryAttribute color_att;color_att.Init(draco::GeometryAttribute::COLOR, nullptr, 4, draco::DT_UINT8,false, sizeof(uint8_t) * 4, 0);draco::PointAttribute pColoratt(color_att);pColoratt.SetIdentityMapping();pColoratt.Reset(lVertNum);//FIddraco::GeometryAttribute gen_att;gen_att.Init(draco::GeometryAttribute::GENERIC, nullptr, 1, draco::DT_UINT32,false, sizeof(uint32_t) * 1, 0);draco::PointAttribute pfeature_index_att(gen_att);pfeature_index_att.SetIdentityMapping();pfeature_index_att.Reset(lVertNum);//UVRegiondraco::GeometryAttribute uv_regions;uv_regions.Init(draco::GeometryAttribute::GENERIC, nullptr, 4, draco::DT_UINT16,false, sizeof(uint16_t) * 4, 0);draco::PointAttribute puv_regions_att(uv_regions);puv_regions_att.SetIdentityMapping();puv_regions_att.Reset(lVertNum);float pts[3];for (uint64_t i = 0; i < lVertNum; i++){ pts[0] = Points[i][0]/i3sScaleX;pts[1] = Points[i][1]/i3sScaleY;pts[2] = Points[i][2];//std::cout << i << ":" << pts[0] << "," << pts[1] << "," << pts[2] << std::endl;pPointAttribute.SetAttributeValue(draco::AttributeValueIndex(i), &pts[0]);}const int pos_att_id_ = pMesh->AddAttribute(pPointAttribute, true, 0);std::unique_ptr<draco::AttributeMetadata> i3s_scale_metadata =std::unique_ptr<draco::AttributeMetadata>(new draco::AttributeMetadata());i3s_scale_metadata->AddEntryDouble("i3s-scale_x", i3sScaleX);i3s_scale_metadata->AddEntryDouble("i3s-scale_y", i3sScaleY);pMesh->AddAttributeMetadata(pos_att_id_, std::move(i3s_scale_metadata));int normal_att_id;if (use_normal) {for (uint64_t i = 0; i < lVertNum; i++){pNormalAttribute.SetAttributeValue(draco::AttributeValueIndex(i), &Normals[i][0]);}normal_att_id= pMesh->AddAttribute(pNormalAttribute, true, 0);}//colorint color_att_id;if (use_color) {for (uint64_t i = 0; i < lVertNum; ++i) {pColoratt.SetAttributeValue(draco::AttributeValueIndex(i), &Colors[i][0]);}color_att_id = pMesh->AddAttribute(pColoratt, true, 0);}//uvint tex_att_id;if (use_uv) {for (uint64_t i = 0; i < lVertNum; i++){pTexCoordAtt.SetAttributeValue(draco::AttributeValueIndex(i), &UV0s[i][0]);}tex_att_id = pMesh->AddAttribute(pTexCoordAtt, true, 0);}//fidint feature_index_att_id;if (use_feature_id) {uint64_t fi = 0;for (uint64_t i = 0; i < lVertNum; i++){ fi = FeatureIds[i][0];pfeature_index_att.SetAttributeValue(draco::AttributeValueIndex(i), &fi);//std::cout << i << ":" << fi << std::endl;}feature_index_att_id = pMesh->AddAttribute(pfeature_index_att, true, 0);std::unique_ptr<draco::AttributeMetadata> fid_meta(new draco::AttributeMetadata());fid_meta->set_att_unique_id(feature_index_att_id);fid_meta->AddEntryIntArray("i3s-feature-ids", fids);fid_meta->AddEntryString("i3s-attribute-type", "feature-index");pMesh->AddAttributeMetadata(feature_index_att_id, std::move(fid_meta));}//uv-regionint uv_regions_att_id;if (use_uvregion) {for (uint64_t i = 0; i < lVertNum; i++){puv_regions_att.SetAttributeValue(draco::AttributeValueIndex(i), &UVRegions[i][0]);}uv_regions_att_id = pMesh->AddAttribute(puv_regions_att, true, 0);std::unique_ptr<draco::AttributeMetadata> region_meta(new draco::AttributeMetadata());region_meta->set_att_unique_id(uv_regions_att_id);region_meta->AddEntryString("i3s-attribute-type", "uv-region");pMesh->AddAttributeMetadata(uv_regions_att_id, std::move(region_meta));}//idxfor (uint32_t ic = 0; ic * 3 < Indices.size(); ic++){uint32_t iIndex0 = Indices[ic * 3][0];uint32_t iIndex1 = Indices[ic * 3 + 1][0];uint32_t iIndex2 = Indices[ic * 3 + 2][0];draco::Mesh::Face face;face[0] = iIndex0;face[1] = iIndex1;face[2] = iIndex2;pMesh->AddFace(face);}int compression_level =7;//7const int speed = 10 - compression_level;draco::Encoder encoder;encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION,14);//14encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL,10);//10encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD,12);//12encoder.SetAttributeQuantization(draco::GeometryAttribute::COLOR,8);//10encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC,6);//8encoder.SetSpeedOptions(speed, speed);draco::EncoderBuffer buffer;try{draco::CycleTimer timer;timer.Start();const draco::Status status = encoder.EncodeMeshToBuffer(*pMesh, &buffer);if (!status.ok()) {printf("Failed to encode the mesh.\n");printf("%s\n", status.error_msg());*outsize = 0;return nullptr;}/*if (indata != nullptr) {delete[]indata;indata = nullptr;}*/timer.Stop();}catch (const std::exception& e){std::cout << "dracoGeo exception:"<<e.what() <<std::endl;*outsize = 0;return nullptr;}*outsize = buffer.size();char* outdata = new char[*outsize];memcpy(outdata, buffer.data(), *outsize);return outdata;
}
参考
- I3S slpk(一) 数据格式解析
- i3s 一种开源的三维地理数据规范 简单解读
- draco 解压缩示例
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
