use draco_core::decoder_buffer::DecoderBuffer;
use draco_core::draco_types::DataType;
use draco_core::encoder_buffer::EncoderBuffer;
use draco_core::encoder_options::EncoderOptions;
use draco_core::geometry_attribute::{GeometryAttributeType, PointAttribute};
use draco_core::geometry_indices::{FaceIndex, PointIndex};
use draco_core::mesh::Mesh;
use draco_core::mesh_decoder::MeshDecoder;
use draco_core::mesh_encoder::MeshEncoder;
fn create_grid_mesh(width: u32, height: u32) -> Mesh {
let mut mesh = Mesh::new();
let num_points = width * height;
mesh.set_num_points(num_points as usize);
let mut pos_attr = PointAttribute::new();
pos_attr.init(
GeometryAttributeType::Position,
3,
DataType::Float32,
false,
num_points as usize,
);
for y in 0..height {
for x in 0..width {
let i = y * width + x;
let coords = [x as f32, y as f32, 0.0f32];
let offset = (i as usize) * 3 * 4;
pos_attr
.buffer_mut()
.update(&coords[0].to_le_bytes(), Some(offset));
pos_attr
.buffer_mut()
.update(&coords[1].to_le_bytes(), Some(offset + 4));
pos_attr
.buffer_mut()
.update(&coords[2].to_le_bytes(), Some(offset + 8));
}
}
mesh.add_attribute(pos_attr);
let mut face_idx = 0;
for y in 0..height - 1 {
for x in 0..width - 1 {
let p0 = y * width + x;
let p1 = y * width + (x + 1);
let p2 = (y + 1) * width + x;
let p3 = (y + 1) * width + (x + 1);
mesh.set_face(
FaceIndex(face_idx),
[PointIndex(p0), PointIndex(p1), PointIndex(p2)],
);
face_idx += 1;
mesh.set_face(
FaceIndex(face_idx),
[PointIndex(p1), PointIndex(p3), PointIndex(p2)],
);
face_idx += 1;
}
}
mesh.set_num_faces(face_idx as usize);
mesh
}
fn verify_mesh_attributes(original: &Mesh, decoded: &Mesh, max_error: f32) {
assert!(
decoded.num_points() >= original.num_points(),
"Decoded points {} < Original points {}",
decoded.num_points(),
original.num_points()
);
let orig_attr = original.attribute(0);
let dec_attr = decoded.attribute(0);
let orig_data = orig_attr.buffer().data();
let dec_data = dec_attr.buffer().data();
let mut decoded_points = Vec::new();
println!("Decoded Points (total: {}):", decoded.num_points());
for i in 0..decoded.num_points() {
let offset = i * 3 * 4;
let dx = f32::from_le_bytes(dec_data[offset..offset + 4].try_into().unwrap());
let dy = f32::from_le_bytes(dec_data[offset + 4..offset + 8].try_into().unwrap());
let dz = f32::from_le_bytes(dec_data[offset + 8..offset + 12].try_into().unwrap());
decoded_points.push([dx, dy, dz]);
}
let min_x = decoded_points
.iter()
.map(|p| p[0])
.fold(f32::INFINITY, f32::min);
let max_x = decoded_points
.iter()
.map(|p| p[0])
.fold(f32::NEG_INFINITY, f32::max);
let min_y = decoded_points
.iter()
.map(|p| p[1])
.fold(f32::INFINITY, f32::min);
let max_y = decoded_points
.iter()
.map(|p| p[1])
.fold(f32::NEG_INFINITY, f32::max);
println!(
" Point range: x=[{:.3}, {:.3}], y=[{:.3}, {:.3}]",
min_x, max_x, min_y, max_y
);
println!("Decoded point values (first 20):");
for (i, p) in decoded_points.iter().enumerate().take(20) {
println!(" Point {}: ({:.3}, {:.3}, {:.3})", i, p[0], p[1], p[2]);
}
println!("Decoded faces (total: {}):", decoded.num_faces());
for i in 0..std::cmp::min(5, decoded.num_faces()) {
let face = decoded.face(FaceIndex(i as u32));
println!(" Face {}: {:?}", i, face);
}
fn round_f32_to_i32(v: f32) -> i32 {
v.round() as i32
}
for i in 0..original.num_points() {
let offset = i * 3 * 4;
let ox = f32::from_le_bytes(orig_data[offset..offset + 4].try_into().unwrap());
let oy = f32::from_le_bytes(orig_data[offset + 4..offset + 8].try_into().unwrap());
let oz = f32::from_le_bytes(orig_data[offset + 8..offset + 12].try_into().unwrap());
let rox = round_f32_to_i32(ox);
let roy = round_f32_to_i32(oy);
let roz = round_f32_to_i32(oz);
let mut found = false;
for dp in &decoded_points {
if round_f32_to_i32(dp[0]) == rox
&& round_f32_to_i32(dp[1]) == roy
&& round_f32_to_i32(dp[2]) == roz
{
found = true;
break;
}
if (ox - dp[0]).abs() <= max_error
&& (oy - dp[1]).abs() <= max_error
&& (oz - dp[2]).abs() <= max_error
{
found = true;
break;
}
}
assert!(
found,
"Point {} ({}, {}, {}) not found in decoded mesh",
i, ox, oy, oz
);
}
}
#[test]
fn test_grid_encoding_parallelogram() {
let mesh = create_grid_mesh(5, 5);
let mut options = EncoderOptions::default();
options.set_global_int("encoding_method", 1); options.set_global_int("encoding_speed", 5); options.set_attribute_int(0, "quantization_bits", 10);
let mut encoder = MeshEncoder::new();
encoder.set_mesh(mesh.clone());
let mut buffer = EncoderBuffer::new();
encoder
.encode(&options, &mut buffer)
.expect("Encode failed");
println!("Parallelogram encoded size: {}", buffer.data().len());
let mut decoder = MeshDecoder::new();
let mut decoded_mesh = Mesh::new();
let mut decoder_buffer = DecoderBuffer::new(buffer.data());
decoder
.decode(&mut decoder_buffer, &mut decoded_mesh)
.expect("Decode failed");
verify_mesh_attributes(&mesh, &decoded_mesh, 0.01);
}
#[test]
fn test_grid_encoding_difference() {
let mesh = create_grid_mesh(10, 10);
let mut options = EncoderOptions::default();
options.set_global_int("encoding_method", 1); options.set_global_int("encoding_speed", 10); options.set_attribute_int(0, "quantization_bits", 14);
let mut encoder = MeshEncoder::new();
encoder.set_mesh(mesh.clone());
let mut buffer = EncoderBuffer::new();
encoder
.encode(&options, &mut buffer)
.expect("Encode failed");
println!("Difference encoded size: {}", buffer.data().len());
let mut decoder = MeshDecoder::new();
let mut decoded_mesh = Mesh::new();
let mut decoder_buffer = DecoderBuffer::new(buffer.data());
decoder
.decode(&mut decoder_buffer, &mut decoded_mesh)
.expect("Decode failed");
verify_mesh_attributes(&mesh, &decoded_mesh, 0.01);
}
#[test]
fn test_quantization_levels() {
let mesh = create_grid_mesh(5, 5);
let q_levels = [8, 10, 16];
for &q in &q_levels {
let mut options = EncoderOptions::default();
options.set_global_int("encoding_method", 1);
options.set_attribute_int(0, "quantization_bits", q);
let mut encoder = MeshEncoder::new();
encoder.set_mesh(mesh.clone());
let mut buffer = EncoderBuffer::new();
encoder
.encode(&options, &mut buffer)
.expect("Encode failed");
let mut decoder = MeshDecoder::new();
let mut decoded_mesh = Mesh::new();
let mut decoder_buffer = DecoderBuffer::new(buffer.data());
decoder
.decode(&mut decoder_buffer, &mut decoded_mesh)
.expect("Decode failed");
let range = 4.0;
let max_error = range / ((1 << q) as f32 - 1.0);
verify_mesh_attributes(&mesh, &decoded_mesh, max_error * 1.5);
}
}
#[test]
fn test_grid_encoding_sequential() {
let mesh = create_grid_mesh(10, 10);
let mut options = EncoderOptions::default();
options.set_global_int("encoding_method", 0); options.set_global_int("encoding_speed", 5); options.set_attribute_int(0, "quantization_bits", 14);
let mut encoder = MeshEncoder::new();
encoder.set_mesh(mesh.clone());
let mut buffer = EncoderBuffer::new();
encoder
.encode(&options, &mut buffer)
.expect("Encode failed");
println!("Sequential encoded size: {}", buffer.data().len());
let mut decoder = MeshDecoder::new();
let mut decoded_mesh = Mesh::new();
let mut decoder_buffer = DecoderBuffer::new(buffer.data());
decoder
.decode(&mut decoder_buffer, &mut decoded_mesh)
.expect("Decode failed");
verify_mesh_attributes(&mesh, &decoded_mesh, 0.002);
}