SLPK bin file unpacked with draco

SLPK bin file unpacked with draco

0.bin

SLPK Binary 0.binThe geometry file storage format used earlier, without dracocompression.

  • 4 bytes represent the number of vertices
  • vertex data
  • Normal data
  • texture data
  • color data
  • FeatureId
  • FaceRange
    insert image description here

Parsing code:

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

Example:
insert image description here

1.bin

SLPK Binary 1.binThe geometry file storage format currently used, using dracocompression processing.

Just use the drao library to decompress it.

draco decompression example


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));
	//UV
	const 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));
	//Color
	const 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::endl
		auto 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 << ":" <<x<<"," << y<<"," << z << std::endl;
			}
		}
	}
	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));
			}
		}
	}

	//fid
	if (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;
			}
		}
	}

	//UVRegion
	if (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));
			}
		}
	}
	//index
	uint32_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 compression example

Compress 3D geometry data 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) {
    
    
			//normal
			inStr.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) {
    
    
			//uv0
			inStr.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) {
    
    
			//colors
			inStr.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<draco::Mesh> 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);
	//position
	draco::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);

	//normal
	draco::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);

	//uv
	draco::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);
	//color
	draco::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);
	//FId
	draco::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);
	//UVRegion
	draco::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);
	}

	//color
	int 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);
	}

	//uv
	int 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);
	}
	
	//fid
	int 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-region
	int 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));
	}
	//idx
	for (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;//7
	const int speed = 10 - compression_level;
	draco::Encoder encoder;
	encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION,
		14);//14
	encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL,
		10);//10
	encoder.SetAttributeQuantization(draco::GeometryAttribute::TEX_COORD,
		12);//12
	encoder.SetAttributeQuantization(draco::GeometryAttribute::COLOR,
		8);//10
	encoder.SetAttributeQuantization(draco::GeometryAttribute::GENERIC,
		6);//8
	encoder.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;
}

reference

  1. I3S slpk (1) Data format analysis
  2. i3s is an open source 3D geographic data specification with a simple interpretation
  3. draco decompression example

Guess you like

Origin blog.csdn.net/mrbaolong/article/details/130527679